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/display.h"
44 #include "libavutil/mem.h"
45 #include "libavutil/opt.h"
46 #include "libavutil/aes.h"
47 #include "libavutil/aes_ctr.h"
48 #include "libavutil/pixdesc.h"
49 #include "libavutil/sha.h"
50 #include "libavutil/spherical.h"
51 #include "libavutil/stereo3d.h"
52 #include "libavutil/timecode.h"
53 #include "libavutil/uuid.h"
54 #include "libavcodec/ac3tab.h"
55 #include "libavcodec/flac.h"
56 #include "libavcodec/hevc/hevc.h"
58 #include "libavcodec/mlp_parse.h"
59 #include "avformat.h"
60 #include "internal.h"
61 #include "avio_internal.h"
62 #include "demux.h"
63 #include "dvdclut.h"
64 #include "iamf_parse.h"
65 #include "iamf_reader.h"
66 #include "dovi_isom.h"
67 #include "riff.h"
68 #include "isom.h"
69 #include "libavcodec/get_bits.h"
70 #include "id3v1.h"
71 #include "mov_chan.h"
72 #include "replaygain.h"
73 
74 #if CONFIG_ZLIB
75 #include <zlib.h>
76 #endif
77 
78 #include "qtpalette.h"
79 
80 /* those functions parse an atom */
81 /* links atom IDs to parse functions */
82 typedef struct MOVParseTableEntry {
83  uint32_t type;
84  int (*parse)(MOVContext *ctx, AVIOContext *pb, MOVAtom atom);
86 
87 static int mov_read_default(MOVContext *c, AVIOContext *pb, MOVAtom atom);
88 static int mov_read_mfra(MOVContext *c, AVIOContext *f);
90 static int64_t add_ctts_entry(MOVCtts** ctts_data, unsigned int* ctts_count, unsigned int* allocated_size,
91  int count, int duration);
92 
94  unsigned len, const char *key)
95 {
96  char buf[16];
97 
98  short current, total = 0;
99  avio_rb16(pb); // unknown
100  current = avio_rb16(pb);
101  if (len >= 6)
102  total = avio_rb16(pb);
103  if (!total)
104  snprintf(buf, sizeof(buf), "%d", current);
105  else
106  snprintf(buf, sizeof(buf), "%d/%d", current, total);
107  c->fc->event_flags |= AVFMT_EVENT_FLAG_METADATA_UPDATED;
108  av_dict_set(&c->fc->metadata, key, buf, 0);
109 
110  return 0;
111 }
112 
114  unsigned len, const char *key)
115 {
116  /* bypass padding bytes */
117  avio_r8(pb);
118  avio_r8(pb);
119  avio_r8(pb);
120 
121  c->fc->event_flags |= AVFMT_EVENT_FLAG_METADATA_UPDATED;
122  av_dict_set_int(&c->fc->metadata, key, avio_r8(pb), 0);
123 
124  return 0;
125 }
126 
128  unsigned len, const char *key)
129 {
130  c->fc->event_flags |= AVFMT_EVENT_FLAG_METADATA_UPDATED;
131  av_dict_set_int(&c->fc->metadata, key, avio_r8(pb), 0);
132 
133  return 0;
134 }
135 
137  unsigned len, const char *key)
138 {
139  short genre;
140 
141  avio_r8(pb); // unknown
142 
143  genre = avio_r8(pb);
144  if (genre < 1 || genre > ID3v1_GENRE_MAX)
145  return 0;
146  c->fc->event_flags |= AVFMT_EVENT_FLAG_METADATA_UPDATED;
147  av_dict_set(&c->fc->metadata, key, ff_id3v1_genre_str[genre-1], 0);
148 
149  return 0;
150 }
151 
152 static const uint32_t mac_to_unicode[128] = {
153  0x00C4,0x00C5,0x00C7,0x00C9,0x00D1,0x00D6,0x00DC,0x00E1,
154  0x00E0,0x00E2,0x00E4,0x00E3,0x00E5,0x00E7,0x00E9,0x00E8,
155  0x00EA,0x00EB,0x00ED,0x00EC,0x00EE,0x00EF,0x00F1,0x00F3,
156  0x00F2,0x00F4,0x00F6,0x00F5,0x00FA,0x00F9,0x00FB,0x00FC,
157  0x2020,0x00B0,0x00A2,0x00A3,0x00A7,0x2022,0x00B6,0x00DF,
158  0x00AE,0x00A9,0x2122,0x00B4,0x00A8,0x2260,0x00C6,0x00D8,
159  0x221E,0x00B1,0x2264,0x2265,0x00A5,0x00B5,0x2202,0x2211,
160  0x220F,0x03C0,0x222B,0x00AA,0x00BA,0x03A9,0x00E6,0x00F8,
161  0x00BF,0x00A1,0x00AC,0x221A,0x0192,0x2248,0x2206,0x00AB,
162  0x00BB,0x2026,0x00A0,0x00C0,0x00C3,0x00D5,0x0152,0x0153,
163  0x2013,0x2014,0x201C,0x201D,0x2018,0x2019,0x00F7,0x25CA,
164  0x00FF,0x0178,0x2044,0x20AC,0x2039,0x203A,0xFB01,0xFB02,
165  0x2021,0x00B7,0x201A,0x201E,0x2030,0x00C2,0x00CA,0x00C1,
166  0x00CB,0x00C8,0x00CD,0x00CE,0x00CF,0x00CC,0x00D3,0x00D4,
167  0xF8FF,0x00D2,0x00DA,0x00DB,0x00D9,0x0131,0x02C6,0x02DC,
168  0x00AF,0x02D8,0x02D9,0x02DA,0x00B8,0x02DD,0x02DB,0x02C7,
169 };
170 
172  char *dst, int dstlen)
173 {
174  char *p = dst;
175  char *end = dst+dstlen-1;
176  int i;
177 
178  for (i = 0; i < len; i++) {
179  uint8_t t, c = avio_r8(pb);
180 
181  if (p >= end)
182  continue;
183 
184  if (c < 0x80)
185  *p++ = c;
186  else if (p < end)
187  PUT_UTF8(mac_to_unicode[c-0x80], t, if (p < end) *p++ = t;);
188  }
189  *p = 0;
190  return p - dst;
191 }
192 
193 /**
194  * Get the current item in the parsing process.
195  */
197 {
198  HEIFItem *item = NULL;
199 
200  for (int i = 0; i < c->nb_heif_item; i++) {
201  if (!c->heif_item[i] || c->heif_item[i]->item_id != c->cur_item_id)
202  continue;
203 
204  item = c->heif_item[i];
205  break;
206  }
207 
208  return item;
209 }
210 
211 /**
212  * Get the current stream in the parsing process. This can either be the
213  * latest stream added to the context, or the stream referenced by an item.
214  */
216 {
217  AVStream *st = NULL;
218  HEIFItem *item;
219 
220  if (c->fc->nb_streams < 1)
221  return NULL;
222 
223  if (c->cur_item_id == -1)
224  return c->fc->streams[c->fc->nb_streams-1];
225 
226  item = heif_cur_item(c);
227  if (item)
228  st = item->st;
229 
230  return st;
231 }
232 
233 static int mov_read_covr(MOVContext *c, AVIOContext *pb, int type, int len)
234 {
235  AVStream *st;
236  MOVStreamContext *sc;
237  enum AVCodecID id;
238  int ret;
239 
240  switch (type) {
241  case 0xd: id = AV_CODEC_ID_MJPEG; break;
242  case 0xe: id = AV_CODEC_ID_PNG; break;
243  case 0x1b: id = AV_CODEC_ID_BMP; break;
244  default:
245  av_log(c->fc, AV_LOG_WARNING, "Unknown cover type: 0x%x.\n", type);
246  avio_skip(pb, len);
247  return 0;
248  }
249 
250  sc = av_mallocz(sizeof(*sc));
251  if (!sc)
252  return AVERROR(ENOMEM);
253  ret = ff_add_attached_pic(c->fc, NULL, pb, NULL, len);
254  if (ret < 0) {
255  av_free(sc);
256  return ret;
257  }
258  st = c->fc->streams[c->fc->nb_streams - 1];
259  st->priv_data = sc;
260  sc->id = st->id;
261  sc->refcount = 1;
262 
263  if (st->attached_pic.size >= 8 && id != AV_CODEC_ID_BMP) {
264  if (AV_RB64(st->attached_pic.data) == 0x89504e470d0a1a0a) {
265  id = AV_CODEC_ID_PNG;
266  } else {
267  id = AV_CODEC_ID_MJPEG;
268  }
269  }
270  st->codecpar->codec_id = id;
271 
272  return 0;
273 }
274 
275 // 3GPP TS 26.244
276 static int mov_metadata_loci(MOVContext *c, AVIOContext *pb, unsigned len)
277 {
278  char language[4] = { 0 };
279  char buf[200], place[100];
280  uint16_t langcode = 0;
281  double longitude, latitude, altitude;
282  const char *key = "location";
283 
284  if (len < 4 + 2 + 1 + 1 + 4 + 4 + 4) {
285  av_log(c->fc, AV_LOG_ERROR, "loci too short\n");
286  return AVERROR_INVALIDDATA;
287  }
288 
289  avio_skip(pb, 4); // version+flags
290  langcode = avio_rb16(pb);
291  ff_mov_lang_to_iso639(langcode, language);
292  len -= 6;
293 
294  len -= avio_get_str(pb, len, place, sizeof(place));
295  if (len < 1) {
296  av_log(c->fc, AV_LOG_ERROR, "place name too long\n");
297  return AVERROR_INVALIDDATA;
298  }
299  avio_skip(pb, 1); // role
300  len -= 1;
301 
302  if (len < 12) {
303  av_log(c->fc, AV_LOG_ERROR,
304  "loci too short (%u bytes left, need at least %d)\n", len, 12);
305  return AVERROR_INVALIDDATA;
306  }
307  longitude = ((int32_t) avio_rb32(pb)) / (float) (1 << 16);
308  latitude = ((int32_t) avio_rb32(pb)) / (float) (1 << 16);
309  altitude = ((int32_t) avio_rb32(pb)) / (float) (1 << 16);
310 
311  // Try to output in the same format as the ?xyz field
312  snprintf(buf, sizeof(buf), "%+08.4f%+09.4f", latitude, longitude);
313  if (altitude)
314  av_strlcatf(buf, sizeof(buf), "%+f", altitude);
315  av_strlcatf(buf, sizeof(buf), "/%s", place);
316 
317  if (*language && strcmp(language, "und")) {
318  char key2[16];
319  snprintf(key2, sizeof(key2), "%s-%s", key, language);
320  av_dict_set(&c->fc->metadata, key2, buf, 0);
321  }
322  c->fc->event_flags |= AVFMT_EVENT_FLAG_METADATA_UPDATED;
323  return av_dict_set(&c->fc->metadata, key, buf, 0);
324 }
325 
326 static int mov_metadata_hmmt(MOVContext *c, AVIOContext *pb, unsigned len)
327 {
328  int i, n_hmmt;
329 
330  if (len < 2)
331  return 0;
332  if (c->ignore_chapters)
333  return 0;
334 
335  n_hmmt = avio_rb32(pb);
336  if (n_hmmt > len / 4)
337  return AVERROR_INVALIDDATA;
338  for (i = 0; i < n_hmmt && !pb->eof_reached; i++) {
339  int moment_time = avio_rb32(pb);
340  avpriv_new_chapter(c->fc, i, av_make_q(1, 1000), moment_time, AV_NOPTS_VALUE, NULL);
341  }
342  if (avio_feof(pb))
343  return AVERROR_INVALIDDATA;
344  return 0;
345 }
346 
348 {
349  char tmp_key[AV_FOURCC_MAX_STRING_SIZE] = {0};
350  char key2[32], language[4] = {0};
351  char *str = NULL;
352  const char *key = NULL;
353  uint16_t langcode = 0;
354  uint32_t data_type = 0, str_size_alloc;
355  uint64_t str_size;
356  int (*parse)(MOVContext*, AVIOContext*, unsigned, const char*) = NULL;
357  int raw = 0;
358  int num = 0;
359 
360  switch (atom.type) {
361  case MKTAG( '@','P','R','M'): key = "premiere_version"; raw = 1; break;
362  case MKTAG( '@','P','R','Q'): key = "quicktime_version"; raw = 1; break;
363  case MKTAG( 'X','M','P','_'):
364  if (c->export_xmp) { key = "xmp"; raw = 1; } break;
365  case MKTAG( 'a','A','R','T'): key = "album_artist"; break;
366  case MKTAG( 'a','k','I','D'): key = "account_type";
368  case MKTAG( 'a','p','I','D'): key = "account_id"; break;
369  case MKTAG( 'c','a','t','g'): key = "category"; break;
370  case MKTAG( 'c','p','i','l'): key = "compilation";
372  case MKTAG( 'c','p','r','t'): key = "copyright"; break;
373  case MKTAG( 'd','e','s','c'): key = "description"; break;
374  case MKTAG( 'd','i','s','k'): key = "disc";
376  case MKTAG( 'e','g','i','d'): key = "episode_uid";
378  case MKTAG( 'F','I','R','M'): key = "firmware"; raw = 1; break;
379  case MKTAG( 'g','n','r','e'): key = "genre";
380  parse = mov_metadata_gnre; break;
381  case MKTAG( 'h','d','v','d'): key = "hd_video";
383  case MKTAG( 'H','M','M','T'):
384  return mov_metadata_hmmt(c, pb, atom.size);
385  case MKTAG( 'k','e','y','w'): key = "keywords"; break;
386  case MKTAG( 'l','d','e','s'): key = "synopsis"; break;
387  case MKTAG( 'l','o','c','i'):
388  return mov_metadata_loci(c, pb, atom.size);
389  case MKTAG( 'm','a','n','u'): key = "make"; break;
390  case MKTAG( 'm','o','d','l'): key = "model"; break;
391  case MKTAG( 'p','c','s','t'): key = "podcast";
393  case MKTAG( 'p','g','a','p'): key = "gapless_playback";
395  case MKTAG( 'p','u','r','d'): key = "purchase_date"; break;
396  case MKTAG( 'r','t','n','g'): key = "rating";
398  case MKTAG( 's','o','a','a'): key = "sort_album_artist"; break;
399  case MKTAG( 's','o','a','l'): key = "sort_album"; break;
400  case MKTAG( 's','o','a','r'): key = "sort_artist"; break;
401  case MKTAG( 's','o','c','o'): key = "sort_composer"; break;
402  case MKTAG( 's','o','n','m'): key = "sort_name"; break;
403  case MKTAG( 's','o','s','n'): key = "sort_show"; break;
404  case MKTAG( 's','t','i','k'): key = "media_type";
406  case MKTAG( 't','r','k','n'): key = "track";
408  case MKTAG( 't','v','e','n'): key = "episode_id"; break;
409  case MKTAG( 't','v','e','s'): key = "episode_sort";
411  case MKTAG( 't','v','n','n'): key = "network"; break;
412  case MKTAG( 't','v','s','h'): key = "show"; break;
413  case MKTAG( 't','v','s','n'): key = "season_number";
415  case MKTAG(0xa9,'A','R','T'): key = "artist"; break;
416  case MKTAG(0xa9,'P','R','D'): key = "producer"; break;
417  case MKTAG(0xa9,'a','l','b'): key = "album"; break;
418  case MKTAG(0xa9,'a','u','t'): key = "artist"; break;
419  case MKTAG(0xa9,'c','h','p'): key = "chapter"; break;
420  case MKTAG(0xa9,'c','m','t'): key = "comment"; break;
421  case MKTAG(0xa9,'c','o','m'): key = "composer"; break;
422  case MKTAG(0xa9,'c','p','y'): key = "copyright"; break;
423  case MKTAG(0xa9,'d','a','y'): key = "date"; break;
424  case MKTAG(0xa9,'d','i','r'): key = "director"; break;
425  case MKTAG(0xa9,'d','i','s'): key = "disclaimer"; break;
426  case MKTAG(0xa9,'e','d','1'): key = "edit_date"; break;
427  case MKTAG(0xa9,'e','n','c'): key = "encoder"; break;
428  case MKTAG(0xa9,'f','m','t'): key = "original_format"; break;
429  case MKTAG(0xa9,'g','e','n'): key = "genre"; break;
430  case MKTAG(0xa9,'g','r','p'): key = "grouping"; break;
431  case MKTAG(0xa9,'h','s','t'): key = "host_computer"; break;
432  case MKTAG(0xa9,'i','n','f'): key = "comment"; break;
433  case MKTAG(0xa9,'l','y','r'): key = "lyrics"; break;
434  case MKTAG(0xa9,'m','a','k'): key = "make"; break;
435  case MKTAG(0xa9,'m','o','d'): key = "model"; break;
436  case MKTAG(0xa9,'n','a','m'): key = "title"; break;
437  case MKTAG(0xa9,'o','p','e'): key = "original_artist"; break;
438  case MKTAG(0xa9,'p','r','d'): key = "producer"; break;
439  case MKTAG(0xa9,'p','r','f'): key = "performers"; break;
440  case MKTAG(0xa9,'r','e','q'): key = "playback_requirements"; break;
441  case MKTAG(0xa9,'s','r','c'): key = "original_source"; break;
442  case MKTAG(0xa9,'s','t','3'): key = "subtitle"; break;
443  case MKTAG(0xa9,'s','w','r'): key = "encoder"; break;
444  case MKTAG(0xa9,'t','o','o'): key = "encoder"; break;
445  case MKTAG(0xa9,'t','r','k'): key = "track"; break;
446  case MKTAG(0xa9,'u','r','l'): key = "URL"; break;
447  case MKTAG(0xa9,'w','r','n'): key = "warning"; break;
448  case MKTAG(0xa9,'w','r','t'): key = "composer"; break;
449  case MKTAG(0xa9,'x','y','z'): key = "location"; break;
450  }
451 retry:
452  if (c->itunes_metadata && atom.size > 8) {
453  int data_size = avio_rb32(pb);
454  int tag = avio_rl32(pb);
455  if (tag == MKTAG('d','a','t','a') && data_size <= atom.size && data_size >= 16) {
456  data_type = avio_rb32(pb); // type
457  avio_rb32(pb); // unknown
458  str_size = data_size - 16;
459  atom.size -= 16;
460 
461  if (!key && c->found_hdlr_mdta && c->meta_keys) {
462  uint32_t index = av_bswap32(atom.type); // BE number has been read as LE
463  if (index < c->meta_keys_count && index > 0) {
464  key = c->meta_keys[index];
465  } else if (atom.type != MKTAG('c', 'o', 'v', 'r')) {
466  av_log(c->fc, AV_LOG_WARNING,
467  "The index of 'data' is out of range: %"PRId32" < 1 or >= %d.\n",
468  index, c->meta_keys_count);
469  }
470  }
471  if (atom.type == MKTAG('c', 'o', 'v', 'r') ||
472  (key && !strcmp(key, "com.apple.quicktime.artwork"))) {
473  int ret = mov_read_covr(c, pb, data_type, str_size);
474  if (ret < 0) {
475  av_log(c->fc, AV_LOG_ERROR, "Error parsing cover art.\n");
476  return ret;
477  }
478  atom.size -= str_size;
479  if (atom.size > 8)
480  goto retry;
481  return ret;
482  }
483  } else return 0;
484  } else if (atom.size > 4 && key && !c->itunes_metadata && !raw) {
485  str_size = avio_rb16(pb); // string length
486  if (str_size > atom.size) {
487  raw = 1;
488  avio_seek(pb, -2, SEEK_CUR);
489  av_log(c->fc, AV_LOG_WARNING, "UDTA parsing failed retrying raw\n");
490  goto retry;
491  }
492  langcode = avio_rb16(pb);
493  ff_mov_lang_to_iso639(langcode, language);
494  atom.size -= 4;
495  } else
496  str_size = atom.size;
497 
498  if (c->export_all && !key) {
499  key = av_fourcc_make_string(tmp_key, atom.type);
500  }
501 
502  if (!key)
503  return 0;
504  if (atom.size < 0 || str_size >= INT_MAX/2)
505  return AVERROR_INVALIDDATA;
506 
507  // Allocates enough space if data_type is a int32 or float32 number, otherwise
508  // worst-case requirement for output string in case of utf8 coded input
509  num = (data_type >= 21 && data_type <= 23);
510  str_size_alloc = (num ? 512 : (raw ? str_size : str_size * 2)) + 1;
511  str = av_mallocz(str_size_alloc);
512  if (!str)
513  return AVERROR(ENOMEM);
514 
515  if (parse)
516  parse(c, pb, str_size, key);
517  else {
518  if (!raw && (data_type == 3 || (data_type == 0 && (langcode < 0x400 || langcode == 0x7fff)))) { // MAC Encoded
519  mov_read_mac_string(c, pb, str_size, str, str_size_alloc);
520  } else if (data_type == 21) { // BE signed integer, variable size
521  int val = 0;
522  if (str_size == 1)
523  val = (int8_t)avio_r8(pb);
524  else if (str_size == 2)
525  val = (int16_t)avio_rb16(pb);
526  else if (str_size == 3)
527  val = ((int32_t)(avio_rb24(pb)<<8))>>8;
528  else if (str_size == 4)
529  val = (int32_t)avio_rb32(pb);
530  if (snprintf(str, str_size_alloc, "%d", val) >= str_size_alloc) {
531  av_log(c->fc, AV_LOG_ERROR,
532  "Failed to store the number (%d) in string.\n", val);
533  av_free(str);
534  return AVERROR_INVALIDDATA;
535  }
536  } else if (data_type == 22) { // BE unsigned integer, variable size
537  unsigned int val = 0;
538  if (str_size == 1)
539  val = avio_r8(pb);
540  else if (str_size == 2)
541  val = avio_rb16(pb);
542  else if (str_size == 3)
543  val = avio_rb24(pb);
544  else if (str_size == 4)
545  val = avio_rb32(pb);
546  if (snprintf(str, str_size_alloc, "%u", val) >= str_size_alloc) {
547  av_log(c->fc, AV_LOG_ERROR,
548  "Failed to store the number (%u) in string.\n", val);
549  av_free(str);
550  return AVERROR_INVALIDDATA;
551  }
552  } else if (data_type == 23 && str_size >= 4) { // BE float32
553  float val = av_int2float(avio_rb32(pb));
554  if (snprintf(str, str_size_alloc, "%f", val) >= str_size_alloc) {
555  av_log(c->fc, AV_LOG_ERROR,
556  "Failed to store the float32 number (%f) in string.\n", val);
557  av_free(str);
558  return AVERROR_INVALIDDATA;
559  }
560  } else if (data_type > 1 && data_type != 4) {
561  // data_type can be 0 if not set at all above. data_type 1 means
562  // UTF8 and 4 means "UTF8 sort". For any other type (UTF16 or e.g.
563  // a picture), don't return it blindly in a string that is supposed
564  // to be UTF8 text.
565  av_log(c->fc, AV_LOG_WARNING, "Skipping unhandled metadata %s of type %d\n", key, data_type);
566  av_free(str);
567  return 0;
568  } else {
569  int ret = ffio_read_size(pb, str, str_size);
570  if (ret < 0) {
571  av_free(str);
572  return ret;
573  }
574  str[str_size] = 0;
575  }
576  c->fc->event_flags |= AVFMT_EVENT_FLAG_METADATA_UPDATED;
577  av_dict_set(&c->fc->metadata, key, str, 0);
578  if (*language && strcmp(language, "und")) {
579  snprintf(key2, sizeof(key2), "%s-%s", key, language);
580  av_dict_set(&c->fc->metadata, key2, str, 0);
581  }
582  if (!strcmp(key, "encoder")) {
583  int major, minor, micro;
584  if (sscanf(str, "HandBrake %d.%d.%d", &major, &minor, &micro) == 3) {
585  c->handbrake_version = 1000000*major + 1000*minor + micro;
586  }
587  }
588  }
589 
590  av_freep(&str);
591  return 0;
592 }
593 
595 {
596  int64_t start;
597  int i, nb_chapters, str_len, version;
598  char str[256+1];
599  int ret;
600 
601  if (c->ignore_chapters)
602  return 0;
603 
604  if ((atom.size -= 5) < 0)
605  return 0;
606 
607  version = avio_r8(pb);
608  avio_rb24(pb);
609  if (version)
610  avio_rb32(pb); // ???
611  nb_chapters = avio_r8(pb);
612 
613  for (i = 0; i < nb_chapters; i++) {
614  if (atom.size < 9)
615  return 0;
616 
617  start = avio_rb64(pb);
618  str_len = avio_r8(pb);
619 
620  if ((atom.size -= 9+str_len) < 0)
621  return 0;
622 
623  ret = ffio_read_size(pb, str, str_len);
624  if (ret < 0)
625  return ret;
626  str[str_len] = 0;
627  avpriv_new_chapter(c->fc, i, (AVRational){1,10000000}, start, AV_NOPTS_VALUE, str);
628  }
629  return 0;
630 }
631 
632 #define MIN_DATA_ENTRY_BOX_SIZE 12
634 {
635  AVStream *st;
636  MOVStreamContext *sc;
637  int entries, i, j;
638 
639  if (c->fc->nb_streams < 1)
640  return 0;
641  st = c->fc->streams[c->fc->nb_streams-1];
642  sc = st->priv_data;
643 
644  avio_rb32(pb); // version + flags
645  entries = avio_rb32(pb);
646  if (!entries ||
647  entries > (atom.size - 1) / MIN_DATA_ENTRY_BOX_SIZE + 1 ||
648  entries >= UINT_MAX / sizeof(*sc->drefs))
649  return AVERROR_INVALIDDATA;
650 
651  for (i = 0; i < sc->drefs_count; i++) {
652  MOVDref *dref = &sc->drefs[i];
653  av_freep(&dref->path);
654  av_freep(&dref->dir);
655  }
656  av_free(sc->drefs);
657  sc->drefs_count = 0;
658  sc->drefs = av_mallocz(entries * sizeof(*sc->drefs));
659  if (!sc->drefs)
660  return AVERROR(ENOMEM);
661  sc->drefs_count = entries;
662 
663  for (i = 0; i < entries; i++) {
664  MOVDref *dref = &sc->drefs[i];
665  uint32_t size = avio_rb32(pb);
666  int64_t next = avio_tell(pb);
667 
668  if (size < 12 || next < 0 || next > INT64_MAX - size)
669  return AVERROR_INVALIDDATA;
670 
671  next += size - 4;
672 
673  dref->type = avio_rl32(pb);
674  avio_rb32(pb); // version + flags
675 
676  if (dref->type == MKTAG('a','l','i','s') && size > 150) {
677  /* macintosh alias record */
678  uint16_t volume_len, len;
679  int16_t type;
680  int ret;
681 
682  avio_skip(pb, 10);
683 
684  volume_len = avio_r8(pb);
685  volume_len = FFMIN(volume_len, 27);
686  ret = ffio_read_size(pb, dref->volume, 27);
687  if (ret < 0)
688  return ret;
689  dref->volume[volume_len] = 0;
690  av_log(c->fc, AV_LOG_DEBUG, "volume %s, len %d\n", dref->volume, volume_len);
691 
692  avio_skip(pb, 12);
693 
694  len = avio_r8(pb);
695  len = FFMIN(len, 63);
696  ret = ffio_read_size(pb, dref->filename, 63);
697  if (ret < 0)
698  return ret;
699  dref->filename[len] = 0;
700  av_log(c->fc, AV_LOG_DEBUG, "filename %s, len %d\n", dref->filename, len);
701 
702  avio_skip(pb, 16);
703 
704  /* read next level up_from_alias/down_to_target */
705  dref->nlvl_from = avio_rb16(pb);
706  dref->nlvl_to = avio_rb16(pb);
707  av_log(c->fc, AV_LOG_DEBUG, "nlvl from %d, nlvl to %d\n",
708  dref->nlvl_from, dref->nlvl_to);
709 
710  avio_skip(pb, 16);
711 
712  for (type = 0; type != -1 && avio_tell(pb) < next; ) {
713  if (avio_feof(pb))
714  return AVERROR_EOF;
715  type = avio_rb16(pb);
716  len = avio_rb16(pb);
717  av_log(c->fc, AV_LOG_DEBUG, "type %d, len %d\n", type, len);
718  if (len&1)
719  len += 1;
720  if (type == 2) { // absolute path
721  av_free(dref->path);
722  dref->path = av_mallocz(len+1);
723  if (!dref->path)
724  return AVERROR(ENOMEM);
725 
726  ret = ffio_read_size(pb, dref->path, len);
727  if (ret < 0) {
728  av_freep(&dref->path);
729  return ret;
730  }
731  if (len > volume_len && !strncmp(dref->path, dref->volume, volume_len)) {
732  len -= volume_len;
733  memmove(dref->path, dref->path+volume_len, len);
734  dref->path[len] = 0;
735  }
736  // trim string of any ending zeros
737  for (j = len - 1; j >= 0; j--) {
738  if (dref->path[j] == 0)
739  len--;
740  else
741  break;
742  }
743  for (j = 0; j < len; j++)
744  if (dref->path[j] == ':' || dref->path[j] == 0)
745  dref->path[j] = '/';
746  av_log(c->fc, AV_LOG_DEBUG, "path %s\n", dref->path);
747  } else if (type == 0) { // directory name
748  av_free(dref->dir);
749  dref->dir = av_malloc(len+1);
750  if (!dref->dir)
751  return AVERROR(ENOMEM);
752 
753  ret = ffio_read_size(pb, dref->dir, len);
754  if (ret < 0) {
755  av_freep(&dref->dir);
756  return ret;
757  }
758  dref->dir[len] = 0;
759  for (j = 0; j < len; j++)
760  if (dref->dir[j] == ':')
761  dref->dir[j] = '/';
762  av_log(c->fc, AV_LOG_DEBUG, "dir %s\n", dref->dir);
763  } else
764  avio_skip(pb, len);
765  }
766  } else {
767  av_log(c->fc, AV_LOG_DEBUG, "Unknown dref type 0x%08"PRIx32" size %"PRIu32"\n",
768  dref->type, size);
769  entries--;
770  i--;
771  }
772  avio_seek(pb, next, SEEK_SET);
773  }
774  return 0;
775 }
776 
778 {
779  AVStream *st;
780  uint32_t type;
781  uint32_t ctype;
782  int64_t title_size;
783  char *title_str;
784  int ret;
785 
786  avio_r8(pb); /* version */
787  avio_rb24(pb); /* flags */
788 
789  /* component type */
790  ctype = avio_rl32(pb);
791  type = avio_rl32(pb); /* component subtype */
792 
793  av_log(c->fc, AV_LOG_TRACE, "ctype=%s\n", av_fourcc2str(ctype));
794  av_log(c->fc, AV_LOG_TRACE, "stype=%s\n", av_fourcc2str(type));
795 
796  if (c->trak_index < 0) { // meta not inside a trak
797  if (type == MKTAG('m','d','t','a')) {
798  c->found_hdlr_mdta = 1;
799  }
800  return 0;
801  }
802 
803  st = c->fc->streams[c->fc->nb_streams-1];
804 
805  if (type == MKTAG('v','i','d','e'))
807  else if (type == MKTAG('s','o','u','n'))
809  else if (type == MKTAG('m','1','a',' '))
811  else if ((type == MKTAG('s','u','b','p')) || (type == MKTAG('c','l','c','p')))
813 
814  avio_rb32(pb); /* component manufacture */
815  avio_rb32(pb); /* component flags */
816  avio_rb32(pb); /* component flags mask */
817 
818  title_size = atom.size - 24;
819  if (title_size > 0) {
820  if (title_size > FFMIN(INT_MAX, SIZE_MAX-1))
821  return AVERROR_INVALIDDATA;
822  title_str = av_malloc(title_size + 1); /* Add null terminator */
823  if (!title_str)
824  return AVERROR(ENOMEM);
825 
826  ret = ffio_read_size(pb, title_str, title_size);
827  if (ret < 0) {
828  av_freep(&title_str);
829  return ret;
830  }
831  title_str[title_size] = 0;
832  if (title_str[0]) {
833  int off = (!c->isom && title_str[0] == title_size - 1);
834  // flag added so as to not set stream handler name if already set from mdia->hdlr
835  av_dict_set(&st->metadata, "handler_name", title_str + off, AV_DICT_DONT_OVERWRITE);
836  }
837  av_freep(&title_str);
838  }
839 
840  return 0;
841 }
842 
844 {
845  return ff_mov_read_esds(c->fc, pb);
846 }
847 
849 {
850  AVStream *st;
851  AVPacketSideData *sd;
852  enum AVAudioServiceType *ast;
853  int ac3info, acmod, lfeon, bsmod;
854  uint64_t mask;
855 
856  if (c->fc->nb_streams < 1)
857  return 0;
858  st = c->fc->streams[c->fc->nb_streams-1];
859 
863  sizeof(*ast), 0);
864  if (!sd)
865  return AVERROR(ENOMEM);
866 
867  ast = (enum AVAudioServiceType*)sd->data;
868  ac3info = avio_rb24(pb);
869  bsmod = (ac3info >> 14) & 0x7;
870  acmod = (ac3info >> 11) & 0x7;
871  lfeon = (ac3info >> 10) & 0x1;
872 
874  if (lfeon)
878 
879  *ast = bsmod;
880  if (st->codecpar->ch_layout.nb_channels > 1 && bsmod == 0x7)
882 
883  return 0;
884 }
885 
886 #if CONFIG_IAMFDEC
887 static int mov_read_iacb(MOVContext *c, AVIOContext *pb, MOVAtom atom)
888 {
889  AVStream *st;
890  MOVStreamContext *sc;
891  FFIOContext b;
892  AVIOContext *descriptor_pb;
893  AVDictionary *metadata;
894  IAMFContext *iamf;
896  unsigned descriptors_size;
897  int nb_frames, disposition;
898  int version, ret;
899 
900  if (atom.size < 5)
901  return AVERROR_INVALIDDATA;
902 
903  if (c->fc->nb_streams < 1)
904  return 0;
905 
906  version = avio_r8(pb);
907  if (version != 1) {
908  av_log(c->fc, AV_LOG_ERROR, "%s configurationVersion %d",
909  version < 1 ? "invalid" : "unsupported", version);
910  return AVERROR_INVALIDDATA;
911  }
912 
913  descriptors_size = ffio_read_leb(pb);
914  if (!descriptors_size || descriptors_size > INT_MAX)
915  return AVERROR_INVALIDDATA;
916 
917  st = c->fc->streams[c->fc->nb_streams - 1];
918  sc = st->priv_data;
919 
920  if (st->codecpar->extradata) {
921  av_log(c->fc, AV_LOG_WARNING, "ignoring iacb\n");
922  return 0;
923  }
924 
925  sc->iamf = av_mallocz(sizeof(*sc->iamf));
926  if (!sc->iamf)
927  return AVERROR(ENOMEM);
928  iamf = &sc->iamf->iamf;
929 
930  st->codecpar->extradata = av_malloc(descriptors_size);
931  if (!st->codecpar->extradata)
932  return AVERROR(ENOMEM);
933  st->codecpar->extradata_size = descriptors_size;
934 
935  ret = avio_read(pb, st->codecpar->extradata, descriptors_size);
936  if (ret != descriptors_size)
937  return ret < 0 ? ret : AVERROR_INVALIDDATA;
938 
939  ffio_init_read_context(&b, st->codecpar->extradata, descriptors_size);
940  descriptor_pb = &b.pub;
941 
942  ret = ff_iamfdec_read_descriptors(iamf, descriptor_pb, descriptors_size, c->fc);
943  if (ret < 0)
944  return ret;
945 
946  metadata = st->metadata;
947  st->metadata = NULL;
948  start_time = st->start_time;
949  nb_frames = st->nb_frames;
950  duration = st->duration;
951  disposition = st->disposition;
952 
953  for (int i = 0; i < iamf->nb_audio_elements; i++) {
954  IAMFAudioElement *audio_element = iamf->audio_elements[i];
955  const AVIAMFAudioElement *element;
956  AVStreamGroup *stg =
958 
959  if (!stg) {
960  ret = AVERROR(ENOMEM);
961  goto fail;
962  }
963 
965  stg->id = audio_element->audio_element_id;
966  /* Transfer ownership */
967  element = stg->params.iamf_audio_element = audio_element->element;
968  audio_element->element = NULL;
969 
970  for (int j = 0; j < audio_element->nb_substreams; j++) {
971  IAMFSubStream *substream = &audio_element->substreams[j];
972  AVStream *stream;
973 
974  if (!i && !j) {
975  if (audio_element->layers[0].substream_count != 1)
976  disposition &= ~AV_DISPOSITION_DEFAULT;
977  stream = st;
978  } else
979  stream = avformat_new_stream(c->fc, NULL);
980  if (!stream) {
981  ret = AVERROR(ENOMEM);
982  goto fail;
983  }
984 
985  stream->start_time = start_time;
986  stream->nb_frames = nb_frames;
987  stream->duration = duration;
988  stream->disposition = disposition;
989  if (stream != st) {
990  stream->priv_data = sc;
991  sc->refcount++;
992  }
993 
996  if (i || j) {
998  if (audio_element->layers[0].substream_count == 1)
1000  }
1001 
1002  ret = avcodec_parameters_copy(stream->codecpar, substream->codecpar);
1003  if (ret < 0)
1004  goto fail;
1005 
1006  stream->id = substream->audio_substream_id;
1007 
1008  avpriv_set_pts_info(st, 64, 1, sc->time_scale);
1009 
1010  ret = avformat_stream_group_add_stream(stg, stream);
1011  if (ret < 0)
1012  goto fail;
1013  }
1014 
1015  ret = av_dict_copy(&stg->metadata, metadata, 0);
1016  if (ret < 0)
1017  goto fail;
1018  }
1019 
1020  for (int i = 0; i < iamf->nb_mix_presentations; i++) {
1021  IAMFMixPresentation *mix_presentation = iamf->mix_presentations[i];
1022  const AVIAMFMixPresentation *mix = mix_presentation->cmix;
1023  AVStreamGroup *stg =
1025 
1026  if (!stg) {
1027  ret = AVERROR(ENOMEM);
1028  goto fail;
1029  }
1030 
1032  stg->id = mix_presentation->mix_presentation_id;
1033  /* Transfer ownership */
1034  stg->params.iamf_mix_presentation = mix_presentation->mix;
1035  mix_presentation->mix = NULL;
1036 
1037  for (int j = 0; j < mix->nb_submixes; j++) {
1038  const AVIAMFSubmix *submix = mix->submixes[j];
1039 
1040  for (int k = 0; k < submix->nb_elements; k++) {
1041  const AVIAMFSubmixElement *submix_element = submix->elements[k];
1042  const AVStreamGroup *audio_element = NULL;
1043 
1044  for (int l = 0; l < c->fc->nb_stream_groups; l++)
1045  if (c->fc->stream_groups[l]->type == AV_STREAM_GROUP_PARAMS_IAMF_AUDIO_ELEMENT &&
1046  c->fc->stream_groups[l]->id == submix_element->audio_element_id) {
1047  audio_element = c->fc->stream_groups[l];
1048  break;
1049  }
1050  av_assert0(audio_element);
1051 
1052  for (int l = 0; l < audio_element->nb_streams; l++) {
1053  ret = avformat_stream_group_add_stream(stg, audio_element->streams[l]);
1054  if (ret < 0 && ret != AVERROR(EEXIST))
1055  goto fail;
1056  }
1057  }
1058  }
1059 
1060  ret = av_dict_copy(&stg->metadata, metadata, 0);
1061  if (ret < 0)
1062  goto fail;
1063  }
1064 
1065  ret = 0;
1066 fail:
1067  av_dict_free(&metadata);
1068 
1069  return ret;
1070 }
1071 #endif
1072 
1074 {
1075  AVStream *st;
1076  AVPacketSideData *sd;
1077  enum AVAudioServiceType *ast;
1078  int eac3info, acmod, lfeon, bsmod;
1079  uint64_t mask;
1080 
1081  if (c->fc->nb_streams < 1)
1082  return 0;
1083  st = c->fc->streams[c->fc->nb_streams-1];
1084 
1088  sizeof(*ast), 0);
1089  if (!sd)
1090  return AVERROR(ENOMEM);
1091 
1092  ast = (enum AVAudioServiceType*)sd->data;
1093 
1094  /* No need to parse fields for additional independent substreams and its
1095  * associated dependent substreams since libavcodec's E-AC-3 decoder
1096  * does not support them yet. */
1097  avio_rb16(pb); /* data_rate and num_ind_sub */
1098  eac3info = avio_rb24(pb);
1099  bsmod = (eac3info >> 12) & 0x1f;
1100  acmod = (eac3info >> 9) & 0x7;
1101  lfeon = (eac3info >> 8) & 0x1;
1102 
1104  if (lfeon)
1108 
1109  *ast = bsmod;
1110  if (st->codecpar->ch_layout.nb_channels > 1 && bsmod == 0x7)
1112 
1113  return 0;
1114 }
1115 
1117 {
1118 #define DDTS_SIZE 20
1119  uint8_t buf[DDTS_SIZE + AV_INPUT_BUFFER_PADDING_SIZE];
1120  AVStream *st = NULL;
1121  uint32_t frame_duration_code = 0;
1122  uint32_t channel_layout_code = 0;
1123  GetBitContext gb;
1124  int ret;
1125 
1126  if ((ret = ffio_read_size(pb, buf, DDTS_SIZE)) < 0)
1127  return ret;
1128 
1129  init_get_bits(&gb, buf, 8 * DDTS_SIZE);
1130 
1131  if (c->fc->nb_streams < 1) {
1132  return 0;
1133  }
1134  st = c->fc->streams[c->fc->nb_streams-1];
1135 
1136  st->codecpar->sample_rate = get_bits_long(&gb, 32);
1137  if (st->codecpar->sample_rate <= 0) {
1138  av_log(c->fc, AV_LOG_ERROR, "Invalid sample rate %d\n", st->codecpar->sample_rate);
1139  return AVERROR_INVALIDDATA;
1140  }
1141  skip_bits_long(&gb, 32); /* max bitrate */
1142  st->codecpar->bit_rate = get_bits_long(&gb, 32);
1143  st->codecpar->bits_per_coded_sample = get_bits(&gb, 8);
1144  frame_duration_code = get_bits(&gb, 2);
1145  skip_bits(&gb, 30); /* various fields */
1146  channel_layout_code = get_bits(&gb, 16);
1147 
1148  st->codecpar->frame_size =
1149  (frame_duration_code == 0) ? 512 :
1150  (frame_duration_code == 1) ? 1024 :
1151  (frame_duration_code == 2) ? 2048 :
1152  (frame_duration_code == 3) ? 4096 : 0;
1153 
1154  if (channel_layout_code > 0xff) {
1155  av_log(c->fc, AV_LOG_WARNING, "Unsupported DTS audio channel layout\n");
1156  }
1159  ((channel_layout_code & 0x1) ? AV_CH_FRONT_CENTER : 0) |
1160  ((channel_layout_code & 0x2) ? AV_CH_FRONT_LEFT : 0) |
1161  ((channel_layout_code & 0x2) ? AV_CH_FRONT_RIGHT : 0) |
1162  ((channel_layout_code & 0x4) ? AV_CH_SIDE_LEFT : 0) |
1163  ((channel_layout_code & 0x4) ? AV_CH_SIDE_RIGHT : 0) |
1164  ((channel_layout_code & 0x8) ? AV_CH_LOW_FREQUENCY : 0));
1165 
1166  return 0;
1167 }
1168 
1170 {
1171  AVStream *st;
1172 
1173  if (c->fc->nb_streams < 1)
1174  return 0;
1175  st = c->fc->streams[c->fc->nb_streams-1];
1176 
1177  if (atom.size < 16)
1178  return 0;
1179 
1180  /* skip version and flags */
1181  avio_skip(pb, 4);
1182 
1183  ff_mov_read_chan(c->fc, pb, st, atom.size - 4);
1184 
1185  return 0;
1186 }
1187 
1189 {
1190  int64_t end = av_sat_add64(avio_tell(pb), atom.size);
1191  int version, flags;
1192  int ret;
1193  AVStream *st;
1194 
1195  if (c->fc->nb_streams < 1)
1196  return 0;
1197  st = c->fc->streams[c->fc->nb_streams-1];
1198 
1199  version = avio_r8(pb);
1200  flags = avio_rb24(pb);
1201  if (version != 0 || flags != 0) {
1202  av_log(c->fc, AV_LOG_ERROR,
1203  "Unsupported 'chnl' box with version %d, flags: %#x",
1204  version, flags);
1205  return AVERROR_INVALIDDATA;
1206  }
1207 
1208  ret = ff_mov_read_chnl(c->fc, pb, st);
1209  if (ret < 0)
1210  return ret;
1211 
1212  if (avio_tell(pb) != end) {
1213  av_log(c->fc, AV_LOG_WARNING, "skip %" PRId64 " bytes of unknown data inside chnl\n",
1214  end - avio_tell(pb));
1215  avio_seek(pb, end, SEEK_SET);
1216  }
1217  return ret;
1218 }
1219 
1221 {
1222  AVStream *st;
1223  int ret;
1224 
1225  if (c->fc->nb_streams < 1)
1226  return 0;
1227  st = c->fc->streams[c->fc->nb_streams-1];
1228 
1229  if ((ret = ff_get_wav_header(c->fc, pb, st->codecpar, atom.size, 0)) < 0)
1230  av_log(c->fc, AV_LOG_WARNING, "get_wav_header failed\n");
1231 
1232  return ret;
1233 }
1234 
1236 {
1237  AVStream *st;
1238  HEIFItem *item;
1239  AVPacketSideData *sd;
1240  int width, height, err = 0;
1241  AVRational aperture_width, aperture_height, horiz_off, vert_off;
1242  AVRational pc_x, pc_y;
1243  uint64_t top, bottom, left, right;
1244 
1245  item = heif_cur_item(c);
1246  st = get_curr_st(c);
1247  if (!st)
1248  return 0;
1249 
1250  width = st->codecpar->width;
1251  height = st->codecpar->height;
1252  if ((!width || !height) && item) {
1253  width = item->width;
1254  height = item->height;
1255  }
1256  if (!width || !height) {
1257  err = AVERROR_INVALIDDATA;
1258  goto fail;
1259  }
1260 
1261  aperture_width.num = avio_rb32(pb);
1262  aperture_width.den = avio_rb32(pb);
1263  aperture_height.num = avio_rb32(pb);
1264  aperture_height.den = avio_rb32(pb);
1265 
1266  horiz_off.num = avio_rb32(pb);
1267  horiz_off.den = avio_rb32(pb);
1268  vert_off.num = avio_rb32(pb);
1269  vert_off.den = avio_rb32(pb);
1270 
1271  if (aperture_width.num < 0 || aperture_width.den < 0 ||
1272  aperture_height.num < 0 || aperture_height.den < 0 ||
1273  horiz_off.den < 0 || vert_off.den < 0) {
1274  err = AVERROR_INVALIDDATA;
1275  goto fail;
1276  }
1277  av_log(c->fc, AV_LOG_TRACE, "clap: apertureWidth %d/%d, apertureHeight %d/%d "
1278  "horizOff %d/%d vertOff %d/%d\n",
1279  aperture_width.num, aperture_width.den, aperture_height.num, aperture_height.den,
1280  horiz_off.num, horiz_off.den, vert_off.num, vert_off.den);
1281 
1282  pc_x = av_mul_q((AVRational) { width - 1, 1 }, (AVRational) { 1, 2 });
1283  pc_x = av_add_q(pc_x, horiz_off);
1284  pc_y = av_mul_q((AVRational) { height - 1, 1 }, (AVRational) { 1, 2 });
1285  pc_y = av_add_q(pc_y, vert_off);
1286 
1287  aperture_width = av_sub_q(aperture_width, (AVRational) { 1, 1 });
1288  aperture_width = av_mul_q(aperture_width, (AVRational) { 1, 2 });
1289  aperture_height = av_sub_q(aperture_height, (AVRational) { 1, 1 });
1290  aperture_height = av_mul_q(aperture_height, (AVRational) { 1, 2 });
1291 
1292  left = av_q2d(av_sub_q(pc_x, aperture_width));
1293  right = av_q2d(av_add_q(pc_x, aperture_width));
1294  top = av_q2d(av_sub_q(pc_y, aperture_height));
1295  bottom = av_q2d(av_add_q(pc_y, aperture_height));
1296 
1297  if (bottom > (height - 1) ||
1298  right > (width - 1)) {
1299  err = AVERROR_INVALIDDATA;
1300  goto fail;
1301  }
1302 
1303  bottom = height - 1 - bottom;
1304  right = width - 1 - right;
1305 
1306  if (!(left | right | top | bottom))
1307  return 0;
1308 
1309  if ((left + right) >= width ||
1310  (top + bottom) >= height) {
1311  err = AVERROR_INVALIDDATA;
1312  goto fail;
1313  }
1314 
1318  sizeof(uint32_t) * 4, 0);
1319  if (!sd)
1320  return AVERROR(ENOMEM);
1321 
1322  AV_WL32A(sd->data, top);
1323  AV_WL32A(sd->data + 4, bottom);
1324  AV_WL32A(sd->data + 8, left);
1325  AV_WL32A(sd->data + 12, right);
1326 
1327 fail:
1328  if (err < 0) {
1329  int explode = !!(c->fc->error_recognition & AV_EF_EXPLODE);
1330  av_log(c->fc, explode ? AV_LOG_ERROR : AV_LOG_WARNING, "Invalid clap box\n");
1331  if (!explode)
1332  err = 0;
1333  }
1334 
1335  return err;
1336 }
1337 
1338 /* This atom overrides any previously set aspect ratio */
1340 {
1341  const int num = avio_rb32(pb);
1342  const int den = avio_rb32(pb);
1343  AVStream *st;
1344  MOVStreamContext *sc;
1345 
1346  if (c->fc->nb_streams < 1)
1347  return 0;
1348  st = c->fc->streams[c->fc->nb_streams-1];
1349  sc = st->priv_data;
1350 
1351  av_log(c->fc, AV_LOG_TRACE, "pasp: hSpacing %d, vSpacing %d\n", num, den);
1352 
1353  if (den != 0) {
1354  sc->h_spacing = num;
1355  sc->v_spacing = den;
1356  }
1357  return 0;
1358 }
1359 
1360 /* this atom contains actual media data */
1362 {
1363  if (atom.size == 0) /* wrong one (MP4) */
1364  return 0;
1365  c->found_mdat=1;
1366  return 0; /* now go for moov */
1367 }
1368 
1369 #define DRM_BLOB_SIZE 56
1370 
1372 {
1373  uint8_t intermediate_key[20];
1374  uint8_t intermediate_iv[20];
1375  uint8_t input[64];
1376  uint8_t output[64];
1377  uint8_t file_checksum[20];
1378  uint8_t calculated_checksum[20];
1379  char checksum_string[2 * sizeof(file_checksum) + 1];
1380  struct AVSHA *sha;
1381  int i;
1382  int ret = 0;
1383  uint8_t *activation_bytes = c->activation_bytes;
1384  uint8_t *fixed_key = c->audible_fixed_key;
1385 
1386  c->aax_mode = 1;
1387 
1388  sha = av_sha_alloc();
1389  if (!sha)
1390  return AVERROR(ENOMEM);
1391  av_free(c->aes_decrypt);
1392  c->aes_decrypt = av_aes_alloc();
1393  if (!c->aes_decrypt) {
1394  ret = AVERROR(ENOMEM);
1395  goto fail;
1396  }
1397 
1398  /* drm blob processing */
1399  avio_read(pb, output, 8); // go to offset 8, absolute position 0x251
1401  avio_read(pb, output, 4); // go to offset 4, absolute position 0x28d
1402  avio_read(pb, file_checksum, 20);
1403 
1404  // required by external tools
1405  ff_data_to_hex(checksum_string, file_checksum, sizeof(file_checksum), 1);
1406  av_log(c->fc, AV_LOG_INFO, "[aax] file checksum == %s\n", checksum_string);
1407 
1408  /* verify activation data */
1409  if (!activation_bytes) {
1410  av_log(c->fc, AV_LOG_WARNING, "[aax] activation_bytes option is missing!\n");
1411  ret = 0; /* allow ffprobe to continue working on .aax files */
1412  goto fail;
1413  }
1414  if (c->activation_bytes_size != 4) {
1415  av_log(c->fc, AV_LOG_FATAL, "[aax] activation_bytes value needs to be 4 bytes!\n");
1416  ret = AVERROR(EINVAL);
1417  goto fail;
1418  }
1419 
1420  /* verify fixed key */
1421  if (c->audible_fixed_key_size != 16) {
1422  av_log(c->fc, AV_LOG_FATAL, "[aax] audible_fixed_key value needs to be 16 bytes!\n");
1423  ret = AVERROR(EINVAL);
1424  goto fail;
1425  }
1426 
1427  /* AAX (and AAX+) key derivation */
1428  av_sha_init(sha, 160);
1429  av_sha_update(sha, fixed_key, 16);
1430  av_sha_update(sha, activation_bytes, 4);
1431  av_sha_final(sha, intermediate_key);
1432  av_sha_init(sha, 160);
1433  av_sha_update(sha, fixed_key, 16);
1434  av_sha_update(sha, intermediate_key, 20);
1435  av_sha_update(sha, activation_bytes, 4);
1436  av_sha_final(sha, intermediate_iv);
1437  av_sha_init(sha, 160);
1438  av_sha_update(sha, intermediate_key, 16);
1439  av_sha_update(sha, intermediate_iv, 16);
1440  av_sha_final(sha, calculated_checksum);
1441  if (memcmp(calculated_checksum, file_checksum, 20)) { // critical error
1442  av_log(c->fc, AV_LOG_ERROR, "[aax] mismatch in checksums!\n");
1444  goto fail;
1445  }
1446  av_aes_init(c->aes_decrypt, intermediate_key, 128, 1);
1447  av_aes_crypt(c->aes_decrypt, output, input, DRM_BLOB_SIZE >> 4, intermediate_iv, 1);
1448  for (i = 0; i < 4; i++) {
1449  // file data (in output) is stored in big-endian mode
1450  if (activation_bytes[i] != output[3 - i]) { // critical error
1451  av_log(c->fc, AV_LOG_ERROR, "[aax] error in drm blob decryption!\n");
1453  goto fail;
1454  }
1455  }
1456  memcpy(c->file_key, output + 8, 16);
1457  memcpy(input, output + 26, 16);
1458  av_sha_init(sha, 160);
1459  av_sha_update(sha, input, 16);
1460  av_sha_update(sha, c->file_key, 16);
1461  av_sha_update(sha, fixed_key, 16);
1462  av_sha_final(sha, c->file_iv);
1463 
1464 fail:
1465  av_free(sha);
1466 
1467  return ret;
1468 }
1469 
1471 {
1472  if (c->audible_key_size != 16) {
1473  av_log(c->fc, AV_LOG_FATAL, "[aaxc] audible_key value needs to be 16 bytes!\n");
1474  return AVERROR(EINVAL);
1475  }
1476 
1477  if (c->audible_iv_size != 16) {
1478  av_log(c->fc, AV_LOG_FATAL, "[aaxc] audible_iv value needs to be 16 bytes!\n");
1479  return AVERROR(EINVAL);
1480  }
1481 
1482  c->aes_decrypt = av_aes_alloc();
1483  if (!c->aes_decrypt) {
1484  return AVERROR(ENOMEM);
1485  }
1486 
1487  memcpy(c->file_key, c->audible_key, 16);
1488  memcpy(c->file_iv, c->audible_iv, 16);
1489  c->aax_mode = 1;
1490 
1491  return 0;
1492 }
1493 
1494 // Audible AAX (and AAX+) bytestream decryption
1495 static int aax_filter(uint8_t *input, int size, MOVContext *c)
1496 {
1497  int blocks = 0;
1498  unsigned char iv[16];
1499 
1500  memcpy(iv, c->file_iv, 16); // iv is overwritten
1501  blocks = size >> 4; // trailing bytes are not encrypted!
1502  av_aes_init(c->aes_decrypt, c->file_key, 128, 1);
1503  av_aes_crypt(c->aes_decrypt, input, input, blocks, iv, 1);
1504 
1505  return 0;
1506 }
1507 
1508 /* read major brand, minor version and compatible brands and store them as metadata */
1510 {
1511  uint32_t minor_ver;
1512  int comp_brand_size;
1513  char* comp_brands_str;
1514  uint8_t type[5] = {0};
1515  int ret = ffio_read_size(pb, type, 4);
1516  if (ret < 0)
1517  return ret;
1518  if (c->fc->nb_streams) {
1519  if (c->fc->strict_std_compliance >= FF_COMPLIANCE_STRICT)
1520  return AVERROR_INVALIDDATA;
1521  av_log(c->fc, AV_LOG_DEBUG, "Ignoring duplicate FTYP\n");
1522  return 0;
1523  }
1524 
1525  if (strcmp(type, "qt "))
1526  c->isom = 1;
1527  av_log(c->fc, AV_LOG_DEBUG, "ISO: File Type Major Brand: %.4s\n",(char *)&type);
1528  av_dict_set(&c->fc->metadata, "major_brand", type, 0);
1529  minor_ver = avio_rb32(pb); /* minor version */
1530  av_dict_set_int(&c->fc->metadata, "minor_version", minor_ver, 0);
1531 
1532  comp_brand_size = atom.size - 8;
1533  if (comp_brand_size < 0 || comp_brand_size == INT_MAX)
1534  return AVERROR_INVALIDDATA;
1535  comp_brands_str = av_malloc(comp_brand_size + 1); /* Add null terminator */
1536  if (!comp_brands_str)
1537  return AVERROR(ENOMEM);
1538 
1539  ret = ffio_read_size(pb, comp_brands_str, comp_brand_size);
1540  if (ret < 0) {
1541  av_freep(&comp_brands_str);
1542  return ret;
1543  }
1544  comp_brands_str[comp_brand_size] = 0;
1545  av_dict_set(&c->fc->metadata, "compatible_brands",
1546  comp_brands_str, AV_DICT_DONT_STRDUP_VAL);
1547 
1548  // Logic for handling Audible's .aaxc files
1549  if (!strcmp(type, "aaxc")) {
1550  mov_aaxc_crypto(c);
1551  }
1552 
1553  return 0;
1554 }
1555 
1556 /* this atom should contain all header atoms */
1558 {
1559  int ret;
1560 
1561  if (c->found_moov) {
1562  av_log(c->fc, AV_LOG_WARNING, "Found duplicated MOOV Atom. Skipped it\n");
1563  avio_skip(pb, atom.size);
1564  return 0;
1565  }
1566 
1567  if ((ret = mov_read_default(c, pb, atom)) < 0)
1568  return ret;
1569  /* we parsed the 'moov' atom, we can terminate the parsing as soon as we find the 'mdat' */
1570  /* so we don't parse the whole file if over a network */
1571  c->found_moov=1;
1572  return 0; /* now go for mdat */
1573 }
1574 
1576  MOVFragmentIndex *frag_index,
1577  int index,
1578  int id)
1579 {
1580  int i;
1581  MOVFragmentIndexItem * item;
1582 
1583  if (index < 0 || index >= frag_index->nb_items)
1584  return NULL;
1585  item = &frag_index->item[index];
1586  for (i = 0; i < item->nb_stream_info; i++)
1587  if (item->stream_info[i].id == id)
1588  return &item->stream_info[i];
1589 
1590  // This shouldn't happen
1591  return NULL;
1592 }
1593 
1594 static void set_frag_stream(MOVFragmentIndex *frag_index, int id)
1595 {
1596  int i;
1597  MOVFragmentIndexItem * item;
1598 
1599  if (frag_index->current < 0 ||
1600  frag_index->current >= frag_index->nb_items)
1601  return;
1602 
1603  item = &frag_index->item[frag_index->current];
1604  for (i = 0; i < item->nb_stream_info; i++)
1605  if (item->stream_info[i].id == id) {
1606  item->current = i;
1607  return;
1608  }
1609 
1610  // id not found. This shouldn't happen.
1611  item->current = -1;
1612 }
1613 
1615  MOVFragmentIndex *frag_index)
1616 {
1617  MOVFragmentIndexItem *item;
1618  if (frag_index->current < 0 ||
1619  frag_index->current >= frag_index->nb_items)
1620  return NULL;
1621 
1622  item = &frag_index->item[frag_index->current];
1623  if (item->current >= 0 && item->current < item->nb_stream_info)
1624  return &item->stream_info[item->current];
1625 
1626  // This shouldn't happen
1627  return NULL;
1628 }
1629 
1631 {
1632  int a, b, m;
1633  int64_t moof_offset;
1634 
1635  // Optimize for appending new entries
1636  if (!frag_index->nb_items ||
1637  frag_index->item[frag_index->nb_items - 1].moof_offset < offset)
1638  return frag_index->nb_items;
1639 
1640  a = -1;
1641  b = frag_index->nb_items;
1642 
1643  while (b - a > 1) {
1644  m = (a + b) >> 1;
1645  moof_offset = frag_index->item[m].moof_offset;
1646  if (moof_offset >= offset)
1647  b = m;
1648  if (moof_offset <= offset)
1649  a = m;
1650  }
1651  return b;
1652 }
1653 
1655 {
1656  av_assert0(frag_stream_info);
1657  if (frag_stream_info->sidx_pts != AV_NOPTS_VALUE)
1658  return frag_stream_info->sidx_pts;
1659  if (frag_stream_info->first_tfra_pts != AV_NOPTS_VALUE)
1660  return frag_stream_info->first_tfra_pts;
1661  return frag_stream_info->tfdt_dts;
1662 }
1663 
1665  MOVFragmentIndex *frag_index, int index)
1666 {
1667  MOVFragmentStreamInfo * frag_stream_info;
1668  MOVStreamContext *sc = dst_st->priv_data;
1669  int64_t timestamp;
1670  int i, j;
1671 
1672  // If the stream is referenced by any sidx, limit the search
1673  // to fragments that referenced this stream in the sidx
1674  if (sc->has_sidx) {
1675  frag_stream_info = get_frag_stream_info(frag_index, index, sc->id);
1676  if (frag_stream_info->sidx_pts != AV_NOPTS_VALUE)
1677  return frag_stream_info->sidx_pts;
1678  if (frag_stream_info->first_tfra_pts != AV_NOPTS_VALUE)
1679  return frag_stream_info->first_tfra_pts;
1680  return frag_stream_info->sidx_pts;
1681  }
1682 
1683  for (i = 0; i < frag_index->item[index].nb_stream_info; i++) {
1684  AVStream *frag_stream = NULL;
1685  frag_stream_info = &frag_index->item[index].stream_info[i];
1686  for (j = 0; j < s->nb_streams; j++) {
1687  MOVStreamContext *sc2 = s->streams[j]->priv_data;
1688  if (sc2->id == frag_stream_info->id)
1689  frag_stream = s->streams[j];
1690  }
1691  if (!frag_stream) {
1692  av_log(s, AV_LOG_WARNING, "No stream matching sidx ID found.\n");
1693  continue;
1694  }
1695  timestamp = get_stream_info_time(frag_stream_info);
1696  if (timestamp != AV_NOPTS_VALUE)
1697  return av_rescale_q(timestamp, frag_stream->time_base, dst_st->time_base);
1698  }
1699  return AV_NOPTS_VALUE;
1700 }
1701 
1703  AVStream *st, int64_t timestamp)
1704 {
1705  int a, b, m, m0;
1706  int64_t frag_time;
1707 
1708  a = -1;
1709  b = frag_index->nb_items;
1710 
1711  while (b - a > 1) {
1712  m0 = m = (a + b) >> 1;
1713 
1714  while (m < b &&
1715  (frag_time = get_frag_time(s, st, frag_index, m)) == AV_NOPTS_VALUE)
1716  m++;
1717 
1718  if (m < b && frag_time <= timestamp)
1719  a = m;
1720  else
1721  b = m0;
1722  }
1723 
1724  return a;
1725 }
1726 
1728 {
1729  int index, i;
1730  MOVFragmentIndexItem * item;
1731  MOVFragmentStreamInfo * frag_stream_info;
1732 
1733  // If moof_offset already exists in frag_index, return index to it
1734  index = search_frag_moof_offset(&c->frag_index, offset);
1735  if (index < c->frag_index.nb_items &&
1736  c->frag_index.item[index].moof_offset == offset)
1737  return index;
1738 
1739  // offset is not yet in frag index.
1740  // Insert new item at index (sorted by moof offset)
1741  item = av_fast_realloc(c->frag_index.item,
1742  &c->frag_index.allocated_size,
1743  (c->frag_index.nb_items + 1) *
1744  sizeof(*c->frag_index.item));
1745  if (!item)
1746  return -1;
1747  c->frag_index.item = item;
1748 
1749  frag_stream_info = av_realloc_array(NULL, c->fc->nb_streams,
1750  sizeof(*item->stream_info));
1751  if (!frag_stream_info)
1752  return -1;
1753 
1754  for (i = 0; i < c->fc->nb_streams; i++) {
1755  // Avoid building frag index if streams lack track id.
1756  MOVStreamContext *sc = c->fc->streams[i]->priv_data;
1757  if (sc->id < 0) {
1758  av_free(frag_stream_info);
1759  return AVERROR_INVALIDDATA;
1760  }
1761 
1762  frag_stream_info[i].id = sc->id;
1763  frag_stream_info[i].sidx_pts = AV_NOPTS_VALUE;
1764  frag_stream_info[i].tfdt_dts = AV_NOPTS_VALUE;
1765  frag_stream_info[i].next_trun_dts = AV_NOPTS_VALUE;
1766  frag_stream_info[i].first_tfra_pts = AV_NOPTS_VALUE;
1767  frag_stream_info[i].index_base = -1;
1768  frag_stream_info[i].index_entry = -1;
1769  frag_stream_info[i].encryption_index = NULL;
1770  frag_stream_info[i].stsd_id = -1;
1771  }
1772 
1773  if (index < c->frag_index.nb_items)
1774  memmove(c->frag_index.item + index + 1, c->frag_index.item + index,
1775  (c->frag_index.nb_items - index) * sizeof(*c->frag_index.item));
1776 
1777  item = &c->frag_index.item[index];
1778  item->headers_read = 0;
1779  item->current = 0;
1780  item->nb_stream_info = c->fc->nb_streams;
1781  item->moof_offset = offset;
1782  item->stream_info = frag_stream_info;
1783  c->frag_index.nb_items++;
1784 
1785  return index;
1786 }
1787 
1788 static void fix_frag_index_entries(MOVFragmentIndex *frag_index, int index,
1789  int id, int entries)
1790 {
1791  int i;
1792  MOVFragmentStreamInfo * frag_stream_info;
1793 
1794  if (index < 0)
1795  return;
1796  for (i = index; i < frag_index->nb_items; i++) {
1797  frag_stream_info = get_frag_stream_info(frag_index, i, id);
1798  if (frag_stream_info && frag_stream_info->index_entry >= 0)
1799  frag_stream_info->index_entry += entries;
1800  }
1801 }
1802 
1804 {
1805  // Set by mov_read_tfhd(). mov_read_trun() will reject files missing tfhd.
1806  c->fragment.found_tfhd = 0;
1807 
1808  if (!c->has_looked_for_mfra && c->use_mfra_for > 0) {
1809  c->has_looked_for_mfra = 1;
1810  if (pb->seekable & AVIO_SEEKABLE_NORMAL) {
1811  int ret;
1812  av_log(c->fc, AV_LOG_VERBOSE, "stream has moof boxes, will look "
1813  "for a mfra\n");
1814  if ((ret = mov_read_mfra(c, pb)) < 0) {
1815  av_log(c->fc, AV_LOG_VERBOSE, "found a moof box but failed to "
1816  "read the mfra (may be a live ismv)\n");
1817  }
1818  } else {
1819  av_log(c->fc, AV_LOG_VERBOSE, "found a moof box but stream is not "
1820  "seekable, can not look for mfra\n");
1821  }
1822  }
1823  c->fragment.moof_offset = c->fragment.implicit_offset = avio_tell(pb) - 8;
1824  av_log(c->fc, AV_LOG_TRACE, "moof offset %"PRIx64"\n", c->fragment.moof_offset);
1825  c->frag_index.current = update_frag_index(c, c->fragment.moof_offset);
1826  return mov_read_default(c, pb, atom);
1827 }
1828 
1830 {
1831  int64_t time;
1832  if (version == 1) {
1833  time = avio_rb64(pb);
1834  avio_rb64(pb);
1835  if (time < 0) {
1836  av_log(c->fc, AV_LOG_DEBUG, "creation_time is negative\n");
1837  return;
1838  }
1839  } else {
1840  time = avio_rb32(pb);
1841  avio_rb32(pb); /* modification time */
1842  if (time > 0 && time < 2082844800) {
1843  av_log(c->fc, AV_LOG_WARNING, "Detected creation time before 1970, parsing as unix timestamp.\n");
1844  time += 2082844800;
1845  }
1846  }
1847  if (time) {
1848  time -= 2082844800; /* seconds between 1904-01-01 and Epoch */
1849 
1850  if ((int64_t)(time * 1000000ULL) / 1000000 != time) {
1851  av_log(c->fc, AV_LOG_DEBUG, "creation_time is not representable\n");
1852  return;
1853  }
1854 
1855  avpriv_dict_set_timestamp(metadata, "creation_time", time * 1000000);
1856  }
1857 }
1858 
1860 {
1861  AVStream *st;
1862  MOVStreamContext *sc;
1863  int version;
1864  char language[4] = {0};
1865  unsigned lang;
1866 
1867  if (c->fc->nb_streams < 1)
1868  return 0;
1869  st = c->fc->streams[c->fc->nb_streams-1];
1870  sc = st->priv_data;
1871 
1872  if (sc->time_scale) {
1873  av_log(c->fc, AV_LOG_ERROR, "Multiple mdhd?\n");
1874  return AVERROR_INVALIDDATA;
1875  }
1876 
1877  version = avio_r8(pb);
1878  if (version > 1) {
1879  avpriv_request_sample(c->fc, "Version %d", version);
1880  return AVERROR_PATCHWELCOME;
1881  }
1882  avio_rb24(pb); /* flags */
1884 
1885  sc->time_scale = avio_rb32(pb);
1886  if (sc->time_scale <= 0) {
1887  av_log(c->fc, AV_LOG_ERROR, "Invalid mdhd time scale %d, defaulting to 1\n", sc->time_scale);
1888  sc->time_scale = 1;
1889  }
1890  st->duration = (version == 1) ? avio_rb64(pb) : avio_rb32(pb); /* duration */
1891 
1892  if ((version == 1 && st->duration == UINT64_MAX) ||
1893  (version != 1 && st->duration == UINT32_MAX)) {
1894  st->duration = 0;
1895  }
1896 
1897  lang = avio_rb16(pb); /* language */
1898  if (ff_mov_lang_to_iso639(lang, language))
1899  av_dict_set(&st->metadata, "language", language, 0);
1900  avio_rb16(pb); /* quality */
1901 
1902  return 0;
1903 }
1904 
1906 {
1907  int i;
1908  int version = avio_r8(pb); /* version */
1909  avio_rb24(pb); /* flags */
1910 
1911  mov_metadata_creation_time(c, pb, &c->fc->metadata, version);
1912  c->time_scale = avio_rb32(pb); /* time scale */
1913  if (c->time_scale <= 0) {
1914  av_log(c->fc, AV_LOG_ERROR, "Invalid mvhd time scale %d, defaulting to 1\n", c->time_scale);
1915  c->time_scale = 1;
1916  }
1917  av_log(c->fc, AV_LOG_TRACE, "time scale = %i\n", c->time_scale);
1918 
1919  c->duration = (version == 1) ? avio_rb64(pb) : avio_rb32(pb); /* duration */
1920  avio_rb32(pb); /* preferred scale */
1921 
1922  avio_rb16(pb); /* preferred volume */
1923 
1924  avio_skip(pb, 10); /* reserved */
1925 
1926  /* movie display matrix, store it in main context and use it later on */
1927  for (i = 0; i < 3; i++) {
1928  c->movie_display_matrix[i][0] = avio_rb32(pb); // 16.16 fixed point
1929  c->movie_display_matrix[i][1] = avio_rb32(pb); // 16.16 fixed point
1930  c->movie_display_matrix[i][2] = avio_rb32(pb); // 2.30 fixed point
1931  }
1932 
1933  avio_rb32(pb); /* preview time */
1934  avio_rb32(pb); /* preview duration */
1935  avio_rb32(pb); /* poster time */
1936  avio_rb32(pb); /* selection time */
1937  avio_rb32(pb); /* selection duration */
1938  avio_rb32(pb); /* current time */
1939  avio_rb32(pb); /* next track ID */
1940 
1941  return 0;
1942 }
1943 
1945 {
1946  AVStream *st;
1947 
1948  if (fc->nb_streams < 1)
1949  return;
1950  st = fc->streams[fc->nb_streams-1];
1951 
1952  switch (st->codecpar->codec_id) {
1953  case AV_CODEC_ID_PCM_S16BE:
1955  break;
1956  case AV_CODEC_ID_PCM_S24BE:
1958  break;
1959  case AV_CODEC_ID_PCM_S32BE:
1961  break;
1962  case AV_CODEC_ID_PCM_F32BE:
1964  break;
1965  case AV_CODEC_ID_PCM_F64BE:
1967  break;
1968  default:
1969  break;
1970  }
1971 }
1972 
1974 {
1975  int little_endian = avio_rb16(pb) & 0xFF;
1976  av_log(c->fc, AV_LOG_TRACE, "enda %d\n", little_endian);
1977  if (little_endian == 1)
1979  return 0;
1980 }
1981 
1983 {
1984  int format_flags;
1985  int version, flags;
1986  int pcm_sample_size;
1987  AVFormatContext *fc = c->fc;
1988  AVStream *st;
1989  MOVStreamContext *sc;
1990 
1991  if (atom.size < 6) {
1992  av_log(c->fc, AV_LOG_ERROR, "Empty pcmC box\n");
1993  return AVERROR_INVALIDDATA;
1994  }
1995 
1996  version = avio_r8(pb);
1997  flags = avio_rb24(pb);
1998 
1999  if (version != 0 || flags != 0) {
2000  av_log(c->fc, AV_LOG_ERROR,
2001  "Unsupported 'pcmC' box with version %d, flags: %x",
2002  version, flags);
2003  return AVERROR_INVALIDDATA;
2004  }
2005 
2006  format_flags = avio_r8(pb);
2007  pcm_sample_size = avio_r8(pb);
2008 
2009  if (fc->nb_streams < 1)
2010  return AVERROR_INVALIDDATA;
2011 
2012  st = fc->streams[fc->nb_streams - 1];
2013  sc = st->priv_data;
2014 
2015  if (sc->format == MOV_MP4_FPCM_TAG) {
2016  switch (pcm_sample_size) {
2017  case 32:
2019  break;
2020  case 64:
2022  break;
2023  default:
2024  av_log(fc, AV_LOG_ERROR, "invalid pcm_sample_size %d for %s\n",
2025  pcm_sample_size,
2026  av_fourcc2str(sc->format));
2027  return AVERROR_INVALIDDATA;
2028  }
2029  } else if (sc->format == MOV_MP4_IPCM_TAG) {
2030  switch (pcm_sample_size) {
2031  case 16:
2033  break;
2034  case 24:
2036  break;
2037  case 32:
2039  break;
2040  default:
2041  av_log(fc, AV_LOG_ERROR, "invalid pcm_sample_size %d for %s\n",
2042  pcm_sample_size,
2043  av_fourcc2str(sc->format));
2044  return AVERROR_INVALIDDATA;
2045  }
2046  } else {
2047  av_log(fc, AV_LOG_ERROR, "'pcmC' with invalid sample entry '%s'\n",
2048  av_fourcc2str(sc->format));
2049  return AVERROR_INVALIDDATA;
2050  }
2051 
2052  if (format_flags & 1) // indicates little-endian format. If not present, big-endian format is used
2055 
2056  return 0;
2057 }
2058 
2060 {
2061  AVStream *st;
2062  HEIFItem *item = NULL;
2063  char color_parameter_type[5] = { 0 };
2064  uint16_t color_primaries, color_trc, color_matrix;
2065  int ret;
2066 
2067  st = get_curr_st(c);
2068  if (!st) {
2069  item = heif_cur_item(c);
2070  if (!item)
2071  return 0;
2072  }
2073 
2074  ret = ffio_read_size(pb, color_parameter_type, 4);
2075  if (ret < 0)
2076  return ret;
2077  if (strncmp(color_parameter_type, "nclx", 4) &&
2078  strncmp(color_parameter_type, "nclc", 4) &&
2079  strncmp(color_parameter_type, "prof", 4)) {
2080  av_log(c->fc, AV_LOG_WARNING, "unsupported color_parameter_type %s\n",
2081  color_parameter_type);
2082  return 0;
2083  }
2084 
2085  if (!strncmp(color_parameter_type, "prof", 4)) {
2086  AVPacketSideData *sd;
2087  uint8_t *icc_profile;
2088  if (st) {
2092  atom.size - 4, 0);
2093  if (!sd)
2094  return AVERROR(ENOMEM);
2095  icc_profile = sd->data;
2096  } else {
2097  av_freep(&item->icc_profile);
2098  icc_profile = item->icc_profile = av_malloc(atom.size - 4);
2099  if (!icc_profile) {
2100  item->icc_profile_size = 0;
2101  return AVERROR(ENOMEM);
2102  }
2103  item->icc_profile_size = atom.size - 4;
2104  }
2105  ret = ffio_read_size(pb, icc_profile, atom.size - 4);
2106  if (ret < 0)
2107  return ret;
2108  } else if (st) {
2109  color_primaries = avio_rb16(pb);
2110  color_trc = avio_rb16(pb);
2111  color_matrix = avio_rb16(pb);
2112 
2113  av_log(c->fc, AV_LOG_TRACE,
2114  "%s: pri %d trc %d matrix %d",
2115  color_parameter_type, color_primaries, color_trc, color_matrix);
2116 
2117  if (!strncmp(color_parameter_type, "nclx", 4)) {
2118  uint8_t color_range = avio_r8(pb) >> 7;
2119  av_log(c->fc, AV_LOG_TRACE, " full %"PRIu8"", color_range);
2120  if (color_range)
2122  else
2124  }
2125 
2128  if (!av_color_transfer_name(color_trc))
2129  color_trc = AVCOL_TRC_UNSPECIFIED;
2130  if (!av_color_space_name(color_matrix))
2131  color_matrix = AVCOL_SPC_UNSPECIFIED;
2132 
2134  st->codecpar->color_trc = color_trc;
2135  st->codecpar->color_space = color_matrix;
2136  av_log(c->fc, AV_LOG_TRACE, "\n");
2137  }
2138  return 0;
2139 }
2140 
2142 {
2143  AVStream *st;
2144  unsigned mov_field_order;
2145  enum AVFieldOrder decoded_field_order = AV_FIELD_UNKNOWN;
2146 
2147  if (c->fc->nb_streams < 1) // will happen with jp2 files
2148  return 0;
2149  st = c->fc->streams[c->fc->nb_streams-1];
2150  if (atom.size < 2)
2151  return AVERROR_INVALIDDATA;
2152  mov_field_order = avio_rb16(pb);
2153  if ((mov_field_order & 0xFF00) == 0x0100)
2154  decoded_field_order = AV_FIELD_PROGRESSIVE;
2155  else if ((mov_field_order & 0xFF00) == 0x0200) {
2156  switch (mov_field_order & 0xFF) {
2157  case 0x01: decoded_field_order = AV_FIELD_TT;
2158  break;
2159  case 0x06: decoded_field_order = AV_FIELD_BB;
2160  break;
2161  case 0x09: decoded_field_order = AV_FIELD_TB;
2162  break;
2163  case 0x0E: decoded_field_order = AV_FIELD_BT;
2164  break;
2165  }
2166  }
2167  if (decoded_field_order == AV_FIELD_UNKNOWN && mov_field_order) {
2168  av_log(c->fc, AV_LOG_ERROR, "Unknown MOV field order 0x%04x\n", mov_field_order);
2169  }
2170  st->codecpar->field_order = decoded_field_order;
2171 
2172  return 0;
2173 }
2174 
2176 {
2177  int err = 0;
2178  uint64_t size = (uint64_t)par->extradata_size + atom.size + 8 + AV_INPUT_BUFFER_PADDING_SIZE;
2179  if (size > INT_MAX || (uint64_t)atom.size > INT_MAX)
2180  return AVERROR_INVALIDDATA;
2181  if ((err = av_reallocp(&par->extradata, size)) < 0) {
2182  par->extradata_size = 0;
2183  return err;
2184  }
2186  return 0;
2187 }
2188 
2189 /* Read a whole atom into the extradata return the size of the atom read, possibly truncated if != atom.size */
2191  AVCodecParameters *par, uint8_t *buf)
2192 {
2193  int64_t result = atom.size;
2194  int err;
2195 
2196  AV_WB32(buf , atom.size + 8);
2197  AV_WL32(buf + 4, atom.type);
2198  err = ffio_read_size(pb, buf + 8, atom.size);
2199  if (err < 0) {
2200  par->extradata_size -= atom.size;
2201  return err;
2202  } else if (err < atom.size) {
2203  av_log(c->fc, AV_LOG_WARNING, "truncated extradata\n");
2204  par->extradata_size -= atom.size - err;
2205  result = err;
2206  }
2207  memset(buf + 8 + err, 0, AV_INPUT_BUFFER_PADDING_SIZE);
2208  return result;
2209 }
2210 
2211 /* FIXME modify QDM2/SVQ3/H.264 decoders to take full atom as extradata */
2213  enum AVCodecID codec_id)
2214 {
2215  AVStream *st;
2216  uint64_t original_size;
2217  int err;
2218 
2219  if (c->fc->nb_streams < 1) // will happen with jp2 files
2220  return 0;
2221  st = c->fc->streams[c->fc->nb_streams-1];
2222 
2223  if (st->codecpar->codec_id != codec_id)
2224  return 0; /* unexpected codec_id - don't mess with extradata */
2225 
2226  original_size = st->codecpar->extradata_size;
2227  err = mov_realloc_extradata(st->codecpar, atom);
2228  if (err)
2229  return err;
2230 
2231  err = mov_read_atom_into_extradata(c, pb, atom, st->codecpar, st->codecpar->extradata + original_size);
2232  if (err < 0)
2233  return err;
2234  return 0; // Note: this is the original behavior to ignore truncation.
2235 }
2236 
2237 /* wrapper functions for reading ALAC/AVS/MJPEG/MJPEG2000 extradata atoms only for those codecs */
2239 {
2240  return mov_read_extradata(c, pb, atom, AV_CODEC_ID_ALAC);
2241 }
2242 
2244 {
2245  return mov_read_extradata(c, pb, atom, AV_CODEC_ID_CAVS);
2246 }
2247 
2249 {
2250  return mov_read_extradata(c, pb, atom, AV_CODEC_ID_JPEG2000);
2251 }
2252 
2254 {
2255  return mov_read_extradata(c, pb, atom, AV_CODEC_ID_R10K);
2256 }
2257 
2259 {
2260  int ret = mov_read_extradata(c, pb, atom, AV_CODEC_ID_AVUI);
2261  if (!ret)
2262  ret = mov_read_extradata(c, pb, atom, AV_CODEC_ID_DNXHD);
2263  return ret;
2264 }
2265 
2267 {
2268  int ret = mov_read_extradata(c, pb, atom, AV_CODEC_ID_TARGA_Y216);
2269 
2270  if (!ret && c->fc->nb_streams >= 1) {
2271  AVCodecParameters *par = c->fc->streams[c->fc->nb_streams-1]->codecpar;
2272  if (par->extradata_size >= 40) {
2273  par->height = AV_RB16(&par->extradata[36]);
2274  par->width = AV_RB16(&par->extradata[38]);
2275  }
2276  }
2277  return ret;
2278 }
2279 
2281 {
2282  if (c->fc->nb_streams >= 1) {
2283  AVStream *const st = c->fc->streams[c->fc->nb_streams - 1];
2284  FFStream *const sti = ffstream(st);
2285  AVCodecParameters *par = st->codecpar;
2286 
2287  if (par->codec_tag == MKTAG('A', 'V', 'i', 'n') &&
2288  par->codec_id == AV_CODEC_ID_H264 &&
2289  atom.size > 11) {
2290  int cid;
2291  avio_skip(pb, 10);
2292  cid = avio_rb16(pb);
2293  /* For AVID AVCI50, force width of 1440 to be able to select the correct SPS and PPS */
2294  if (cid == 0xd4d || cid == 0xd4e)
2295  par->width = 1440;
2296  return 0;
2297  } else if ((par->codec_tag == MKTAG('A', 'V', 'd', '1') ||
2298  par->codec_tag == MKTAG('A', 'V', 'j', '2') ||
2299  par->codec_tag == MKTAG('A', 'V', 'd', 'n')) &&
2300  atom.size >= 24) {
2301  int num, den;
2302  avio_skip(pb, 12);
2303  num = avio_rb32(pb);
2304  den = avio_rb32(pb);
2305  if (num <= 0 || den <= 0)
2306  return 0;
2307  switch (avio_rb32(pb)) {
2308  case 2:
2309  if (den >= INT_MAX / 2)
2310  return 0;
2311  den *= 2;
2312  case 1:
2313  sti->display_aspect_ratio = (AVRational){ num, den };
2314  default:
2315  return 0;
2316  }
2317  }
2318  }
2319 
2320  return mov_read_avid(c, pb, atom);
2321 }
2322 
2324 {
2325  int ret = 0;
2326  int length = 0;
2327  uint64_t original_size;
2328  if (c->fc->nb_streams >= 1) {
2329  AVCodecParameters *par = c->fc->streams[c->fc->nb_streams-1]->codecpar;
2330  if (par->codec_id == AV_CODEC_ID_H264)
2331  return 0;
2332  if (atom.size == 16) {
2333  original_size = par->extradata_size;
2334  ret = mov_realloc_extradata(par, atom);
2335  if (!ret) {
2336  length = mov_read_atom_into_extradata(c, pb, atom, par, par->extradata + original_size);
2337  if (length == atom.size) {
2338  const uint8_t range_value = par->extradata[original_size + 19];
2339  switch (range_value) {
2340  case 1:
2342  break;
2343  case 2:
2345  break;
2346  default:
2347  av_log(c->fc, AV_LOG_WARNING, "ignored unknown aclr value (%d)\n", range_value);
2348  break;
2349  }
2350  ff_dlog(c->fc, "color_range: %d\n", par->color_range);
2351  } else {
2352  /* For some reason the whole atom was not added to the extradata */
2353  av_log(c->fc, AV_LOG_ERROR, "aclr not decoded - incomplete atom\n");
2354  }
2355  } else {
2356  av_log(c->fc, AV_LOG_ERROR, "aclr not decoded - unable to add atom to extradata\n");
2357  }
2358  } else {
2359  av_log(c->fc, AV_LOG_WARNING, "aclr not decoded - unexpected size %"PRId64"\n", atom.size);
2360  }
2361  }
2362 
2363  return ret;
2364 }
2365 
2367 {
2368  return mov_read_extradata(c, pb, atom, AV_CODEC_ID_SVQ3);
2369 }
2370 
2372 {
2373  AVStream *st;
2374  int ret;
2375 
2376  if (c->fc->nb_streams < 1)
2377  return 0;
2378  st = c->fc->streams[c->fc->nb_streams-1];
2379 
2380  if ((uint64_t)atom.size > (1<<30))
2381  return AVERROR_INVALIDDATA;
2382 
2383  if (st->codecpar->codec_id == AV_CODEC_ID_QDM2 ||
2386  // pass all frma atom to codec, needed at least for QDMC and QDM2
2387  ret = ff_get_extradata(c->fc, st->codecpar, pb, atom.size);
2388  if (ret < 0)
2389  return ret;
2390  } else if (atom.size > 8) { /* to read frma, esds atoms */
2391  if (st->codecpar->codec_id == AV_CODEC_ID_ALAC && atom.size >= 24) {
2392  uint64_t buffer;
2393  ret = ffio_ensure_seekback(pb, 8);
2394  if (ret < 0)
2395  return ret;
2396  buffer = avio_rb64(pb);
2397  atom.size -= 8;
2398  if ( (buffer & 0xFFFFFFFF) == MKBETAG('f','r','m','a')
2399  && buffer >> 32 <= atom.size
2400  && buffer >> 32 >= 8) {
2401  avio_skip(pb, -8);
2402  atom.size += 8;
2403  } else if (!st->codecpar->extradata_size) {
2404 #define ALAC_EXTRADATA_SIZE 36
2406  if (!st->codecpar->extradata)
2407  return AVERROR(ENOMEM);
2410  AV_WB32(st->codecpar->extradata + 4, MKTAG('a','l','a','c'));
2411  AV_WB64(st->codecpar->extradata + 12, buffer);
2412  avio_read(pb, st->codecpar->extradata + 20, 16);
2413  avio_skip(pb, atom.size - 24);
2414  return 0;
2415  }
2416  }
2417  if ((ret = mov_read_default(c, pb, atom)) < 0)
2418  return ret;
2419  } else
2420  avio_skip(pb, atom.size);
2421  return 0;
2422 }
2423 
2424 /**
2425  * This function reads atom content and puts data in extradata without tag
2426  * nor size unlike mov_read_extradata.
2427  */
2429 {
2430  AVStream *st;
2431  int ret;
2432 
2433  st = get_curr_st(c);
2434  if (!st)
2435  return 0;
2436 
2437  if ((uint64_t)atom.size > (1<<30))
2438  return AVERROR_INVALIDDATA;
2439 
2440  if (atom.type == MKTAG('v','v','c','C')) {
2441  avio_skip(pb, 4);
2442  atom.size -= 4;
2443  }
2444 
2445  if (atom.size >= 10) {
2446  // Broken files created by legacy versions of libavformat will
2447  // wrap a whole fiel atom inside of a glbl atom.
2448  unsigned size = avio_rb32(pb);
2449  unsigned type = avio_rl32(pb);
2450  if (avio_feof(pb))
2451  return AVERROR_INVALIDDATA;
2452  avio_seek(pb, -8, SEEK_CUR);
2453  if (type == MKTAG('f','i','e','l') && size == atom.size)
2454  return mov_read_default(c, pb, atom);
2455  }
2456  if (st->codecpar->extradata_size > 1 && st->codecpar->extradata) {
2457  av_log(c->fc, AV_LOG_WARNING, "ignoring multiple glbl\n");
2458  return 0;
2459  }
2460  ret = ff_get_extradata(c->fc, st->codecpar, pb, atom.size);
2461  if (ret < 0)
2462  return ret;
2463  if (atom.type == MKTAG('h','v','c','C') && st->codecpar->codec_tag == MKTAG('d','v','h','1'))
2464  /* HEVC-based Dolby Vision derived from hvc1.
2465  Happens to match with an identifier
2466  previously utilized for DV. Thus, if we have
2467  the hvcC extradata box available as specified,
2468  set codec to HEVC */
2470 
2471  return 0;
2472 }
2473 
2475 {
2476  AVStream *st;
2477  uint8_t profile_level;
2478  int ret;
2479 
2480  if (c->fc->nb_streams < 1)
2481  return 0;
2482  st = c->fc->streams[c->fc->nb_streams-1];
2483 
2484  if (atom.size >= (1<<28) || atom.size < 7)
2485  return AVERROR_INVALIDDATA;
2486 
2487  profile_level = avio_r8(pb);
2488  if ((profile_level & 0xf0) != 0xc0)
2489  return 0;
2490 
2491  avio_seek(pb, 6, SEEK_CUR);
2492  ret = ff_get_extradata(c->fc, st->codecpar, pb, atom.size - 7);
2493  if (ret < 0)
2494  return ret;
2495 
2496  return 0;
2497 }
2498 
2500 {
2501  AVStream* st;
2502  MOVStreamContext* sc;
2503 
2504  if (c->fc->nb_streams < 1)
2505  return 0;
2506 
2507  /* For SBAS this should be fine - though beware if someone implements a
2508  * tref atom processor that doesn't drop down to default then this may
2509  * be lost. */
2510  if (atom.size > 4) {
2511  av_log(c->fc, AV_LOG_ERROR, "Only a single tref of type sbas is supported\n");
2512  return AVERROR_PATCHWELCOME;
2513  }
2514 
2515  st = c->fc->streams[c->fc->nb_streams - 1];
2516  sc = st->priv_data;
2517  sc->tref_id = avio_rb32(pb);
2519 
2520  return 0;
2521 }
2522 
2523 /**
2524  * An strf atom is a BITMAPINFOHEADER struct. This struct is 40 bytes itself,
2525  * but can have extradata appended at the end after the 40 bytes belonging
2526  * to the struct.
2527  */
2529 {
2530  AVStream *st;
2531  int ret;
2532 
2533  if (c->fc->nb_streams < 1)
2534  return 0;
2535  if (atom.size <= 40)
2536  return 0;
2537  st = c->fc->streams[c->fc->nb_streams-1];
2538 
2539  if ((uint64_t)atom.size > (1<<30))
2540  return AVERROR_INVALIDDATA;
2541 
2542  avio_skip(pb, 40);
2543  ret = ff_get_extradata(c->fc, st->codecpar, pb, atom.size - 40);
2544  if (ret < 0)
2545  return ret;
2546 
2547  return 0;
2548 }
2549 
2551 {
2552  AVStream *st;
2553  MOVStreamContext *sc;
2554  unsigned int i, entries;
2555 
2556  if (c->trak_index < 0) {
2557  av_log(c->fc, AV_LOG_WARNING, "STCO outside TRAK\n");
2558  return 0;
2559  }
2560  if (c->fc->nb_streams < 1)
2561  return 0;
2562  st = c->fc->streams[c->fc->nb_streams-1];
2563  sc = st->priv_data;
2564 
2565  avio_r8(pb); /* version */
2566  avio_rb24(pb); /* flags */
2567 
2568  // Clamp allocation size for `chunk_offsets` -- don't throw an error for an
2569  // invalid count since the EOF path doesn't throw either.
2570  entries = avio_rb32(pb);
2571  entries =
2572  FFMIN(entries,
2573  FFMAX(0, (atom.size - 8) /
2574  (atom.type == MKTAG('s', 't', 'c', 'o') ? 4 : 8)));
2575 
2576  if (!entries)
2577  return 0;
2578 
2579  if (sc->chunk_offsets) {
2580  av_log(c->fc, AV_LOG_WARNING, "Ignoring duplicated STCO atom\n");
2581  return 0;
2582  }
2583 
2584  av_free(sc->chunk_offsets);
2585  sc->chunk_count = 0;
2586  sc->chunk_offsets = av_malloc_array(entries, sizeof(*sc->chunk_offsets));
2587  if (!sc->chunk_offsets)
2588  return AVERROR(ENOMEM);
2589  sc->chunk_count = entries;
2590 
2591  if (atom.type == MKTAG('s','t','c','o'))
2592  for (i = 0; i < entries && !pb->eof_reached; i++)
2593  sc->chunk_offsets[i] = avio_rb32(pb);
2594  else if (atom.type == MKTAG('c','o','6','4'))
2595  for (i = 0; i < entries && !pb->eof_reached; i++) {
2596  sc->chunk_offsets[i] = avio_rb64(pb);
2597  if (sc->chunk_offsets[i] < 0) {
2598  av_log(c->fc, AV_LOG_WARNING, "Impossible chunk_offset\n");
2599  sc->chunk_offsets[i] = 0;
2600  }
2601  }
2602  else
2603  return AVERROR_INVALIDDATA;
2604 
2605  sc->chunk_count = i;
2606 
2607  if (pb->eof_reached) {
2608  av_log(c->fc, AV_LOG_WARNING, "reached eof, corrupted STCO atom\n");
2609  return AVERROR_EOF;
2610  }
2611 
2612  return 0;
2613 }
2614 
2615 static int mov_codec_id(AVStream *st, uint32_t format)
2616 {
2618 
2619  if (id <= 0 &&
2620  ((format & 0xFFFF) == 'm' + ('s' << 8) ||
2621  (format & 0xFFFF) == 'T' + ('S' << 8)))
2623 
2624  if (st->codecpar->codec_type != AVMEDIA_TYPE_VIDEO && id > 0) {
2626  } else if (st->codecpar->codec_type != AVMEDIA_TYPE_AUDIO &&
2627  /* skip old ASF MPEG-4 tag */
2628  format && format != MKTAG('m','p','4','s')) {
2630  if (id <= 0)
2632  if (id > 0)
2634  else if (st->codecpar->codec_type == AVMEDIA_TYPE_DATA ||
2636  st->codecpar->codec_id == AV_CODEC_ID_NONE)) {
2638  if (id <= 0) {
2640  AV_CODEC_ID_TTML : id;
2641  }
2642 
2643  if (id > 0)
2645  else
2647  }
2648  }
2649 
2650  st->codecpar->codec_tag = format;
2651 
2652  return id;
2653 }
2654 
2656  AVStream *st, MOVStreamContext *sc)
2657 {
2658  uint8_t codec_name[32] = { 0 };
2659  int64_t stsd_start;
2660  unsigned int len;
2661  uint32_t id = 0;
2662 
2663  /* The first 16 bytes of the video sample description are already
2664  * read in ff_mov_read_stsd_entries() */
2665  stsd_start = avio_tell(pb) - 16;
2666 
2667  avio_rb16(pb); /* version */
2668  avio_rb16(pb); /* revision level */
2669  id = avio_rl32(pb); /* vendor */
2670  av_dict_set(&st->metadata, "vendor_id", av_fourcc2str(id), 0);
2671  avio_rb32(pb); /* temporal quality */
2672  avio_rb32(pb); /* spatial quality */
2673 
2674  st->codecpar->width = avio_rb16(pb); /* width */
2675  st->codecpar->height = avio_rb16(pb); /* height */
2676 
2677  avio_rb32(pb); /* horiz resolution */
2678  avio_rb32(pb); /* vert resolution */
2679  avio_rb32(pb); /* data size, always 0 */
2680  avio_rb16(pb); /* frames per samples */
2681 
2682  len = avio_r8(pb); /* codec name, pascal string */
2683  if (len > 31)
2684  len = 31;
2685  mov_read_mac_string(c, pb, len, codec_name, sizeof(codec_name));
2686  if (len < 31)
2687  avio_skip(pb, 31 - len);
2688 
2689  if (codec_name[0])
2690  av_dict_set(&st->metadata, "encoder", codec_name, 0);
2691 
2692  /* codec_tag YV12 triggers an UV swap in rawdec.c */
2693  if (!strncmp(codec_name, "Planar Y'CbCr 8-bit 4:2:0", 25)) {
2694  st->codecpar->codec_tag = MKTAG('I', '4', '2', '0');
2695  st->codecpar->width &= ~1;
2696  st->codecpar->height &= ~1;
2697  }
2698  /* Flash Media Server uses tag H.263 with Sorenson Spark */
2699  if (st->codecpar->codec_tag == MKTAG('H','2','6','3') &&
2700  !strncmp(codec_name, "Sorenson H263", 13))
2702 
2703  st->codecpar->bits_per_coded_sample = avio_rb16(pb); /* depth */
2704 
2705  avio_seek(pb, stsd_start, SEEK_SET);
2706 
2707  if (ff_get_qtpalette(st->codecpar->codec_id, pb, sc->palette)) {
2708  st->codecpar->bits_per_coded_sample &= 0x1F;
2709  sc->has_palette = 1;
2710  }
2711 }
2712 
2714  AVStream *st, MOVStreamContext *sc)
2715 {
2716  int bits_per_sample, flags;
2717  uint16_t version = avio_rb16(pb);
2718  uint32_t id = 0;
2719  AVDictionaryEntry *compatible_brands = av_dict_get(c->fc->metadata, "compatible_brands", NULL, AV_DICT_MATCH_CASE);
2720  int channel_count;
2721 
2722  avio_rb16(pb); /* revision level */
2723  id = avio_rl32(pb); /* vendor */
2724  av_dict_set(&st->metadata, "vendor_id", av_fourcc2str(id), 0);
2725 
2726  channel_count = avio_rb16(pb);
2727 
2729  st->codecpar->ch_layout.nb_channels = channel_count;
2730  st->codecpar->bits_per_coded_sample = avio_rb16(pb); /* sample size */
2731  av_log(c->fc, AV_LOG_TRACE, "audio channels %d\n", channel_count);
2732 
2733  sc->audio_cid = avio_rb16(pb);
2734  avio_rb16(pb); /* packet size = 0 */
2735 
2736  st->codecpar->sample_rate = ((avio_rb32(pb) >> 16));
2737 
2738  // Read QT version 1 fields. In version 0 these do not exist.
2739  av_log(c->fc, AV_LOG_TRACE, "version =%d, isom =%d\n", version, c->isom);
2740  if (!c->isom ||
2741  (compatible_brands && strstr(compatible_brands->value, "qt ")) ||
2742  (sc->stsd_version == 0 && version > 0)) {
2743  if (version == 1) {
2744  sc->samples_per_frame = avio_rb32(pb);
2745  avio_rb32(pb); /* bytes per packet */
2746  sc->bytes_per_frame = avio_rb32(pb);
2747  avio_rb32(pb); /* bytes per sample */
2748  } else if (version == 2) {
2749  avio_rb32(pb); /* sizeof struct only */
2751  channel_count = avio_rb32(pb);
2753  st->codecpar->ch_layout.nb_channels = channel_count;
2754  avio_rb32(pb); /* always 0x7F000000 */
2756 
2757  flags = avio_rb32(pb); /* lpcm format specific flag */
2758  sc->bytes_per_frame = avio_rb32(pb);
2759  sc->samples_per_frame = avio_rb32(pb);
2760  if (st->codecpar->codec_tag == MKTAG('l','p','c','m'))
2761  st->codecpar->codec_id =
2763  flags);
2764  }
2765  if (version == 0 || (version == 1 && sc->audio_cid != -2)) {
2766  /* can't correctly handle variable sized packet as audio unit */
2767  switch (st->codecpar->codec_id) {
2768  case AV_CODEC_ID_MP2:
2769  case AV_CODEC_ID_MP3:
2771  break;
2772  }
2773  }
2774  }
2775 
2776  if (sc->format == 0) {
2777  if (st->codecpar->bits_per_coded_sample == 8)
2778  st->codecpar->codec_id = mov_codec_id(st, MKTAG('r','a','w',' '));
2779  else if (st->codecpar->bits_per_coded_sample == 16)
2780  st->codecpar->codec_id = mov_codec_id(st, MKTAG('t','w','o','s'));
2781  }
2782 
2783  switch (st->codecpar->codec_id) {
2784  case AV_CODEC_ID_PCM_S8:
2785  case AV_CODEC_ID_PCM_U8:
2786  if (st->codecpar->bits_per_coded_sample == 16)
2788  break;
2789  case AV_CODEC_ID_PCM_S16LE:
2790  case AV_CODEC_ID_PCM_S16BE:
2791  if (st->codecpar->bits_per_coded_sample == 8)
2793  else if (st->codecpar->bits_per_coded_sample == 24)
2794  st->codecpar->codec_id =
2797  else if (st->codecpar->bits_per_coded_sample == 32)
2798  st->codecpar->codec_id =
2801  break;
2802  /* set values for old format before stsd version 1 appeared */
2803  case AV_CODEC_ID_MACE3:
2804  sc->samples_per_frame = 6;
2806  break;
2807  case AV_CODEC_ID_MACE6:
2808  sc->samples_per_frame = 6;
2810  break;
2812  sc->samples_per_frame = 64;
2814  break;
2815  case AV_CODEC_ID_GSM:
2816  sc->samples_per_frame = 160;
2817  sc->bytes_per_frame = 33;
2818  break;
2819  default:
2820  break;
2821  }
2822 
2823  bits_per_sample = av_get_bits_per_sample(st->codecpar->codec_id);
2824  if (bits_per_sample && (bits_per_sample >> 3) * (uint64_t)st->codecpar->ch_layout.nb_channels <= INT_MAX) {
2825  st->codecpar->bits_per_coded_sample = bits_per_sample;
2826  sc->sample_size = (bits_per_sample >> 3) * st->codecpar->ch_layout.nb_channels;
2827  }
2828 }
2829 
2831  AVStream *st, MOVStreamContext *sc,
2832  int64_t size)
2833 {
2834  // ttxt stsd contains display flags, justification, background
2835  // color, fonts, and default styles, so fake an atom to read it
2836  MOVAtom fake_atom = { .size = size };
2837  // mp4s contains a regular esds atom, dfxp ISMV TTML has no content
2838  // in extradata unlike stpp MP4 TTML.
2839  if (st->codecpar->codec_tag != AV_RL32("mp4s") &&
2841  mov_read_glbl(c, pb, fake_atom);
2842  st->codecpar->width = sc->width;
2843  st->codecpar->height = sc->height;
2844 }
2845 
2847  AVStream *st, MOVStreamContext *sc,
2848  int64_t size)
2849 {
2850  int ret;
2851 
2852  if (st->codecpar->codec_tag == MKTAG('t','m','c','d')) {
2853  if ((int)size != size)
2854  return AVERROR(ENOMEM);
2855 
2856  ret = ff_get_extradata(c->fc, st->codecpar, pb, size);
2857  if (ret < 0)
2858  return ret;
2859  if (size > 16) {
2860  MOVStreamContext *tmcd_ctx = st->priv_data;
2861  int val;
2862  val = AV_RB32(st->codecpar->extradata + 4);
2863  tmcd_ctx->tmcd_flags = val;
2864  st->avg_frame_rate.num = AV_RB32(st->codecpar->extradata + 8); /* timescale */
2865  st->avg_frame_rate.den = AV_RB32(st->codecpar->extradata + 12); /* frameDuration */
2866  tmcd_ctx->tmcd_nb_frames = st->codecpar->extradata[16]; /* number of frames */
2867  if (size > 30) {
2868  uint32_t len = AV_RB32(st->codecpar->extradata + 18); /* name atom length */
2869  uint32_t format = AV_RB32(st->codecpar->extradata + 22);
2870  if (format == AV_RB32("name") && (int64_t)size >= (int64_t)len + 18) {
2871  uint16_t str_size = AV_RB16(st->codecpar->extradata + 26); /* string length */
2872  if (str_size > 0 && size >= (int)str_size + 30 &&
2873  st->codecpar->extradata[30] /* Don't add empty string */) {
2874  char *reel_name = av_malloc(str_size + 1);
2875  if (!reel_name)
2876  return AVERROR(ENOMEM);
2877  memcpy(reel_name, st->codecpar->extradata + 30, str_size);
2878  reel_name[str_size] = 0; /* Add null terminator */
2879  av_dict_set(&st->metadata, "reel_name", reel_name,
2881  }
2882  }
2883  }
2884  }
2885  } else {
2886  /* other codec type, just skip (rtp, mp4s ...) */
2887  avio_skip(pb, size);
2888  }
2889  return 0;
2890 }
2891 
2893  AVStream *st, MOVStreamContext *sc)
2894 {
2895  FFStream *const sti = ffstream(st);
2896 
2897  if (st->codecpar->codec_type == AVMEDIA_TYPE_AUDIO &&
2898  !st->codecpar->sample_rate && sc->time_scale > 1)
2899  st->codecpar->sample_rate = sc->time_scale;
2900 
2901  /* special codec parameters handling */
2902  switch (st->codecpar->codec_id) {
2903 #if CONFIG_DV_DEMUXER
2904  case AV_CODEC_ID_DVAUDIO:
2905  if (c->dv_fctx) {
2906  avpriv_request_sample(c->fc, "multiple DV audio streams");
2907  return AVERROR(ENOSYS);
2908  }
2909 
2910  c->dv_fctx = avformat_alloc_context();
2911  if (!c->dv_fctx) {
2912  av_log(c->fc, AV_LOG_ERROR, "dv demux context alloc error\n");
2913  return AVERROR(ENOMEM);
2914  }
2915  c->dv_demux = avpriv_dv_init_demux(c->dv_fctx);
2916  if (!c->dv_demux) {
2917  av_log(c->fc, AV_LOG_ERROR, "dv demux context init error\n");
2918  return AVERROR(ENOMEM);
2919  }
2920  sc->dv_audio_container = 1;
2922  break;
2923 #endif
2924  /* no ifdef since parameters are always those */
2925  case AV_CODEC_ID_QCELP:
2928  // force sample rate for qcelp when not stored in mov
2929  if (st->codecpar->codec_tag != MKTAG('Q','c','l','p'))
2930  st->codecpar->sample_rate = 8000;
2931  // FIXME: Why is the following needed for some files?
2932  sc->samples_per_frame = 160;
2933  if (!sc->bytes_per_frame)
2934  sc->bytes_per_frame = 35;
2935  break;
2936  case AV_CODEC_ID_AMR_NB:
2939  /* force sample rate for amr, stsd in 3gp does not store sample rate */
2940  st->codecpar->sample_rate = 8000;
2941  break;
2942  case AV_CODEC_ID_AMR_WB:
2945  st->codecpar->sample_rate = 16000;
2946  break;
2947  case AV_CODEC_ID_MP2:
2948  case AV_CODEC_ID_MP3:
2949  /* force type after stsd for m1a hdlr */
2951  break;
2952  case AV_CODEC_ID_GSM:
2953  case AV_CODEC_ID_ADPCM_MS:
2955  case AV_CODEC_ID_ILBC:
2956  case AV_CODEC_ID_MACE3:
2957  case AV_CODEC_ID_MACE6:
2958  case AV_CODEC_ID_QDM2:
2960  break;
2961  case AV_CODEC_ID_ALAC:
2962  if (st->codecpar->extradata_size == 36) {
2963  int channel_count = AV_RB8(st->codecpar->extradata + 21);
2964  if (st->codecpar->ch_layout.nb_channels != channel_count) {
2967  st->codecpar->ch_layout.nb_channels = channel_count;
2968  }
2969  st->codecpar->sample_rate = AV_RB32(st->codecpar->extradata + 32);
2970  }
2971  break;
2972  case AV_CODEC_ID_AC3:
2973  case AV_CODEC_ID_EAC3:
2975  case AV_CODEC_ID_VC1:
2976  case AV_CODEC_ID_VP8:
2977  case AV_CODEC_ID_VP9:
2979  break;
2980  case AV_CODEC_ID_EVC:
2981  case AV_CODEC_ID_AV1:
2982  /* field_order detection of H264 requires parsing */
2983  case AV_CODEC_ID_H264:
2985  break;
2986  default:
2987  break;
2988  }
2989  return 0;
2990 }
2991 
2993  int codec_tag, int format,
2994  int64_t size)
2995 {
2996  if (codec_tag &&
2997  (codec_tag != format &&
2998  // AVID 1:1 samples with differing data format and codec tag exist
2999  (codec_tag != AV_RL32("AV1x") || format != AV_RL32("AVup")) &&
3000  // prores is allowed to have differing data format and codec tag
3001  codec_tag != AV_RL32("apcn") && codec_tag != AV_RL32("apch") &&
3002  // so is dv (sigh)
3003  codec_tag != AV_RL32("dvpp") && codec_tag != AV_RL32("dvcp") &&
3004  (c->fc->video_codec_id ? ff_codec_get_id(ff_codec_movvideo_tags, format) != c->fc->video_codec_id
3005  : codec_tag != MKTAG('j','p','e','g')))) {
3006  /* Multiple fourcc, we skip JPEG. This is not correct, we should
3007  * export it as a separate AVStream but this needs a few changes
3008  * in the MOV demuxer, patch welcome. */
3009 
3010  av_log(c->fc, AV_LOG_WARNING, "multiple fourcc not supported\n");
3011  avio_skip(pb, size);
3012  return 1;
3013  }
3014 
3015  return 0;
3016 }
3017 
3019 {
3020  AVStream *st;
3021  MOVStreamContext *sc;
3022  int pseudo_stream_id;
3023 
3024  av_assert0 (c->fc->nb_streams >= 1);
3025  st = c->fc->streams[c->fc->nb_streams-1];
3026  sc = st->priv_data;
3027 
3028  for (pseudo_stream_id = 0;
3029  pseudo_stream_id < entries && !pb->eof_reached;
3030  pseudo_stream_id++) {
3031  //Parsing Sample description table
3032  enum AVCodecID id;
3033  int ret, dref_id = 1;
3034  MOVAtom a = { AV_RL32("stsd") };
3035  int64_t start_pos = avio_tell(pb);
3036  int64_t size = avio_rb32(pb); /* size */
3037  uint32_t format = avio_rl32(pb); /* data format */
3038 
3039  if (size >= 16) {
3040  avio_rb32(pb); /* reserved */
3041  avio_rb16(pb); /* reserved */
3042  dref_id = avio_rb16(pb);
3043  } else if (size <= 7) {
3044  av_log(c->fc, AV_LOG_ERROR,
3045  "invalid size %"PRId64" in stsd\n", size);
3046  return AVERROR_INVALIDDATA;
3047  }
3048 
3050  size - (avio_tell(pb) - start_pos))) {
3051  sc->stsd_count++;
3052  continue;
3053  }
3054 
3055  sc->pseudo_stream_id = st->codecpar->codec_tag ? -1 : pseudo_stream_id;
3056  sc->dref_id= dref_id;
3057  sc->format = format;
3058 
3059  id = mov_codec_id(st, format);
3060 
3061  av_log(c->fc, AV_LOG_TRACE,
3062  "size=%"PRId64" 4CC=%s codec_type=%d\n", size,
3064 
3065  st->codecpar->codec_id = id;
3067  mov_parse_stsd_video(c, pb, st, sc);
3068  } else if (st->codecpar->codec_type==AVMEDIA_TYPE_AUDIO) {
3069  mov_parse_stsd_audio(c, pb, st, sc);
3070  if (st->codecpar->sample_rate < 0) {
3071  av_log(c->fc, AV_LOG_ERROR, "Invalid sample rate %d\n", st->codecpar->sample_rate);
3072  return AVERROR_INVALIDDATA;
3073  }
3074  if (st->codecpar->ch_layout.nb_channels < 0) {
3075  av_log(c->fc, AV_LOG_ERROR, "Invalid channels %d\n", st->codecpar->ch_layout.nb_channels);
3076  return AVERROR_INVALIDDATA;
3077  }
3078  } else if (st->codecpar->codec_type==AVMEDIA_TYPE_SUBTITLE){
3079  mov_parse_stsd_subtitle(c, pb, st, sc,
3080  size - (avio_tell(pb) - start_pos));
3081  } else {
3082  ret = mov_parse_stsd_data(c, pb, st, sc,
3083  size - (avio_tell(pb) - start_pos));
3084  if (ret < 0)
3085  return ret;
3086  }
3087  /* this will read extra atoms at the end (wave, alac, damr, avcC, hvcC, SMI ...) */
3088  a.size = size - (avio_tell(pb) - start_pos);
3089  if (a.size > 8) {
3090  if ((ret = mov_read_default(c, pb, a)) < 0)
3091  return ret;
3092  } else if (a.size > 0)
3093  avio_skip(pb, a.size);
3094 
3095  if (sc->extradata && st->codecpar->extradata) {
3096  int extra_size = st->codecpar->extradata_size;
3097 
3098  /* Move the current stream extradata to the stream context one. */
3099  sc->extradata_size[pseudo_stream_id] = extra_size;
3100  sc->extradata[pseudo_stream_id] = st->codecpar->extradata;
3101  st->codecpar->extradata = NULL;
3102  st->codecpar->extradata_size = 0;
3103  }
3104  sc->stsd_count++;
3105  }
3106 
3107  if (pb->eof_reached) {
3108  av_log(c->fc, AV_LOG_WARNING, "reached eof, corrupted STSD atom\n");
3109  return AVERROR_EOF;
3110  }
3111 
3112  return 0;
3113 }
3114 
3116 {
3117  AVStream *st;
3118  MOVStreamContext *sc;
3119  int ret, entries;
3120 
3121  if (c->fc->nb_streams < 1)
3122  return 0;
3123  st = c->fc->streams[c->fc->nb_streams - 1];
3124  sc = st->priv_data;
3125 
3126  sc->stsd_version = avio_r8(pb);
3127  avio_rb24(pb); /* flags */
3128  entries = avio_rb32(pb);
3129 
3130  /* Each entry contains a size (4 bytes) and format (4 bytes). */
3131  if (entries <= 0 || entries > atom.size / 8 || entries > 1024) {
3132  av_log(c->fc, AV_LOG_ERROR, "invalid STSD entries %d\n", entries);
3133  return AVERROR_INVALIDDATA;
3134  }
3135 
3136  if (sc->extradata) {
3137  av_log(c->fc, AV_LOG_ERROR,
3138  "Duplicate stsd found in this track.\n");
3139  return AVERROR_INVALIDDATA;
3140  }
3141 
3142  /* Prepare space for hosting multiple extradata. */
3143  sc->extradata = av_calloc(entries, sizeof(*sc->extradata));
3144  if (!sc->extradata)
3145  return AVERROR(ENOMEM);
3146 
3147  sc->extradata_size = av_calloc(entries, sizeof(*sc->extradata_size));
3148  if (!sc->extradata_size) {
3149  ret = AVERROR(ENOMEM);
3150  goto fail;
3151  }
3152 
3153  ret = ff_mov_read_stsd_entries(c, pb, entries);
3154  if (ret < 0)
3155  goto fail;
3156 
3157  /* Restore back the primary extradata. */
3158  av_freep(&st->codecpar->extradata);
3159  st->codecpar->extradata_size = sc->extradata_size[0];
3160  if (sc->extradata_size[0]) {
3162  if (!st->codecpar->extradata)
3163  return AVERROR(ENOMEM);
3164  memcpy(st->codecpar->extradata, sc->extradata[0], sc->extradata_size[0]);
3165  }
3166 
3167  return mov_finalize_stsd_codec(c, pb, st, sc);
3168 fail:
3169  if (sc->extradata) {
3170  int j;
3171  for (j = 0; j < sc->stsd_count; j++)
3172  av_freep(&sc->extradata[j]);
3173  }
3174 
3175  av_freep(&sc->extradata);
3176  av_freep(&sc->extradata_size);
3177  return ret;
3178 }
3179 
3181 {
3182  AVStream *st;
3183  MOVStreamContext *sc;
3184  unsigned int i, entries;
3185 
3186  if (c->trak_index < 0) {
3187  av_log(c->fc, AV_LOG_WARNING, "STSC outside TRAK\n");
3188  return 0;
3189  }
3190 
3191  if (c->fc->nb_streams < 1)
3192  return 0;
3193  st = c->fc->streams[c->fc->nb_streams-1];
3194  sc = st->priv_data;
3195 
3196  avio_r8(pb); /* version */
3197  avio_rb24(pb); /* flags */
3198 
3199  entries = avio_rb32(pb);
3200  if ((uint64_t)entries * 12 + 4 > atom.size)
3201  return AVERROR_INVALIDDATA;
3202 
3203  av_log(c->fc, AV_LOG_TRACE, "track[%u].stsc.entries = %u\n", c->fc->nb_streams - 1, entries);
3204 
3205  if (!entries)
3206  return 0;
3207  if (sc->stsc_data) {
3208  av_log(c->fc, AV_LOG_WARNING, "Ignoring duplicated STSC atom\n");
3209  return 0;
3210  }
3211  av_free(sc->stsc_data);
3212  sc->stsc_count = 0;
3213  sc->stsc_data = av_malloc_array(entries, sizeof(*sc->stsc_data));
3214  if (!sc->stsc_data)
3215  return AVERROR(ENOMEM);
3216 
3217  for (i = 0; i < entries && !pb->eof_reached; i++) {
3218  sc->stsc_data[i].first = avio_rb32(pb);
3219  sc->stsc_data[i].count = avio_rb32(pb);
3220  sc->stsc_data[i].id = avio_rb32(pb);
3221  }
3222 
3223  sc->stsc_count = i;
3224  for (i = sc->stsc_count - 1; i < UINT_MAX; i--) {
3225  int64_t first_min = i + 1;
3226  if ((i+1 < sc->stsc_count && sc->stsc_data[i].first >= sc->stsc_data[i+1].first) ||
3227  (i > 0 && sc->stsc_data[i].first <= sc->stsc_data[i-1].first) ||
3228  sc->stsc_data[i].first < first_min ||
3229  sc->stsc_data[i].count < 1 ||
3230  sc->stsc_data[i].id < 1) {
3231  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);
3232  if (i+1 >= sc->stsc_count) {
3233  if (sc->stsc_data[i].count == 0 && i > 0) {
3234  sc->stsc_count --;
3235  continue;
3236  }
3237  sc->stsc_data[i].first = FFMAX(sc->stsc_data[i].first, first_min);
3238  if (i > 0 && sc->stsc_data[i].first <= sc->stsc_data[i-1].first)
3239  sc->stsc_data[i].first = FFMIN(sc->stsc_data[i-1].first + 1LL, INT_MAX);
3240  sc->stsc_data[i].count = FFMAX(sc->stsc_data[i].count, 1);
3241  sc->stsc_data[i].id = FFMAX(sc->stsc_data[i].id, 1);
3242  continue;
3243  }
3244  av_assert0(sc->stsc_data[i+1].first >= 2);
3245  // We replace this entry by the next valid
3246  sc->stsc_data[i].first = sc->stsc_data[i+1].first - 1;
3247  sc->stsc_data[i].count = sc->stsc_data[i+1].count;
3248  sc->stsc_data[i].id = sc->stsc_data[i+1].id;
3249  }
3250  }
3251 
3252  if (pb->eof_reached) {
3253  av_log(c->fc, AV_LOG_WARNING, "reached eof, corrupted STSC atom\n");
3254  return AVERROR_EOF;
3255  }
3256 
3257  return 0;
3258 }
3259 
3260 static inline int mov_stsc_index_valid(unsigned int index, unsigned int count)
3261 {
3262  return index < count - 1;
3263 }
3264 
3265 /* Compute the samples value for the stsc entry at the given index. */
3266 static inline int64_t mov_get_stsc_samples(MOVStreamContext *sc, unsigned int index)
3267 {
3268  int chunk_count;
3269 
3271  chunk_count = sc->stsc_data[index + 1].first - sc->stsc_data[index].first;
3272  else {
3273  // Validation for stsc / stco happens earlier in mov_read_stsc + mov_read_trak.
3275  chunk_count = sc->chunk_count - (sc->stsc_data[index].first - 1);
3276  }
3277 
3278  return sc->stsc_data[index].count * (int64_t)chunk_count;
3279 }
3280 
3282 {
3283  AVStream *st;
3284  MOVStreamContext *sc;
3285  unsigned i, entries;
3286 
3287  if (c->trak_index < 0) {
3288  av_log(c->fc, AV_LOG_WARNING, "STPS outside TRAK\n");
3289  return 0;
3290  }
3291 
3292  if (c->fc->nb_streams < 1)
3293  return 0;
3294  st = c->fc->streams[c->fc->nb_streams-1];
3295  sc = st->priv_data;
3296 
3297  avio_rb32(pb); // version + flags
3298 
3299  entries = avio_rb32(pb);
3300  if (sc->stps_data)
3301  av_log(c->fc, AV_LOG_WARNING, "Duplicated STPS atom\n");
3302  av_free(sc->stps_data);
3303  sc->stps_count = 0;
3304  sc->stps_data = av_malloc_array(entries, sizeof(*sc->stps_data));
3305  if (!sc->stps_data)
3306  return AVERROR(ENOMEM);
3307 
3308  for (i = 0; i < entries && !pb->eof_reached; i++) {
3309  sc->stps_data[i] = avio_rb32(pb);
3310  }
3311 
3312  sc->stps_count = i;
3313 
3314  if (pb->eof_reached) {
3315  av_log(c->fc, AV_LOG_WARNING, "reached eof, corrupted STPS atom\n");
3316  return AVERROR_EOF;
3317  }
3318 
3319  return 0;
3320 }
3321 
3323 {
3324  AVStream *st;
3325  FFStream *sti;
3326  MOVStreamContext *sc;
3327  unsigned int i, entries;
3328 
3329  if (c->trak_index < 0) {
3330  av_log(c->fc, AV_LOG_WARNING, "STSS outside TRAK\n");
3331  return 0;
3332  }
3333 
3334  if (c->fc->nb_streams < 1)
3335  return 0;
3336  st = c->fc->streams[c->fc->nb_streams-1];
3337  sti = ffstream(st);
3338  sc = st->priv_data;
3339 
3340  avio_r8(pb); /* version */
3341  avio_rb24(pb); /* flags */
3342 
3343  entries = avio_rb32(pb);
3344 
3345  av_log(c->fc, AV_LOG_TRACE, "keyframe_count = %u\n", entries);
3346 
3347  if (!entries) {
3348  sc->keyframe_absent = 1;
3349  if (!sti->need_parsing && st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO)
3351  return 0;
3352  }
3353  if (sc->keyframes)
3354  av_log(c->fc, AV_LOG_WARNING, "Duplicated STSS atom\n");
3355  if (entries >= UINT_MAX / sizeof(int))
3356  return AVERROR_INVALIDDATA;
3357  av_freep(&sc->keyframes);
3358  sc->keyframe_count = 0;
3359  sc->keyframes = av_malloc_array(entries, sizeof(*sc->keyframes));
3360  if (!sc->keyframes)
3361  return AVERROR(ENOMEM);
3362 
3363  for (i = 0; i < entries && !pb->eof_reached; i++) {
3364  sc->keyframes[i] = avio_rb32(pb);
3365  }
3366 
3367  sc->keyframe_count = i;
3368 
3369  if (pb->eof_reached) {
3370  av_log(c->fc, AV_LOG_WARNING, "reached eof, corrupted STSS atom\n");
3371  return AVERROR_EOF;
3372  }
3373 
3374  return 0;
3375 }
3376 
3378 {
3379  AVStream *st;
3380  MOVStreamContext *sc;
3381  unsigned int i, entries, sample_size, field_size, num_bytes;
3382  GetBitContext gb;
3383  unsigned char* buf;
3384  int ret;
3385 
3386  if (c->trak_index < 0) {
3387  av_log(c->fc, AV_LOG_WARNING, "STSZ outside TRAK\n");
3388  return 0;
3389  }
3390 
3391  if (c->fc->nb_streams < 1)
3392  return 0;
3393  st = c->fc->streams[c->fc->nb_streams-1];
3394  sc = st->priv_data;
3395 
3396  avio_r8(pb); /* version */
3397  avio_rb24(pb); /* flags */
3398 
3399  if (atom.type == MKTAG('s','t','s','z')) {
3400  sample_size = avio_rb32(pb);
3401  if (!sc->sample_size) /* do not overwrite value computed in stsd */
3402  sc->sample_size = sample_size;
3403  sc->stsz_sample_size = sample_size;
3404  field_size = 32;
3405  } else {
3406  sample_size = 0;
3407  avio_rb24(pb); /* reserved */
3408  field_size = avio_r8(pb);
3409  }
3410  entries = avio_rb32(pb);
3411 
3412  av_log(c->fc, AV_LOG_TRACE, "sample_size = %u sample_count = %u\n", sc->sample_size, entries);
3413 
3414  sc->sample_count = entries;
3415  if (sample_size)
3416  return 0;
3417 
3418  if (field_size != 4 && field_size != 8 && field_size != 16 && field_size != 32) {
3419  av_log(c->fc, AV_LOG_ERROR, "Invalid sample field size %u\n", field_size);
3420  return AVERROR_INVALIDDATA;
3421  }
3422 
3423  if (!entries)
3424  return 0;
3425  if (entries >= (INT_MAX - 4 - 8 * AV_INPUT_BUFFER_PADDING_SIZE) / field_size)
3426  return AVERROR_INVALIDDATA;
3427  if (sc->sample_sizes)
3428  av_log(c->fc, AV_LOG_WARNING, "Duplicated STSZ atom\n");
3429  av_free(sc->sample_sizes);
3430  sc->sample_count = 0;
3431  sc->sample_sizes = av_malloc_array(entries, sizeof(*sc->sample_sizes));
3432  if (!sc->sample_sizes)
3433  return AVERROR(ENOMEM);
3434 
3435  num_bytes = (entries*field_size+4)>>3;
3436 
3437  buf = av_malloc(num_bytes+AV_INPUT_BUFFER_PADDING_SIZE);
3438  if (!buf) {
3439  av_freep(&sc->sample_sizes);
3440  return AVERROR(ENOMEM);
3441  }
3442 
3443  ret = ffio_read_size(pb, buf, num_bytes);
3444  if (ret < 0) {
3445  av_freep(&sc->sample_sizes);
3446  av_free(buf);
3447  av_log(c->fc, AV_LOG_WARNING, "STSZ atom truncated\n");
3448  return 0;
3449  }
3450 
3451  init_get_bits(&gb, buf, 8*num_bytes);
3452 
3453  for (i = 0; i < entries; i++) {
3454  sc->sample_sizes[i] = get_bits_long(&gb, field_size);
3455  if (sc->sample_sizes[i] > INT64_MAX - sc->data_size) {
3456  av_free(buf);
3457  av_log(c->fc, AV_LOG_ERROR, "Sample size overflow in STSZ\n");
3458  return AVERROR_INVALIDDATA;
3459  }
3460  sc->data_size += sc->sample_sizes[i];
3461  }
3462 
3463  sc->sample_count = i;
3464 
3465  av_free(buf);
3466 
3467  return 0;
3468 }
3469 
3471 {
3472  AVStream *st;
3473  MOVStreamContext *sc;
3474  unsigned int i, entries;
3475  int64_t duration = 0;
3476  int64_t total_sample_count = 0;
3477  int64_t current_dts = 0;
3478  int64_t corrected_dts = 0;
3479 
3480  if (c->trak_index < 0) {
3481  av_log(c->fc, AV_LOG_WARNING, "STTS outside TRAK\n");
3482  return 0;
3483  }
3484 
3485  if (c->fc->nb_streams < 1)
3486  return 0;
3487  st = c->fc->streams[c->fc->nb_streams-1];
3488  sc = st->priv_data;
3489 
3490  avio_r8(pb); /* version */
3491  avio_rb24(pb); /* flags */
3492  entries = avio_rb32(pb);
3493 
3494  av_log(c->fc, AV_LOG_TRACE, "track[%u].stts.entries = %u\n",
3495  c->fc->nb_streams-1, entries);
3496 
3497  if (sc->stts_data)
3498  av_log(c->fc, AV_LOG_WARNING, "Duplicated STTS atom\n");
3499  av_freep(&sc->stts_data);
3500  sc->stts_count = 0;
3501  if (entries >= INT_MAX / sizeof(*sc->stts_data))
3502  return AVERROR(ENOMEM);
3503 
3504  for (i = 0; i < entries && !pb->eof_reached; i++) {
3505  unsigned int sample_duration;
3506  unsigned int sample_count;
3507  unsigned int min_entries = FFMIN(FFMAX(i + 1, 1024 * 1024), entries);
3508  MOVStts *stts_data = av_fast_realloc(sc->stts_data, &sc->stts_allocated_size,
3509  min_entries * sizeof(*sc->stts_data));
3510  if (!stts_data) {
3511  av_freep(&sc->stts_data);
3512  sc->stts_count = 0;
3513  return AVERROR(ENOMEM);
3514  }
3515  sc->stts_count = min_entries;
3516  sc->stts_data = stts_data;
3517 
3518  sample_count = avio_rb32(pb);
3519  sample_duration = avio_rb32(pb);
3520 
3521  sc->stts_data[i].count= sample_count;
3522  sc->stts_data[i].duration= sample_duration;
3523 
3524  av_log(c->fc, AV_LOG_TRACE, "sample_count=%u, sample_duration=%u\n",
3525  sample_count, sample_duration);
3526 
3527  /* STTS sample offsets are uint32 but some files store it as int32
3528  * with negative values used to correct DTS delays.
3529  There may be abnormally large values as well. */
3530  if (sample_duration > c->max_stts_delta) {
3531  // assume high delta is a correction if negative when cast as int32
3532  int32_t delta_magnitude = (int32_t)sample_duration;
3533  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",
3534  sample_duration, i, sample_count, st->index);
3535  sc->stts_data[i].duration = 1;
3536  corrected_dts += (delta_magnitude < 0 ? (int64_t)delta_magnitude : 1) * sample_count;
3537  } else {
3538  corrected_dts += sample_duration * (uint64_t)sample_count;
3539  }
3540 
3541  current_dts += sc->stts_data[i].duration * (uint64_t)sample_count;
3542 
3543  if (current_dts > corrected_dts) {
3544  int64_t drift = (current_dts - corrected_dts)/FFMAX(sample_count, 1);
3545  uint32_t correction = (sc->stts_data[i].duration > drift) ? drift : sc->stts_data[i].duration - 1;
3546  current_dts -= correction * (uint64_t)sample_count;
3547  sc->stts_data[i].duration -= correction;
3548  }
3549 
3550  duration+=(int64_t)sc->stts_data[i].duration*(uint64_t)sc->stts_data[i].count;
3551  total_sample_count+=sc->stts_data[i].count;
3552  }
3553 
3554  sc->stts_count = i;
3555 
3556  if (duration > 0 &&
3557  duration <= INT64_MAX - sc->duration_for_fps &&
3558  total_sample_count <= INT_MAX - sc->nb_frames_for_fps) {
3559  sc->duration_for_fps += duration;
3560  sc->nb_frames_for_fps += total_sample_count;
3561  }
3562 
3563  if (pb->eof_reached) {
3564  av_log(c->fc, AV_LOG_WARNING, "reached eof, corrupted STTS atom\n");
3565  return AVERROR_EOF;
3566  }
3567 
3568  st->nb_frames= total_sample_count;
3569  if (duration)
3570  st->duration= FFMIN(st->duration, duration);
3571 
3572  // All samples have zero duration. They have higher chance be chose by
3573  // mov_find_next_sample, which leads to seek again and again.
3574  //
3575  // It's AVERROR_INVALIDDATA actually, but such files exist in the wild.
3576  // So only mark data stream as discarded for safety.
3577  if (!duration && sc->stts_count &&
3579  av_log(c->fc, AV_LOG_WARNING,
3580  "All samples in data stream index:id [%d:%d] have zero "
3581  "duration, stream set to be discarded by default. Override "
3582  "using AVStream->discard or -discard for ffmpeg command.\n",
3583  st->index, sc->id);
3584  st->discard = AVDISCARD_ALL;
3585  }
3586  sc->track_end = duration;
3587  return 0;
3588 }
3589 
3591 {
3592  AVStream *st;
3593  MOVStreamContext *sc;
3594  int64_t i, entries;
3595 
3596  if (c->fc->nb_streams < 1)
3597  return 0;
3598  st = c->fc->streams[c->fc->nb_streams - 1];
3599  sc = st->priv_data;
3600 
3601  avio_r8(pb); /* version */
3602  avio_rb24(pb); /* flags */
3603  entries = atom.size - 4;
3604 
3605  av_log(c->fc, AV_LOG_TRACE, "track[%u].sdtp.entries = %" PRId64 "\n",
3606  c->fc->nb_streams - 1, entries);
3607 
3608  if (sc->sdtp_data)
3609  av_log(c->fc, AV_LOG_WARNING, "Duplicated SDTP atom\n");
3610  av_freep(&sc->sdtp_data);
3611  sc->sdtp_count = 0;
3612 
3613  sc->sdtp_data = av_malloc(entries);
3614  if (!sc->sdtp_data)
3615  return AVERROR(ENOMEM);
3616 
3617  for (i = 0; i < entries && !pb->eof_reached; i++)
3618  sc->sdtp_data[i] = avio_r8(pb);
3619  sc->sdtp_count = i;
3620 
3621  return 0;
3622 }
3623 
3624 static void mov_update_dts_shift(MOVStreamContext *sc, int duration, void *logctx)
3625 {
3626  if (duration < 0) {
3627  if (duration == INT_MIN) {
3628  av_log(logctx, AV_LOG_WARNING, "mov_update_dts_shift(): dts_shift set to %d\n", INT_MAX);
3629  duration++;
3630  }
3631  sc->dts_shift = FFMAX(sc->dts_shift, -duration);
3632  }
3633 }
3634 
3636 {
3637  AVStream *st;
3638  MOVStreamContext *sc;
3639  unsigned int i, entries, ctts_count = 0;
3640 
3641  if (c->trak_index < 0) {
3642  av_log(c->fc, AV_LOG_WARNING, "CTTS outside TRAK\n");
3643  return 0;
3644  }
3645 
3646  if (c->fc->nb_streams < 1)
3647  return 0;
3648  st = c->fc->streams[c->fc->nb_streams-1];
3649  sc = st->priv_data;
3650 
3651  avio_r8(pb); /* version */
3652  avio_rb24(pb); /* flags */
3653  entries = avio_rb32(pb);
3654 
3655  av_log(c->fc, AV_LOG_TRACE, "track[%u].ctts.entries = %u\n", c->fc->nb_streams - 1, entries);
3656 
3657  if (!entries)
3658  return 0;
3659  if (entries >= UINT_MAX / sizeof(*sc->ctts_data))
3660  return AVERROR_INVALIDDATA;
3661  av_freep(&sc->ctts_data);
3662  sc->ctts_data = av_fast_realloc(NULL, &sc->ctts_allocated_size, entries * sizeof(*sc->ctts_data));
3663  if (!sc->ctts_data)
3664  return AVERROR(ENOMEM);
3665 
3666  for (i = 0; i < entries && !pb->eof_reached; i++) {
3667  int count = avio_rb32(pb);
3668  int duration = avio_rb32(pb);
3669 
3670  if (count <= 0) {
3671  av_log(c->fc, AV_LOG_TRACE,
3672  "ignoring CTTS entry with count=%d duration=%d\n",
3673  count, duration);
3674  continue;
3675  }
3676 
3677  add_ctts_entry(&sc->ctts_data, &ctts_count, &sc->ctts_allocated_size,
3678  count, duration);
3679 
3680  av_log(c->fc, AV_LOG_TRACE, "count=%d, duration=%d\n",
3681  count, duration);
3682 
3683  if (FFNABS(duration) < -(1<<28) && i+2<entries) {
3684  av_log(c->fc, AV_LOG_WARNING, "CTTS invalid\n");
3685  av_freep(&sc->ctts_data);
3686  sc->ctts_count = 0;
3687  return 0;
3688  }
3689 
3690  if (i+2<entries)
3691  mov_update_dts_shift(sc, duration, c->fc);
3692  }
3693 
3694  sc->ctts_count = ctts_count;
3695 
3696  if (pb->eof_reached) {
3697  av_log(c->fc, AV_LOG_WARNING, "reached eof, corrupted CTTS atom\n");
3698  return AVERROR_EOF;
3699  }
3700 
3701  av_log(c->fc, AV_LOG_TRACE, "dts shift %d\n", sc->dts_shift);
3702 
3703  return 0;
3704 }
3705 
3707 {
3708  AVStream *st;
3709  MOVStreamContext *sc;
3710  uint8_t version;
3711  uint32_t grouping_type;
3712  uint32_t default_length;
3713  av_unused uint32_t default_group_description_index;
3714  uint32_t entry_count;
3715 
3716  if (c->fc->nb_streams < 1)
3717  return 0;
3718  st = c->fc->streams[c->fc->nb_streams - 1];
3719  sc = st->priv_data;
3720 
3721  version = avio_r8(pb); /* version */
3722  avio_rb24(pb); /* flags */
3723  grouping_type = avio_rl32(pb);
3724 
3725  /*
3726  * This function only supports "sync" boxes, but the code is able to parse
3727  * other boxes (such as "tscl", "tsas" and "stsa")
3728  */
3729  if (grouping_type != MKTAG('s','y','n','c'))
3730  return 0;
3731 
3732  default_length = version >= 1 ? avio_rb32(pb) : 0;
3733  default_group_description_index = version >= 2 ? avio_rb32(pb) : 0;
3734  entry_count = avio_rb32(pb);
3735 
3736  av_freep(&sc->sgpd_sync);
3737  sc->sgpd_sync_count = entry_count;
3738  sc->sgpd_sync = av_calloc(entry_count, sizeof(*sc->sgpd_sync));
3739  if (!sc->sgpd_sync)
3740  return AVERROR(ENOMEM);
3741 
3742  for (uint32_t i = 0; i < entry_count && !pb->eof_reached; i++) {
3743  uint32_t description_length = default_length;
3744  if (version >= 1 && default_length == 0)
3745  description_length = avio_rb32(pb);
3746  if (grouping_type == MKTAG('s','y','n','c')) {
3747  const uint8_t nal_unit_type = avio_r8(pb) & 0x3f;
3748  sc->sgpd_sync[i] = nal_unit_type;
3749  description_length -= 1;
3750  }
3751  avio_skip(pb, description_length);
3752  }
3753 
3754  if (pb->eof_reached) {
3755  av_log(c->fc, AV_LOG_WARNING, "reached eof, corrupted SGPD atom\n");
3756  return AVERROR_EOF;
3757  }
3758 
3759  return 0;
3760 }
3761 
3763 {
3764  AVStream *st;
3765  MOVStreamContext *sc;
3766  unsigned int i, entries;
3767  uint8_t version;
3768  uint32_t grouping_type;
3769  MOVSbgp *table, **tablep;
3770  int *table_count;
3771 
3772  if (c->fc->nb_streams < 1)
3773  return 0;
3774  st = c->fc->streams[c->fc->nb_streams-1];
3775  sc = st->priv_data;
3776 
3777  version = avio_r8(pb); /* version */
3778  avio_rb24(pb); /* flags */
3779  grouping_type = avio_rl32(pb);
3780 
3781  if (grouping_type == MKTAG('r','a','p',' ')) {
3782  tablep = &sc->rap_group;
3783  table_count = &sc->rap_group_count;
3784  } else if (grouping_type == MKTAG('s','y','n','c')) {
3785  tablep = &sc->sync_group;
3786  table_count = &sc->sync_group_count;
3787  } else {
3788  return 0;
3789  }
3790 
3791  if (version == 1)
3792  avio_rb32(pb); /* grouping_type_parameter */
3793 
3794  entries = avio_rb32(pb);
3795  if (!entries)
3796  return 0;
3797  if (*tablep)
3798  av_log(c->fc, AV_LOG_WARNING, "Duplicated SBGP %s atom\n", av_fourcc2str(grouping_type));
3799  av_freep(tablep);
3800  table = av_malloc_array(entries, sizeof(*table));
3801  if (!table)
3802  return AVERROR(ENOMEM);
3803  *tablep = table;
3804 
3805  for (i = 0; i < entries && !pb->eof_reached; i++) {
3806  table[i].count = avio_rb32(pb); /* sample_count */
3807  table[i].index = avio_rb32(pb); /* group_description_index */
3808  }
3809 
3810  *table_count = i;
3811 
3812  if (pb->eof_reached) {
3813  av_log(c->fc, AV_LOG_WARNING, "reached eof, corrupted SBGP atom\n");
3814  return AVERROR_EOF;
3815  }
3816 
3817  return 0;
3818 }
3819 
3820 /**
3821  * Get ith edit list entry (media time, duration).
3822  */
3824  const MOVStreamContext *msc,
3825  unsigned int edit_list_index,
3826  int64_t *edit_list_media_time,
3827  int64_t *edit_list_duration,
3828  int64_t global_timescale)
3829 {
3830  if (edit_list_index == msc->elst_count) {
3831  return 0;
3832  }
3833  *edit_list_media_time = msc->elst_data[edit_list_index].time;
3834  *edit_list_duration = msc->elst_data[edit_list_index].duration;
3835 
3836  /* duration is in global timescale units;convert to msc timescale */
3837  if (global_timescale == 0) {
3838  avpriv_request_sample(mov->fc, "Support for mvhd.timescale = 0 with editlists");
3839  return 0;
3840  }
3841  *edit_list_duration = av_rescale(*edit_list_duration, msc->time_scale,
3842  global_timescale);
3843 
3844  if (*edit_list_duration + (uint64_t)*edit_list_media_time > INT64_MAX)
3845  *edit_list_duration = 0;
3846 
3847  return 1;
3848 }
3849 
3850 /**
3851  * Find the closest previous frame to the timestamp_pts, in e_old index
3852  * entries. Searching for just any frame / just key frames can be controlled by
3853  * last argument 'flag'.
3854  * Note that if ctts_data is not NULL, we will always search for a key frame
3855  * irrespective of the value of 'flag'. If we don't find any keyframe, we will
3856  * return the first frame of the video.
3857  *
3858  * Here the timestamp_pts is considered to be a presentation timestamp and
3859  * the timestamp of index entries are considered to be decoding timestamps.
3860  *
3861  * Returns 0 if successful in finding a frame, else returns -1.
3862  * Places the found index corresponding output arg.
3863  *
3864  * If ctts_old is not NULL, then refines the searched entry by searching
3865  * backwards from the found timestamp, to find the frame with correct PTS.
3866  *
3867  * Places the found ctts_index and ctts_sample in corresponding output args.
3868  */
3870  AVIndexEntry *e_old,
3871  int nb_old,
3872  MOVStts* stts_data,
3873  int64_t stts_count,
3874  MOVCtts* ctts_data,
3875  int64_t ctts_count,
3876  int64_t timestamp_pts,
3877  int flag,
3878  int64_t* index,
3879  int64_t* stts_index,
3880  int64_t* stts_sample,
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 
3924  if (stts_data) {
3925  av_assert0(stts_index);
3926  av_assert0(stts_sample);
3927 
3928  *stts_index = 0;
3929  *stts_sample = 0;
3930  }
3931 
3932  for (index_ctts_count = 0; index_ctts_count < *index; index_ctts_count++) {
3933  if (*ctts_index < ctts_count) {
3934  (*ctts_sample)++;
3935  if (ctts_data[*ctts_index].count == *ctts_sample) {
3936  (*ctts_index)++;
3937  *ctts_sample = 0;
3938  }
3939  }
3940  if (stts_data && *stts_index < stts_count) {
3941  (*stts_sample)++;
3942  if (stts_data[*stts_index].count == *stts_sample) {
3943  (*stts_index)++;
3944  *stts_sample = 0;
3945  }
3946  }
3947  }
3948 
3949  while (*index >= 0 && (*ctts_index) >= 0 && (*ctts_index) < ctts_count) {
3950  // Find a "key frame" with PTS <= timestamp_pts (So that we can decode B-frames correctly).
3951  // No need to add dts_shift to the timestamp here becase timestamp_pts has already been
3952  // compensated by dts_shift above.
3953  if ((e_old[*index].timestamp + ctts_data[*ctts_index].offset) <= timestamp_pts &&
3954  (e_old[*index].flags & AVINDEX_KEYFRAME)) {
3955  break;
3956  }
3957 
3958  (*index)--;
3959  if (*ctts_sample == 0) {
3960  (*ctts_index)--;
3961  if (*ctts_index >= 0)
3962  *ctts_sample = ctts_data[*ctts_index].count - 1;
3963  } else {
3964  (*ctts_sample)--;
3965  }
3966  if (stts_data) {
3967  if (*stts_sample == 0) {
3968  (*stts_index)--;
3969  if (*stts_index >= 0) {
3970  *stts_sample = stts_data[*stts_index].count - 1;
3971  }
3972  } else {
3973  (*stts_sample)--;
3974  }
3975  }
3976  }
3977  }
3978 
3979  /* restore AVStream state*/
3980  sti->index_entries = e_keep;
3981  sti->nb_index_entries = nb_keep;
3982  return *index >= 0 ? 0 : -1;
3983 }
3984 
3985 /**
3986  * Add index entry with the given values, to the end of ffstream(st)->index_entries.
3987  * Returns the new size ffstream(st)->index_entries if successful, else returns -1.
3988  *
3989  * This function is similar to ff_add_index_entry in libavformat/utils.c
3990  * except that here we are always unconditionally adding an index entry to
3991  * the end, instead of searching the entries list and skipping the add if
3992  * there is an existing entry with the same timestamp.
3993  * This is needed because the mov_fix_index calls this func with the same
3994  * unincremented timestamp for successive discarded frames.
3995  */
3997  int size, int distance, int flags)
3998 {
3999  FFStream *const sti = ffstream(st);
4000  AVIndexEntry *entries, *ie;
4001  int64_t index = -1;
4002  const size_t min_size_needed = (sti->nb_index_entries + 1) * sizeof(AVIndexEntry);
4003 
4004  // Double the allocation each time, to lower memory fragmentation.
4005  // Another difference from ff_add_index_entry function.
4006  const size_t requested_size =
4007  min_size_needed > sti->index_entries_allocated_size ?
4008  FFMAX(min_size_needed, 2 * sti->index_entries_allocated_size) :
4009  min_size_needed;
4010 
4011  if (sti->nb_index_entries + 1U >= UINT_MAX / sizeof(AVIndexEntry))
4012  return -1;
4013 
4014  entries = av_fast_realloc(sti->index_entries,
4016  requested_size);
4017  if (!entries)
4018  return -1;
4019 
4020  sti->index_entries = entries;
4021 
4022  index = sti->nb_index_entries++;
4023  ie= &entries[index];
4024 
4025  ie->pos = pos;
4026  ie->timestamp = timestamp;
4027  ie->min_distance= distance;
4028  ie->size= size;
4029  ie->flags = flags;
4030  return index;
4031 }
4032 
4033 /**
4034  * Rewrite timestamps of index entries in the range [end_index - frame_duration_buffer_size, end_index)
4035  * by subtracting end_ts successively by the amounts given in frame_duration_buffer.
4036  */
4037 static void fix_index_entry_timestamps(AVStream* st, int end_index, int64_t end_ts,
4038  int64_t* frame_duration_buffer,
4039  int frame_duration_buffer_size) {
4040  FFStream *const sti = ffstream(st);
4041  int i = 0;
4042  av_assert0(end_index >= 0 && end_index <= sti->nb_index_entries);
4043  for (i = 0; i < frame_duration_buffer_size; i++) {
4044  end_ts -= frame_duration_buffer[frame_duration_buffer_size - 1 - i];
4045  sti->index_entries[end_index - 1 - i].timestamp = end_ts;
4046  }
4047 }
4048 
4049 static int64_t add_stts_entry(MOVStts** stts_data, unsigned int* stts_count, unsigned int* allocated_size,
4050  int count, int duration)
4051 {
4052  MOVStts *stts_buf_new;
4053  const size_t min_size_needed = (*stts_count + 1) * sizeof(MOVStts);
4054  const size_t requested_size =
4055  min_size_needed > *allocated_size ?
4056  FFMAX(min_size_needed, 2 * (*allocated_size)) :
4057  min_size_needed;
4058 
4059  if ((unsigned)(*stts_count) >= UINT_MAX / sizeof(MOVStts) - 1)
4060  return -1;
4061 
4062  stts_buf_new = av_fast_realloc(*stts_data, allocated_size, requested_size);
4063 
4064  if (!stts_buf_new)
4065  return -1;
4066 
4067  *stts_data = stts_buf_new;
4068 
4069  stts_buf_new[*stts_count].count = count;
4070  stts_buf_new[*stts_count].duration = duration;
4071 
4072  *stts_count = (*stts_count) + 1;
4073  return *stts_count;
4074 }
4075 
4076 /**
4077  * Append a new ctts entry to ctts_data.
4078  * Returns the new ctts_count if successful, else returns -1.
4079  */
4080 static int64_t add_ctts_entry(MOVCtts** ctts_data, unsigned int* ctts_count, unsigned int* allocated_size,
4081  int count, int offset)
4082 {
4083  MOVCtts *ctts_buf_new;
4084  const size_t min_size_needed = (*ctts_count + 1) * sizeof(MOVCtts);
4085  const size_t requested_size =
4086  min_size_needed > *allocated_size ?
4087  FFMAX(min_size_needed, 2 * (*allocated_size)) :
4088  min_size_needed;
4089 
4090  if ((unsigned)(*ctts_count) >= UINT_MAX / sizeof(MOVCtts) - 1)
4091  return -1;
4092 
4093  ctts_buf_new = av_fast_realloc(*ctts_data, allocated_size, requested_size);
4094 
4095  if (!ctts_buf_new)
4096  return -1;
4097 
4098  *ctts_data = ctts_buf_new;
4099 
4100  ctts_buf_new[*ctts_count].count = count;
4101  ctts_buf_new[*ctts_count].offset = offset;
4102 
4103  *ctts_count = (*ctts_count) + 1;
4104  return *ctts_count;
4105 }
4106 
4107 #define MAX_REORDER_DELAY 16
4109 {
4110  MOVStreamContext *msc = st->priv_data;
4111  FFStream *const sti = ffstream(st);
4112  int ctts_ind = 0;
4113  int ctts_sample = 0;
4114  int64_t pts_buf[MAX_REORDER_DELAY + 1]; // Circular buffer to sort pts.
4115  int buf_start = 0;
4116  int j, r, num_swaps;
4117 
4118  for (j = 0; j < MAX_REORDER_DELAY + 1; j++)
4119  pts_buf[j] = INT64_MIN;
4120 
4121  if (st->codecpar->video_delay <= 0 && msc->ctts_data &&
4123  st->codecpar->video_delay = 0;
4124  for (int ind = 0; ind < sti->nb_index_entries && ctts_ind < msc->ctts_count; ++ind) {
4125  // Point j to the last elem of the buffer and insert the current pts there.
4126  j = buf_start;
4127  buf_start = (buf_start + 1);
4128  if (buf_start == MAX_REORDER_DELAY + 1)
4129  buf_start = 0;
4130 
4131  pts_buf[j] = sti->index_entries[ind].timestamp + msc->ctts_data[ctts_ind].offset;
4132 
4133  // The timestamps that are already in the sorted buffer, and are greater than the
4134  // current pts, are exactly the timestamps that need to be buffered to output PTS
4135  // in correct sorted order.
4136  // Hence the video delay (which is the buffer size used to sort DTS and output PTS),
4137  // can be computed as the maximum no. of swaps any particular timestamp needs to
4138  // go through, to keep this buffer in sorted order.
4139  num_swaps = 0;
4140  while (j != buf_start) {
4141  r = j - 1;
4142  if (r < 0) r = MAX_REORDER_DELAY;
4143  if (pts_buf[j] < pts_buf[r]) {
4144  FFSWAP(int64_t, pts_buf[j], pts_buf[r]);
4145  ++num_swaps;
4146  } else {
4147  break;
4148  }
4149  j = r;
4150  }
4151  st->codecpar->video_delay = FFMAX(st->codecpar->video_delay, num_swaps);
4152 
4153  ctts_sample++;
4154  if (ctts_sample == msc->ctts_data[ctts_ind].count) {
4155  ctts_ind++;
4156  ctts_sample = 0;
4157  }
4158  }
4159  av_log(c->fc, AV_LOG_DEBUG, "Setting codecpar->delay to %d for stream st: %d\n",
4160  st->codecpar->video_delay, st->index);
4161  }
4162 }
4163 
4165 {
4166  sc->current_sample++;
4167  sc->current_index++;
4168  if (sc->index_ranges &&
4169  sc->current_index >= sc->current_index_range->end &&
4170  sc->current_index_range->end) {
4171  sc->current_index_range++;
4173  }
4174 }
4175 
4177 {
4178  sc->current_sample--;
4179  sc->current_index--;
4180  if (sc->index_ranges &&
4182  sc->current_index_range > sc->index_ranges) {
4183  sc->current_index_range--;
4184  sc->current_index = sc->current_index_range->end - 1;
4185  }
4186 }
4187 
4188 static void mov_current_sample_set(MOVStreamContext *sc, int current_sample)
4189 {
4190  int64_t range_size;
4191 
4192  sc->current_sample = current_sample;
4193  sc->current_index = current_sample;
4194  if (!sc->index_ranges) {
4195  return;
4196  }
4197 
4198  for (sc->current_index_range = sc->index_ranges;
4199  sc->current_index_range->end;
4200  sc->current_index_range++) {
4201  range_size = sc->current_index_range->end - sc->current_index_range->start;
4202  if (range_size > current_sample) {
4203  sc->current_index = sc->current_index_range->start + current_sample;
4204  break;
4205  }
4206  current_sample -= range_size;
4207  }
4208 }
4209 
4210 /**
4211  * Fix ffstream(st)->index_entries, so that it contains only the entries (and the entries
4212  * which are needed to decode them) that fall in the edit list time ranges.
4213  * Also fixes the timestamps of the index entries to match the timeline
4214  * specified the edit lists.
4215  */
4216 static void mov_fix_index(MOVContext *mov, AVStream *st)
4217 {
4218  MOVStreamContext *msc = st->priv_data;
4219  FFStream *const sti = ffstream(st);
4220  AVIndexEntry *e_old = sti->index_entries;
4221  int nb_old = sti->nb_index_entries;
4222  const AVIndexEntry *e_old_end = e_old + nb_old;
4223  const AVIndexEntry *current = NULL;
4224  MOVStts *stts_data_old = msc->stts_data;
4225  int64_t stts_index_old = 0;
4226  int64_t stts_sample_old = 0;
4227  int64_t stts_count_old = msc->stts_count;
4228  MOVCtts *ctts_data_old = msc->ctts_data;
4229  int64_t ctts_index_old = 0;
4230  int64_t ctts_sample_old = 0;
4231  int64_t ctts_count_old = msc->ctts_count;
4232  int64_t edit_list_media_time = 0;
4233  int64_t edit_list_duration = 0;
4234  int64_t frame_duration = 0;
4235  int64_t edit_list_dts_counter = 0;
4236  int64_t edit_list_dts_entry_end = 0;
4237  int64_t edit_list_start_stts_sample = 0;
4238  int64_t edit_list_start_ctts_sample = 0;
4239  int64_t curr_cts;
4240  int64_t curr_ctts = 0;
4241  int64_t empty_edits_sum_duration = 0;
4242  int64_t edit_list_index = 0;
4243  int64_t index;
4244  int flags;
4245  int64_t start_dts = 0;
4246  int64_t edit_list_start_encountered = 0;
4247  int64_t search_timestamp = 0;
4248  int64_t* frame_duration_buffer = NULL;
4249  int num_discarded_begin = 0;
4250  int first_non_zero_audio_edit = -1;
4251  int packet_skip_samples = 0;
4252  MOVIndexRange *current_index_range = NULL;
4253  int found_keyframe_after_edit = 0;
4254  int found_non_empty_edit = 0;
4255 
4256  if (!msc->elst_data || msc->elst_count <= 0 || nb_old <= 0) {
4257  return;
4258  }
4259 
4260  // allocate the index ranges array
4261  msc->index_ranges = av_malloc_array(msc->elst_count + 1,
4262  sizeof(msc->index_ranges[0]));
4263  if (!msc->index_ranges) {
4264  av_log(mov->fc, AV_LOG_ERROR, "Cannot allocate index ranges buffer\n");
4265  return;
4266  }
4267  msc->current_index_range = msc->index_ranges;
4268 
4269  // Clean AVStream from traces of old index
4270  sti->index_entries = NULL;
4272  sti->nb_index_entries = 0;
4273 
4274  // Clean time to sample fields of MOVStreamContext
4275  msc->stts_data = NULL;
4276  msc->stts_count = 0;
4277  msc->stts_index = 0;
4278  msc->stts_sample = 0;
4279  msc->stts_allocated_size = 0;
4280  msc->ctts_data = NULL;
4281  msc->ctts_count = 0;
4282  msc->ctts_index = 0;
4283  msc->ctts_sample = 0;
4284  msc->ctts_allocated_size = 0;
4285 
4286  // Reinitialize min_corrected_pts so that it can be computed again.
4287  msc->min_corrected_pts = -1;
4288 
4289  // If the dts_shift is positive (in case of negative ctts values in mov),
4290  // then negate the DTS by dts_shift
4291  if (msc->dts_shift > 0) {
4292  edit_list_dts_entry_end -= msc->dts_shift;
4293  av_log(mov->fc, AV_LOG_DEBUG, "Shifting DTS by %d because of negative CTTS.\n", msc->dts_shift);
4294  }
4295 
4296  start_dts = edit_list_dts_entry_end;
4297 
4298  while (get_edit_list_entry(mov, msc, edit_list_index, &edit_list_media_time,
4299  &edit_list_duration, mov->time_scale)) {
4300  av_log(mov->fc, AV_LOG_DEBUG, "Processing st: %d, edit list %"PRId64" - media time: %"PRId64", duration: %"PRId64"\n",
4301  st->index, edit_list_index, edit_list_media_time, edit_list_duration);
4302  edit_list_index++;
4303  edit_list_dts_counter = edit_list_dts_entry_end;
4304  edit_list_dts_entry_end += edit_list_duration;
4305  num_discarded_begin = 0;
4306  if (!found_non_empty_edit && edit_list_media_time == -1) {
4307  empty_edits_sum_duration += edit_list_duration;
4308  continue;
4309  }
4310  found_non_empty_edit = 1;
4311 
4312  // If we encounter a non-negative edit list reset the skip_samples/start_pad fields and set them
4313  // according to the edit list below.
4314  if (st->codecpar->codec_type == AVMEDIA_TYPE_AUDIO) {
4315  if (first_non_zero_audio_edit < 0) {
4316  first_non_zero_audio_edit = 1;
4317  } else {
4318  first_non_zero_audio_edit = 0;
4319  }
4320 
4321  if (first_non_zero_audio_edit > 0)
4322  sti->skip_samples = msc->start_pad = 0;
4323  }
4324 
4325  // While reordering frame index according to edit list we must handle properly
4326  // the scenario when edit list entry starts from none key frame.
4327  // We find closest previous key frame and preserve it and consequent frames in index.
4328  // All frames which are outside edit list entry time boundaries will be dropped after decoding.
4329  search_timestamp = edit_list_media_time;
4330  if (st->codecpar->codec_type == AVMEDIA_TYPE_AUDIO) {
4331  // Audio decoders like AAC need need a decoder delay samples previous to the current sample,
4332  // to correctly decode this frame. Hence for audio we seek to a frame 1 sec. before the
4333  // edit_list_media_time to cover the decoder delay.
4334  search_timestamp = FFMAX(search_timestamp - msc->time_scale, e_old[0].timestamp);
4335  }
4336 
4337  if (find_prev_closest_index(st, e_old, nb_old, stts_data_old, stts_count_old, ctts_data_old, ctts_count_old, search_timestamp, 0,
4338  &index, &stts_index_old, &stts_sample_old, &ctts_index_old, &ctts_sample_old) < 0) {
4339  av_log(mov->fc, AV_LOG_WARNING,
4340  "st: %d edit list: %"PRId64" Missing key frame while searching for timestamp: %"PRId64"\n",
4341  st->index, edit_list_index, search_timestamp);
4342  if (find_prev_closest_index(st, e_old, nb_old, stts_data_old, stts_count_old, ctts_data_old, ctts_count_old, search_timestamp, AVSEEK_FLAG_ANY,
4343  &index, &stts_index_old, &stts_sample_old, &ctts_index_old, &ctts_sample_old) < 0) {
4344  av_log(mov->fc, AV_LOG_WARNING,
4345  "st: %d edit list %"PRId64" Cannot find an index entry before timestamp: %"PRId64".\n",
4346  st->index, edit_list_index, search_timestamp);
4347  index = 0;
4348  stts_index_old = 0;
4349  stts_sample_old = 0;
4350  ctts_index_old = 0;
4351  ctts_sample_old = 0;
4352  }
4353  }
4354  current = e_old + index;
4355  edit_list_start_ctts_sample = ctts_sample_old;
4356  edit_list_start_stts_sample = stts_sample_old;
4357 
4358  // Iterate over index and arrange it according to edit list
4359  edit_list_start_encountered = 0;
4360  found_keyframe_after_edit = 0;
4361  for (; current < e_old_end; current++, index++) {
4362  // check if frame outside edit list mark it for discard
4363  frame_duration = (current + 1 < e_old_end) ?
4364  ((current + 1)->timestamp - current->timestamp) : edit_list_duration;
4365 
4366  flags = current->flags;
4367 
4368  // frames (pts) before or after edit list
4369  curr_cts = current->timestamp + msc->dts_shift;
4370  curr_ctts = 0;
4371 
4372  if (stts_data_old && stts_index_old < stts_count_old) {
4373  stts_sample_old++;
4374  if (stts_sample_old == stts_data_old[stts_index_old].count) {
4375  if (add_stts_entry(&msc->stts_data, &msc->stts_count,
4376  &msc->stts_allocated_size,
4377  stts_data_old[stts_index_old].count - edit_list_start_stts_sample,
4378  stts_data_old[stts_index_old].duration) == -1) {
4379  av_log(mov->fc, AV_LOG_ERROR, "Cannot add STTS entry %"PRId64" - {%"PRId64", %d}\n",
4380  stts_index_old,
4381  stts_data_old[stts_index_old].count - edit_list_start_stts_sample,
4382  stts_data_old[stts_index_old].duration);
4383  break;
4384  }
4385  stts_index_old++;
4386  stts_sample_old = 0;
4387  edit_list_start_stts_sample = 0;
4388  }
4389  }
4390  if (ctts_data_old && ctts_index_old < ctts_count_old) {
4391  curr_ctts = ctts_data_old[ctts_index_old].offset;
4392  av_log(mov->fc, AV_LOG_TRACE, "stts: %"PRId64" ctts: %"PRId64", ctts_index: %"PRId64", ctts_count: %"PRId64"\n",
4393  curr_cts, curr_ctts, ctts_index_old, ctts_count_old);
4394  curr_cts += curr_ctts;
4395  ctts_sample_old++;
4396  if (ctts_sample_old == ctts_data_old[ctts_index_old].count) {
4397  if (add_ctts_entry(&msc->ctts_data, &msc->ctts_count,
4398  &msc->ctts_allocated_size,
4399  ctts_data_old[ctts_index_old].count - edit_list_start_ctts_sample,
4400  ctts_data_old[ctts_index_old].offset) == -1) {
4401  av_log(mov->fc, AV_LOG_ERROR, "Cannot add CTTS entry %"PRId64" - {%"PRId64", %d}\n",
4402  ctts_index_old,
4403  ctts_data_old[ctts_index_old].count - edit_list_start_ctts_sample,
4404  ctts_data_old[ctts_index_old].offset);
4405  break;
4406  }
4407  ctts_index_old++;
4408  ctts_sample_old = 0;
4409  edit_list_start_ctts_sample = 0;
4410  }
4411  }
4412 
4413  if (curr_cts < edit_list_media_time || curr_cts >= (edit_list_duration + edit_list_media_time)) {
4415  curr_cts < edit_list_media_time && curr_cts + frame_duration > edit_list_media_time &&
4416  first_non_zero_audio_edit > 0) {
4417  packet_skip_samples = edit_list_media_time - curr_cts;
4418  sti->skip_samples += packet_skip_samples;
4419 
4420  // Shift the index entry timestamp by packet_skip_samples to be correct.
4421  edit_list_dts_counter -= packet_skip_samples;
4422  if (edit_list_start_encountered == 0) {
4423  edit_list_start_encountered = 1;
4424  // Make timestamps strictly monotonically increasing for audio, by rewriting timestamps for
4425  // discarded packets.
4426  if (frame_duration_buffer) {
4427  fix_index_entry_timestamps(st, sti->nb_index_entries, edit_list_dts_counter,
4428  frame_duration_buffer, num_discarded_begin);
4429  av_freep(&frame_duration_buffer);
4430  }
4431  }
4432 
4433  av_log(mov->fc, AV_LOG_DEBUG, "skip %d audio samples from curr_cts: %"PRId64"\n", packet_skip_samples, curr_cts);
4434  } else {
4436  av_log(mov->fc, AV_LOG_DEBUG, "drop a frame at curr_cts: %"PRId64" @ %"PRId64"\n", curr_cts, index);
4437 
4438  if (edit_list_start_encountered == 0) {
4439  num_discarded_begin++;
4440  frame_duration_buffer = av_realloc(frame_duration_buffer,
4441  num_discarded_begin * sizeof(int64_t));
4442  if (!frame_duration_buffer) {
4443  av_log(mov->fc, AV_LOG_ERROR, "Cannot reallocate frame duration buffer\n");
4444  break;
4445  }
4446  frame_duration_buffer[num_discarded_begin - 1] = frame_duration;
4447 
4448  // Increment skip_samples for the first non-zero audio edit list
4449  if (st->codecpar->codec_type == AVMEDIA_TYPE_AUDIO &&
4450  first_non_zero_audio_edit > 0 && st->codecpar->codec_id != AV_CODEC_ID_VORBIS) {
4451  sti->skip_samples += frame_duration;
4452  }
4453  }
4454  }
4455  } else {
4456  if (msc->min_corrected_pts < 0) {
4457  msc->min_corrected_pts = edit_list_dts_counter + curr_ctts + msc->dts_shift;
4458  } else {
4459  msc->min_corrected_pts = FFMIN(msc->min_corrected_pts, edit_list_dts_counter + curr_ctts + msc->dts_shift);
4460  }
4461  if (edit_list_start_encountered == 0) {
4462  edit_list_start_encountered = 1;
4463  // Make timestamps strictly monotonically increasing by rewriting timestamps for
4464  // discarded packets.
4465  if (frame_duration_buffer) {
4466  fix_index_entry_timestamps(st, sti->nb_index_entries, edit_list_dts_counter,
4467  frame_duration_buffer, num_discarded_begin);
4468  av_freep(&frame_duration_buffer);
4469  }
4470  }
4471  }
4472 
4473  if (add_index_entry(st, current->pos, edit_list_dts_counter, current->size,
4474  current->min_distance, flags) == -1) {
4475  av_log(mov->fc, AV_LOG_ERROR, "Cannot add index entry\n");
4476  break;
4477  }
4478 
4479  // Update the index ranges array
4480  if (!current_index_range || index != current_index_range->end) {
4481  current_index_range = current_index_range ? current_index_range + 1
4482  : msc->index_ranges;
4483  current_index_range->start = index;
4484  }
4485  current_index_range->end = index + 1;
4486 
4487  // Only start incrementing DTS in frame_duration amounts, when we encounter a frame in edit list.
4488  if (edit_list_start_encountered > 0) {
4489  edit_list_dts_counter = edit_list_dts_counter + frame_duration;
4490  }
4491 
4492  // Break when found first key frame after edit entry completion
4493  if ((curr_cts + frame_duration >= (edit_list_duration + edit_list_media_time)) &&
4495  if (ctts_data_old) {
4496  // If we have CTTS and this is the first keyframe after edit elist,
4497  // wait for one more, because there might be trailing B-frames after this I-frame
4498  // that do belong to the edit.
4499  if (st->codecpar->codec_type != AVMEDIA_TYPE_AUDIO && found_keyframe_after_edit == 0) {
4500  found_keyframe_after_edit = 1;
4501  continue;
4502  }
4503  if (ctts_sample_old != 0) {
4504  if (stts_data_old &&
4505  add_stts_entry(&msc->stts_data, &msc->stts_count,
4506  &msc->stts_allocated_size,
4507  stts_sample_old - edit_list_start_stts_sample,
4508  stts_data_old[stts_index_old].duration) == -1) {
4509  av_log(mov->fc, AV_LOG_ERROR, "Cannot add STTS entry %"PRId64" - {%"PRId64", %d}\n",
4510  stts_index_old, stts_sample_old - edit_list_start_stts_sample,
4511  stts_data_old[stts_index_old].duration);
4512  break;
4513  }
4514  if (add_ctts_entry(&msc->ctts_data, &msc->ctts_count,
4515  &msc->ctts_allocated_size,
4516  ctts_sample_old - edit_list_start_ctts_sample,
4517  ctts_data_old[ctts_index_old].offset) == -1) {
4518  av_log(mov->fc, AV_LOG_ERROR, "Cannot add CTTS entry %"PRId64" - {%"PRId64", %d}\n",
4519  ctts_index_old, ctts_sample_old - edit_list_start_ctts_sample,
4520  ctts_data_old[ctts_index_old].offset);
4521  break;
4522  }
4523  }
4524  }
4525  break;
4526  }
4527  }
4528  }
4529  // If there are empty edits, then msc->min_corrected_pts might be positive
4530  // intentionally. So we subtract the sum duration of emtpy edits here.
4531  msc->min_corrected_pts -= empty_edits_sum_duration;
4532 
4533  // If the minimum pts turns out to be greater than zero after fixing the index, then we subtract the
4534  // dts by that amount to make the first pts zero.
4535  if (st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO) {
4536  if (msc->min_corrected_pts > 0) {
4537  av_log(mov->fc, AV_LOG_DEBUG, "Offset DTS by %"PRId64" to make first pts zero.\n", msc->min_corrected_pts);
4538  for (int i = 0; i < sti->nb_index_entries; ++i)
4540  }
4541  }
4542  // Start time should be equal to zero or the duration of any empty edits.
4543  st->start_time = empty_edits_sum_duration;
4544 
4545  // Update av stream length, if it ends up shorter than the track's media duration
4546  st->duration = FFMIN(st->duration, edit_list_dts_entry_end - start_dts);
4547  msc->start_pad = sti->skip_samples;
4548 
4549  // Free the old index and the old CTTS structures
4550  av_free(e_old);
4551  av_free(stts_data_old);
4552  av_free(ctts_data_old);
4553  av_freep(&frame_duration_buffer);
4554 
4555  // Null terminate the index ranges array
4556  current_index_range = current_index_range ? current_index_range + 1
4557  : msc->index_ranges;
4558  current_index_range->start = 0;
4559  current_index_range->end = 0;
4560  msc->current_index = msc->index_ranges[0].start;
4561 }
4562 
4563 static uint32_t get_sgpd_sync_index(const MOVStreamContext *sc, int nal_unit_type)
4564 {
4565  for (uint32_t i = 0; i < sc->sgpd_sync_count; i++)
4566  if (sc->sgpd_sync[i] == HEVC_NAL_CRA_NUT)
4567  return i + 1;
4568  return 0;
4569 }
4570 
4572 {
4573  int k;
4574  int sample_id = 0;
4575  uint32_t cra_index;
4576  MOVStreamContext *sc = st->priv_data;
4577 
4578  if (st->codecpar->codec_id != AV_CODEC_ID_HEVC || !sc->sync_group_count)
4579  return 0;
4580 
4581  /* Build an unrolled index of the samples */
4582  sc->sample_offsets_count = 0;
4583  for (uint32_t i = 0; i < sc->ctts_count; i++) {
4584  if (sc->ctts_data[i].count > INT_MAX - sc->sample_offsets_count)
4585  return AVERROR(ENOMEM);
4586  sc->sample_offsets_count += sc->ctts_data[i].count;
4587  }
4588  av_freep(&sc->sample_offsets);
4590  if (!sc->sample_offsets)
4591  return AVERROR(ENOMEM);
4592  k = 0;
4593  for (uint32_t i = 0; i < sc->ctts_count; i++)
4594  for (int j = 0; j < sc->ctts_data[i].count; j++)
4595  sc->sample_offsets[k++] = sc->ctts_data[i].offset;
4596 
4597  /* The following HEVC NAL type reveal the use of open GOP sync points
4598  * (TODO: BLA types may also be concerned) */
4599  cra_index = get_sgpd_sync_index(sc, HEVC_NAL_CRA_NUT); /* Clean Random Access */
4600  if (!cra_index)
4601  return 0;
4602 
4603  /* Build a list of open-GOP key samples */
4604  sc->open_key_samples_count = 0;
4605  for (uint32_t i = 0; i < sc->sync_group_count; i++)
4606  if (sc->sync_group[i].index == cra_index) {
4607  if (sc->sync_group[i].count > INT_MAX - sc->open_key_samples_count)
4608  return AVERROR(ENOMEM);
4610  }
4611  av_freep(&sc->open_key_samples);
4613  if (!sc->open_key_samples)
4614  return AVERROR(ENOMEM);
4615  k = 0;
4616  for (uint32_t i = 0; i < sc->sync_group_count; i++) {
4617  const MOVSbgp *sg = &sc->sync_group[i];
4618  if (sg->index == cra_index)
4619  for (uint32_t j = 0; j < sg->count; j++)
4620  sc->open_key_samples[k++] = sample_id;
4621  if (sg->count > INT_MAX - sample_id)
4622  return AVERROR_PATCHWELCOME;
4623  sample_id += sg->count;
4624  }
4625 
4626  /* Identify the minimal time step between samples */
4627  sc->min_sample_duration = UINT_MAX;
4628  for (uint32_t i = 0; i < sc->stts_count; i++)
4630 
4631  return 0;
4632 }
4633 
4634 static void mov_build_index(MOVContext *mov, AVStream *st)
4635 {
4636  MOVStreamContext *sc = st->priv_data;
4637  FFStream *const sti = ffstream(st);
4638  int64_t current_offset;
4639  int64_t current_dts = 0;
4640  unsigned int stts_index = 0;
4641  unsigned int stsc_index = 0;
4642  unsigned int stss_index = 0;
4643  unsigned int stps_index = 0;
4644  unsigned int i, j;
4645  uint64_t stream_size = 0;
4646  MOVStts *stts_data_old = sc->stts_data;
4647  MOVCtts *ctts_data_old = sc->ctts_data;
4648  unsigned int stts_count_old = sc->stts_count;
4649  unsigned int ctts_count_old = sc->ctts_count;
4650 
4651  int ret = build_open_gop_key_points(st);
4652  if (ret < 0)
4653  return;
4654 
4655  if (sc->elst_count) {
4656  int i, edit_start_index = 0, multiple_edits = 0;
4657  int64_t empty_duration = 0; // empty duration of the first edit list entry
4658  int64_t start_time = 0; // start time of the media
4659 
4660  for (i = 0; i < sc->elst_count; i++) {
4661  const MOVElst *e = &sc->elst_data[i];
4662  if (i == 0 && e->time == -1) {
4663  /* if empty, the first entry is the start time of the stream
4664  * relative to the presentation itself */
4665  empty_duration = e->duration;
4666  edit_start_index = 1;
4667  } else if (i == edit_start_index && e->time >= 0) {
4668  start_time = e->time;
4669  } else {
4670  multiple_edits = 1;
4671  }
4672  }
4673 
4674  if (multiple_edits && !mov->advanced_editlist) {
4676  av_log(mov->fc, AV_LOG_WARNING, "multiple edit list entries, "
4677  "not supported in fragmented MP4 files\n");
4678  else
4679  av_log(mov->fc, AV_LOG_WARNING, "multiple edit list entries, "
4680  "Use -advanced_editlist to correctly decode otherwise "
4681  "a/v desync might occur\n");
4682  }
4683 
4684  /* adjust first dts according to edit list */
4685  if ((empty_duration || start_time) && mov->time_scale > 0) {
4686  if (empty_duration)
4687  empty_duration = av_rescale(empty_duration, sc->time_scale, mov->time_scale);
4688 
4689  if (av_sat_sub64(start_time, empty_duration) != start_time - (uint64_t)empty_duration)
4690  av_log(mov->fc, AV_LOG_WARNING, "start_time - empty_duration is not representable\n");
4691 
4692  sc->time_offset = start_time - (uint64_t)empty_duration;
4694  if (!mov->advanced_editlist)
4695  current_dts = -sc->time_offset;
4696  }
4697 
4698  if (!multiple_edits && !mov->advanced_editlist &&
4700  sc->start_pad = start_time;
4701  }
4702 
4703  /* only use old uncompressed audio chunk demuxing when stts specifies it */
4704  if (!(st->codecpar->codec_type == AVMEDIA_TYPE_AUDIO &&
4705  sc->stts_count == 1 && sc->stts_data[0].duration == 1)) {
4706  unsigned int current_sample = 0;
4707  unsigned int stts_sample = 0;
4708  unsigned int sample_size;
4709  unsigned int distance = 0;
4710  unsigned int rap_group_index = 0;
4711  unsigned int rap_group_sample = 0;
4712  int rap_group_present = sc->rap_group_count && sc->rap_group;
4713  int key_off = (sc->keyframe_count && sc->keyframes[0] > 0) || (sc->stps_count && sc->stps_data[0] > 0);
4714 
4715  current_dts -= sc->dts_shift;
4716 
4717  if (!sc->sample_count || sti->nb_index_entries)
4718  return;
4719  if (sc->sample_count >= UINT_MAX / sizeof(*sti->index_entries) - sti->nb_index_entries)
4720  return;
4721  if (av_reallocp_array(&sti->index_entries,
4722  sti->nb_index_entries + sc->sample_count,
4723  sizeof(*sti->index_entries)) < 0) {
4724  sti->nb_index_entries = 0;
4725  return;
4726  }
4727  sti->index_entries_allocated_size = (sti->nb_index_entries + sc->sample_count) * sizeof(*sti->index_entries);
4728 
4729  if (ctts_data_old) {
4730  // Expand ctts entries such that we have a 1-1 mapping with samples
4731  if (sc->sample_count >= UINT_MAX / sizeof(*sc->ctts_data))
4732  return;
4733  sc->ctts_count = 0;
4734  sc->ctts_allocated_size = 0;
4736  sc->sample_count * sizeof(*sc->ctts_data));
4737  if (!sc->ctts_data) {
4738  av_free(ctts_data_old);
4739  return;
4740  }
4741 
4742  memset((uint8_t*)(sc->ctts_data), 0, sc->ctts_allocated_size);
4743 
4744  for (i = 0; i < ctts_count_old &&
4745  sc->ctts_count < sc->sample_count; i++)
4746  for (j = 0; j < ctts_data_old[i].count &&
4747  sc->ctts_count < sc->sample_count; j++)
4748  add_ctts_entry(&sc->ctts_data, &sc->ctts_count,
4749  &sc->ctts_allocated_size, 1,
4750  ctts_data_old[i].offset);
4751  av_free(ctts_data_old);
4752  }
4753  if (stts_data_old) {
4754  // Expand stts entries such that we have a 1-1 mapping with samples
4755  if (sc->sample_count >= UINT_MAX / sizeof(*sc->stts_data))
4756  return;
4757  sc->stts_count = 0;
4758  sc->stts_allocated_size = 0;
4760  sc->sample_count * sizeof(*sc->stts_data));
4761  if (!sc->stts_data) {
4762  av_free(stts_data_old);
4763  return;
4764  }
4765 
4766  memset((uint8_t*)(sc->stts_data), 0, sc->stts_allocated_size);
4767 
4768  for (i = 0; i < stts_count_old &&
4769  sc->stts_count < sc->sample_count; i++)
4770  for (j = 0; j < stts_data_old[i].count &&
4771  sc->stts_count < sc->sample_count; j++)
4772  add_stts_entry(&sc->stts_data, &sc->stts_count,
4773  &sc->stts_allocated_size, 1,
4774  stts_data_old[i].duration);
4775  av_free(stts_data_old);
4776  }
4777 
4778  for (i = 0; i < sc->chunk_count; i++) {
4779  int64_t next_offset = i+1 < sc->chunk_count ? sc->chunk_offsets[i+1] : INT64_MAX;
4780  current_offset = sc->chunk_offsets[i];
4781  while (mov_stsc_index_valid(stsc_index, sc->stsc_count) &&
4782  i + 1 == sc->stsc_data[stsc_index + 1].first)
4783  stsc_index++;
4784 
4785  if (next_offset > current_offset && sc->sample_size>0 && sc->sample_size < sc->stsz_sample_size &&
4786  sc->stsc_data[stsc_index].count * (int64_t)sc->stsz_sample_size > next_offset - current_offset) {
4787  av_log(mov->fc, AV_LOG_WARNING, "STSZ sample size %d invalid (too large), ignoring\n", sc->stsz_sample_size);
4788  sc->stsz_sample_size = sc->sample_size;
4789  }
4790  if (sc->stsz_sample_size>0 && sc->stsz_sample_size < sc->sample_size) {
4791  av_log(mov->fc, AV_LOG_WARNING, "STSZ sample size %d invalid (too small), ignoring\n", sc->stsz_sample_size);
4792  sc->stsz_sample_size = sc->sample_size;
4793  }
4794 
4795  for (j = 0; j < sc->stsc_data[stsc_index].count; j++) {
4796  int keyframe = 0;
4797  if (current_sample >= sc->sample_count) {
4798  av_log(mov->fc, AV_LOG_ERROR, "wrong sample count\n");
4799  return;
4800  }
4801 
4802  if (!sc->keyframe_absent && (!sc->keyframe_count || current_sample+key_off == sc->keyframes[stss_index])) {
4803  keyframe = 1;
4804  if (stss_index + 1 < sc->keyframe_count)
4805  stss_index++;
4806  } else if (sc->stps_count && current_sample+key_off == sc->stps_data[stps_index]) {
4807  keyframe = 1;
4808  if (stps_index + 1 < sc->stps_count)
4809  stps_index++;
4810  }
4811  if (rap_group_present && rap_group_index < sc->rap_group_count) {
4812  if (sc->rap_group[rap_group_index].index > 0)
4813  keyframe = 1;
4814  if (++rap_group_sample == sc->rap_group[rap_group_index].count) {
4815  rap_group_sample = 0;
4816  rap_group_index++;
4817  }
4818  }
4819  if (sc->keyframe_absent
4820  && !sc->stps_count
4821  && !rap_group_present
4822  && (st->codecpar->codec_type == AVMEDIA_TYPE_AUDIO || (i==0 && j==0)))
4823  keyframe = 1;
4824  if (keyframe)
4825  distance = 0;
4826  sample_size = sc->stsz_sample_size > 0 ? sc->stsz_sample_size : sc->sample_sizes[current_sample];
4827  if (current_offset > INT64_MAX - sample_size) {
4828  av_log(mov->fc, AV_LOG_ERROR, "Current offset %"PRId64" or sample size %u is too large\n",
4829  current_offset,
4830  sample_size);
4831  return;
4832  }
4833 
4834  if (sc->pseudo_stream_id == -1 ||
4835  sc->stsc_data[stsc_index].id - 1 == sc->pseudo_stream_id) {
4836  AVIndexEntry *e;
4837  if (sample_size > 0x3FFFFFFF) {
4838  av_log(mov->fc, AV_LOG_ERROR, "Sample size %u is too large\n", sample_size);
4839  return;
4840  }
4841  e = &sti->index_entries[sti->nb_index_entries++];
4842  e->pos = current_offset;
4843  e->timestamp = current_dts;
4844  e->size = sample_size;
4845  e->min_distance = distance;
4846  e->flags = keyframe ? AVINDEX_KEYFRAME : 0;
4847  av_log(mov->fc, AV_LOG_TRACE, "AVIndex stream %d, sample %u, offset %"PRIx64", dts %"PRId64", "
4848  "size %u, distance %u, keyframe %d\n", st->index, current_sample,
4849  current_offset, current_dts, sample_size, distance, keyframe);
4850  if (st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO && sti->nb_index_entries < 100)
4851  ff_rfps_add_frame(mov->fc, st, current_dts);
4852  }
4853 
4854  current_offset += sample_size;
4855  stream_size += sample_size;
4856 
4857  current_dts += sc->stts_data[stts_index].duration;
4858 
4859  distance++;
4860  stts_sample++;
4861  current_sample++;
4862  if (stts_index + 1 < sc->stts_count && stts_sample == sc->stts_data[stts_index].count) {
4863  stts_sample = 0;
4864  stts_index++;
4865  }
4866  }
4867  }
4868  if (st->duration > 0)
4869  st->codecpar->bit_rate = stream_size*8*sc->time_scale/st->duration;
4870  } else {
4871  unsigned chunk_samples, total = 0;
4872 
4873  if (!sc->chunk_count)
4874  return;
4875 
4876  // compute total chunk count
4877  for (i = 0; i < sc->stsc_count; i++) {
4878  unsigned count, chunk_count;
4879 
4880  chunk_samples = sc->stsc_data[i].count;
4881  if (i != sc->stsc_count - 1 &&
4882  sc->samples_per_frame && chunk_samples % sc->samples_per_frame) {
4883  av_log(mov->fc, AV_LOG_ERROR, "error unaligned chunk\n");
4884  return;
4885  }
4886 
4887  if (sc->samples_per_frame >= 160) { // gsm
4888  count = chunk_samples / sc->samples_per_frame;
4889  } else if (sc->samples_per_frame > 1) {
4890  unsigned samples = (1024/sc->samples_per_frame)*sc->samples_per_frame;
4891  count = (chunk_samples+samples-1) / samples;
4892  } else {
4893  count = (chunk_samples+1023) / 1024;
4894  }
4895 
4896  if (mov_stsc_index_valid(i, sc->stsc_count))
4897  chunk_count = sc->stsc_data[i+1].first - sc->stsc_data[i].first;
4898  else
4899  chunk_count = sc->chunk_count - (sc->stsc_data[i].first - 1);
4900  total += chunk_count * count;
4901  }
4902 
4903  av_log(mov->fc, AV_LOG_TRACE, "chunk count %u\n", total);
4904  if (total >= UINT_MAX / sizeof(*sti->index_entries) - sti->nb_index_entries)
4905  return;
4906  if (av_reallocp_array(&sti->index_entries,
4907  sti->nb_index_entries + total,
4908  sizeof(*sti->index_entries)) < 0) {
4909  sti->nb_index_entries = 0;
4910  return;
4911  }
4912  sti->index_entries_allocated_size = (sti->nb_index_entries + total) * sizeof(*sti->index_entries);
4913 
4914  // populate index
4915  for (i = 0; i < sc->chunk_count; i++) {
4916  current_offset = sc->chunk_offsets[i];
4917  if (mov_stsc_index_valid(stsc_index, sc->stsc_count) &&
4918  i + 1 == sc->stsc_data[stsc_index + 1].first)
4919  stsc_index++;
4920  chunk_samples = sc->stsc_data[stsc_index].count;
4921 
4922  while (chunk_samples > 0) {
4923  AVIndexEntry *e;
4924  unsigned size, samples;
4925 
4926  if (sc->samples_per_frame > 1 && !sc->bytes_per_frame) {
4928  "Zero bytes per frame, but %d samples per frame",
4929  sc->samples_per_frame);
4930  return;
4931  }
4932 
4933  if (sc->samples_per_frame >= 160) { // gsm
4934  samples = sc->samples_per_frame;
4935  size = sc->bytes_per_frame;
4936  } else {
4937  if (sc->samples_per_frame > 1) {
4938  samples = FFMIN((1024 / sc->samples_per_frame)*
4939  sc->samples_per_frame, chunk_samples);
4941  } else {
4942  samples = FFMIN(1024, chunk_samples);
4943  size = samples * sc->sample_size;
4944  }
4945  }
4946 
4947  if (sti->nb_index_entries >= total) {
4948  av_log(mov->fc, AV_LOG_ERROR, "wrong chunk count %u\n", total);
4949  return;
4950  }
4951  if (size > 0x3FFFFFFF) {
4952  av_log(mov->fc, AV_LOG_ERROR, "Sample size %u is too large\n", size);
4953  return;
4954  }
4955  e = &sti->index_entries[sti->nb_index_entries++];
4956  e->pos = current_offset;
4957  e->timestamp = current_dts;
4958  e->size = size;
4959  e->min_distance = 0;
4960  e->flags = AVINDEX_KEYFRAME;
4961  av_log(mov->fc, AV_LOG_TRACE, "AVIndex stream %d, chunk %u, offset %"PRIx64", dts %"PRId64", "
4962  "size %u, duration %u\n", st->index, i, current_offset, current_dts,
4963  size, samples);
4964 
4965  current_offset += size;
4966  current_dts += samples;
4967  chunk_samples -= samples;
4968  }
4969  }
4970  }
4971 
4972  if (!mov->ignore_editlist && mov->advanced_editlist) {
4973  // Fix index according to edit lists.
4974  mov_fix_index(mov, st);
4975  }
4976 
4977  // Update start time of the stream.
4979  st->start_time = sti->index_entries[0].timestamp + sc->dts_shift;
4980  if (sc->ctts_data) {
4981  st->start_time += sc->ctts_data[0].offset;
4982  }
4983  }
4984 
4985  mov_estimate_video_delay(mov, st);
4986 }
4987 
4988 static int test_same_origin(const char *src, const char *ref) {
4989  char src_proto[64];
4990  char ref_proto[64];
4991  char src_auth[256];
4992  char ref_auth[256];
4993  char src_host[256];
4994  char ref_host[256];
4995  int src_port=-1;
4996  int ref_port=-1;
4997 
4998  av_url_split(src_proto, sizeof(src_proto), src_auth, sizeof(src_auth), src_host, sizeof(src_host), &src_port, NULL, 0, src);
4999  av_url_split(ref_proto, sizeof(ref_proto), ref_auth, sizeof(ref_auth), ref_host, sizeof(ref_host), &ref_port, NULL, 0, ref);
5000 
5001  if (strlen(src) == 0) {
5002  return -1;
5003  } else if (strlen(src_auth) + 1 >= sizeof(src_auth) ||
5004  strlen(ref_auth) + 1 >= sizeof(ref_auth) ||
5005  strlen(src_host) + 1 >= sizeof(src_host) ||
5006  strlen(ref_host) + 1 >= sizeof(ref_host)) {
5007  return 0;
5008  } else if (strcmp(src_proto, ref_proto) ||
5009  strcmp(src_auth, ref_auth) ||
5010  strcmp(src_host, ref_host) ||
5011  src_port != ref_port) {
5012  return 0;
5013  } else
5014  return 1;
5015 }
5016 
5017 static int mov_open_dref(MOVContext *c, AVIOContext **pb, const char *src, MOVDref *ref)
5018 {
5019  /* try relative path, we do not try the absolute because it can leak information about our
5020  system to an attacker */
5021  if (ref->nlvl_to > 0 && ref->nlvl_from > 0) {
5022  char filename[1025];
5023  const char *src_path;
5024  int i, l;
5025 
5026  /* find a source dir */
5027  src_path = strrchr(src, '/');
5028  if (src_path)
5029  src_path++;
5030  else
5031  src_path = src;
5032 
5033  /* find a next level down to target */
5034  for (i = 0, l = strlen(ref->path) - 1; l >= 0; l--)
5035  if (ref->path[l] == '/') {
5036  if (i == ref->nlvl_to - 1)
5037  break;
5038  else
5039  i++;
5040  }
5041 
5042  /* compose filename if next level down to target was found */
5043  if (i == ref->nlvl_to - 1 && src_path - src < sizeof(filename)) {
5044  memcpy(filename, src, src_path - src);
5045  filename[src_path - src] = 0;
5046 
5047  for (i = 1; i < ref->nlvl_from; i++)
5048  av_strlcat(filename, "../", sizeof(filename));
5049 
5050  av_strlcat(filename, ref->path + l + 1, sizeof(filename));
5051  if (!c->use_absolute_path) {
5052  int same_origin = test_same_origin(src, filename);
5053 
5054  if (!same_origin) {
5055  av_log(c->fc, AV_LOG_ERROR,
5056  "Reference with mismatching origin, %s not tried for security reasons, "
5057  "set demuxer option use_absolute_path to allow it anyway\n",
5058  ref->path);
5059  return AVERROR(ENOENT);
5060  }
5061 
5062  if (strstr(ref->path + l + 1, "..") ||
5063  strstr(ref->path + l + 1, ":") ||
5064  (ref->nlvl_from > 1 && same_origin < 0) ||
5065  (filename[0] == '/' && src_path == src))
5066  return AVERROR(ENOENT);
5067  }
5068 
5069  if (strlen(filename) + 1 == sizeof(filename))
5070  return AVERROR(ENOENT);
5071  if (!c->fc->io_open(c->fc, pb, filename, AVIO_FLAG_READ, NULL))
5072  return 0;
5073  }
5074  } else if (c->use_absolute_path) {
5075  av_log(c->fc, AV_LOG_WARNING, "Using absolute path on user request, "
5076  "this is a possible security issue\n");
5077  if (!c->fc->io_open(c->fc, pb, ref->path, AVIO_FLAG_READ, NULL))
5078  return 0;
5079  } else {
5080  av_log(c->fc, AV_LOG_ERROR,
5081  "Absolute path %s not tried for security reasons, "
5082  "set demuxer option use_absolute_path to allow absolute paths\n",
5083  ref->path);
5084  }
5085 
5086  return AVERROR(ENOENT);
5087 }
5088 
5090 {
5091  if (sc->time_scale <= 0) {
5092  av_log(c->fc, AV_LOG_WARNING, "stream %d, timescale not set\n", sc->ffindex);
5093  sc->time_scale = c->time_scale;
5094  if (sc->time_scale <= 0)
5095  sc->time_scale = 1;
5096  }
5097 }
5098 
5099 #if CONFIG_IAMFDEC
5100 static int mov_update_iamf_streams(MOVContext *c, const AVStream *st)
5101 {
5102  const MOVStreamContext *sc = st->priv_data;
5103  const IAMFContext *iamf = &sc->iamf->iamf;
5104 
5105  for (int i = 0; i < iamf->nb_audio_elements; i++) {
5106  const AVStreamGroup *stg = NULL;
5107 
5108  for (int j = 0; j < c->fc->nb_stream_groups; j++)
5109  if (c->fc->stream_groups[j]->id == iamf->audio_elements[i]->audio_element_id)
5110  stg = c->fc->stream_groups[j];
5111  av_assert0(stg);
5112 
5113  for (int j = 0; j < stg->nb_streams; j++) {
5114  const FFStream *sti = cffstream(st);
5115  AVStream *out = stg->streams[j];
5116  FFStream *out_sti = ffstream(stg->streams[j]);
5117 
5118  out->codecpar->bit_rate = 0;
5119 
5120  if (out == st)
5121  continue;
5122 
5123  out->time_base = st->time_base;
5124  out->start_time = st->start_time;
5125  out->duration = st->duration;
5126  out->nb_frames = st->nb_frames;
5127  out->discard = st->discard;
5128 
5129  av_assert0(!out_sti->index_entries);
5131  if (!out_sti->index_entries)
5132  return AVERROR(ENOMEM);
5133 
5135  out_sti->nb_index_entries = sti->nb_index_entries;
5136  out_sti->skip_samples = sti->skip_samples;
5137  memcpy(out_sti->index_entries, sti->index_entries, sti->index_entries_allocated_size);
5138  }
5139  }
5140 
5141  return 0;
5142 }
5143 #endif
5144 
5146 {
5147  AVStream *st;
5148  MOVStreamContext *sc;
5149  int ret;
5150 
5151  st = avformat_new_stream(c->fc, NULL);
5152  if (!st) return AVERROR(ENOMEM);
5153  st->id = -1;
5154  sc = av_mallocz(sizeof(MOVStreamContext));
5155  if (!sc) return AVERROR(ENOMEM);
5156 
5157  st->priv_data = sc;
5159  sc->ffindex = st->index;
5160  c->trak_index = st->index;
5161  sc->tref_flags = 0;
5162  sc->tref_id = -1;
5163  sc->refcount = 1;
5164 
5165  if ((ret = mov_read_default(c, pb, atom)) < 0)
5166  return ret;
5167 
5168  c->trak_index = -1;
5169 
5170  // Here stsc refers to a chunk not described in stco. This is technically invalid,
5171  // but we can overlook it (clearing stsc) whenever stts_count == 0 (indicating no samples).
5172  if (!sc->chunk_count && !sc->stts_count && sc->stsc_count) {
5173  sc->stsc_count = 0;
5174  av_freep(&sc->stsc_data);
5175  }
5176 
5177  /* sanity checks */
5178  if ((sc->chunk_count && (!sc->stts_count || !sc->stsc_count ||
5179  (!sc->sample_size && !sc->sample_count))) ||
5180  (!sc->chunk_count && sc->sample_count)) {
5181  av_log(c->fc, AV_LOG_ERROR, "stream %d, missing mandatory atoms, broken header\n",
5182  st->index);
5183  return 0;
5184  }
5185  if (sc->stsc_count && sc->stsc_data[ sc->stsc_count - 1 ].first > sc->chunk_count) {
5186  av_log(c->fc, AV_LOG_ERROR, "stream %d, contradictionary STSC and STCO\n",
5187  st->index);
5188  return AVERROR_INVALIDDATA;
5189  }
5190 
5191  fix_timescale(c, sc);
5192 
5193  avpriv_set_pts_info(st, 64, 1, sc->time_scale);
5194 
5195  /*
5196  * Advanced edit list support does not work with fragemented MP4s, which
5197  * have stsc, stsz, stco, and stts with zero entries in the moov atom.
5198  * In these files, trun atoms may be streamed in.
5199  */
5200  if (!sc->stts_count && c->advanced_editlist) {
5201 
5202  av_log(c->fc, AV_LOG_VERBOSE, "advanced_editlist does not work with fragmented "
5203  "MP4. disabling.\n");
5204  c->advanced_editlist = 0;
5205  c->advanced_editlist_autodisabled = 1;
5206  }
5207 
5208  mov_build_index(c, st);
5209 
5210 #if CONFIG_IAMFDEC
5211  if (sc->iamf) {
5212  ret = mov_update_iamf_streams(c, st);
5213  if (ret < 0)
5214  return ret;
5215  }
5216 #endif
5217 
5218  if (sc->dref_id-1 < sc->drefs_count && sc->drefs[sc->dref_id-1].path) {
5219  MOVDref *dref = &sc->drefs[sc->dref_id - 1];
5220  if (c->enable_drefs) {
5221  if (mov_open_dref(c, &sc->pb, c->fc->url, dref) < 0)
5222  av_log(c->fc, AV_LOG_ERROR,
5223  "stream %d, error opening alias: path='%s', dir='%s', "
5224  "filename='%s', volume='%s', nlvl_from=%d, nlvl_to=%d\n",
5225  st->index, dref->path, dref->dir, dref->filename,
5226  dref->volume, dref->nlvl_from, dref->nlvl_to);
5227  } else {
5228  av_log(c->fc, AV_LOG_WARNING,
5229  "Skipped opening external track: "
5230  "stream %d, alias: path='%s', dir='%s', "
5231  "filename='%s', volume='%s', nlvl_from=%d, nlvl_to=%d."
5232  "Set enable_drefs to allow this.\n",
5233  st->index, dref->path, dref->dir, dref->filename,
5234  dref->volume, dref->nlvl_from, dref->nlvl_to);
5235  }
5236  } else {
5237  sc->pb = c->fc->pb;
5238  sc->pb_is_copied = 1;
5239  }
5240 
5241  if (st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO) {
5242  int stts_constant = !!sc->stts_count;
5243  if (sc->h_spacing && sc->v_spacing)
5245  sc->h_spacing, sc->v_spacing, INT_MAX);
5246  if (!st->sample_aspect_ratio.num && st->codecpar->width && st->codecpar->height &&
5247  sc->height && sc->width &&
5248  (st->codecpar->width != sc->width || st->codecpar->height != sc->height)) {
5250  (int64_t)st->codecpar->height * sc->width,
5251  (int64_t)st->codecpar->width * sc->height, INT_MAX);
5252  }
5253 
5254 #if FF_API_R_FRAME_RATE
5255  for (int i = 1; sc->stts_count && i < sc->stts_count - 1; i++) {
5256  if (sc->stts_data[i].duration == sc->stts_data[0].duration)
5257  continue;
5258  stts_constant = 0;
5259  }
5260  if (stts_constant)
5262  sc->time_scale, sc->stts_data[0].duration, INT_MAX);
5263 #endif
5264  }
5265 
5266  // done for ai5q, ai52, ai55, ai1q, ai12 and ai15.
5267  if (!st->codecpar->extradata_size && st->codecpar->codec_id == AV_CODEC_ID_H264 &&
5268  TAG_IS_AVCI(st->codecpar->codec_tag)) {
5270  if (ret < 0)
5271  return ret;
5272  }
5273 
5274  switch (st->codecpar->codec_id) {
5275 #if CONFIG_H261_DECODER
5276  case AV_CODEC_ID_H261:
5277 #endif
5278 #if CONFIG_H263_DECODER
5279  case AV_CODEC_ID_H263:
5280 #endif
5281 #if CONFIG_MPEG4_DECODER
5282  case AV_CODEC_ID_MPEG4:
5283 #endif
5284  st->codecpar->width = 0; /* let decoder init width/height */
5285  st->codecpar->height= 0;
5286  break;
5287  }
5288 
5289  // If the duration of the mp3 packets is not constant, then they could need a parser
5290  if (st->codecpar->codec_id == AV_CODEC_ID_MP3
5291  && sc->time_scale == st->codecpar->sample_rate) {
5292  int stts_constant = 1;
5293  for (int i = 1; i < sc->stts_count; i++) {
5294  if (sc->stts_data[i].duration == sc->stts_data[0].duration)
5295  continue;
5296  stts_constant = 0;
5297  }
5298  if (!stts_constant)
5300  }
5301  /* Do not need those anymore. */
5302  av_freep(&sc->chunk_offsets);
5303  av_freep(&sc->sample_sizes);
5304  av_freep(&sc->keyframes);
5305  av_freep(&sc->stps_data);
5306  av_freep(&sc->elst_data);
5307  av_freep(&sc->rap_group);
5308  av_freep(&sc->sync_group);
5309  av_freep(&sc->sgpd_sync);
5310 
5311  return 0;
5312 }
5313 
5315 {
5316  int ret;
5317  c->itunes_metadata = 1;
5318  ret = mov_read_default(c, pb, atom);
5319  c->itunes_metadata = 0;
5320  return ret;
5321 }
5322 
5324 {
5325  uint32_t count;
5326  uint32_t i;
5327 
5328  if (atom.size < 8)
5329  return 0;
5330 
5331  avio_skip(pb, 4);
5332  count = avio_rb32(pb);
5333  atom.size -= 8;
5334  if (count >= UINT_MAX / sizeof(*c->meta_keys)) {
5335  av_log(c->fc, AV_LOG_ERROR,
5336  "The 'keys' atom with the invalid key count: %"PRIu32"\n", count);
5337  return AVERROR_INVALIDDATA;
5338  }
5339 
5340  c->meta_keys_count = count + 1;
5341  c->meta_keys = av_mallocz(c->meta_keys_count * sizeof(*c->meta_keys));
5342  if (!c->meta_keys)
5343  return AVERROR(ENOMEM);
5344 
5345  for (i = 1; i <= count; ++i) {
5346  uint32_t key_size = avio_rb32(pb);
5347  uint32_t type = avio_rl32(pb);
5348  if (key_size < 8 || key_size > atom.size) {
5349  av_log(c->fc, AV_LOG_ERROR,
5350  "The key# %"PRIu32" in meta has invalid size:"
5351  "%"PRIu32"\n", i, key_size);
5352  return AVERROR_INVALIDDATA;
5353  }
5354  atom.size -= key_size;
5355  key_size -= 8;
5356  if (type != MKTAG('m','d','t','a')) {
5357  avio_skip(pb, key_size);
5358  continue;
5359  }
5360  c->meta_keys[i] = av_mallocz(key_size + 1);
5361  if (!c->meta_keys[i])
5362  return AVERROR(ENOMEM);
5363  avio_read(pb, c->meta_keys[i], key_size);
5364  }
5365 
5366  return 0;
5367 }
5368 
5370 {
5371  int64_t end = av_sat_add64(avio_tell(pb), atom.size);
5372  uint8_t *key = NULL, *val = NULL, *mean = NULL;
5373  int i;
5374  int ret = 0;
5375  AVStream *st;
5376  MOVStreamContext *sc;
5377 
5378  if (c->fc->nb_streams < 1)
5379  return 0;
5380  st = c->fc->streams[c->fc->nb_streams-1];
5381  sc = st->priv_data;
5382 
5383  for (i = 0; i < 3; i++) {
5384  uint8_t **p;
5385  uint32_t len, tag;
5386 
5387  if (end - avio_tell(pb) <= 12)
5388  break;
5389 
5390  len = avio_rb32(pb);
5391  tag = avio_rl32(pb);
5392  avio_skip(pb, 4); // flags
5393 
5394  if (len < 12 || len - 12 > end - avio_tell(pb))
5395  break;
5396  len -= 12;
5397 
5398  if (tag == MKTAG('m', 'e', 'a', 'n'))
5399  p = &mean;
5400  else if (tag == MKTAG('n', 'a', 'm', 'e'))
5401  p = &key;
5402  else if (tag == MKTAG('d', 'a', 't', 'a') && len > 4) {
5403  avio_skip(pb, 4);
5404  len -= 4;
5405  p = &val;
5406  } else
5407  break;
5408 
5409  if (*p)
5410  break;
5411 
5412  *p = av_malloc(len + 1);
5413  if (!*p) {
5414  ret = AVERROR(ENOMEM);
5415  break;
5416  }
5417  ret = ffio_read_size(pb, *p, len);
5418  if (ret < 0) {
5419  av_freep(p);
5420  break;
5421  }
5422  (*p)[len] = 0;
5423  }
5424 
5425  if (mean && key && val) {
5426  if (strcmp(key, "iTunSMPB") == 0) {
5427  int priming, remainder, samples;
5428  if(sscanf(val, "%*X %X %X %X", &priming, &remainder, &samples) == 3){
5429  if(priming>0 && priming<16384)
5430  sc->start_pad = priming;
5431  }
5432  }
5433  if (strcmp(key, "cdec") != 0) {
5434  av_dict_set(&c->fc->metadata, key, val,
5436  key = val = NULL;
5437  }
5438  } else {
5439  av_log(c->fc, AV_LOG_VERBOSE,
5440  "Unhandled or malformed custom metadata of size %"PRId64"\n", atom.size);
5441  }
5442 
5443  avio_seek(pb, end, SEEK_SET);
5444  av_freep(&key);
5445  av_freep(&val);
5446  av_freep(&mean);
5447  return ret;
5448 }
5449 
5451 {
5452  MOVStreamContext *sc;
5453  AVStream *st;
5454 
5455  st = avformat_new_stream(c->fc, NULL);
5456  if (!st)
5457  return AVERROR(ENOMEM);
5458  sc = av_mallocz(sizeof(MOVStreamContext));
5459  if (!sc)
5460  return AVERROR(ENOMEM);
5461 
5462  item->st = st;
5463  st->id = item->item_id;
5464  st->priv_data = sc;
5466  st->codecpar->codec_id = mov_codec_id(st, item->type);
5467  sc->id = st->id;
5468  sc->ffindex = st->index;
5469  st->avg_frame_rate.num = st->avg_frame_rate.den = 1;
5470  st->time_base.num = st->time_base.den = 1;
5471  st->nb_frames = 1;
5472  sc->time_scale = 1;
5473  sc->pb = c->fc->pb;
5474  sc->pb_is_copied = 1;
5475  sc->refcount = 1;
5476 
5477  if (item->name)
5478  av_dict_set(&st->metadata, "title", item->name, 0);
5479 
5480  // Populate the necessary fields used by mov_build_index.
5481  sc->stsc_count = 1;
5482  sc->stsc_data = av_malloc_array(1, sizeof(*sc->stsc_data));
5483  if (!sc->stsc_data)
5484  return AVERROR(ENOMEM);
5485  sc->stsc_data[0].first = 1;
5486  sc->stsc_data[0].count = 1;
5487  sc->stsc_data[0].id = 1;
5488  sc->chunk_count = 1;
5489  sc->chunk_offsets = av_malloc_array(1, sizeof(*sc->chunk_offsets));
5490  if (!sc->chunk_offsets)
5491  return AVERROR(ENOMEM);
5492  sc->sample_count = 1;
5493  sc->sample_sizes = av_malloc_array(1, sizeof(*sc->sample_sizes));
5494  if (!sc->sample_sizes)
5495  return AVERROR(ENOMEM);
5496  sc->stts_count = 1;
5497  sc->stts_data = av_malloc_array(1, sizeof(*sc->stts_data));
5498  if (!sc->stts_data)
5499  return AVERROR(ENOMEM);
5500  sc->stts_data[0].count = 1;
5501  // Not used for still images. But needed by mov_build_index.
5502  sc->stts_data[0].duration = 0;
5503 
5504  return 0;
5505 }
5506 
5508 {
5509  while (atom.size > 8) {
5510  uint32_t tag;
5511  if (avio_feof(pb))
5512  return AVERROR_EOF;
5513  tag = avio_rl32(pb);
5514  atom.size -= 4;
5515  if (tag == MKTAG('h','d','l','r')) {
5516  avio_seek(pb, -8, SEEK_CUR);
5517  atom.size += 8;
5518  return mov_read_default(c, pb, atom);
5519  }
5520  }
5521  return 0;
5522 }
5523 
5524 // return 1 when matrix is identity, 0 otherwise
5525 #define IS_MATRIX_IDENT(matrix) \
5526  ( (matrix)[0][0] == (1 << 16) && \
5527  (matrix)[1][1] == (1 << 16) && \
5528  (matrix)[2][2] == (1 << 30) && \
5529  !(matrix)[0][1] && !(matrix)[0][2] && \
5530  !(matrix)[1][0] && !(matrix)[1][2] && \
5531  !(matrix)[2][0] && !(matrix)[2][1])
5532 
5534 {
5535  int i, j, e;
5536  int width;
5537  int height;
5538  int display_matrix[3][3];
5539  int res_display_matrix[3][3] = { { 0 } };
5540  AVStream *st;
5541  MOVStreamContext *sc;
5542  int version;
5543  int flags;
5544 
5545  if (c->fc->nb_streams < 1)
5546  return 0;
5547  st = c->fc->streams[c->fc->nb_streams-1];
5548  sc = st->priv_data;
5549 
5550  // Each stream (trak) should have exactly 1 tkhd. This catches bad files and
5551  // avoids corrupting AVStreams mapped to an earlier tkhd.
5552  if (st->id != -1)
5553  return AVERROR_INVALIDDATA;
5554 
5555  version = avio_r8(pb);
5556  flags = avio_rb24(pb);
5558 
5559  if (version == 1) {
5560  avio_rb64(pb);
5561  avio_rb64(pb);
5562  } else {
5563  avio_rb32(pb); /* creation time */
5564  avio_rb32(pb); /* modification time */
5565  }
5566  st->id = (int)avio_rb32(pb); /* track id (NOT 0 !)*/
5567  sc->id = st->id;
5568  avio_rb32(pb); /* reserved */
5569 
5570  /* highlevel (considering edits) duration in movie timebase */
5571  (version == 1) ? avio_rb64(pb) : avio_rb32(pb);
5572  avio_rb32(pb); /* reserved */
5573  avio_rb32(pb); /* reserved */
5574 
5575  avio_rb16(pb); /* layer */
5576  avio_rb16(pb); /* alternate group */
5577  avio_rb16(pb); /* volume */
5578  avio_rb16(pb); /* reserved */
5579 
5580  //read in the display matrix (outlined in ISO 14496-12, Section 6.2.2)
5581  // they're kept in fixed point format through all calculations
5582  // save u,v,z to store the whole matrix in the AV_PKT_DATA_DISPLAYMATRIX
5583  // side data, but the scale factor is not needed to calculate aspect ratio
5584  for (i = 0; i < 3; i++) {
5585  display_matrix[i][0] = avio_rb32(pb); // 16.16 fixed point
5586  display_matrix[i][1] = avio_rb32(pb); // 16.16 fixed point
5587  display_matrix[i][2] = avio_rb32(pb); // 2.30 fixed point
5588  }
5589 
5590  width = avio_rb32(pb); // 16.16 fixed point track width
5591  height = avio_rb32(pb); // 16.16 fixed point track height
5592  sc->width = width >> 16;
5593  sc->height = height >> 16;
5594 
5595  // apply the moov display matrix (after the tkhd one)
5596  for (i = 0; i < 3; i++) {
5597  const int sh[3] = { 16, 16, 30 };
5598  for (j = 0; j < 3; j++) {
5599  for (e = 0; e < 3; e++) {
5600  res_display_matrix[i][j] +=
5601  ((int64_t) display_matrix[i][e] *
5602  c->movie_display_matrix[e][j]) >> sh[e];
5603  }
5604  }
5605  }
5606 
5607  // save the matrix when it is not the default identity
5608  if (!IS_MATRIX_IDENT(res_display_matrix)) {
5609  av_freep(&sc->display_matrix);
5610  sc->display_matrix = av_malloc(sizeof(int32_t) * 9);
5611  if (!sc->display_matrix)
5612  return AVERROR(ENOMEM);
5613 
5614  for (i = 0; i < 3; i++)
5615  for (j = 0; j < 3; j++)
5616  sc->display_matrix[i * 3 + j] = res_display_matrix[i][j];
5617  }
5618 
5619  // transform the display width/height according to the matrix
5620  // to keep the same scale, use [width height 1<<16]
5621  if (width && height && sc->display_matrix) {
5622  double disp_transform[2];
5623 
5624  for (i = 0; i < 2; i++)
5625  disp_transform[i] = hypot(sc->display_matrix[0 + i],
5626  sc->display_matrix[3 + i]);
5627 
5628  if (disp_transform[0] > 1 && disp_transform[1] > 1 &&
5629  disp_transform[0] < (1<<24) && disp_transform[1] < (1<<24) &&
5630  fabs((disp_transform[0] / disp_transform[1]) - 1.0) > 0.01)
5632  disp_transform[0] / disp_transform[1],
5633  INT_MAX);
5634  }
5635  return 0;
5636 }
5637 
5639 {
5640  MOVFragment *frag = &c->fragment;
5641  MOVTrackExt *trex = NULL;
5642  int flags, track_id, i;
5643  MOVFragmentStreamInfo * frag_stream_info;
5644 
5645  avio_r8(pb); /* version */
5646  flags = avio_rb24(pb);
5647 
5648  track_id = avio_rb32(pb);
5649  if (!track_id)
5650  return AVERROR_INVALIDDATA;
5651  for (i = 0; i < c->trex_count; i++)
5652  if (c->trex_data[i].track_id == track_id) {
5653  trex = &c->trex_data[i];
5654  break;
5655  }
5656  if (!trex) {
5657  av_log(c->fc, AV_LOG_WARNING, "could not find corresponding trex (id %u)\n", track_id);
5658  return 0;
5659  }
5660  c->fragment.found_tfhd = 1;
5661  frag->track_id = track_id;
5662  set_frag_stream(&c->frag_index, track_id);
5663 
5666  frag->moof_offset : frag->implicit_offset;
5667  frag->stsd_id = flags & MOV_TFHD_STSD_ID ? avio_rb32(pb) : trex->stsd_id;
5668 
5670  avio_rb32(pb) : trex->duration;
5671  frag->size = flags & MOV_TFHD_DEFAULT_SIZE ?
5672  avio_rb32(pb) : trex->size;
5673  frag->flags = flags & MOV_TFHD_DEFAULT_FLAGS ?
5674  avio_rb32(pb) : trex->flags;
5675  av_log(c->fc, AV_LOG_TRACE, "frag flags 0x%x\n", frag->flags);
5676 
5677  frag_stream_info = get_current_frag_stream_info(&c->frag_index);
5678  if (frag_stream_info) {
5679  frag_stream_info->next_trun_dts = AV_NOPTS_VALUE;
5680  frag_stream_info->stsd_id = frag->stsd_id;
5681  }
5682  return 0;
5683 }
5684 
5686 {
5687  unsigned i, num;
5688  void *new_tracks;
5689 
5690  num = atom.size / 4;
5691  if (!(new_tracks = av_malloc_array(num, sizeof(int))))
5692  return AVERROR(ENOMEM);
5693 
5694  av_free(c->chapter_tracks);
5695  c->chapter_tracks = new_tracks;
5696  c->nb_chapter_tracks = num;
5697 
5698  for (i = 0; i < num && !pb->eof_reached; i++)
5699  c->chapter_tracks[i] = avio_rb32(pb);
5700 
5701  c->nb_chapter_tracks = i;
5702 
5703  return 0;
5704 }
5705 
5707 {
5708  MOVTrackExt *trex;
5709  int err;
5710 
5711  if ((uint64_t)c->trex_count+1 >= UINT_MAX / sizeof(*c->trex_data))
5712  return AVERROR_INVALIDDATA;
5713  if ((err = av_reallocp_array(&c->trex_data, c->trex_count + 1,
5714  sizeof(*c->trex_data))) < 0) {
5715  c->trex_count = 0;
5716  return err;
5717  }
5718 
5719  c->fc->duration = AV_NOPTS_VALUE; // the duration from mvhd is not representing the whole file when fragments are used.
5720 
5721  trex = &c->trex_data[c->trex_count++];
5722  avio_r8(pb); /* version */
5723  avio_rb24(pb); /* flags */
5724  trex->track_id = avio_rb32(pb);
5725  trex->stsd_id = avio_rb32(pb);
5726  trex->duration = avio_rb32(pb);
5727  trex->size = avio_rb32(pb);
5728  trex->flags = avio_rb32(pb);
5729  return 0;
5730 }
5731 
5733 {
5734  MOVFragment *frag = &c->fragment;
5735  AVStream *st = NULL;
5736  MOVStreamContext *sc;
5737  int version, i;
5738  MOVFragmentStreamInfo * frag_stream_info;
5739  int64_t base_media_decode_time;
5740 
5741  for (i = 0; i < c->fc->nb_streams; i++) {
5742  sc = c->fc->streams[i]->priv_data;
5743  if (sc->id == frag->track_id) {
5744  st = c->fc->streams[i];
5745  break;
5746  }
5747  }
5748  if (!st) {
5749  av_log(c->fc, AV_LOG_WARNING, "could not find corresponding track id %u\n", frag->track_id);
5750  return 0;
5751  }
5752  sc = st->priv_data;
5753  if (sc->pseudo_stream_id + 1 != frag->stsd_id && sc->pseudo_stream_id != -1)
5754  return 0;
5755  version = avio_r8(pb);
5756  avio_rb24(pb); /* flags */
5757  if (version) {
5758  base_media_decode_time = avio_rb64(pb);
5759  } else {
5760  base_media_decode_time = avio_rb32(pb);
5761  }
5762 
5763  frag_stream_info = get_current_frag_stream_info(&c->frag_index);
5764  if (frag_stream_info)
5765  frag_stream_info->tfdt_dts = base_media_decode_time;
5766  sc->track_end = base_media_decode_time;
5767 
5768  return 0;
5769 }
5770 
5772 {
5773  MOVFragment *frag = &c->fragment;
5774  AVStream *st = NULL;
5775  FFStream *sti = NULL;
5776  MOVStreamContext *sc;
5777  MOVStts *stts_data;
5778  MOVCtts *ctts_data;
5779  uint64_t offset;
5780  int64_t dts, pts = AV_NOPTS_VALUE;
5781  int data_offset = 0;
5782  unsigned entries, first_sample_flags = frag->flags;
5783  int flags, distance, i;
5784  int64_t prev_dts = AV_NOPTS_VALUE;
5785  int next_frag_index = -1, index_entry_pos;
5786  size_t requested_size;
5787  size_t old_allocated_size;
5788  AVIndexEntry *new_entries;
5789  MOVFragmentStreamInfo * frag_stream_info;
5790 
5791  if (!frag->found_tfhd) {
5792  av_log(c->fc, AV_LOG_ERROR, "trun track id unknown, no tfhd was found\n");
5793  return AVERROR_INVALIDDATA;
5794  }
5795 
5796  for (i = 0; i < c->fc->nb_streams; i++) {
5797  sc = c->fc->streams[i]->priv_data;
5798  if (sc->id == frag->track_id) {
5799  st = c->fc->streams[i];
5800  sti = ffstream(st);
5801  break;
5802  }
5803  }
5804  if (!st) {
5805  av_log(c->fc, AV_LOG_WARNING, "could not find corresponding track id %u\n", frag->track_id);
5806  return 0;
5807  }
5808  sc = st->priv_data;
5809  if (sc->pseudo_stream_id+1 != frag->stsd_id && sc->pseudo_stream_id != -1)
5810  return 0;
5811 
5812  // Find the next frag_index index that has a valid index_entry for
5813  // the current track_id.
5814  //
5815  // A valid index_entry means the trun for the fragment was read
5816  // and it's samples are in index_entries at the given position.
5817  // New index entries will be inserted before the index_entry found.
5818  index_entry_pos = sti->nb_index_entries;
5819  for (i = c->frag_index.current + 1; i < c->frag_index.nb_items; i++) {
5820  frag_stream_info = get_frag_stream_info(&c->frag_index, i, frag->track_id);
5821  if (frag_stream_info && frag_stream_info->index_entry >= 0) {
5822  next_frag_index = i;
5823  index_entry_pos = frag_stream_info->index_entry;
5824  break;
5825  }
5826  }
5827  av_assert0(index_entry_pos <= sti->nb_index_entries);
5828 
5829  avio_r8(pb); /* version */
5830  flags = avio_rb24(pb);
5831  entries = avio_rb32(pb);
5832  av_log(c->fc, AV_LOG_TRACE, "flags 0x%x entries %u\n", flags, entries);
5833 
5834  if ((uint64_t)entries+sc->ctts_count >= UINT_MAX/sizeof(*sc->ctts_data))
5835  return AVERROR_INVALIDDATA;
5836  if (flags & MOV_TRUN_DATA_OFFSET) data_offset = avio_rb32(pb);
5837  if (flags & MOV_TRUN_FIRST_SAMPLE_FLAGS) first_sample_flags = avio_rb32(pb);
5838 
5839  frag_stream_info = get_current_frag_stream_info(&c->frag_index);
5840  if (frag_stream_info) {
5841  if (frag_stream_info->next_trun_dts != AV_NOPTS_VALUE) {
5842  dts = frag_stream_info->next_trun_dts - sc->time_offset;
5843  } else if (frag_stream_info->first_tfra_pts != AV_NOPTS_VALUE &&
5844  c->use_mfra_for == FF_MOV_FLAG_MFRA_PTS) {
5845  pts = frag_stream_info->first_tfra_pts;
5846  av_log(c->fc, AV_LOG_DEBUG, "found mfra time %"PRId64
5847  ", using it for pts\n", pts);
5848  } else if (frag_stream_info->first_tfra_pts != AV_NOPTS_VALUE &&
5849  c->use_mfra_for == FF_MOV_FLAG_MFRA_DTS) {
5850  dts = frag_stream_info->first_tfra_pts;
5851  av_log(c->fc, AV_LOG_DEBUG, "found mfra time %"PRId64
5852  ", using it for dts\n", pts);
5853  } else {
5854  int has_tfdt = frag_stream_info->tfdt_dts != AV_NOPTS_VALUE;
5855  int has_sidx = frag_stream_info->sidx_pts != AV_NOPTS_VALUE;
5856  int fallback_tfdt = !c->use_tfdt && !has_sidx && has_tfdt;
5857  int fallback_sidx = c->use_tfdt && !has_tfdt && has_sidx;
5858 
5859  if (fallback_sidx) {
5860  av_log(c->fc, AV_LOG_DEBUG, "use_tfdt set but no tfdt found, using sidx instead\n");
5861  }
5862  if (fallback_tfdt) {
5863  av_log(c->fc, AV_LOG_DEBUG, "use_tfdt not set but no sidx found, using tfdt instead\n");
5864  }
5865 
5866  if (has_tfdt && c->use_tfdt || fallback_tfdt) {
5867  dts = frag_stream_info->tfdt_dts - sc->time_offset;
5868  av_log(c->fc, AV_LOG_DEBUG, "found tfdt time %"PRId64
5869  ", using it for dts\n", dts);
5870  } else if (has_sidx && !c->use_tfdt || fallback_sidx) {
5871  // FIXME: sidx earliest_presentation_time is *PTS*, s.b.
5872  // pts = frag_stream_info->sidx_pts;
5873  dts = frag_stream_info->sidx_pts - sc->time_offset;
5874  av_log(c->fc, AV_LOG_DEBUG, "found sidx time %"PRId64
5875  ", using it for dts\n", frag_stream_info->sidx_pts);
5876  } else {
5877  dts = sc->track_end - sc->time_offset;
5878  av_log(c->fc, AV_LOG_DEBUG, "found track end time %"PRId64
5879  ", using it for dts\n", dts);
5880  }
5881  }
5882  } else {
5883  dts = sc->track_end - sc->time_offset;
5884  av_log(c->fc, AV_LOG_DEBUG, "found track end time %"PRId64
5885  ", using it for dts\n", dts);
5886  }
5887  offset = frag->base_data_offset + data_offset;
5888  distance = 0;
5889  av_log(c->fc, AV_LOG_TRACE, "first sample flags 0x%x\n", first_sample_flags);
5890 
5891  // realloc space for new index entries
5892  if ((uint64_t)sti->nb_index_entries + entries >= UINT_MAX / sizeof(AVIndexEntry)) {
5893  entries = UINT_MAX / sizeof(AVIndexEntry) - sti->nb_index_entries;
5894  av_log(c->fc, AV_LOG_ERROR, "Failed to add index entry\n");
5895  }
5896  if (entries == 0)
5897  return 0;
5898 
5899  requested_size = (sti->nb_index_entries + entries) * sizeof(AVIndexEntry);
5900  new_entries = av_fast_realloc(sti->index_entries,
5902  requested_size);
5903  if (!new_entries)
5904  return AVERROR(ENOMEM);
5905  sti->index_entries= new_entries;
5906 
5907  requested_size = (sti->nb_index_entries + entries) * sizeof(*sc->ctts_data);
5908  old_allocated_size = sc->ctts_allocated_size;
5909  ctts_data = av_fast_realloc(sc->ctts_data, &sc->ctts_allocated_size,
5910  requested_size);
5911  if (!ctts_data)
5912  return AVERROR(ENOMEM);
5913  sc->ctts_data = ctts_data;
5914 
5915  // In case there were samples without ctts entries, ensure they get
5916  // zero valued entries. This ensures clips which mix boxes with and
5917  // without ctts entries don't pickup uninitialized data.
5918  memset((uint8_t*)(sc->ctts_data) + old_allocated_size, 0,
5919  sc->ctts_allocated_size - old_allocated_size);
5920 
5921  requested_size = (sti->nb_index_entries + entries) * sizeof(*sc->stts_data);
5922  old_allocated_size = sc->stts_allocated_size;
5923  stts_data = av_fast_realloc(sc->stts_data, &sc->stts_allocated_size,
5924  requested_size);
5925  if (!stts_data)
5926  return AVERROR(ENOMEM);
5927  sc->stts_data = stts_data;
5928 
5929  // See the comment for ctts above.
5930  memset((uint8_t*)(sc->stts_data) + old_allocated_size, 0,
5931  sc->stts_allocated_size - old_allocated_size);
5932 
5933  if (index_entry_pos < sti->nb_index_entries) {
5934  // Make hole in index_entries and ctts_data for new samples
5935  memmove(sti->index_entries + index_entry_pos + entries,
5936  sti->index_entries + index_entry_pos,
5937  sizeof(*sti->index_entries) *
5938  (sti->nb_index_entries - index_entry_pos));
5939  memmove(sc->ctts_data + index_entry_pos + entries,
5940  sc->ctts_data + index_entry_pos,
5941  sizeof(*sc->ctts_data) * (sc->ctts_count - index_entry_pos));
5942  memmove(sc->stts_data + index_entry_pos + entries,
5943  sc->stts_data + index_entry_pos,
5944  sizeof(*sc->stts_data) * (sc->stts_count - index_entry_pos));
5945  if (index_entry_pos < sc->current_sample) {
5946  sc->current_sample += entries;
5947  }
5948  }
5949 
5950  sti->nb_index_entries += entries;
5951  sc->ctts_count = sti->nb_index_entries;
5952  sc->stts_count = sti->nb_index_entries;
5953 
5954  // Record the index_entry position in frag_index of this fragment
5955  if (frag_stream_info) {
5956  frag_stream_info->index_entry = index_entry_pos;
5957  if (frag_stream_info->index_base < 0)
5958  frag_stream_info->index_base = index_entry_pos;
5959  }
5960 
5961  if (index_entry_pos > 0)
5962  prev_dts = sti->index_entries[index_entry_pos-1].timestamp;
5963 
5964  for (i = 0; i < entries && !pb->eof_reached; i++) {
5965  unsigned sample_size = frag->size;
5966  int sample_flags = i ? frag->flags : first_sample_flags;
5967  unsigned sample_duration = frag->duration;
5968  unsigned ctts_duration = 0;
5969  int keyframe = 0;
5970  int index_entry_flags = 0;
5971 
5972  if (flags & MOV_TRUN_SAMPLE_DURATION) sample_duration = avio_rb32(pb);
5973  if (flags & MOV_TRUN_SAMPLE_SIZE) sample_size = avio_rb32(pb);
5974  if (flags & MOV_TRUN_SAMPLE_FLAGS) sample_flags = avio_rb32(pb);
5975  if (flags & MOV_TRUN_SAMPLE_CTS) ctts_duration = avio_rb32(pb);
5976 
5977  mov_update_dts_shift(sc, ctts_duration, c->fc);
5978  if (pts != AV_NOPTS_VALUE) {
5979  dts = pts - sc->dts_shift;
5980  if (flags & MOV_TRUN_SAMPLE_CTS) {
5981  dts -= ctts_duration;
5982  } else {
5983  dts -= sc->time_offset;
5984  }
5985  av_log(c->fc, AV_LOG_DEBUG,
5986  "pts %"PRId64" calculated dts %"PRId64
5987  " sc->dts_shift %d ctts.duration %d"
5988  " sc->time_offset %"PRId64
5989  " flags & MOV_TRUN_SAMPLE_CTS %d\n",
5990  pts, dts,
5991  sc->dts_shift, ctts_duration,
5993  pts = AV_NOPTS_VALUE;
5994  }
5995 
5996  keyframe =
5997  !(sample_flags & (MOV_FRAG_SAMPLE_FLAG_IS_NON_SYNC |
5999  if (keyframe) {
6000  distance = 0;
6001  index_entry_flags |= AVINDEX_KEYFRAME;
6002  }
6003  // Fragments can overlap in time. Discard overlapping frames after
6004  // decoding.
6005  if (prev_dts >= dts)
6006  index_entry_flags |= AVINDEX_DISCARD_FRAME;
6007 
6008  sti->index_entries[index_entry_pos].pos = offset;
6009  sti->index_entries[index_entry_pos].timestamp = dts;
6010  sti->index_entries[index_entry_pos].size = sample_size;
6011  sti->index_entries[index_entry_pos].min_distance = distance;
6012  sti->index_entries[index_entry_pos].flags = index_entry_flags;
6013 
6014  sc->ctts_data[index_entry_pos].count = 1;
6015  sc->ctts_data[index_entry_pos].offset = ctts_duration;
6016  sc->stts_data[index_entry_pos].count = 1;
6017  sc->stts_data[index_entry_pos].duration = sample_duration;
6018  index_entry_pos++;
6019 
6020  av_log(c->fc, AV_LOG_TRACE, "AVIndex stream %d, sample %d, offset %"PRIx64", dts %"PRId64", "
6021  "size %u, distance %d, keyframe %d\n", st->index,
6022  index_entry_pos, offset, dts, sample_size, distance, keyframe);
6023  distance++;
6024  if (av_sat_add64(dts, sample_duration) != dts + (uint64_t)sample_duration)
6025  return AVERROR_INVALIDDATA;
6026  if (!sample_size)
6027  return AVERROR_INVALIDDATA;
6028  dts += sample_duration;
6029  offset += sample_size;
6030  sc->data_size += sample_size;
6031 
6032  if (sample_duration <= INT64_MAX - sc->duration_for_fps &&
6033  1 <= INT_MAX - sc->nb_frames_for_fps
6034  ) {
6035  sc->duration_for_fps += sample_duration;
6036  sc->nb_frames_for_fps ++;
6037  }
6038  }
6039  if (frag_stream_info)
6040  frag_stream_info->next_trun_dts = dts + sc->time_offset;
6041  if (i < entries) {
6042  // EOF found before reading all entries. Fix the hole this would
6043  // leave in index_entries and ctts_data
6044  int gap = entries - i;
6045  memmove(sti->index_entries + index_entry_pos,
6046  sti->index_entries + index_entry_pos + gap,
6047  sizeof(*sti->index_entries) *
6048  (sti->nb_index_entries - (index_entry_pos + gap)));
6049  memmove(sc->ctts_data + index_entry_pos,
6050  sc->ctts_data + index_entry_pos + gap,
6051  sizeof(*sc->ctts_data) *
6052  (sc->ctts_count - (index_entry_pos + gap)));
6053  memmove(sc->stts_data + index_entry_pos,
6054  sc->stts_data + index_entry_pos + gap,
6055  sizeof(*sc->stts_data) *
6056  (sc->stts_count - (index_entry_pos + gap)));
6057 
6058  sti->nb_index_entries -= gap;
6059  sc->ctts_count -= gap;
6060  sc->stts_count -= gap;
6061  if (index_entry_pos < sc->current_sample) {
6062  sc->current_sample -= gap;
6063  }
6064  entries = i;
6065  }
6066 
6067  // The end of this new fragment may overlap in time with the start
6068  // of the next fragment in index_entries. Mark the samples in the next
6069  // fragment that overlap with AVINDEX_DISCARD_FRAME
6070  prev_dts = AV_NOPTS_VALUE;
6071  if (index_entry_pos > 0)
6072  prev_dts = sti->index_entries[index_entry_pos-1].timestamp;
6073  for (int i = index_entry_pos; i < sti->nb_index_entries; i++) {
6074  if (prev_dts < sti->index_entries[i].timestamp)
6075  break;
6077  }
6078 
6079  // If a hole was created to insert the new index_entries into,
6080  // the index_entry recorded for all subsequent moof must
6081  // be incremented by the number of entries inserted.
6082  fix_frag_index_entries(&c->frag_index, next_frag_index,
6083  frag->track_id, entries);
6084 
6085  if (pb->eof_reached) {
6086  av_log(c->fc, AV_LOG_WARNING, "reached eof, corrupted TRUN atom\n");
6087  return AVERROR_EOF;
6088  }
6089 
6090  frag->implicit_offset = offset;
6091 
6092  sc->track_end = dts + sc->time_offset;
6093  if (st->duration < sc->track_end)
6094  st->duration = sc->track_end;
6095 
6096  return 0;
6097 }
6098 
6100 {
6101  int64_t stream_size = avio_size(pb);
6102  int64_t offset = av_sat_add64(avio_tell(pb), atom.size), pts, timestamp;
6103  uint8_t version, is_complete;
6104  int64_t offadd;
6105  unsigned i, j, track_id, item_count;
6106  AVStream *st = NULL;
6107  AVStream *ref_st = NULL;
6108  MOVStreamContext *sc, *ref_sc = NULL;
6109  AVRational timescale;
6110 
6111  version = avio_r8(pb);
6112  if (version > 1) {
6113  avpriv_request_sample(c->fc, "sidx version %u", version);
6114  return 0;
6115  }
6116 
6117  avio_rb24(pb); // flags
6118 
6119  track_id = avio_rb32(pb); // Reference ID
6120  for (i = 0; i < c->fc->nb_streams; i++) {
6121  sc = c->fc->streams[i]->priv_data;
6122  if (sc->id == track_id) {
6123  st = c->fc->streams[i];
6124  break;
6125  }
6126  }
6127  if (!st) {
6128  av_log(c->fc, AV_LOG_WARNING, "could not find corresponding track id %d\n", track_id);
6129  return 0;
6130  }
6131 
6132  sc = st->priv_data;
6133 
6134  timescale = av_make_q(1, avio_rb32(pb));
6135 
6136  if (timescale.den <= 0) {
6137  av_log(c->fc, AV_LOG_ERROR, "Invalid sidx timescale 1/%d\n", timescale.den);
6138  return AVERROR_INVALIDDATA;
6139  }
6140 
6141  if (version == 0) {
6142  pts = avio_rb32(pb);
6143  offadd= avio_rb32(pb);
6144  } else {
6145  pts = avio_rb64(pb);
6146  offadd= avio_rb64(pb);
6147  }
6148  if (av_sat_add64(offset, offadd) != offset + (uint64_t)offadd)
6149  return AVERROR_INVALIDDATA;
6150 
6151  offset += (uint64_t)offadd;
6152 
6153  avio_rb16(pb); // reserved
6154 
6155  item_count = avio_rb16(pb);
6156  if (item_count == 0)
6157  return AVERROR_INVALIDDATA;
6158 
6159  for (i = 0; i < item_count; i++) {
6160  int index;
6161  MOVFragmentStreamInfo * frag_stream_info;
6162  uint32_t size = avio_rb32(pb);
6163  uint32_t duration = avio_rb32(pb);
6164  if (size & 0x80000000) {
6165  avpriv_request_sample(c->fc, "sidx reference_type 1");
6166  return AVERROR_PATCHWELCOME;
6167  }
6168  avio_rb32(pb); // sap_flags
6169  timestamp = av_rescale_q(pts, timescale, st->time_base);
6170 
6172  frag_stream_info = get_frag_stream_info(&c->frag_index, index, track_id);
6173  if (frag_stream_info)
6174  frag_stream_info->sidx_pts = timestamp;
6175 
6176  if (av_sat_add64(offset, size) != offset + (uint64_t)size ||
6177  av_sat_add64(pts, duration) != pts + (uint64_t)duration
6178  )
6179  return AVERROR_INVALIDDATA;
6180  offset += size;
6181  pts += duration;
6182  }
6183 
6184  st->duration = sc->track_end = pts;
6185 
6186  sc->has_sidx = 1;
6187 
6188  // See if the remaining bytes are just an mfra which we can ignore.
6189  is_complete = offset == stream_size;
6190  if (!is_complete && (pb->seekable & AVIO_SEEKABLE_NORMAL) && stream_size > 0 ) {
6191  int64_t ret;
6192  int64_t original_pos = avio_tell(pb);
6193  if (!c->have_read_mfra_size) {
6194  if ((ret = avio_seek(pb, stream_size - 4, SEEK_SET)) < 0)
6195  return ret;
6196  c->mfra_size = avio_rb32(pb);
6197  c->have_read_mfra_size = 1;
6198  if ((ret = avio_seek(pb, original_pos, SEEK_SET)) < 0)
6199  return ret;
6200  }
6201  if (offset == stream_size - c->mfra_size)
6202  is_complete = 1;
6203  }
6204 
6205  if (is_complete) {
6206  // Find first entry in fragment index that came from an sidx.
6207  // This will pretty much always be the first entry.
6208  for (i = 0; i < c->frag_index.nb_items; i++) {
6209  MOVFragmentIndexItem * item = &c->frag_index.item[i];
6210  for (j = 0; ref_st == NULL && j < item->nb_stream_info; j++) {
6211  MOVFragmentStreamInfo * si;
6212  si = &item->stream_info[j];
6213  if (si->sidx_pts != AV_NOPTS_VALUE) {
6214  ref_st = c->fc->streams[j];
6215  ref_sc = ref_st->priv_data;
6216  break;
6217  }
6218  }
6219  }
6220  if (ref_st) for (i = 0; i < c->fc->nb_streams; i++) {
6221  st = c->fc->streams[i];
6222  sc = st->priv_data;
6223  if (!sc->has_sidx) {
6224  st->duration = sc->track_end = av_rescale(ref_st->duration, sc->time_scale, ref_sc->time_scale);
6225  }
6226  }
6227 
6228  c->frag_index.complete = 1;
6229  }
6230 
6231  return 0;
6232 }
6233 
6234 /* this atom should be null (from specs), but some buggy files put the 'moov' atom inside it... */
6235 /* like the files created with Adobe Premiere 5.0, for samples see */
6236 /* http://graphics.tudelft.nl/~wouter/publications/soundtests/ */
6238 {
6239  int err;
6240 
6241  if (atom.size < 8)
6242  return 0; /* continue */
6243  if (avio_rb32(pb) != 0) { /* 0 sized mdat atom... use the 'wide' atom size */
6244  avio_skip(pb, atom.size - 4);
6245  return 0;
6246  }
6247  atom.type = avio_rl32(pb);
6248  atom.size -= 8;
6249  if (atom.type != MKTAG('m','d','a','t')) {
6250  avio_skip(pb, atom.size);
6251  return 0;
6252  }
6253  err = mov_read_mdat(c, pb, atom);
6254  return err;
6255 }
6256 
6258 {
6259 #if CONFIG_ZLIB
6260  FFIOContext ctx;
6261  uint8_t *cmov_data;
6262  uint8_t *moov_data; /* uncompressed data */
6263  long cmov_len, moov_len;
6264  int ret = -1;
6265 
6266  avio_rb32(pb); /* dcom atom */
6267  if (avio_rl32(pb) != MKTAG('d','c','o','m'))
6268  return AVERROR_INVALIDDATA;
6269  if (avio_rl32(pb) != MKTAG('z','l','i','b')) {
6270  av_log(c->fc, AV_LOG_ERROR, "unknown compression for cmov atom !\n");
6271  return AVERROR_INVALIDDATA;
6272  }
6273  avio_rb32(pb); /* cmvd atom */
6274  if (avio_rl32(pb) != MKTAG('c','m','v','d'))
6275  return AVERROR_INVALIDDATA;
6276  moov_len = avio_rb32(pb); /* uncompressed size */
6277  cmov_len = atom.size - 6 * 4;
6278 
6279  cmov_data = av_malloc(cmov_len);
6280  if (!cmov_data)
6281  return AVERROR(ENOMEM);
6282  moov_data = av_malloc(moov_len);
6283  if (!moov_data) {
6284  av_free(cmov_data);
6285  return AVERROR(ENOMEM);
6286  }
6287  ret = ffio_read_size(pb, cmov_data, cmov_len);
6288  if (ret < 0)
6289  goto free_and_return;
6290 
6292  if (uncompress (moov_data, (uLongf *) &moov_len, (const Bytef *)cmov_data, cmov_len) != Z_OK)
6293  goto free_and_return;
6294  ffio_init_read_context(&ctx, moov_data, moov_len);
6295  ctx.pub.seekable = AVIO_SEEKABLE_NORMAL;
6296  atom.type = MKTAG('m','o','o','v');
6297  atom.size = moov_len;
6298  ret = mov_read_default(c, &ctx.pub, atom);
6299 free_and_return:
6300  av_free(moov_data);
6301  av_free(cmov_data);
6302  return ret;
6303 #else
6304  av_log(c->fc, AV_LOG_ERROR, "this file requires zlib support compiled in\n");
6305  return AVERROR(ENOSYS);
6306 #endif
6307 }
6308 
6309 /* edit list atom */
6311 {
6312  MOVStreamContext *sc;
6313  int i, edit_count, version;
6314  int64_t elst_entry_size;
6315 
6316  if (c->fc->nb_streams < 1 || c->ignore_editlist)
6317  return 0;
6318  sc = c->fc->streams[c->fc->nb_streams-1]->priv_data;
6319 
6320  version = avio_r8(pb); /* version */
6321  avio_rb24(pb); /* flags */
6322  edit_count = avio_rb32(pb); /* entries */
6323  atom.size -= 8;
6324 
6325  elst_entry_size = version == 1 ? 20 : 12;
6326  if (atom.size != edit_count * elst_entry_size) {
6327  if (c->fc->strict_std_compliance >= FF_COMPLIANCE_STRICT) {
6328  av_log(c->fc, AV_LOG_ERROR, "Invalid edit list entry_count: %d for elst atom of size: %"PRId64" bytes.\n",
6329  edit_count, atom.size + 8);
6330  return AVERROR_INVALIDDATA;
6331  } else {
6332  edit_count = atom.size / elst_entry_size;
6333  if (edit_count * elst_entry_size != atom.size) {
6334  av_log(c->fc, AV_LOG_WARNING, "ELST atom of %"PRId64" bytes, bigger than %d entries.\n", atom.size, edit_count);
6335  }
6336  }
6337  }
6338 
6339  if (!edit_count)
6340  return 0;
6341  if (sc->elst_data)
6342  av_log(c->fc, AV_LOG_WARNING, "Duplicated ELST atom\n");
6343  av_free(sc->elst_data);
6344  sc->elst_count = 0;
6345  sc->elst_data = av_malloc_array(edit_count, sizeof(*sc->elst_data));
6346  if (!sc->elst_data)
6347  return AVERROR(ENOMEM);
6348 
6349  av_log(c->fc, AV_LOG_TRACE, "track[%u].edit_count = %i\n", c->fc->nb_streams - 1, edit_count);
6350  for (i = 0; i < edit_count && atom.size > 0 && !pb->eof_reached; i++) {
6351  MOVElst *e = &sc->elst_data[i];
6352 
6353  if (version == 1) {
6354  e->duration = avio_rb64(pb);
6355  e->time = avio_rb64(pb);
6356  atom.size -= 16;
6357  } else {
6358  e->duration = avio_rb32(pb); /* segment duration */
6359  e->time = (int32_t)avio_rb32(pb); /* media time */
6360  atom.size -= 8;
6361  }
6362  e->rate = avio_rb32(pb) / 65536.0;
6363  atom.size -= 4;
6364  av_log(c->fc, AV_LOG_TRACE, "duration=%"PRId64" time=%"PRId64" rate=%f\n",
6365  e->duration, e->time, e->rate);
6366 
6367  if (e->time < 0 && e->time != -1 &&
6368  c->fc->strict_std_compliance >= FF_COMPLIANCE_STRICT) {
6369  av_log(c->fc, AV_LOG_ERROR, "Track %d, edit %d: Invalid edit list media time=%"PRId64"\n",
6370  c->fc->nb_streams-1, i, e->time);
6371  return AVERROR_INVALIDDATA;
6372  }
6373  }
6374  sc->elst_count = i;
6375 
6376  return 0;
6377 }
6378 
6380 {
6381  MOVStreamContext *sc;
6382 
6383  if (c->fc->nb_streams < 1)
6384  return AVERROR_INVALIDDATA;
6385  sc = c->fc->streams[c->fc->nb_streams - 1]->priv_data;
6386  sc->timecode_track = avio_rb32(pb);
6387  return 0;
6388 }
6389 
6391 {
6392  AVStream *st;
6393  int version, color_range, color_primaries, color_trc, color_space;
6394 
6395  if (c->fc->nb_streams < 1)
6396  return 0;
6397  st = c->fc->streams[c->fc->nb_streams - 1];
6398 
6399  if (atom.size < 5) {
6400  av_log(c->fc, AV_LOG_ERROR, "Empty VP Codec Configuration box\n");
6401  return AVERROR_INVALIDDATA;
6402  }
6403 
6404  version = avio_r8(pb);
6405  if (version != 1) {
6406  av_log(c->fc, AV_LOG_WARNING, "Unsupported VP Codec Configuration box version %d\n", version);
6407  return 0;
6408  }
6409  avio_skip(pb, 3); /* flags */
6410 
6411  avio_skip(pb, 2); /* profile + level */
6412  color_range = avio_r8(pb); /* bitDepth, chromaSubsampling, videoFullRangeFlag */
6413  color_primaries = avio_r8(pb);
6414  color_trc = avio_r8(pb);
6415  color_space = avio_r8(pb);
6416  if (avio_rb16(pb)) /* codecIntializationDataSize */
6417  return AVERROR_INVALIDDATA;
6418 
6421  if (!av_color_transfer_name(color_trc))
6422  color_trc = AVCOL_TRC_UNSPECIFIED;
6423  if (!av_color_space_name(color_space))
6424  color_space = AVCOL_SPC_UNSPECIFIED;
6425 
6428  st->codecpar->color_trc = color_trc;
6429  st->codecpar->color_space = color_space;
6430 
6431  return 0;
6432 }
6433 
6435 {
6436  MOVStreamContext *sc;
6437  int i, version;
6438 
6439  if (c->fc->nb_streams < 1)
6440  return AVERROR_INVALIDDATA;
6441 
6442  sc = c->fc->streams[c->fc->nb_streams - 1]->priv_data;
6443 
6444  if (atom.size < 5) {
6445  av_log(c->fc, AV_LOG_ERROR, "Empty Mastering Display Metadata box\n");
6446  return AVERROR_INVALIDDATA;
6447  }
6448 
6449  version = avio_r8(pb);
6450  if (version) {
6451  av_log(c->fc, AV_LOG_WARNING, "Unsupported Mastering Display Metadata box version %d\n", version);
6452  return 0;
6453  }
6454  if (sc->mastering) {
6455  av_log(c->fc, AV_LOG_WARNING, "Ignoring duplicate Mastering Display Metadata\n");
6456  return 0;
6457  }
6458 
6459  avio_skip(pb, 3); /* flags */
6460 
6462  if (!sc->mastering)
6463  return AVERROR(ENOMEM);
6464 
6465  for (i = 0; i < 3; i++) {
6466  sc->mastering->display_primaries[i][0] = av_make_q(avio_rb16(pb), 1 << 16);
6467  sc->mastering->display_primaries[i][1] = av_make_q(avio_rb16(pb), 1 << 16);
6468  }
6469  sc->mastering->white_point[0] = av_make_q(avio_rb16(pb), 1 << 16);
6470  sc->mastering->white_point[1] = av_make_q(avio_rb16(pb), 1 << 16);
6471 
6472  sc->mastering->max_luminance = av_make_q(avio_rb32(pb), 1 << 8);
6473  sc->mastering->min_luminance = av_make_q(avio_rb32(pb), 1 << 14);
6474 
6475  sc->mastering->has_primaries = 1;
6476  sc->mastering->has_luminance = 1;
6477 
6478  return 0;
6479 }
6480 
6482 {
6483  MOVStreamContext *sc;
6484  const int mapping[3] = {1, 2, 0};
6485  const int chroma_den = 50000;
6486  const int luma_den = 10000;
6487  int i;
6488 
6489  if (c->fc->nb_streams < 1)
6490  return AVERROR_INVALIDDATA;
6491 
6492  sc = c->fc->streams[c->fc->nb_streams - 1]->priv_data;
6493 
6494  if (atom.size < 24) {
6495  av_log(c->fc, AV_LOG_ERROR, "Invalid Mastering Display Color Volume box\n");
6496  return AVERROR_INVALIDDATA;
6497  }
6498 
6499  if (sc->mastering) {
6500  av_log(c->fc, AV_LOG_WARNING, "Ignoring duplicate Mastering Display Color Volume\n");
6501  return 0;
6502  }
6503 
6505  if (!sc->mastering)
6506  return AVERROR(ENOMEM);
6507 
6508  for (i = 0; i < 3; i++) {
6509  const int j = mapping[i];
6510  sc->mastering->display_primaries[j][0] = av_make_q(avio_rb16(pb), chroma_den);
6511  sc->mastering->display_primaries[j][1] = av_make_q(avio_rb16(pb), chroma_den);
6512  }
6513  sc->mastering->white_point[0] = av_make_q(avio_rb16(pb), chroma_den);
6514  sc->mastering->white_point[1] = av_make_q(avio_rb16(pb), chroma_den);
6515 
6516  sc->mastering->max_luminance = av_make_q(avio_rb32(pb), luma_den);
6517  sc->mastering->min_luminance = av_make_q(avio_rb32(pb), luma_den);
6518 
6519  sc->mastering->has_luminance = 1;
6520  sc->mastering->has_primaries = 1;
6521 
6522  return 0;
6523 }
6524 
6526 {
6527  MOVStreamContext *sc;
6528  int version;
6529 
6530  if (c->fc->nb_streams < 1)
6531  return AVERROR_INVALIDDATA;
6532 
6533  sc = c->fc->streams[c->fc->nb_streams - 1]->priv_data;
6534 
6535  if (atom.size < 5) {
6536  av_log(c->fc, AV_LOG_ERROR, "Empty Content Light Level box\n");
6537  return AVERROR_INVALIDDATA;
6538  }
6539 
6540  version = avio_r8(pb);
6541  if (version) {
6542  av_log(c->fc, AV_LOG_WARNING, "Unsupported Content Light Level box version %d\n", version);
6543  return 0;
6544  }
6545  avio_skip(pb, 3); /* flags */
6546 
6547  if (sc->coll){
6548  av_log(c->fc, AV_LOG_WARNING, "Ignoring duplicate COLL\n");
6549  return 0;
6550  }
6551 
6553  if (!sc->coll)
6554  return AVERROR(ENOMEM);
6555 
6556  sc->coll->MaxCLL = avio_rb16(pb);
6557  sc->coll->MaxFALL = avio_rb16(pb);
6558 
6559  return 0;
6560 }
6561 
6563 {
6564  MOVStreamContext *sc;
6565 
6566  if (c->fc->nb_streams < 1)
6567  return AVERROR_INVALIDDATA;
6568 
6569  sc = c->fc->streams[c->fc->nb_streams - 1]->priv_data;
6570 
6571  if (atom.size < 4) {
6572  av_log(c->fc, AV_LOG_ERROR, "Empty Content Light Level Info box\n");
6573  return AVERROR_INVALIDDATA;
6574  }
6575 
6576  if (sc->coll){
6577  av_log(c->fc, AV_LOG_WARNING, "Ignoring duplicate CLLI/COLL\n");
6578  return 0;
6579  }
6580 
6582  if (!sc->coll)
6583  return AVERROR(ENOMEM);
6584 
6585  sc->coll->MaxCLL = avio_rb16(pb);
6586  sc->coll->MaxFALL = avio_rb16(pb);
6587 
6588  return 0;
6589 }
6590 
6592 {
6593  MOVStreamContext *sc;
6594  const int illuminance_den = 10000;
6595  const int ambient_den = 50000;
6596  if (c->fc->nb_streams < 1)
6597  return AVERROR_INVALIDDATA;
6598  sc = c->fc->streams[c->fc->nb_streams - 1]->priv_data;
6599  if (atom.size < 6) {
6600  av_log(c->fc, AV_LOG_ERROR, "Empty Ambient Viewing Environment Info box\n");
6601  return AVERROR_INVALIDDATA;
6602  }
6603  if (sc->ambient){
6604  av_log(c->fc, AV_LOG_WARNING, "Ignoring duplicate AMVE\n");
6605  return 0;
6606  }
6608  if (!sc->ambient)
6609  return AVERROR(ENOMEM);
6610  sc->ambient->ambient_illuminance = av_make_q(avio_rb32(pb), illuminance_den);
6611  sc->ambient->ambient_light_x = av_make_q(avio_rb16(pb), ambient_den);
6612  sc->ambient->ambient_light_y = av_make_q(avio_rb16(pb), ambient_den);
6613  return 0;
6614 }
6615 
6617 {
6618  AVStream *st;
6619  MOVStreamContext *sc;
6620  enum AVStereo3DType type;
6621  int mode;
6622 
6623  if (c->fc->nb_streams < 1)
6624  return 0;
6625 
6626  st = c->fc->streams[c->fc->nb_streams - 1];
6627  sc = st->priv_data;
6628 
6629  if (atom.size < 5) {
6630  av_log(c->fc, AV_LOG_ERROR, "Empty stereoscopic video box\n");
6631  return AVERROR_INVALIDDATA;
6632  }
6633 
6634  if (sc->stereo3d)
6635  return AVERROR_INVALIDDATA;
6636 
6637  avio_skip(pb, 4); /* version + flags */
6638 
6639  mode = avio_r8(pb);
6640  switch (mode) {
6641  case 0:
6642  type = AV_STEREO3D_2D;
6643  break;
6644  case 1:
6646  break;
6647  case 2:
6649  break;
6650  default:
6651  av_log(c->fc, AV_LOG_WARNING, "Unknown st3d mode value %d\n", mode);
6652  return 0;
6653  }
6654 
6656  if (!sc->stereo3d)
6657  return AVERROR(ENOMEM);
6658 
6659  sc->stereo3d->type = type;
6660  return 0;
6661 }
6662 
6664 {
6665  AVStream *st;
6666  MOVStreamContext *sc;
6667  int size, version, layout;
6668  int32_t yaw, pitch, roll;
6669  uint32_t l = 0, t = 0, r = 0, b = 0;
6670  uint32_t tag, padding = 0;
6671  enum AVSphericalProjection projection;
6672 
6673  if (c->fc->nb_streams < 1)
6674  return 0;
6675 
6676  st = c->fc->streams[c->fc->nb_streams - 1];
6677  sc = st->priv_data;
6678 
6679  if (atom.size < 8) {
6680  av_log(c->fc, AV_LOG_ERROR, "Empty spherical video box\n");
6681  return AVERROR_INVALIDDATA;
6682  }
6683 
6684  size = avio_rb32(pb);
6685  if (size <= 12 || size > atom.size)
6686  return AVERROR_INVALIDDATA;
6687 
6688  tag = avio_rl32(pb);
6689  if (tag != MKTAG('s','v','h','d')) {
6690  av_log(c->fc, AV_LOG_ERROR, "Missing spherical video header\n");
6691  return 0;
6692  }
6693  version = avio_r8(pb);
6694  if (version != 0) {
6695  av_log(c->fc, AV_LOG_WARNING, "Unknown spherical version %d\n",
6696  version);
6697  return 0;
6698  }
6699  avio_skip(pb, 3); /* flags */
6700  avio_skip(pb, size - 12); /* metadata_source */
6701 
6702  size = avio_rb32(pb);
6703  if (size > atom.size)
6704  return AVERROR_INVALIDDATA;
6705 
6706  tag = avio_rl32(pb);
6707  if (tag != MKTAG('p','r','o','j')) {
6708  av_log(c->fc, AV_LOG_ERROR, "Missing projection box\n");
6709  return 0;
6710  }
6711 
6712  size = avio_rb32(pb);
6713  if (size > atom.size)
6714  return AVERROR_INVALIDDATA;
6715 
6716  tag = avio_rl32(pb);
6717  if (tag != MKTAG('p','r','h','d')) {
6718  av_log(c->fc, AV_LOG_ERROR, "Missing projection header box\n");
6719  return 0;
6720  }
6721  version = avio_r8(pb);
6722  if (version != 0) {
6723  av_log(c->fc, AV_LOG_WARNING, "Unknown spherical version %d\n",
6724  version);
6725  return 0;
6726  }
6727  avio_skip(pb, 3); /* flags */
6728 
6729  /* 16.16 fixed point */
6730  yaw = avio_rb32(pb);
6731  pitch = avio_rb32(pb);
6732  roll = avio_rb32(pb);
6733 
6734  size = avio_rb32(pb);
6735  if (size > atom.size)
6736  return AVERROR_INVALIDDATA;
6737 
6738  tag = avio_rl32(pb);
6739  version = avio_r8(pb);
6740  if (version != 0) {
6741  av_log(c->fc, AV_LOG_WARNING, "Unknown spherical version %d\n",
6742  version);
6743  return 0;
6744  }
6745  avio_skip(pb, 3); /* flags */
6746  switch (tag) {
6747  case MKTAG('c','b','m','p'):
6748  layout = avio_rb32(pb);
6749  if (layout) {
6750  av_log(c->fc, AV_LOG_WARNING,
6751  "Unsupported cubemap layout %d\n", layout);
6752  return 0;
6753  }
6754  projection = AV_SPHERICAL_CUBEMAP;
6755  padding = avio_rb32(pb);
6756  break;
6757  case MKTAG('e','q','u','i'):
6758  t = avio_rb32(pb);
6759  b = avio_rb32(pb);
6760  l = avio_rb32(pb);
6761  r = avio_rb32(pb);
6762 
6763  if (b >= UINT_MAX - t || r >= UINT_MAX - l) {
6764  av_log(c->fc, AV_LOG_ERROR,
6765  "Invalid bounding rectangle coordinates "
6766  "%"PRIu32",%"PRIu32",%"PRIu32",%"PRIu32"\n", l, t, r, b);
6767  return AVERROR_INVALIDDATA;
6768  }
6769 
6770  if (l || t || r || b)
6771  projection = AV_SPHERICAL_EQUIRECTANGULAR_TILE;
6772  else
6773  projection = AV_SPHERICAL_EQUIRECTANGULAR;
6774  break;
6775  default:
6776  av_log(c->fc, AV_LOG_ERROR, "Unknown projection type: %s\n", av_fourcc2str(tag));
6777  return 0;
6778  }
6779 
6781  if (!sc->spherical)
6782  return AVERROR(ENOMEM);
6783 
6784  sc->spherical->projection = projection;
6785 
6786  sc->spherical->yaw = yaw;
6787  sc->spherical->pitch = pitch;
6788  sc->spherical->roll = roll;
6789 
6790  sc->spherical->padding = padding;
6791 
6792  sc->spherical->bound_left = l;
6793  sc->spherical->bound_top = t;
6794  sc->spherical->bound_right = r;
6795  sc->spherical->bound_bottom = b;
6796 
6797  return 0;
6798 }
6799 
6801 {
6802  AVStream *st;
6803  MOVStreamContext *sc;
6804  int size;
6805  uint32_t tag;
6806  enum AVSphericalProjection projection;
6807 
6808  if (c->fc->nb_streams < 1)
6809  return 0;
6810 
6811  st = c->fc->streams[c->fc->nb_streams - 1];
6812  sc = st->priv_data;
6813 
6814  if (atom.size != 16) {
6815  av_log(c->fc, AV_LOG_ERROR, "Invalid size for proj box: %"PRIu64"\n", atom.size);
6816  return AVERROR_INVALIDDATA;
6817  }
6818 
6819  size = avio_rb32(pb);
6820  if (size != 16) {
6821  av_log(c->fc, AV_LOG_ERROR, "Invalid size for prji box: %d\n", size);
6822  return AVERROR_INVALIDDATA;
6823  }
6824 
6825  tag = avio_rl32(pb);
6826  if (tag != MKTAG('p','r','j','i')) {
6827  av_log(c->fc, AV_LOG_ERROR, "Invalid child box of proj box: 0x%08X\n", tag);
6828  return AVERROR_INVALIDDATA;
6829  }
6830 
6831  avio_skip(pb, 1); // version
6832  avio_skip(pb, 3); // flags
6833 
6834  tag = avio_rl32(pb);
6835  switch (tag) {
6836  case MKTAG('r','e','c','t'):
6837  projection = AV_SPHERICAL_RECTILINEAR;
6838  break;
6839  case MKTAG('e','q','u','i'):
6840  projection = AV_SPHERICAL_EQUIRECTANGULAR;
6841  break;
6842  case MKTAG('h','e','q','u'):
6843  projection = AV_SPHERICAL_HALF_EQUIRECTANGULAR;
6844  break;
6845  case MKTAG('f','i','s','h'):
6846  projection = AV_SPHERICAL_FISHEYE;
6847  break;
6848  default:
6849  av_log(c->fc, AV_LOG_ERROR, "Invalid projection type in prji box: 0x%08X\n", tag);
6850  return AVERROR_INVALIDDATA;
6851  }
6852 
6854  if (!sc->spherical)
6855  return AVERROR(ENOMEM);
6856 
6857  sc->spherical->projection = projection;
6858 
6859  return 0;
6860 }
6861 
6863 {
6864  AVStream *st;
6865  MOVStreamContext *sc;
6866  int size, flags = 0;
6867  int64_t remaining;
6868  uint32_t tag, baseline = 0;
6871  enum AVStereo3DPrimaryEye primary_eye = AV_PRIMARY_EYE_NONE;
6872  AVRational horizontal_disparity_adjustment = { 0, 1 };
6873 
6874  if (c->fc->nb_streams < 1)
6875  return 0;
6876 
6877  st = c->fc->streams[c->fc->nb_streams - 1];
6878  sc = st->priv_data;
6879 
6880  remaining = atom.size;
6881  while (remaining > 0) {
6882  size = avio_rb32(pb);
6883  if (size < 8 || size > remaining ) {
6884  av_log(c->fc, AV_LOG_ERROR, "Invalid child size in eyes box\n");
6885  return AVERROR_INVALIDDATA;
6886  }
6887 
6888  tag = avio_rl32(pb);
6889  switch (tag) {
6890  case MKTAG('s','t','r','i'): {
6891  int has_right, has_left;
6892  uint8_t tmp;
6893  if (size != 13) {
6894  av_log(c->fc, AV_LOG_ERROR, "Invalid size of stri box: %d\n", size);
6895  return AVERROR_INVALIDDATA;
6896  }
6897  avio_skip(pb, 1); // version
6898  avio_skip(pb, 3); // flags
6899 
6900  tmp = avio_r8(pb);
6901 
6902  // eye_views_reversed
6903  if (tmp & 8) {
6905  }
6906  // has_additional_views
6907  if (tmp & 4) {
6908  // skip...
6909  }
6910 
6911  has_right = tmp & 2; // has_right_eye_view
6912  has_left = tmp & 1; // has_left_eye_view
6913 
6914  if (has_left && has_right)
6915  view = AV_STEREO3D_VIEW_PACKED;
6916  else if (has_left)
6917  view = AV_STEREO3D_VIEW_LEFT;
6918  else if (has_right)
6919  view = AV_STEREO3D_VIEW_RIGHT;
6920  if (has_left || has_right)
6922 
6923  break;
6924  }
6925  case MKTAG('h','e','r','o'): {
6926  int tmp;
6927  if (size != 13) {
6928  av_log(c->fc, AV_LOG_ERROR, "Invalid size of hero box: %d\n", size);
6929  return AVERROR_INVALIDDATA;
6930  }
6931  avio_skip(pb, 1); // version
6932  avio_skip(pb, 3); // flags
6933 
6934  tmp = avio_r8(pb);
6935  if (tmp == 0)
6936  primary_eye = AV_PRIMARY_EYE_NONE;
6937  else if (tmp == 1)
6938  primary_eye = AV_PRIMARY_EYE_LEFT;
6939  else if (tmp == 2)
6940  primary_eye = AV_PRIMARY_EYE_RIGHT;
6941  else
6942  av_log(c->fc, AV_LOG_WARNING, "Unknown hero eye type: %d\n", tmp);
6943 
6944  break;
6945  }
6946  case MKTAG('c','a','m','s'): {
6947  uint32_t subtag;
6948  int subsize;
6949  if (size != 24) {
6950  av_log(c->fc, AV_LOG_ERROR, "Invalid size of cams box: %d\n", size);
6951  return AVERROR_INVALIDDATA;
6952  }
6953 
6954  subsize = avio_rb32(pb);
6955  if (subsize != 16) {
6956  av_log(c->fc, AV_LOG_ERROR, "Invalid size of blin box: %d\n", size);
6957  return AVERROR_INVALIDDATA;
6958  }
6959 
6960  subtag = avio_rl32(pb);
6961  if (subtag != MKTAG('b','l','i','n')) {
6962  av_log(c->fc, AV_LOG_ERROR, "Expected blin box, got 0x%08X\n", subtag);
6963  return AVERROR_INVALIDDATA;
6964  }
6965 
6966  avio_skip(pb, 1); // version
6967  avio_skip(pb, 3); // flags
6968 
6969  baseline = avio_rb32(pb);
6970 
6971  break;
6972  }
6973  case MKTAG('c','m','f','y'): {
6974  uint32_t subtag;
6975  int subsize;
6976  int32_t adjustment;
6977  if (size != 24) {
6978  av_log(c->fc, AV_LOG_ERROR, "Invalid size of cmfy box: %d\n", size);
6979  return AVERROR_INVALIDDATA;
6980  }
6981 
6982  subsize = avio_rb32(pb);
6983  if (subsize != 16) {
6984  av_log(c->fc, AV_LOG_ERROR, "Invalid size of dadj box: %d\n", size);
6985  return AVERROR_INVALIDDATA;
6986  }
6987 
6988  subtag = avio_rl32(pb);
6989  if (subtag != MKTAG('d','a','d','j')) {
6990  av_log(c->fc, AV_LOG_ERROR, "Expected dadj box, got 0x%08X\n", subtag);
6991  return AVERROR_INVALIDDATA;
6992  }
6993 
6994  avio_skip(pb, 1); // version
6995  avio_skip(pb, 3); // flags
6996 
6997  adjustment = (int32_t) avio_rb32(pb);
6998 
6999  horizontal_disparity_adjustment.num = (int) adjustment;
7000  horizontal_disparity_adjustment.den = 10000;
7001 
7002  break;
7003  }
7004  default:
7005  av_log(c->fc, AV_LOG_WARNING, "Unknown tag in eyes: 0x%08X\n", tag);
7006  avio_skip(pb, size - 8);
7007  break;
7008  }
7009  remaining -= size;
7010  }
7011 
7012  if (remaining != 0) {
7013  av_log(c->fc, AV_LOG_ERROR, "Broken eyes box\n");
7014  return AVERROR_INVALIDDATA;
7015  }
7016 
7017  if (type == AV_STEREO3D_2D)
7018  return 0;
7019 
7020  if (!sc->stereo3d) {
7022  if (!sc->stereo3d)
7023  return AVERROR(ENOMEM);
7024  }
7025 
7026  sc->stereo3d->flags = flags;
7027  sc->stereo3d->type = type;
7028  sc->stereo3d->view = view;
7029  sc->stereo3d->primary_eye = primary_eye;
7030  sc->stereo3d->baseline = baseline;
7031  sc->stereo3d->horizontal_disparity_adjustment = horizontal_disparity_adjustment;
7032 
7033  return 0;
7034 }
7035 
7037 {
7038  int size;
7039  int64_t remaining;
7040  uint32_t tag;
7041 
7042  if (c->fc->nb_streams < 1)
7043  return 0;
7044 
7045  if (atom.size < 8) {
7046  av_log(c->fc, AV_LOG_ERROR, "Empty video extension usage box\n");
7047  return AVERROR_INVALIDDATA;
7048  }
7049 
7050  remaining = atom.size;
7051  while (remaining > 0) {
7052  size = avio_rb32(pb);
7053  if (size < 8 || size > remaining ) {
7054  av_log(c->fc, AV_LOG_ERROR, "Invalid child size in vexu box\n");
7055  return AVERROR_INVALIDDATA;
7056  }
7057 
7058  tag = avio_rl32(pb);
7059  switch (tag) {
7060  case MKTAG('p','r','o','j'): {
7061  MOVAtom proj = { tag, size - 8 };
7062  int ret = mov_read_vexu_proj(c, pb, proj);
7063  if (ret < 0)
7064  return ret;
7065  break;
7066  }
7067  case MKTAG('e','y','e','s'): {
7068  MOVAtom eyes = { tag, size - 8 };
7069  int ret = mov_read_eyes(c, pb, eyes);
7070  if (ret < 0)
7071  return ret;
7072  break;
7073  }
7074  default:
7075  av_log(c->fc, AV_LOG_WARNING, "Unknown tag in vexu: 0x%08X\n", tag);
7076  avio_skip(pb, size - 8);
7077  break;
7078  }
7079  remaining -= size;
7080  }
7081 
7082  if (remaining != 0) {
7083  av_log(c->fc, AV_LOG_ERROR, "Broken vexu box\n");
7084  return AVERROR_INVALIDDATA;
7085  }
7086 
7087  return 0;
7088 }
7089 
7091 {
7092  AVStream *st;
7093  MOVStreamContext *sc;
7094 
7095  if (c->fc->nb_streams < 1)
7096  return 0;
7097 
7098  st = c->fc->streams[c->fc->nb_streams - 1];
7099  sc = st->priv_data;
7100 
7101  if (atom.size != 4) {
7102  av_log(c->fc, AV_LOG_ERROR, "Invalid size of hfov box: %"PRIu64"\n", atom.size);
7103  return AVERROR_INVALIDDATA;
7104  }
7105 
7106 
7107  if (!sc->stereo3d) {
7109  if (!sc->stereo3d)
7110  return AVERROR(ENOMEM);
7111  }
7112 
7114  sc->stereo3d->horizontal_field_of_view.den = 1000; // thousands of a degree
7115 
7116  return 0;
7117 }
7118 
7120 {
7121  int ret = 0;
7122  uint8_t *buffer = av_malloc(len + 1);
7123  const char *val;
7124 
7125  if (!buffer)
7126  return AVERROR(ENOMEM);
7127  buffer[len] = '\0';
7128 
7129  ret = ffio_read_size(pb, buffer, len);
7130  if (ret < 0)
7131  goto out;
7132 
7133  /* Check for mandatory keys and values, try to support XML as best-effort */
7134  if (!sc->spherical &&
7135  av_stristr(buffer, "<GSpherical:StitchingSoftware>") &&
7136  (val = av_stristr(buffer, "<GSpherical:Spherical>")) &&
7137  av_stristr(val, "true") &&
7138  (val = av_stristr(buffer, "<GSpherical:Stitched>")) &&
7139  av_stristr(val, "true") &&
7140  (val = av_stristr(buffer, "<GSpherical:ProjectionType>")) &&
7141  av_stristr(val, "equirectangular")) {
7143  if (!sc->spherical)
7144  goto out;
7145 
7147 
7148  if (av_stristr(buffer, "<GSpherical:StereoMode>") && !sc->stereo3d) {
7149  enum AVStereo3DType mode;
7150 
7151  if (av_stristr(buffer, "left-right"))
7153  else if (av_stristr(buffer, "top-bottom"))
7155  else
7156  mode = AV_STEREO3D_2D;
7157 
7159  if (!sc->stereo3d)
7160  goto out;
7161 
7162  sc->stereo3d->type = mode;
7163  }
7164 
7165  /* orientation */
7166  val = av_stristr(buffer, "<GSpherical:InitialViewHeadingDegrees>");
7167  if (val)
7168  sc->spherical->yaw = strtol(val, NULL, 10) * (1 << 16);
7169  val = av_stristr(buffer, "<GSpherical:InitialViewPitchDegrees>");
7170  if (val)
7171  sc->spherical->pitch = strtol(val, NULL, 10) * (1 << 16);
7172  val = av_stristr(buffer, "<GSpherical:InitialViewRollDegrees>");
7173  if (val)
7174  sc->spherical->roll = strtol(val, NULL, 10) * (1 << 16);
7175  }
7176 
7177 out:
7178  av_free(buffer);
7179  return ret;
7180 }
7181 
7183 {
7184  AVStream *st;
7185  MOVStreamContext *sc;
7186  int64_t ret;
7187  AVUUID uuid;
7188  static const AVUUID uuid_isml_manifest = {
7189  0xa5, 0xd4, 0x0b, 0x30, 0xe8, 0x14, 0x11, 0xdd,
7190  0xba, 0x2f, 0x08, 0x00, 0x20, 0x0c, 0x9a, 0x66
7191  };
7192  static const AVUUID uuid_xmp = {
7193  0xbe, 0x7a, 0xcf, 0xcb, 0x97, 0xa9, 0x42, 0xe8,
7194  0x9c, 0x71, 0x99, 0x94, 0x91, 0xe3, 0xaf, 0xac
7195  };
7196  static const AVUUID uuid_spherical = {
7197  0xff, 0xcc, 0x82, 0x63, 0xf8, 0x55, 0x4a, 0x93,
7198  0x88, 0x14, 0x58, 0x7a, 0x02, 0x52, 0x1f, 0xdd,
7199  };
7200 
7201  if (atom.size < AV_UUID_LEN || atom.size >= FFMIN(INT_MAX, SIZE_MAX))
7202  return AVERROR_INVALIDDATA;
7203 
7204  if (c->fc->nb_streams < 1)
7205  return 0;
7206  st = c->fc->streams[c->fc->nb_streams - 1];
7207  sc = st->priv_data;
7208 
7209  ret = ffio_read_size(pb, uuid, AV_UUID_LEN);
7210  if (ret < 0)
7211  return ret;
7212  if (av_uuid_equal(uuid, uuid_isml_manifest)) {
7213  uint8_t *buffer, *ptr;
7214  char *endptr;
7215  size_t len = atom.size - AV_UUID_LEN;
7216 
7217  if (len < 4) {
7218  return AVERROR_INVALIDDATA;
7219  }
7220  ret = avio_skip(pb, 4); // zeroes
7221  len -= 4;
7222 
7223  buffer = av_mallocz(len + 1);
7224  if (!buffer) {
7225  return AVERROR(ENOMEM);
7226  }
7227  ret = ffio_read_size(pb, buffer, len);
7228  if (ret < 0) {
7229  av_free(buffer);
7230  return ret;
7231  }
7232 
7233  ptr = buffer;
7234  while ((ptr = av_stristr(ptr, "systemBitrate=\""))) {
7235  ptr += sizeof("systemBitrate=\"") - 1;
7236  c->bitrates_count++;
7237  c->bitrates = av_realloc_f(c->bitrates, c->bitrates_count, sizeof(*c->bitrates));
7238  if (!c->bitrates) {
7239  c->bitrates_count = 0;
7240  av_free(buffer);
7241  return AVERROR(ENOMEM);
7242  }
7243  errno = 0;
7244  ret = strtol(ptr, &endptr, 10);
7245  if (ret < 0 || errno || *endptr != '"') {
7246  c->bitrates[c->bitrates_count - 1] = 0;
7247  } else {
7248  c->bitrates[c->bitrates_count - 1] = ret;
7249  }
7250  }
7251 
7252  av_free(buffer);
7253  } else if (av_uuid_equal(uuid, uuid_xmp)) {
7254  uint8_t *buffer;
7255  size_t len = atom.size - AV_UUID_LEN;
7256  if (c->export_xmp) {
7257  buffer = av_mallocz(len + 1);
7258  if (!buffer) {
7259  return AVERROR(ENOMEM);
7260  }
7261  ret = ffio_read_size(pb, buffer, len);
7262  if (ret < 0) {
7263  av_free(buffer);
7264  return ret;
7265  }
7266  buffer[len] = '\0';
7267  av_dict_set(&c->fc->metadata, "xmp",
7269  } else {
7270  // skip all uuid atom, which makes it fast for long uuid-xmp file
7271  ret = avio_skip(pb, len);
7272  if (ret < 0)
7273  return ret;
7274  }
7275  } else if (av_uuid_equal(uuid, uuid_spherical)) {
7276  size_t len = atom.size - AV_UUID_LEN;
7277  ret = mov_parse_uuid_spherical(sc, pb, len);
7278  if (ret < 0)
7279  return ret;
7280  if (!sc->spherical)
7281  av_log(c->fc, AV_LOG_WARNING, "Invalid spherical metadata found\n");
7282  }
7283 
7284  return 0;
7285 }
7286 
7288 {
7289  int ret;
7290  uint8_t content[16];
7291 
7292  if (atom.size < 8)
7293  return 0;
7294 
7295  ret = ffio_read_size(pb, content, FFMIN(sizeof(content), atom.size));
7296  if (ret < 0)
7297  return ret;
7298 
7299  if ( !c->found_moov
7300  && !c->found_mdat
7301  && !memcmp(content, "Anevia\x1A\x1A", 8)
7302  && c->use_mfra_for == FF_MOV_FLAG_MFRA_AUTO) {
7303  c->use_mfra_for = FF_MOV_FLAG_MFRA_PTS;
7304  }
7305 
7306  return 0;
7307 }
7308 
7310 {
7311  uint32_t format = avio_rl32(pb);
7312  MOVStreamContext *sc;
7313  enum AVCodecID id;
7314  AVStream *st;
7315 
7316  if (c->fc->nb_streams < 1)
7317  return 0;
7318  st = c->fc->streams[c->fc->nb_streams - 1];
7319  sc = st->priv_data;
7320 
7321  switch (sc->format)
7322  {
7323  case MKTAG('e','n','c','v'): // encrypted video
7324  case MKTAG('e','n','c','a'): // encrypted audio
7325  id = mov_codec_id(st, format);
7326  if (st->codecpar->codec_id != AV_CODEC_ID_NONE &&
7327  st->codecpar->codec_id != id) {
7328  av_log(c->fc, AV_LOG_WARNING,
7329  "ignoring 'frma' atom of '%.4s', stream has codec id %d\n",
7330  (char*)&format, st->codecpar->codec_id);
7331  break;
7332  }
7333 
7334  st->codecpar->codec_id = id;
7335  sc->format = format;
7336  break;
7337 
7338  default:
7339  if (format != sc->format) {
7340  av_log(c->fc, AV_LOG_WARNING,
7341  "ignoring 'frma' atom of '%.4s', stream format is '%.4s'\n",
7342  (char*)&format, (char*)&sc->format);
7343  }
7344  break;
7345  }
7346 
7347  return 0;
7348 }
7349 
7350 /**
7351  * Gets the current encryption info and associated current stream context. If
7352  * we are parsing a track fragment, this will return the specific encryption
7353  * info for this fragment; otherwise this will return the global encryption
7354  * info for the current stream.
7355  */
7357 {
7358  MOVFragmentStreamInfo *frag_stream_info;
7359  AVStream *st;
7360  int i;
7361 
7362  frag_stream_info = get_current_frag_stream_info(&c->frag_index);
7363  if (frag_stream_info) {
7364  for (i = 0; i < c->fc->nb_streams; i++) {
7365  *sc = c->fc->streams[i]->priv_data;
7366  if ((*sc)->id == frag_stream_info->id) {
7367  st = c->fc->streams[i];
7368  break;
7369  }
7370  }
7371  if (i == c->fc->nb_streams)
7372  return 0;
7373  *sc = st->priv_data;
7374 
7375  if (!frag_stream_info->encryption_index) {
7376  // If this stream isn't encrypted, don't create the index.
7377  if (!(*sc)->cenc.default_encrypted_sample)
7378  return 0;
7379  frag_stream_info->encryption_index = av_mallocz(sizeof(*frag_stream_info->encryption_index));
7380  if (!frag_stream_info->encryption_index)
7381  return AVERROR(ENOMEM);
7382  }
7383  *encryption_index = frag_stream_info->encryption_index;
7384  return 1;
7385  } else {
7386  // No current track fragment, using stream level encryption info.
7387 
7388  if (c->fc->nb_streams < 1)
7389  return 0;
7390  st = c->fc->streams[c->fc->nb_streams - 1];
7391  *sc = st->priv_data;
7392 
7393  if (!(*sc)->cenc.encryption_index) {
7394  // If this stream isn't encrypted, don't create the index.
7395  if (!(*sc)->cenc.default_encrypted_sample)
7396  return 0;
7397  (*sc)->cenc.encryption_index = av_mallocz(sizeof(*frag_stream_info->encryption_index));
7398  if (!(*sc)->cenc.encryption_index)
7399  return AVERROR(ENOMEM);
7400  }
7401 
7402  *encryption_index = (*sc)->cenc.encryption_index;
7403  return 1;
7404  }
7405 }
7406 
7408 {
7409  int i, ret;
7410  unsigned int subsample_count;
7411  AVSubsampleEncryptionInfo *subsamples;
7412 
7413  if (!sc->cenc.default_encrypted_sample) {
7414  av_log(c->fc, AV_LOG_ERROR, "Missing schm or tenc\n");
7415  return AVERROR_INVALIDDATA;
7416  }
7417 
7418  if (sc->cenc.per_sample_iv_size || use_subsamples) {
7420  if (!*sample)
7421  return AVERROR(ENOMEM);
7422  } else
7423  *sample = NULL;
7424 
7425  if (sc->cenc.per_sample_iv_size != 0) {
7426  if ((ret = ffio_read_size(pb, (*sample)->iv, sc->cenc.per_sample_iv_size)) < 0) {
7427  av_log(c->fc, AV_LOG_ERROR, "failed to read the initialization vector\n");
7429  *sample = NULL;
7430  return ret;
7431  }
7432  }
7433 
7434  if (use_subsamples) {
7435  subsample_count = avio_rb16(pb);
7436  av_free((*sample)->subsamples);
7437  (*sample)->subsamples = av_calloc(subsample_count, sizeof(*subsamples));
7438  if (!(*sample)->subsamples) {
7440  *sample = NULL;
7441  return AVERROR(ENOMEM);
7442  }
7443 
7444  for (i = 0; i < subsample_count && !pb->eof_reached; i++) {
7445  (*sample)->subsamples[i].bytes_of_clear_data = avio_rb16(pb);
7446  (*sample)->subsamples[i].bytes_of_protected_data = avio_rb32(pb);
7447  }
7448 
7449  if (pb->eof_reached) {
7450  av_log(c->fc, AV_LOG_ERROR, "hit EOF while reading sub-sample encryption info\n");
7452  *sample = NULL;
7453  return AVERROR_INVALIDDATA;
7454  }
7455  (*sample)->subsample_count = subsample_count;
7456  }
7457 
7458  return 0;
7459 }
7460 
7462 {
7463  AVEncryptionInfo **encrypted_samples;
7464  MOVEncryptionIndex *encryption_index;
7465  MOVStreamContext *sc;
7466  int use_subsamples, ret;
7467  unsigned int sample_count, i, alloc_size = 0;
7468 
7469  ret = get_current_encryption_info(c, &encryption_index, &sc);
7470  if (ret != 1)
7471  return ret;
7472 
7473  if (encryption_index->nb_encrypted_samples) {
7474  // This can happen if we have both saio/saiz and senc atoms.
7475  av_log(c->fc, AV_LOG_DEBUG, "Ignoring duplicate encryption info in senc\n");
7476  return 0;
7477  }
7478 
7479  avio_r8(pb); /* version */
7480  use_subsamples = avio_rb24(pb) & 0x02; /* flags */
7481 
7482  sample_count = avio_rb32(pb);
7483  if (sample_count >= INT_MAX / sizeof(*encrypted_samples))
7484  return AVERROR(ENOMEM);
7485 
7486  for (i = 0; i < sample_count; i++) {
7487  unsigned int min_samples = FFMIN(FFMAX(i + 1, 1024 * 1024), sample_count);
7488  encrypted_samples = av_fast_realloc(encryption_index->encrypted_samples, &alloc_size,
7489  min_samples * sizeof(*encrypted_samples));
7490  if (encrypted_samples) {
7491  encryption_index->encrypted_samples = encrypted_samples;
7492 
7494  c, pb, sc, &encryption_index->encrypted_samples[i], use_subsamples);
7495  } else {
7496  ret = AVERROR(ENOMEM);
7497  }
7498  if (pb->eof_reached) {
7499  av_log(c->fc, AV_LOG_ERROR, "Hit EOF while reading senc\n");
7500  if (ret >= 0)
7501  av_encryption_info_free(encryption_index->encrypted_samples[i]);
7503  }
7504 
7505  if (ret < 0) {
7506  for (; i > 0; i--)
7507  av_encryption_info_free(encryption_index->encrypted_samples[i - 1]);
7508  av_freep(&encryption_index->encrypted_samples);
7509  return ret;
7510  }
7511  }
7512  encryption_index->nb_encrypted_samples = sample_count;
7513 
7514  return 0;
7515 }
7516 
7518 {
7519  AVEncryptionInfo **sample, **encrypted_samples;
7520  int64_t prev_pos;
7521  size_t sample_count, sample_info_size, i;
7522  int ret = 0;
7523  unsigned int alloc_size = 0;
7524 
7525  if (encryption_index->nb_encrypted_samples)
7526  return 0;
7527  sample_count = encryption_index->auxiliary_info_sample_count;
7528  if (encryption_index->auxiliary_offsets_count != 1) {
7529  av_log(c->fc, AV_LOG_ERROR, "Multiple auxiliary info chunks are not supported\n");
7530  return AVERROR_PATCHWELCOME;
7531  }
7532  if (sample_count >= INT_MAX / sizeof(*encrypted_samples))
7533  return AVERROR(ENOMEM);
7534 
7535  prev_pos = avio_tell(pb);
7536  if (!(pb->seekable & AVIO_SEEKABLE_NORMAL) ||
7537  avio_seek(pb, encryption_index->auxiliary_offsets[0], SEEK_SET) != encryption_index->auxiliary_offsets[0]) {
7538  av_log(c->fc, AV_LOG_INFO, "Failed to seek for auxiliary info, will only parse senc atoms for encryption info\n");
7539  goto finish;
7540  }
7541 
7542  for (i = 0; i < sample_count && !pb->eof_reached; i++) {
7543  unsigned int min_samples = FFMIN(FFMAX(i + 1, 1024 * 1024), sample_count);
7544  encrypted_samples = av_fast_realloc(encryption_index->encrypted_samples, &alloc_size,
7545  min_samples * sizeof(*encrypted_samples));
7546  if (!encrypted_samples) {
7547  ret = AVERROR(ENOMEM);
7548  goto finish;
7549  }
7550  encryption_index->encrypted_samples = encrypted_samples;
7551 
7552  sample = &encryption_index->encrypted_samples[i];
7553  sample_info_size = encryption_index->auxiliary_info_default_size
7554  ? encryption_index->auxiliary_info_default_size
7555  : encryption_index->auxiliary_info_sizes[i];
7556 
7557  ret = mov_read_sample_encryption_info(c, pb, sc, sample, sample_info_size > sc->cenc.per_sample_iv_size);
7558  if (ret < 0)
7559  goto finish;
7560  }
7561  if (pb->eof_reached) {
7562  av_log(c->fc, AV_LOG_ERROR, "Hit EOF while reading auxiliary info\n");
7564  } else {
7565  encryption_index->nb_encrypted_samples = sample_count;
7566  }
7567 
7568 finish:
7569  avio_seek(pb, prev_pos, SEEK_SET);
7570  if (ret < 0) {
7571  for (; i > 0; i--) {
7572  av_encryption_info_free(encryption_index->encrypted_samples[i - 1]);
7573  }
7574  av_freep(&encryption_index->encrypted_samples);
7575  }
7576  return ret;
7577 }
7578 
7580 {
7581  MOVEncryptionIndex *encryption_index;
7582  MOVStreamContext *sc;
7583  int ret;
7584  unsigned int sample_count, aux_info_type, aux_info_param;
7585 
7586  ret = get_current_encryption_info(c, &encryption_index, &sc);
7587  if (ret != 1)
7588  return ret;
7589 
7590  if (encryption_index->nb_encrypted_samples) {
7591  // This can happen if we have both saio/saiz and senc atoms.
7592  av_log(c->fc, AV_LOG_DEBUG, "Ignoring duplicate encryption info in saiz\n");
7593  return 0;
7594  }
7595 
7596  if (encryption_index->auxiliary_info_sample_count) {
7597  av_log(c->fc, AV_LOG_ERROR, "Duplicate saiz atom\n");
7598  return AVERROR_INVALIDDATA;
7599  }
7600 
7601  avio_r8(pb); /* version */
7602  if (avio_rb24(pb) & 0x01) { /* flags */
7603  aux_info_type = avio_rb32(pb);
7604  aux_info_param = avio_rb32(pb);
7605  if (sc->cenc.default_encrypted_sample) {
7606  if (aux_info_type != sc->cenc.default_encrypted_sample->scheme) {
7607  av_log(c->fc, AV_LOG_DEBUG, "Ignoring saiz box with non-zero aux_info_type\n");
7608  return 0;
7609  }
7610  if (aux_info_param != 0) {
7611  av_log(c->fc, AV_LOG_DEBUG, "Ignoring saiz box with non-zero aux_info_type_parameter\n");
7612  return 0;
7613  }
7614  } else {
7615  // Didn't see 'schm' or 'tenc', so this isn't encrypted.
7616  if ((aux_info_type == MKBETAG('c','e','n','c') ||
7617  aux_info_type == MKBETAG('c','e','n','s') ||
7618  aux_info_type == MKBETAG('c','b','c','1') ||
7619  aux_info_type == MKBETAG('c','b','c','s')) &&
7620  aux_info_param == 0) {
7621  av_log(c->fc, AV_LOG_ERROR, "Saw encrypted saiz without schm/tenc\n");
7622  return AVERROR_INVALIDDATA;
7623  } else {
7624  return 0;
7625  }
7626  }
7627  } else if (!sc->cenc.default_encrypted_sample) {
7628  // Didn't see 'schm' or 'tenc', so this isn't encrypted.
7629  return 0;
7630  }
7631 
7632  encryption_index->auxiliary_info_default_size = avio_r8(pb);
7633  sample_count = avio_rb32(pb);
7634 
7635  if (encryption_index->auxiliary_info_default_size == 0) {
7636  if (sample_count == 0)
7637  return AVERROR_INVALIDDATA;
7638 
7639  encryption_index->auxiliary_info_sizes = av_malloc(sample_count);
7640  if (!encryption_index->auxiliary_info_sizes)
7641  return AVERROR(ENOMEM);
7642 
7643  ret = avio_read(pb, encryption_index->auxiliary_info_sizes, sample_count);
7644  if (ret != sample_count) {
7645  av_freep(&encryption_index->auxiliary_info_sizes);
7646 
7647  if (ret >= 0)
7649  av_log(c->fc, AV_LOG_ERROR, "Failed to read the auxiliary info, %s\n",
7650  av_err2str(ret));
7651  return ret;
7652  }
7653  }
7654  encryption_index->auxiliary_info_sample_count = sample_count;
7655 
7656  if (encryption_index->auxiliary_offsets_count) {
7657  return mov_parse_auxiliary_info(c, sc, pb, encryption_index);
7658  }
7659 
7660  return 0;
7661 }
7662 
7664 {
7665  uint64_t *auxiliary_offsets;
7666  MOVEncryptionIndex *encryption_index;
7667  MOVStreamContext *sc;
7668  int i, ret;
7669  unsigned int version, entry_count, aux_info_type, aux_info_param;
7670  unsigned int alloc_size = 0;
7671 
7672  ret = get_current_encryption_info(c, &encryption_index, &sc);
7673  if (ret != 1)
7674  return ret;
7675 
7676  if (encryption_index->nb_encrypted_samples) {
7677  // This can happen if we have both saio/saiz and senc atoms.
7678  av_log(c->fc, AV_LOG_DEBUG, "Ignoring duplicate encryption info in saio\n");
7679  return 0;
7680  }
7681 
7682  if (encryption_index->auxiliary_offsets_count) {
7683  av_log(c->fc, AV_LOG_ERROR, "Duplicate saio atom\n");
7684  return AVERROR_INVALIDDATA;
7685  }
7686 
7687  version = avio_r8(pb); /* version */
7688  if (avio_rb24(pb) & 0x01) { /* flags */
7689  aux_info_type = avio_rb32(pb);
7690  aux_info_param = avio_rb32(pb);
7691  if (sc->cenc.default_encrypted_sample) {
7692  if (aux_info_type != sc->cenc.default_encrypted_sample->scheme) {
7693  av_log(c->fc, AV_LOG_DEBUG, "Ignoring saio box with non-zero aux_info_type\n");
7694  return 0;
7695  }
7696  if (aux_info_param != 0) {
7697  av_log(c->fc, AV_LOG_DEBUG, "Ignoring saio box with non-zero aux_info_type_parameter\n");
7698  return 0;
7699  }
7700  } else {
7701  // Didn't see 'schm' or 'tenc', so this isn't encrypted.
7702  if ((aux_info_type == MKBETAG('c','e','n','c') ||
7703  aux_info_type == MKBETAG('c','e','n','s') ||
7704  aux_info_type == MKBETAG('c','b','c','1') ||
7705  aux_info_type == MKBETAG('c','b','c','s')) &&
7706  aux_info_param == 0) {
7707  av_log(c->fc, AV_LOG_ERROR, "Saw encrypted saio without schm/tenc\n");
7708  return AVERROR_INVALIDDATA;
7709  } else {
7710  return 0;
7711  }
7712  }
7713  } else if (!sc->cenc.default_encrypted_sample) {
7714  // Didn't see 'schm' or 'tenc', so this isn't encrypted.
7715  return 0;
7716  }
7717 
7718  entry_count = avio_rb32(pb);
7719  if (entry_count >= INT_MAX / sizeof(*auxiliary_offsets))
7720  return AVERROR(ENOMEM);
7721 
7722  for (i = 0; i < entry_count && !pb->eof_reached; i++) {
7723  unsigned int min_offsets = FFMIN(FFMAX(i + 1, 1024), entry_count);
7724  auxiliary_offsets = av_fast_realloc(
7725  encryption_index->auxiliary_offsets, &alloc_size,
7726  min_offsets * sizeof(*auxiliary_offsets));
7727  if (!auxiliary_offsets) {
7728  av_freep(&encryption_index->auxiliary_offsets);
7729  return AVERROR(ENOMEM);
7730  }
7731  encryption_index->auxiliary_offsets = auxiliary_offsets;
7732 
7733  if (version == 0) {
7734  encryption_index->auxiliary_offsets[i] = avio_rb32(pb);
7735  } else {
7736  encryption_index->auxiliary_offsets[i] = avio_rb64(pb);
7737  }
7738  if (c->frag_index.current >= 0) {
7739  encryption_index->auxiliary_offsets[i] += c->fragment.base_data_offset;
7740  }
7741  }
7742 
7743  if (pb->eof_reached) {
7744  av_log(c->fc, AV_LOG_ERROR, "Hit EOF while reading saio\n");
7745  av_freep(&encryption_index->auxiliary_offsets);
7746  return AVERROR_INVALIDDATA;
7747  }
7748 
7749  encryption_index->auxiliary_offsets_count = entry_count;
7750 
7751  if (encryption_index->auxiliary_info_sample_count) {
7752  return mov_parse_auxiliary_info(c, sc, pb, encryption_index);
7753  }
7754 
7755  return 0;
7756 }
7757 
7759 {
7760  AVEncryptionInitInfo *info, *old_init_info;
7761  uint8_t **key_ids;
7762  AVStream *st;
7763  const AVPacketSideData *old_side_data;
7764  uint8_t *side_data, *extra_data;
7765  size_t side_data_size;
7766  int ret = 0;
7767  unsigned int version, kid_count, extra_data_size, alloc_size = 0;
7768 
7769  if (c->fc->nb_streams < 1)
7770  return 0;
7771  st = c->fc->streams[c->fc->nb_streams-1];
7772 
7773  version = avio_r8(pb); /* version */
7774  avio_rb24(pb); /* flags */
7775 
7776  info = av_encryption_init_info_alloc(/* system_id_size */ 16, /* num_key_ids */ 0,
7777  /* key_id_size */ 16, /* data_size */ 0);
7778  if (!info)
7779  return AVERROR(ENOMEM);
7780 
7781  if ((ret = ffio_read_size(pb, info->system_id, 16)) < 0) {
7782  av_log(c->fc, AV_LOG_ERROR, "Failed to read the system id\n");
7783  goto finish;
7784  }
7785 
7786  if (version > 0) {
7787  kid_count = avio_rb32(pb);
7788  if (kid_count >= INT_MAX / sizeof(*key_ids)) {
7789  ret = AVERROR(ENOMEM);
7790  goto finish;
7791  }
7792 
7793  for (unsigned int i = 0; i < kid_count && !pb->eof_reached; i++) {
7794  unsigned int min_kid_count = FFMIN(FFMAX(i + 1, 1024), kid_count);
7795  key_ids = av_fast_realloc(info->key_ids, &alloc_size,
7796  min_kid_count * sizeof(*key_ids));
7797  if (!key_ids) {
7798  ret = AVERROR(ENOMEM);
7799  goto finish;
7800  }
7801  info->key_ids = key_ids;
7802 
7803  info->key_ids[i] = av_mallocz(16);
7804  if (!info->key_ids[i]) {
7805  ret = AVERROR(ENOMEM);
7806  goto finish;
7807  }
7808  info->num_key_ids = i + 1;
7809 
7810  if ((ret = ffio_read_size(pb, info->key_ids[i], 16)) < 0) {
7811  av_log(c->fc, AV_LOG_ERROR, "Failed to read the key id\n");
7812  goto finish;
7813  }
7814  }
7815 
7816  if (pb->eof_reached) {
7817  av_log(c->fc, AV_LOG_ERROR, "Hit EOF while reading pssh\n");
7819  goto finish;
7820  }
7821  }
7822 
7823  extra_data_size = avio_rb32(pb);
7824  extra_data = av_malloc(extra_data_size);
7825  if (!extra_data) {
7826  ret = AVERROR(ENOMEM);
7827  goto finish;
7828  }
7829  ret = avio_read(pb, extra_data, extra_data_size);
7830  if (ret != extra_data_size) {
7831  av_free(extra_data);
7832 
7833  if (ret >= 0)
7835  goto finish;
7836  }
7837 
7838  av_freep(&info->data); // malloc(0) may still allocate something.
7839  info->data = extra_data;
7840  info->data_size = extra_data_size;
7841 
7842  // If there is existing initialization data, append to the list.
7845  if (old_side_data) {
7846  old_init_info = av_encryption_init_info_get_side_data(old_side_data->data, old_side_data->size);
7847  if (old_init_info) {
7848  // Append to the end of the list.
7849  for (AVEncryptionInitInfo *cur = old_init_info;; cur = cur->next) {
7850  if (!cur->next) {
7851  cur->next = info;
7852  break;
7853  }
7854  }
7855  info = old_init_info;
7856  } else {
7857  // Assume existing side-data will be valid, so the only error we could get is OOM.
7858  ret = AVERROR(ENOMEM);
7859  goto finish;
7860  }
7861  }
7862 
7863  side_data = av_encryption_init_info_add_side_data(info, &side_data_size);
7864  if (!side_data) {
7865  ret = AVERROR(ENOMEM);
7866  goto finish;
7867  }
7871  side_data, side_data_size, 0))
7872  av_free(side_data);
7873 
7874 finish:
7876  return ret;
7877 }
7878 
7880 {
7881  AVStream *st;
7882  MOVStreamContext *sc;
7883 
7884  if (c->fc->nb_streams < 1)
7885  return 0;
7886  st = c->fc->streams[c->fc->nb_streams-1];
7887  sc = st->priv_data;
7888 
7889  if (sc->pseudo_stream_id != 0) {
7890  av_log(c->fc, AV_LOG_ERROR, "schm boxes are only supported in first sample descriptor\n");
7891  return AVERROR_PATCHWELCOME;
7892  }
7893 
7894  if (atom.size < 8)
7895  return AVERROR_INVALIDDATA;
7896 
7897  avio_rb32(pb); /* version and flags */
7898 
7899  if (!sc->cenc.default_encrypted_sample) {
7901  if (!sc->cenc.default_encrypted_sample) {
7902  return AVERROR(ENOMEM);
7903  }
7904  }
7905 
7907  return 0;
7908 }
7909 
7911 {
7912  AVStream *st;
7913  MOVStreamContext *sc;
7914  unsigned int version, pattern, is_protected, iv_size;
7915 
7916  if (c->fc->nb_streams < 1)
7917  return 0;
7918  st = c->fc->streams[c->fc->nb_streams-1];
7919  sc = st->priv_data;
7920 
7921  if (sc->pseudo_stream_id != 0) {
7922  av_log(c->fc, AV_LOG_ERROR, "tenc atom are only supported in first sample descriptor\n");
7923  return AVERROR_PATCHWELCOME;
7924  }
7925 
7926  if (!sc->cenc.default_encrypted_sample) {
7928  if (!sc->cenc.default_encrypted_sample) {
7929  return AVERROR(ENOMEM);
7930  }
7931  }
7932 
7933  if (atom.size < 20)
7934  return AVERROR_INVALIDDATA;
7935 
7936  version = avio_r8(pb); /* version */
7937  avio_rb24(pb); /* flags */
7938 
7939  avio_r8(pb); /* reserved */
7940  pattern = avio_r8(pb);
7941 
7942  if (version > 0) {
7943  sc->cenc.default_encrypted_sample->crypt_byte_block = pattern >> 4;
7944  sc->cenc.default_encrypted_sample->skip_byte_block = pattern & 0xf;
7945  }
7946 
7947  is_protected = avio_r8(pb);
7948  if (is_protected && !sc->cenc.encryption_index) {
7949  // The whole stream should be by-default encrypted.
7951  if (!sc->cenc.encryption_index)
7952  return AVERROR(ENOMEM);
7953  }
7954  sc->cenc.per_sample_iv_size = avio_r8(pb);
7955  if (sc->cenc.per_sample_iv_size != 0 && sc->cenc.per_sample_iv_size != 8 &&
7956  sc->cenc.per_sample_iv_size != 16) {
7957  av_log(c->fc, AV_LOG_ERROR, "invalid per-sample IV size value\n");
7958  return AVERROR_INVALIDDATA;
7959  }
7960  if (avio_read(pb, sc->cenc.default_encrypted_sample->key_id, 16) != 16) {
7961  av_log(c->fc, AV_LOG_ERROR, "failed to read the default key ID\n");
7962  return AVERROR_INVALIDDATA;
7963  }
7964 
7965  if (is_protected && !sc->cenc.per_sample_iv_size) {
7966  iv_size = avio_r8(pb);
7967  if (iv_size != 8 && iv_size != 16) {
7968  av_log(c->fc, AV_LOG_ERROR, "invalid default_constant_IV_size in tenc atom\n");
7969  return AVERROR_INVALIDDATA;
7970  }
7971 
7972  if (avio_read(pb, sc->cenc.default_encrypted_sample->iv, iv_size) != iv_size) {
7973  av_log(c->fc, AV_LOG_ERROR, "failed to read the default IV\n");
7974  return AVERROR_INVALIDDATA;
7975  }
7976  }
7977 
7978  return 0;
7979 }
7980 
7982 {
7983  AVStream *st;
7984  int last, type, size, ret;
7985  uint8_t buf[4];
7986 
7987  if (c->fc->nb_streams < 1)
7988  return 0;
7989  st = c->fc->streams[c->fc->nb_streams-1];
7990 
7991  if ((uint64_t)atom.size > (1<<30) || atom.size < 42)
7992  return AVERROR_INVALIDDATA;
7993 
7994  /* Check FlacSpecificBox version. */
7995  if (avio_r8(pb) != 0)
7996  return AVERROR_INVALIDDATA;
7997 
7998  avio_rb24(pb); /* Flags */
7999 
8000  if (avio_read(pb, buf, sizeof(buf)) != sizeof(buf)) {
8001  av_log(c->fc, AV_LOG_ERROR, "failed to read FLAC metadata block header\n");
8002  return pb->error < 0 ? pb->error : AVERROR_INVALIDDATA;
8003  }
8004  flac_parse_block_header(buf, &last, &type, &size);
8005 
8007  av_log(c->fc, AV_LOG_ERROR, "STREAMINFO must be first FLACMetadataBlock\n");
8008  return AVERROR_INVALIDDATA;
8009  }
8010 
8011  ret = ff_get_extradata(c->fc, st->codecpar, pb, size);
8012  if (ret < 0)
8013  return ret;
8014 
8015  if (!last)
8016  av_log(c->fc, AV_LOG_WARNING, "non-STREAMINFO FLACMetadataBlock(s) ignored\n");
8017 
8018  return 0;
8019 }
8020 
8022 {
8023  int i, ret;
8024  int bytes_of_protected_data;
8025 
8026  if (!sc->cenc.aes_ctr) {
8027  /* initialize the cipher */
8028  sc->cenc.aes_ctr = av_aes_ctr_alloc();
8029  if (!sc->cenc.aes_ctr) {
8030  return AVERROR(ENOMEM);
8031  }
8032 
8033  ret = av_aes_ctr_init(sc->cenc.aes_ctr, c->decryption_key);
8034  if (ret < 0) {
8035  return ret;
8036  }
8037  }
8038 
8040 
8041  if (!sample->subsample_count) {
8042  /* decrypt the whole packet */
8044  return 0;
8045  }
8046 
8047  for (i = 0; i < sample->subsample_count; i++) {
8048  if (sample->subsamples[i].bytes_of_clear_data + sample->subsamples[i].bytes_of_protected_data > size) {
8049  av_log(c->fc, AV_LOG_ERROR, "subsample size exceeds the packet size left\n");
8050  return AVERROR_INVALIDDATA;
8051  }
8052 
8053  /* skip the clear bytes */
8054  input += sample->subsamples[i].bytes_of_clear_data;
8055  size -= sample->subsamples[i].bytes_of_clear_data;
8056 
8057  /* decrypt the encrypted bytes */
8058 
8059  bytes_of_protected_data = sample->subsamples[i].bytes_of_protected_data;
8060  av_aes_ctr_crypt(sc->cenc.aes_ctr, input, input, bytes_of_protected_data);
8061 
8062  input += bytes_of_protected_data;
8063  size -= bytes_of_protected_data;
8064  }
8065 
8066  if (size > 0) {
8067  av_log(c->fc, AV_LOG_ERROR, "leftover packet bytes after subsample processing\n");
8068  return AVERROR_INVALIDDATA;
8069  }
8070 
8071  return 0;
8072 }
8073 
8075 {
8076  int i, ret;
8077  int num_of_encrypted_blocks;
8078  uint8_t iv[16];
8079 
8080  if (!sc->cenc.aes_ctx) {
8081  /* initialize the cipher */
8082  sc->cenc.aes_ctx = av_aes_alloc();
8083  if (!sc->cenc.aes_ctx) {
8084  return AVERROR(ENOMEM);
8085  }
8086 
8087  ret = av_aes_init(sc->cenc.aes_ctx, c->decryption_key, 16 * 8, 1);
8088  if (ret < 0) {
8089  return ret;
8090  }
8091  }
8092 
8093  memcpy(iv, sample->iv, 16);
8094 
8095  /* whole-block full sample encryption */
8096  if (!sample->subsample_count) {
8097  /* decrypt the whole packet */
8098  av_aes_crypt(sc->cenc.aes_ctx, input, input, size/16, iv, 1);
8099  return 0;
8100  }
8101 
8102  for (i = 0; i < sample->subsample_count; i++) {
8103  if (sample->subsamples[i].bytes_of_clear_data + sample->subsamples[i].bytes_of_protected_data > size) {
8104  av_log(c->fc, AV_LOG_ERROR, "subsample size exceeds the packet size left\n");
8105  return AVERROR_INVALIDDATA;
8106  }
8107 
8108  if (sample->subsamples[i].bytes_of_protected_data % 16) {
8109  av_log(c->fc, AV_LOG_ERROR, "subsample BytesOfProtectedData is not a multiple of 16\n");
8110  return AVERROR_INVALIDDATA;
8111  }
8112 
8113  /* skip the clear bytes */
8114  input += sample->subsamples[i].bytes_of_clear_data;
8115  size -= sample->subsamples[i].bytes_of_clear_data;
8116 
8117  /* decrypt the encrypted bytes */
8118  num_of_encrypted_blocks = sample->subsamples[i].bytes_of_protected_data/16;
8119  if (num_of_encrypted_blocks > 0) {
8120  av_aes_crypt(sc->cenc.aes_ctx, input, input, num_of_encrypted_blocks, iv, 1);
8121  }
8122  input += sample->subsamples[i].bytes_of_protected_data;
8123  size -= sample->subsamples[i].bytes_of_protected_data;
8124  }
8125 
8126  if (size > 0) {
8127  av_log(c->fc, AV_LOG_ERROR, "leftover packet bytes after subsample processing\n");
8128  return AVERROR_INVALIDDATA;
8129  }
8130 
8131  return 0;
8132 }
8133 
8135 {
8136  int i, ret, rem_bytes;
8137  uint8_t *data;
8138 
8139  if (!sc->cenc.aes_ctr) {
8140  /* initialize the cipher */
8141  sc->cenc.aes_ctr = av_aes_ctr_alloc();
8142  if (!sc->cenc.aes_ctr) {
8143  return AVERROR(ENOMEM);
8144  }
8145 
8146  ret = av_aes_ctr_init(sc->cenc.aes_ctr, c->decryption_key);
8147  if (ret < 0) {
8148  return ret;
8149  }
8150  }
8151 
8153 
8154  /* whole-block full sample encryption */
8155  if (!sample->subsample_count) {
8156  /* decrypt the whole packet */
8158  return 0;
8159  } else if (!sample->crypt_byte_block && !sample->skip_byte_block) {
8160  av_log(c->fc, AV_LOG_ERROR, "pattern encryption is not present in 'cens' scheme\n");
8161  return AVERROR_INVALIDDATA;
8162  }
8163 
8164  for (i = 0; i < sample->subsample_count; i++) {
8165  if (sample->subsamples[i].bytes_of_clear_data + sample->subsamples[i].bytes_of_protected_data > size) {
8166  av_log(c->fc, AV_LOG_ERROR, "subsample size exceeds the packet size left\n");
8167  return AVERROR_INVALIDDATA;
8168  }
8169 
8170  /* skip the clear bytes */
8171  input += sample->subsamples[i].bytes_of_clear_data;
8172  size -= sample->subsamples[i].bytes_of_clear_data;
8173 
8174  /* decrypt the encrypted bytes */
8175  data = input;
8176  rem_bytes = sample->subsamples[i].bytes_of_protected_data;
8177  while (rem_bytes > 0) {
8178  if (rem_bytes < 16*sample->crypt_byte_block) {
8179  break;
8180  }
8181  av_aes_ctr_crypt(sc->cenc.aes_ctr, data, data, 16*sample->crypt_byte_block);
8182  data += 16*sample->crypt_byte_block;
8183  rem_bytes -= 16*sample->crypt_byte_block;
8184  data += FFMIN(16*sample->skip_byte_block, rem_bytes);
8185  rem_bytes -= FFMIN(16*sample->skip_byte_block, rem_bytes);
8186  }
8187  input += sample->subsamples[i].bytes_of_protected_data;
8188  size -= sample->subsamples[i].bytes_of_protected_data;
8189  }
8190 
8191  if (size > 0) {
8192  av_log(c->fc, AV_LOG_ERROR, "leftover packet bytes after subsample processing\n");
8193  return AVERROR_INVALIDDATA;
8194  }
8195 
8196  return 0;
8197 }
8198 
8200 {
8201  int i, ret, rem_bytes;
8202  uint8_t iv[16];
8203  uint8_t *data;
8204 
8205  if (!sc->cenc.aes_ctx) {
8206  /* initialize the cipher */
8207  sc->cenc.aes_ctx = av_aes_alloc();
8208  if (!sc->cenc.aes_ctx) {
8209  return AVERROR(ENOMEM);
8210  }
8211 
8212  ret = av_aes_init(sc->cenc.aes_ctx, c->decryption_key, 16 * 8, 1);
8213  if (ret < 0) {
8214  return ret;
8215  }
8216  }
8217 
8218  /* whole-block full sample encryption */
8219  if (!sample->subsample_count) {
8220  /* decrypt the whole packet */
8221  memcpy(iv, sample->iv, 16);
8222  av_aes_crypt(sc->cenc.aes_ctx, input, input, size/16, iv, 1);
8223  return 0;
8224  } else if (!sample->crypt_byte_block && !sample->skip_byte_block) {
8225  av_log(c->fc, AV_LOG_ERROR, "pattern encryption is not present in 'cbcs' scheme\n");
8226  return AVERROR_INVALIDDATA;
8227  }
8228 
8229  for (i = 0; i < sample->subsample_count; i++) {
8230  if (sample->subsamples[i].bytes_of_clear_data + sample->subsamples[i].bytes_of_protected_data > size) {
8231  av_log(c->fc, AV_LOG_ERROR, "subsample size exceeds the packet size left\n");
8232  return AVERROR_INVALIDDATA;
8233  }
8234 
8235  /* skip the clear bytes */
8236  input += sample->subsamples[i].bytes_of_clear_data;
8237  size -= sample->subsamples[i].bytes_of_clear_data;
8238 
8239  /* decrypt the encrypted bytes */
8240  memcpy(iv, sample->iv, 16);
8241  data = input;
8242  rem_bytes = sample->subsamples[i].bytes_of_protected_data;
8243  while (rem_bytes > 0) {
8244  if (rem_bytes < 16*sample->crypt_byte_block) {
8245  break;
8246  }
8247  av_aes_crypt(sc->cenc.aes_ctx, data, data, sample->crypt_byte_block, iv, 1);
8248  data += 16*sample->crypt_byte_block;
8249  rem_bytes -= 16*sample->crypt_byte_block;
8250  data += FFMIN(16*sample->skip_byte_block, rem_bytes);
8251  rem_bytes -= FFMIN(16*sample->skip_byte_block, rem_bytes);
8252  }
8253  input += sample->subsamples[i].bytes_of_protected_data;
8254  size -= sample->subsamples[i].bytes_of_protected_data;
8255  }
8256 
8257  if (size > 0) {
8258  av_log(c->fc, AV_LOG_ERROR, "leftover packet bytes after subsample processing\n");
8259  return AVERROR_INVALIDDATA;
8260  }
8261 
8262  return 0;
8263 }
8264 
8266 {
8267  if (sample->scheme == MKBETAG('c','e','n','c') && !sample->crypt_byte_block && !sample->skip_byte_block) {
8268  return cenc_scheme_decrypt(c, sc, sample, input, size);
8269  } else if (sample->scheme == MKBETAG('c','b','c','1') && !sample->crypt_byte_block && !sample->skip_byte_block) {
8270  return cbc1_scheme_decrypt(c, sc, sample, input, size);
8271  } else if (sample->scheme == MKBETAG('c','e','n','s')) {
8272  return cens_scheme_decrypt(c, sc, sample, input, size);
8273  } else if (sample->scheme == MKBETAG('c','b','c','s')) {
8274  return cbcs_scheme_decrypt(c, sc, sample, input, size);
8275  } else {
8276  av_log(c->fc, AV_LOG_ERROR, "invalid encryption scheme\n");
8277  return AVERROR_INVALIDDATA;
8278  }
8279 }
8280 
8282 {
8283  int current = frag_index->current;
8284 
8285  if (!frag_index->nb_items)
8286  return NULL;
8287 
8288  // Check frag_index->current is the right one for pkt. It can out of sync.
8289  if (current >= 0 && current < frag_index->nb_items) {
8290  if (frag_index->item[current].moof_offset < pkt->pos &&
8291  (current + 1 == frag_index->nb_items ||
8292  frag_index->item[current + 1].moof_offset > pkt->pos))
8293  return get_frag_stream_info(frag_index, current, id);
8294  }
8295 
8296 
8297  for (int i = 0; i < frag_index->nb_items; i++) {
8298  if (frag_index->item[i].moof_offset > pkt->pos)
8299  break;
8300  current = i;
8301  }
8302  frag_index->current = current;
8303  return get_frag_stream_info(frag_index, current, id);
8304 }
8305 
8306 static int cenc_filter(MOVContext *mov, AVStream* st, MOVStreamContext *sc, AVPacket *pkt, int current_index)
8307 {
8308  MOVFragmentStreamInfo *frag_stream_info;
8309  MOVEncryptionIndex *encryption_index;
8310  AVEncryptionInfo *encrypted_sample;
8311  int encrypted_index, ret;
8312 
8313  frag_stream_info = get_frag_stream_info_from_pkt(&mov->frag_index, pkt, sc->id);
8314  encrypted_index = current_index;
8315  encryption_index = NULL;
8316  if (frag_stream_info) {
8317  // Note this only supports encryption info in the first sample descriptor.
8318  if (frag_stream_info->stsd_id == 1) {
8319  if (frag_stream_info->encryption_index) {
8320  encrypted_index = current_index - frag_stream_info->index_base;
8321  encryption_index = frag_stream_info->encryption_index;
8322  } else {
8323  encryption_index = sc->cenc.encryption_index;
8324  }
8325  }
8326  } else {
8327  encryption_index = sc->cenc.encryption_index;
8328  }
8329 
8330  if (encryption_index) {
8331  if (encryption_index->auxiliary_info_sample_count &&
8332  !encryption_index->nb_encrypted_samples) {
8333  av_log(mov->fc, AV_LOG_ERROR, "saiz atom found without saio\n");
8334  return AVERROR_INVALIDDATA;
8335  }
8336  if (encryption_index->auxiliary_offsets_count &&
8337  !encryption_index->nb_encrypted_samples) {
8338  av_log(mov->fc, AV_LOG_ERROR, "saio atom found without saiz\n");
8339  return AVERROR_INVALIDDATA;
8340  }
8341 
8342  encrypted_sample = NULL;
8343  if (!encryption_index->nb_encrypted_samples) {
8344  // Full-sample encryption with default settings.
8345  encrypted_sample = sc->cenc.default_encrypted_sample;
8346  } else if (encrypted_index >= 0 && encrypted_index < encryption_index->nb_encrypted_samples) {
8347  // Per-sample setting override.
8348  encrypted_sample = encryption_index->encrypted_samples[encrypted_index];
8349  if (!encrypted_sample) {
8350  encrypted_sample = sc->cenc.default_encrypted_sample;
8351  }
8352  }
8353 
8354  if (!encrypted_sample) {
8355  av_log(mov->fc, AV_LOG_ERROR, "Incorrect number of samples in encryption info\n");
8356  return AVERROR_INVALIDDATA;
8357  }
8358 
8359  if (mov->decryption_key) {
8360  return cenc_decrypt(mov, sc, encrypted_sample, pkt->data, pkt->size);
8361  } else {
8362  size_t size;
8363  uint8_t *side_data = av_encryption_info_add_side_data(encrypted_sample, &size);
8364  if (!side_data)
8365  return AVERROR(ENOMEM);
8367  if (ret < 0)
8368  av_free(side_data);
8369  return ret;
8370  }
8371  }
8372 
8373  return 0;
8374 }
8375 
8377 {
8378  const int OPUS_SEEK_PREROLL_MS = 80;
8379  int ret;
8380  AVStream *st;
8381  size_t size;
8382  uint16_t pre_skip;
8383 
8384  if (c->fc->nb_streams < 1)
8385  return 0;
8386  st = c->fc->streams[c->fc->nb_streams-1];
8387 
8388  if ((uint64_t)atom.size > (1<<30) || atom.size < 11)
8389  return AVERROR_INVALIDDATA;
8390 
8391  /* Check OpusSpecificBox version. */
8392  if (avio_r8(pb) != 0) {
8393  av_log(c->fc, AV_LOG_ERROR, "unsupported OpusSpecificBox version\n");
8394  return AVERROR_INVALIDDATA;
8395  }
8396 
8397  /* OpusSpecificBox size plus magic for Ogg OpusHead header. */
8398  size = atom.size + 8;
8399 
8400  if ((ret = ff_alloc_extradata(st->codecpar, size)) < 0)
8401  return ret;
8402 
8403  AV_WL32A(st->codecpar->extradata, MKTAG('O','p','u','s'));
8404  AV_WL32A(st->codecpar->extradata + 4, MKTAG('H','e','a','d'));
8405  AV_WB8(st->codecpar->extradata + 8, 1); /* OpusHead version */
8406  avio_read(pb, st->codecpar->extradata + 9, size - 9);
8407 
8408  /* OpusSpecificBox is stored in big-endian, but OpusHead is
8409  little-endian; aside from the preceeding magic and version they're
8410  otherwise currently identical. Data after output gain at offset 16
8411  doesn't need to be bytewapped. */
8412  pre_skip = AV_RB16A(st->codecpar->extradata + 10);
8413  AV_WL16A(st->codecpar->extradata + 10, pre_skip);
8414  AV_WL32A(st->codecpar->extradata + 12, AV_RB32A(st->codecpar->extradata + 12));
8415  AV_WL16A(st->codecpar->extradata + 16, AV_RB16A(st->codecpar->extradata + 16));
8416 
8417  st->codecpar->initial_padding = pre_skip;
8419  (AVRational){1, 1000},
8420  (AVRational){1, 48000});
8421 
8422  return 0;
8423 }
8424 
8426 {
8427  AVStream *st;
8428  unsigned format_info;
8429  int channel_assignment, channel_assignment1, channel_assignment2;
8430  int ratebits;
8431  uint64_t chmask;
8432 
8433  if (c->fc->nb_streams < 1)
8434  return 0;
8435  st = c->fc->streams[c->fc->nb_streams-1];
8436 
8437  if (atom.size < 10)
8438  return AVERROR_INVALIDDATA;
8439 
8440  format_info = avio_rb32(pb);
8441 
8442  ratebits = (format_info >> 28) & 0xF;
8443  channel_assignment1 = (format_info >> 15) & 0x1F;
8444  channel_assignment2 = format_info & 0x1FFF;
8445  if (channel_assignment2)
8446  channel_assignment = channel_assignment2;
8447  else
8448  channel_assignment = channel_assignment1;
8449 
8450  st->codecpar->frame_size = 40 << (ratebits & 0x7);
8451  st->codecpar->sample_rate = mlp_samplerate(ratebits);
8452 
8454  chmask = truehd_layout(channel_assignment);
8456 
8457  return 0;
8458 }
8459 
8461 {
8462  AVStream *st;
8463  uint8_t buf[ISOM_DVCC_DVVC_SIZE];
8464  int ret;
8465  int64_t read_size = atom.size;
8466 
8467  if (c->fc->nb_streams < 1)
8468  return 0;
8469  st = c->fc->streams[c->fc->nb_streams-1];
8470 
8471  // At most 24 bytes
8472  read_size = FFMIN(read_size, ISOM_DVCC_DVVC_SIZE);
8473 
8474  if ((ret = ffio_read_size(pb, buf, read_size)) < 0)
8475  return ret;
8476 
8477  return ff_isom_parse_dvcc_dvvc(c->fc, st, buf, read_size);
8478 }
8479 
8481 {
8482  AVStream *st;
8483  uint8_t *buf;
8484  int ret, old_size, num_arrays;
8485 
8486  if (c->fc->nb_streams < 1)
8487  return 0;
8488  st = c->fc->streams[c->fc->nb_streams-1];
8489 
8490  if (!st->codecpar->extradata_size)
8491  // TODO: handle lhvC when present before hvcC
8492  return 0;
8493 
8494  if (atom.size < 6 || st->codecpar->extradata_size < 23)
8495  return AVERROR_INVALIDDATA;
8496 
8498  if (!buf)
8499  return AVERROR(ENOMEM);
8500  memset(buf + atom.size, 0, AV_INPUT_BUFFER_PADDING_SIZE);
8501 
8502  ret = ffio_read_size(pb, buf, atom.size);
8503  if (ret < 0) {
8504  av_free(buf);
8505  av_log(c->fc, AV_LOG_WARNING, "lhvC atom truncated\n");
8506  return 0;
8507  }
8508 
8509  num_arrays = buf[5];
8510  old_size = st->codecpar->extradata_size;
8511  atom.size -= 8 /* account for mov_realloc_extradata offseting */
8512  + 6 /* lhvC bytes before the arrays*/;
8513 
8514  ret = mov_realloc_extradata(st->codecpar, atom);
8515  if (ret < 0) {
8516  av_free(buf);
8517  return ret;
8518  }
8519 
8520  st->codecpar->extradata[22] += num_arrays;
8521  memcpy(st->codecpar->extradata + old_size, buf + 6, atom.size + 8);
8522 
8524 
8525  av_free(buf);
8526  return 0;
8527 }
8528 
8530 {
8531  AVFormatContext *ctx = c->fc;
8532  AVStream *st = NULL;
8533  AVBPrint scheme_buf, value_buf;
8534  int64_t scheme_str_len = 0, value_str_len = 0;
8535  int version, flags, ret = AVERROR_BUG;
8536  int64_t size = atom.size;
8537 
8538  if (atom.size < 6)
8539  // 4 bytes for version + flags, 2x 1 byte for null
8540  return AVERROR_INVALIDDATA;
8541 
8542  if (c->fc->nb_streams < 1)
8543  return 0;
8544  st = c->fc->streams[c->fc->nb_streams-1];
8545 
8546  version = avio_r8(pb);
8547  flags = avio_rb24(pb);
8548  size -= 4;
8549 
8550  if (version != 0 || flags != 0) {
8552  "Unsupported 'kind' box with version %d, flags: %x",
8553  version, flags);
8554  return AVERROR_INVALIDDATA;
8555  }
8556 
8557  av_bprint_init(&scheme_buf, 0, AV_BPRINT_SIZE_UNLIMITED);
8558  av_bprint_init(&value_buf, 0, AV_BPRINT_SIZE_UNLIMITED);
8559 
8560  if ((scheme_str_len = ff_read_string_to_bprint_overwrite(pb, &scheme_buf,
8561  size)) < 0) {
8562  ret = scheme_str_len;
8563  goto cleanup;
8564  }
8565 
8566  if (scheme_str_len + 1 >= size) {
8567  // we need to have another string, even if nullptr.
8568  // we check with + 1 since we expect that if size was not hit,
8569  // an additional null was read.
8571  goto cleanup;
8572  }
8573 
8574  size -= scheme_str_len + 1;
8575 
8576  if ((value_str_len = ff_read_string_to_bprint_overwrite(pb, &value_buf,
8577  size)) < 0) {
8578  ret = value_str_len;
8579  goto cleanup;
8580  }
8581 
8582  if (value_str_len == size) {
8583  // in case of no trailing null, box is not valid.
8585  goto cleanup;
8586  }
8587 
8589  "%s stream %d KindBox(scheme: %s, value: %s)\n",
8591  st->index,
8592  scheme_buf.str, value_buf.str);
8593 
8594  for (int i = 0; ff_mov_track_kind_table[i].scheme_uri; i++) {
8596  if (!av_strstart(scheme_buf.str, map.scheme_uri, NULL))
8597  continue;
8598 
8599  for (int j = 0; map.value_maps[j].disposition; j++) {
8600  const struct MP4TrackKindValueMapping value_map = map.value_maps[j];
8601  if (!av_strstart(value_buf.str, value_map.value, NULL))
8602  continue;
8603 
8604  st->disposition |= value_map.disposition;
8605  }
8606  }
8607 
8608  ret = 0;
8609 
8610 cleanup:
8611 
8612  av_bprint_finalize(&scheme_buf, NULL);
8613  av_bprint_finalize(&value_buf, NULL);
8614 
8615  return ret;
8616 }
8617 
8619 {
8620  AVStream *st;
8621  AVChannelLayout ch_layout = { 0 };
8622  int ret, i, version, type;
8623  int ambisonic_order, channel_order, normalization, channel_count;
8624  int ambi_channels, non_diegetic_channels;
8625 
8626  if (c->fc->nb_streams < 1)
8627  return 0;
8628 
8629  st = c->fc->streams[c->fc->nb_streams - 1];
8630 
8631  if (atom.size < 16) {
8632  av_log(c->fc, AV_LOG_ERROR, "SA3D audio box too small\n");
8633  return AVERROR_INVALIDDATA;
8634  }
8635 
8636  version = avio_r8(pb);
8637  if (version) {
8638  av_log(c->fc, AV_LOG_WARNING, "Unsupported SA3D box version %d\n", version);
8639  return 0;
8640  }
8641 
8642  type = avio_r8(pb);
8643  if (type & 0x7f) {
8644  av_log(c->fc, AV_LOG_WARNING,
8645  "Unsupported ambisonic type %d\n", type & 0x7f);
8646  return 0;
8647  }
8648  non_diegetic_channels = (type >> 7) * 2; // head_locked_stereo
8649 
8650  ambisonic_order = avio_rb32(pb);
8651 
8652  channel_order = avio_r8(pb);
8653  if (channel_order) {
8654  av_log(c->fc, AV_LOG_WARNING,
8655  "Unsupported channel_order %d\n", channel_order);
8656  return 0;
8657  }
8658 
8659  normalization = avio_r8(pb);
8660  if (normalization) {
8661  av_log(c->fc, AV_LOG_WARNING,
8662  "Unsupported normalization %d\n", normalization);
8663  return 0;
8664  }
8665 
8666  channel_count = avio_rb32(pb);
8667  if (ambisonic_order < 0 || ambisonic_order > 31 ||
8668  channel_count != ((ambisonic_order + 1LL) * (ambisonic_order + 1LL) +
8669  non_diegetic_channels)) {
8670  av_log(c->fc, AV_LOG_ERROR,
8671  "Invalid number of channels (%d / %d)\n",
8672  channel_count, ambisonic_order);
8673  return 0;
8674  }
8675  ambi_channels = channel_count - non_diegetic_channels;
8676 
8677  ret = av_channel_layout_custom_init(&ch_layout, channel_count);
8678  if (ret < 0)
8679  return 0;
8680 
8681  for (i = 0; i < channel_count; i++) {
8682  unsigned channel = avio_rb32(pb);
8683 
8684  if (channel >= channel_count) {
8685  av_log(c->fc, AV_LOG_ERROR, "Invalid channel index (%d / %d)\n",
8686  channel, ambisonic_order);
8687  av_channel_layout_uninit(&ch_layout);
8688  return 0;
8689  }
8690  if (channel >= ambi_channels)
8691  ch_layout.u.map[i].id = channel - ambi_channels;
8692  else
8693  ch_layout.u.map[i].id = AV_CHAN_AMBISONIC_BASE + channel;
8694  }
8695 
8697  if (ret < 0) {
8698  av_channel_layout_uninit(&ch_layout);
8699  return 0;
8700  }
8701 
8703  st->codecpar->ch_layout = ch_layout;
8704 
8705  return 0;
8706 }
8707 
8709 {
8710  AVStream *st;
8711  int version;
8712 
8713  if (c->fc->nb_streams < 1)
8714  return 0;
8715 
8716  st = c->fc->streams[c->fc->nb_streams - 1];
8717 
8718  if (atom.size < 5) {
8719  av_log(c->fc, AV_LOG_ERROR, "Empty SAND audio box\n");
8720  return AVERROR_INVALIDDATA;
8721  }
8722 
8723  version = avio_r8(pb);
8724  if (version) {
8725  av_log(c->fc, AV_LOG_WARNING, "Unsupported SAND box version %d\n", version);
8726  return 0;
8727  }
8728 
8730 
8731  return 0;
8732 }
8733 
8734 static int rb_size(AVIOContext *pb, int64_t *value, int size)
8735 {
8736  if (size == 0)
8737  *value = 0;
8738  else if (size == 1)
8739  *value = avio_r8(pb);
8740  else if (size == 2)
8741  *value = avio_rb16(pb);
8742  else if (size == 4)
8743  *value = avio_rb32(pb);
8744  else if (size == 8) {
8745  *value = avio_rb64(pb);
8746  if (*value < 0)
8747  return -1;
8748  } else
8749  return -1;
8750  return size;
8751 }
8752 
8754 {
8755  avio_rb32(pb); // version & flags.
8756  c->primary_item_id = avio_rb16(pb);
8757  av_log(c->fc, AV_LOG_TRACE, "pitm: primary_item_id %d\n", c->primary_item_id);
8758  return atom.size;
8759 }
8760 
8762 {
8763  c->idat_offset = avio_tell(pb);
8764  return 0;
8765 }
8766 
8768 {
8769  HEIFItem **heif_item;
8770  int version, offset_size, length_size, base_offset_size, index_size;
8771  int item_count, extent_count;
8772  int64_t base_offset, extent_offset, extent_length;
8773  uint8_t value;
8774 
8775  if (c->found_iloc) {
8776  av_log(c->fc, AV_LOG_INFO, "Duplicate iloc box found\n");
8777  return 0;
8778  }
8779 
8780  version = avio_r8(pb);
8781  avio_rb24(pb); // flags.
8782 
8783  value = avio_r8(pb);
8784  offset_size = (value >> 4) & 0xF;
8785  length_size = value & 0xF;
8786  value = avio_r8(pb);
8787  base_offset_size = (value >> 4) & 0xF;
8788  index_size = !version ? 0 : (value & 0xF);
8789  if (index_size) {
8790  avpriv_report_missing_feature(c->fc, "iloc: index_size != 0");
8791  return AVERROR_PATCHWELCOME;
8792  }
8793  item_count = (version < 2) ? avio_rb16(pb) : avio_rb32(pb);
8794 
8795  heif_item = av_realloc_array(c->heif_item, FFMAX(item_count, c->nb_heif_item), sizeof(*c->heif_item));
8796  if (!heif_item)
8797  return AVERROR(ENOMEM);
8798  c->heif_item = heif_item;
8799  if (item_count > c->nb_heif_item)
8800  memset(&c->heif_item[c->nb_heif_item], 0,
8801  sizeof(*c->heif_item) * (item_count - c->nb_heif_item));
8802  c->nb_heif_item = FFMAX(c->nb_heif_item, item_count);
8803 
8804  av_log(c->fc, AV_LOG_TRACE, "iloc: item_count %d\n", item_count);
8805  for (int i = 0; i < item_count; i++) {
8806  HEIFItem *item = c->heif_item[i];
8807  int item_id = (version < 2) ? avio_rb16(pb) : avio_rb32(pb);
8808  int offset_type = (version > 0) ? avio_rb16(pb) & 0xf : 0;
8809 
8810  if (avio_feof(pb))
8811  return AVERROR_INVALIDDATA;
8812  if (offset_type > 1) {
8813  avpriv_report_missing_feature(c->fc, "iloc offset type %d", offset_type);
8814  return AVERROR_PATCHWELCOME;
8815  }
8816 
8817  avio_rb16(pb); // data_reference_index.
8818  if (rb_size(pb, &base_offset, base_offset_size) < 0)
8819  return AVERROR_INVALIDDATA;
8820  extent_count = avio_rb16(pb);
8821  if (extent_count > 1) {
8822  // For still AVIF images, we only support one extent item.
8823  avpriv_report_missing_feature(c->fc, "iloc: extent_count > 1");
8824  return AVERROR_PATCHWELCOME;
8825  }
8826 
8827  if (rb_size(pb, &extent_offset, offset_size) < 0 ||
8828  rb_size(pb, &extent_length, length_size) < 0 ||
8829  base_offset > INT64_MAX - extent_offset)
8830  return AVERROR_INVALIDDATA;
8831 
8832  if (!item)
8833  item = c->heif_item[i] = av_mallocz(sizeof(*item));
8834  if (!item)
8835  return AVERROR(ENOMEM);
8836 
8837  item->item_id = item_id;
8838 
8839  if (offset_type == 1)
8840  item->is_idat_relative = 1;
8841  item->extent_length = extent_length;
8842  item->extent_offset = base_offset + extent_offset;
8843  av_log(c->fc, AV_LOG_TRACE, "iloc: item_idx %d, offset_type %d, "
8844  "extent_offset %"PRId64", extent_length %"PRId64"\n",
8845  i, offset_type, item->extent_offset, item->extent_length);
8846  }
8847 
8848  c->found_iloc = 1;
8849  return atom.size;
8850 }
8851 
8852 static int mov_read_infe(MOVContext *c, AVIOContext *pb, MOVAtom atom, int idx)
8853 {
8854  HEIFItem *item;
8855  AVBPrint item_name;
8856  int64_t size = atom.size;
8857  uint32_t item_type;
8858  int item_id;
8859  int version, ret;
8860 
8861  version = avio_r8(pb);
8862  avio_rb24(pb); // flags.
8863  size -= 4;
8864  if (size < 0)
8865  return AVERROR_INVALIDDATA;
8866 
8867  if (version < 2) {
8868  avpriv_report_missing_feature(c->fc, "infe version < 2");
8869  avio_skip(pb, size);
8870  return 1;
8871  }
8872 
8873  item_id = version > 2 ? avio_rb32(pb) : avio_rb16(pb);
8874  avio_rb16(pb); // item_protection_index
8875  item_type = avio_rl32(pb);
8876  size -= 8;
8877  if (size < 1)
8878  return AVERROR_INVALIDDATA;
8879 
8882  if (ret < 0) {
8884  return ret;
8885  }
8886 
8887  av_log(c->fc, AV_LOG_TRACE, "infe: item_id %d, item_type %s, item_name %s\n",
8888  item_id, av_fourcc2str(item_type), item_name.str);
8889 
8890  size -= ret + 1;
8891  if (size > 0)
8892  avio_skip(pb, size);
8893 
8894  item = c->heif_item[idx];
8895  if (!item)
8896  item = c->heif_item[idx] = av_mallocz(sizeof(*item));
8897  if (!item)
8898  return AVERROR(ENOMEM);
8899 
8900  if (ret)
8901  av_bprint_finalize(&item_name, &c->heif_item[idx]->name);
8902  c->heif_item[idx]->item_id = item_id;
8903  c->heif_item[idx]->type = item_type;
8904 
8905  switch (item_type) {
8906  case MKTAG('a','v','0','1'):
8907  case MKTAG('h','v','c','1'):
8908  ret = heif_add_stream(c, c->heif_item[idx]);
8909  if (ret < 0)
8910  return ret;
8911  break;
8912  }
8913 
8914  return 0;
8915 }
8916 
8918 {
8919  HEIFItem **heif_item;
8920  int entry_count;
8921  int version, got_stream = 0, ret, i;
8922 
8923  if (c->found_iinf) {
8924  av_log(c->fc, AV_LOG_WARNING, "Duplicate iinf box found\n");
8925  return 0;
8926  }
8927 
8928  version = avio_r8(pb);
8929  avio_rb24(pb); // flags.
8930  entry_count = version ? avio_rb32(pb) : avio_rb16(pb);
8931 
8932  heif_item = av_realloc_array(c->heif_item, FFMAX(entry_count, c->nb_heif_item), sizeof(*c->heif_item));
8933  if (!heif_item)
8934  return AVERROR(ENOMEM);
8935  c->heif_item = heif_item;
8936  if (entry_count > c->nb_heif_item)
8937  memset(&c->heif_item[c->nb_heif_item], 0,
8938  sizeof(*c->heif_item) * (entry_count - c->nb_heif_item));
8939  c->nb_heif_item = FFMAX(c->nb_heif_item, entry_count);
8940 
8941  for (i = 0; i < entry_count; i++) {
8942  MOVAtom infe;
8943 
8944  if (avio_feof(pb)) {
8946  goto fail;
8947  }
8948  infe.size = avio_rb32(pb) - 8;
8949  infe.type = avio_rl32(pb);
8950  ret = mov_read_infe(c, pb, infe, i);
8951  if (ret < 0)
8952  goto fail;
8953  if (!ret)
8954  got_stream = 1;
8955  }
8956 
8957  c->found_iinf = got_stream;
8958  return 0;
8959 fail:
8960  for (; i >= 0; i--) {
8961  HEIFItem *item = c->heif_item[i];
8962 
8963  if (!item)
8964  continue;
8965 
8966  av_freep(&item->name);
8967  if (!item->st)
8968  continue;
8969 
8970  mov_free_stream_context(c->fc, item->st);
8971  ff_remove_stream(c->fc, item->st);
8972  item->st = NULL;
8973  }
8974  return ret;
8975 }
8976 
8978 {
8979  HEIFItem *item = NULL;
8980  HEIFGrid *grid;
8981  int entries, i;
8982  int from_item_id = version ? avio_rb32(pb) : avio_rb16(pb);
8983 
8984  for (int i = 0; i < c->nb_heif_grid; i++) {
8985  if (c->heif_grid[i].item->item_id == from_item_id) {
8986  av_log(c->fc, AV_LOG_ERROR, "More than one 'dimg' box "
8987  "referencing the same Derived Image item\n");
8988  return AVERROR_INVALIDDATA;
8989  }
8990  }
8991  for (int i = 0; i < c->nb_heif_item; i++) {
8992  if (!c->heif_item[i] || c->heif_item[i]->item_id != from_item_id)
8993  continue;
8994  item = c->heif_item[i];
8995 
8996  switch (item->type) {
8997  case MKTAG('g','r','i','d'):
8998  case MKTAG('i','o','v','l'):
8999  break;
9000  default:
9001  avpriv_report_missing_feature(c->fc, "Derived Image item of type %s",
9002  av_fourcc2str(item->type));
9003  return 0;
9004  }
9005  break;
9006  }
9007  if (!item) {
9008  av_log(c->fc, AV_LOG_ERROR, "Missing grid information\n");
9009  return AVERROR_INVALIDDATA;
9010  }
9011 
9012  grid = av_realloc_array(c->heif_grid, c->nb_heif_grid + 1U,
9013  sizeof(*c->heif_grid));
9014  if (!grid)
9015  return AVERROR(ENOMEM);
9016  c->heif_grid = grid;
9017  grid = &grid[c->nb_heif_grid++];
9018 
9019  entries = avio_rb16(pb);
9020  grid->tile_id_list = av_malloc_array(entries, sizeof(*grid->tile_id_list));
9021  grid->tile_item_list = av_calloc(entries, sizeof(*grid->tile_item_list));
9022  if (!grid->tile_id_list || !grid->tile_item_list)
9023  return AVERROR(ENOMEM);
9024  /* 'to' item ids */
9025  for (i = 0; i < entries; i++)
9026  grid->tile_id_list[i] = version ? avio_rb32(pb) : avio_rb16(pb);
9027  grid->nb_tiles = entries;
9028  grid->item = item;
9029 
9030  av_log(c->fc, AV_LOG_TRACE, "dimg: from_item_id %d, entries %d\n",
9031  from_item_id, entries);
9032 
9033  return 0;
9034 }
9035 
9037 {
9038  int entries;
9039  int to_item_id, from_item_id = version ? avio_rb32(pb) : avio_rb16(pb);
9040 
9041  entries = avio_rb16(pb);
9042  if (entries > 1) {
9043  avpriv_request_sample(c->fc, "thmb in iref referencing several items");
9044  return AVERROR_PATCHWELCOME;
9045  }
9046  /* 'to' item ids */
9047  to_item_id = version ? avio_rb32(pb) : avio_rb16(pb);
9048 
9049  if (to_item_id != c->primary_item_id)
9050  return 0;
9051 
9052  c->thmb_item_id = from_item_id;
9053 
9054  av_log(c->fc, AV_LOG_TRACE, "thmb: from_item_id %d, entries %d\n",
9055  from_item_id, entries);
9056 
9057  return 0;
9058 }
9059 
9061 {
9062  int version = avio_r8(pb);
9063  avio_rb24(pb); // flags
9064  atom.size -= 4;
9065 
9066  if (version > 1) {
9067  av_log(c->fc, AV_LOG_WARNING, "Unknown iref box version %d\n", version);
9068  return 0;
9069  }
9070 
9071  while (atom.size) {
9072  uint32_t type, size = avio_rb32(pb);
9073  int64_t next = avio_tell(pb);
9074 
9075  if (size < 14 || next < 0 || next > INT64_MAX - size)
9076  return AVERROR_INVALIDDATA;
9077 
9078  next += size - 4;
9079  type = avio_rl32(pb);
9080  switch (type) {
9081  case MKTAG('d','i','m','g'):
9083  break;
9084  case MKTAG('t','h','m','b'):
9086  break;
9087  default:
9088  av_log(c->fc, AV_LOG_DEBUG, "Unknown iref type %s size %"PRIu32"\n",
9089  av_fourcc2str(type), size);
9090  }
9091 
9092  atom.size -= size;
9093  avio_seek(pb, next, SEEK_SET);
9094  }
9095  return 0;
9096 }
9097 
9099 {
9100  HEIFItem *item;
9101  uint32_t width, height;
9102 
9103  avio_r8(pb); /* version */
9104  avio_rb24(pb); /* flags */
9105  width = avio_rb32(pb);
9106  height = avio_rb32(pb);
9107 
9108  av_log(c->fc, AV_LOG_TRACE, "ispe: item_id %d, width %u, height %u\n",
9109  c->cur_item_id, width, height);
9110 
9111  item = heif_cur_item(c);
9112  if (item) {
9113  item->width = width;
9114  item->height = height;
9115  }
9116 
9117  return 0;
9118 }
9119 
9121 {
9122  HEIFItem *item;
9123  int angle;
9124 
9125  angle = avio_r8(pb) & 0x3;
9126 
9127  av_log(c->fc, AV_LOG_TRACE, "irot: item_id %d, angle %u\n",
9128  c->cur_item_id, angle);
9129 
9130  item = heif_cur_item(c);
9131  if (item) {
9132  // angle * 90 specifies the angle (in anti-clockwise direction)
9133  // in units of degrees.
9134  item->rotation = angle * 90;
9135  }
9136 
9137  return 0;
9138 }
9139 
9141 {
9142  HEIFItem *item;
9143  int axis;
9144 
9145  axis = avio_r8(pb) & 0x1;
9146 
9147  av_log(c->fc, AV_LOG_TRACE, "imir: item_id %d, axis %u\n",
9148  c->cur_item_id, axis);
9149 
9150  item = heif_cur_item(c);
9151  if (item) {
9152  item->hflip = axis;
9153  item->vflip = !axis;
9154  }
9155 
9156  return 0;
9157 }
9158 
9160 {
9161  typedef struct MOVAtoms {
9162  FFIOContext b;
9163  uint32_t type;
9164  int64_t size;
9165  uint8_t *data;
9166  } MOVAtoms;
9167  MOVAtoms *atoms = NULL;
9168  MOVAtom a;
9169  unsigned count;
9170  int nb_atoms = 0;
9171  int version, flags;
9172  int ret;
9173 
9174  a.size = avio_rb32(pb);
9175  a.type = avio_rl32(pb);
9176 
9177  if (a.size < 8 || a.type != MKTAG('i','p','c','o'))
9178  return AVERROR_INVALIDDATA;
9179 
9180  a.size -= 8;
9181  while (a.size >= 8) {
9182  MOVAtoms *ref = av_dynarray2_add((void**)&atoms, &nb_atoms, sizeof(MOVAtoms), NULL);
9183  if (!ref) {
9184  ret = AVERROR(ENOMEM);
9185  goto fail;
9186  }
9187  ref->data = NULL;
9188  ref->size = avio_rb32(pb);
9189  ref->type = avio_rl32(pb);
9190  if (ref->size > a.size || ref->size < 8)
9191  break;
9192  ref->data = av_malloc(ref->size);
9193  if (!ref->data) {
9195  goto fail;
9196  }
9197  av_log(c->fc, AV_LOG_TRACE, "ipco: index %d, box type %s\n", nb_atoms, av_fourcc2str(ref->type));
9198  avio_seek(pb, -8, SEEK_CUR);
9199  if (avio_read(pb, ref->data, ref->size) != ref->size) {
9201  goto fail;
9202  }
9203  ffio_init_read_context(&ref->b, ref->data, ref->size);
9204  a.size -= ref->size;
9205  }
9206 
9207  if (a.size) {
9209  goto fail;
9210  }
9211 
9212  a.size = avio_rb32(pb);
9213  a.type = avio_rl32(pb);
9214 
9215  if (a.size < 8 || a.type != MKTAG('i','p','m','a')) {
9217  goto fail;
9218  }
9219 
9220  version = avio_r8(pb);
9221  flags = avio_rb24(pb);
9222  count = avio_rb32(pb);
9223 
9224  for (int i = 0; i < count; i++) {
9225  int item_id = version ? avio_rb32(pb) : avio_rb16(pb);
9226  int assoc_count = avio_r8(pb);
9227 
9228  if (avio_feof(pb)) {
9230  goto fail;
9231  }
9232 
9233  for (int j = 0; j < assoc_count; j++) {
9234  MOVAtoms *ref;
9235  int index = avio_r8(pb) & 0x7f;
9236  if (flags & 1) {
9237  index <<= 8;
9238  index |= avio_r8(pb);
9239  }
9240  if (index > nb_atoms || index <= 0) {
9242  goto fail;
9243  }
9244  ref = &atoms[--index];
9245 
9246  av_log(c->fc, AV_LOG_TRACE, "ipma: property_index %d, item_id %d, item_type %s\n",
9247  index + 1, item_id, av_fourcc2str(ref->type));
9248 
9249  c->cur_item_id = item_id;
9250 
9251  ret = mov_read_default(c, &ref->b.pub,
9252  (MOVAtom) { .size = ref->size,
9253  .type = MKTAG('i','p','c','o') });
9254  if (ret < 0)
9255  goto fail;
9256  ffio_init_read_context(&ref->b, ref->data, ref->size);
9257  }
9258  }
9259 
9260  ret = 0;
9261 fail:
9262  c->cur_item_id = -1;
9263  for (int i = 0; i < nb_atoms; i++)
9264  av_free(atoms[i].data);
9265  av_free(atoms);
9266 
9267  return ret;
9268 }
9269 
9271 { MKTAG('A','C','L','R'), mov_read_aclr },
9272 { MKTAG('A','P','R','G'), mov_read_avid },
9273 { MKTAG('A','A','L','P'), mov_read_avid },
9274 { MKTAG('A','R','E','S'), mov_read_ares },
9275 { MKTAG('a','v','s','s'), mov_read_avss },
9276 { MKTAG('a','v','1','C'), mov_read_glbl },
9277 { MKTAG('c','h','p','l'), mov_read_chpl },
9278 { MKTAG('c','o','6','4'), mov_read_stco },
9279 { MKTAG('c','o','l','r'), mov_read_colr },
9280 { MKTAG('c','t','t','s'), mov_read_ctts }, /* composition time to sample */
9281 { MKTAG('d','i','n','f'), mov_read_default },
9282 { MKTAG('D','p','x','E'), mov_read_dpxe },
9283 { MKTAG('d','r','e','f'), mov_read_dref },
9284 { MKTAG('e','d','t','s'), mov_read_default },
9285 { MKTAG('e','l','s','t'), mov_read_elst },
9286 { MKTAG('e','n','d','a'), mov_read_enda },
9287 { MKTAG('f','i','e','l'), mov_read_fiel },
9288 { MKTAG('a','d','r','m'), mov_read_adrm },
9289 { MKTAG('f','t','y','p'), mov_read_ftyp },
9290 { MKTAG('g','l','b','l'), mov_read_glbl },
9291 { MKTAG('h','d','l','r'), mov_read_hdlr },
9292 { MKTAG('i','l','s','t'), mov_read_ilst },
9293 { MKTAG('j','p','2','h'), mov_read_jp2h },
9294 { MKTAG('m','d','a','t'), mov_read_mdat },
9295 { MKTAG('m','d','h','d'), mov_read_mdhd },
9296 { MKTAG('m','d','i','a'), mov_read_default },
9297 { MKTAG('m','e','t','a'), mov_read_meta },
9298 { MKTAG('m','i','n','f'), mov_read_default },
9299 { MKTAG('m','o','o','f'), mov_read_moof },
9300 { MKTAG('m','o','o','v'), mov_read_moov },
9301 { MKTAG('m','v','e','x'), mov_read_default },
9302 { MKTAG('m','v','h','d'), mov_read_mvhd },
9303 { MKTAG('S','M','I',' '), mov_read_svq3 },
9304 { MKTAG('a','l','a','c'), mov_read_alac }, /* alac specific atom */
9305 { MKTAG('a','v','c','C'), mov_read_glbl },
9306 { MKTAG('p','a','s','p'), mov_read_pasp },
9307 { MKTAG('c','l','a','p'), mov_read_clap },
9308 { MKTAG('s','b','a','s'), mov_read_sbas },
9309 { MKTAG('s','i','d','x'), mov_read_sidx },
9310 { MKTAG('s','t','b','l'), mov_read_default },
9311 { MKTAG('s','t','c','o'), mov_read_stco },
9312 { MKTAG('s','t','p','s'), mov_read_stps },
9313 { MKTAG('s','t','r','f'), mov_read_strf },
9314 { MKTAG('s','t','s','c'), mov_read_stsc },
9315 { MKTAG('s','t','s','d'), mov_read_stsd }, /* sample description */
9316 { MKTAG('s','t','s','s'), mov_read_stss }, /* sync sample */
9317 { MKTAG('s','t','s','z'), mov_read_stsz }, /* sample size */
9318 { MKTAG('s','t','t','s'), mov_read_stts },
9319 { MKTAG('s','t','z','2'), mov_read_stsz }, /* compact sample size */
9320 { MKTAG('s','d','t','p'), mov_read_sdtp }, /* independent and disposable samples */
9321 { MKTAG('t','k','h','d'), mov_read_tkhd }, /* track header */
9322 { MKTAG('t','f','d','t'), mov_read_tfdt },
9323 { MKTAG('t','f','h','d'), mov_read_tfhd }, /* track fragment header */
9324 { MKTAG('t','r','a','k'), mov_read_trak },
9325 { MKTAG('t','r','a','f'), mov_read_default },
9326 { MKTAG('t','r','e','f'), mov_read_default },
9327 { MKTAG('t','m','c','d'), mov_read_tmcd },
9328 { MKTAG('c','h','a','p'), mov_read_chap },
9329 { MKTAG('t','r','e','x'), mov_read_trex },
9330 { MKTAG('t','r','u','n'), mov_read_trun },
9331 { MKTAG('u','d','t','a'), mov_read_default },
9332 { MKTAG('w','a','v','e'), mov_read_wave },
9333 { MKTAG('e','s','d','s'), mov_read_esds },
9334 { MKTAG('d','a','c','3'), mov_read_dac3 }, /* AC-3 info */
9335 { MKTAG('d','e','c','3'), mov_read_dec3 }, /* EAC-3 info */
9336 { MKTAG('d','d','t','s'), mov_read_ddts }, /* DTS audio descriptor */
9337 { MKTAG('w','i','d','e'), mov_read_wide }, /* place holder */
9338 { MKTAG('w','f','e','x'), mov_read_wfex },
9339 { MKTAG('c','m','o','v'), mov_read_cmov },
9340 { MKTAG('c','h','a','n'), mov_read_chan }, /* channel layout from quicktime */
9341 { MKTAG('c','h','n','l'), mov_read_chnl }, /* channel layout from ISO-14496-12 */
9342 { MKTAG('d','v','c','1'), mov_read_dvc1 },
9343 { MKTAG('s','g','p','d'), mov_read_sgpd },
9344 { MKTAG('s','b','g','p'), mov_read_sbgp },
9345 { MKTAG('h','v','c','C'), mov_read_glbl },
9346 { MKTAG('v','v','c','C'), mov_read_glbl },
9347 { MKTAG('u','u','i','d'), mov_read_uuid },
9348 { MKTAG('C','i','n', 0x8e), mov_read_targa_y216 },
9349 { MKTAG('f','r','e','e'), mov_read_free },
9350 { MKTAG('-','-','-','-'), mov_read_custom },
9351 { MKTAG('s','i','n','f'), mov_read_default },
9352 { MKTAG('f','r','m','a'), mov_read_frma },
9353 { MKTAG('s','e','n','c'), mov_read_senc },
9354 { MKTAG('s','a','i','z'), mov_read_saiz },
9355 { MKTAG('s','a','i','o'), mov_read_saio },
9356 { MKTAG('p','s','s','h'), mov_read_pssh },
9357 { MKTAG('s','c','h','m'), mov_read_schm },
9358 { MKTAG('s','c','h','i'), mov_read_default },
9359 { MKTAG('t','e','n','c'), mov_read_tenc },
9360 { MKTAG('d','f','L','a'), mov_read_dfla },
9361 { MKTAG('s','t','3','d'), mov_read_st3d }, /* stereoscopic 3D video box */
9362 { MKTAG('s','v','3','d'), mov_read_sv3d }, /* spherical video box */
9363 { MKTAG('v','e','x','u'), mov_read_vexu }, /* video extension usage */
9364 { MKTAG('h','f','o','v'), mov_read_hfov },
9365 { MKTAG('d','O','p','s'), mov_read_dops },
9366 { MKTAG('d','m','l','p'), mov_read_dmlp },
9367 { MKTAG('S','m','D','m'), mov_read_smdm },
9368 { MKTAG('C','o','L','L'), mov_read_coll },
9369 { MKTAG('v','p','c','C'), mov_read_vpcc },
9370 { MKTAG('m','d','c','v'), mov_read_mdcv },
9371 { MKTAG('c','l','l','i'), mov_read_clli },
9372 { MKTAG('d','v','c','C'), mov_read_dvcc_dvvc },
9373 { MKTAG('d','v','v','C'), mov_read_dvcc_dvvc },
9374 { MKTAG('d','v','w','C'), mov_read_dvcc_dvvc },
9375 { MKTAG('k','i','n','d'), mov_read_kind },
9376 { MKTAG('S','A','3','D'), mov_read_SA3D }, /* ambisonic audio box */
9377 { MKTAG('S','A','N','D'), mov_read_SAND }, /* non diegetic audio box */
9378 { MKTAG('i','l','o','c'), mov_read_iloc },
9379 { MKTAG('p','c','m','C'), mov_read_pcmc }, /* PCM configuration box */
9380 { MKTAG('p','i','t','m'), mov_read_pitm },
9381 { MKTAG('e','v','c','C'), mov_read_glbl },
9382 { MKTAG('i','d','a','t'), mov_read_idat },
9383 { MKTAG('i','m','i','r'), mov_read_imir },
9384 { MKTAG('i','r','e','f'), mov_read_iref },
9385 { MKTAG('i','s','p','e'), mov_read_ispe },
9386 { MKTAG('i','r','o','t'), mov_read_irot },
9387 { MKTAG('i','p','r','p'), mov_read_iprp },
9388 { MKTAG('i','i','n','f'), mov_read_iinf },
9389 { MKTAG('a','m','v','e'), mov_read_amve }, /* ambient viewing environment box */
9390 { MKTAG('l','h','v','C'), mov_read_lhvc },
9391 { MKTAG('l','v','c','C'), mov_read_glbl },
9392 #if CONFIG_IAMFDEC
9393 { MKTAG('i','a','c','b'), mov_read_iacb },
9394 #endif
9395 { 0, NULL }
9396 };
9397 
9399 {
9400  int64_t total_size = 0;
9401  MOVAtom a;
9402  int i;
9403 
9404  if (c->atom_depth > 10) {
9405  av_log(c->fc, AV_LOG_ERROR, "Atoms too deeply nested\n");
9406  return AVERROR_INVALIDDATA;
9407  }
9408  c->atom_depth ++;
9409 
9410  if (atom.size < 0)
9411  atom.size = INT64_MAX;
9412  while (total_size <= atom.size - 8) {
9413  int (*parse)(MOVContext*, AVIOContext*, MOVAtom) = NULL;
9414  a.size = avio_rb32(pb);
9415  a.type = avio_rl32(pb);
9416  if (avio_feof(pb))
9417  break;
9418  if (((a.type == MKTAG('f','r','e','e') && c->moov_retry) ||
9419  a.type == MKTAG('h','o','o','v')) &&
9420  a.size >= 8 &&
9421  c->fc->strict_std_compliance < FF_COMPLIANCE_STRICT) {
9422  uint32_t type;
9423  avio_skip(pb, 4);
9424  type = avio_rl32(pb);
9425  if (avio_feof(pb))
9426  break;
9427  avio_seek(pb, -8, SEEK_CUR);
9428  if (type == MKTAG('m','v','h','d') ||
9429  type == MKTAG('c','m','o','v')) {
9430  av_log(c->fc, AV_LOG_ERROR, "Detected moov in a free or hoov atom.\n");
9431  a.type = MKTAG('m','o','o','v');
9432  }
9433  }
9434  if (atom.type != MKTAG('r','o','o','t') &&
9435  atom.type != MKTAG('m','o','o','v')) {
9436  if (a.type == MKTAG('t','r','a','k') ||
9437  a.type == MKTAG('m','d','a','t')) {
9438  av_log(c->fc, AV_LOG_ERROR, "Broken file, trak/mdat not at top-level\n");
9439  avio_skip(pb, -8);
9440  c->atom_depth --;
9441  return 0;
9442  }
9443  }
9444  total_size += 8;
9445  if (a.size == 1 && total_size + 8 <= atom.size) { /* 64 bit extended size */
9446  a.size = avio_rb64(pb) - 8;
9447  total_size += 8;
9448  }
9449  av_log(c->fc, AV_LOG_TRACE, "type:'%s' parent:'%s' sz: %"PRId64" %"PRId64" %"PRId64"\n",
9450  av_fourcc2str(a.type), av_fourcc2str(atom.type), a.size, total_size, atom.size);
9451  if (a.size == 0) {
9452  a.size = atom.size - total_size + 8;
9453  }
9454  if (a.size < 0)
9455  break;
9456  a.size -= 8;
9457  if (a.size < 0)
9458  break;
9459  a.size = FFMIN(a.size, atom.size - total_size);
9460 
9461  for (i = 0; mov_default_parse_table[i].type; i++)
9462  if (mov_default_parse_table[i].type == a.type) {
9464  break;
9465  }
9466 
9467  // container is user data
9468  if (!parse && (atom.type == MKTAG('u','d','t','a') ||
9469  atom.type == MKTAG('i','l','s','t')))
9471 
9472  // Supports parsing the QuickTime Metadata Keys.
9473  // https://developer.apple.com/library/mac/documentation/QuickTime/QTFF/Metadata/Metadata.html
9474  if (!parse && c->found_hdlr_mdta &&
9475  atom.type == MKTAG('m','e','t','a') &&
9476  a.type == MKTAG('k','e','y','s') &&
9477  c->meta_keys_count == 0) {
9478  parse = mov_read_keys;
9479  }
9480 
9481  if (!parse) { /* skip leaf atoms data */
9482  avio_skip(pb, a.size);
9483  } else {
9484  int64_t start_pos = avio_tell(pb);
9485  int64_t left;
9486  int err = parse(c, pb, a);
9487  if (err < 0) {
9488  c->atom_depth --;
9489  return err;
9490  }
9491  if (c->found_moov && c->found_mdat && a.size <= INT64_MAX - start_pos &&
9492  ((!(pb->seekable & AVIO_SEEKABLE_NORMAL) || c->fc->flags & AVFMT_FLAG_IGNIDX || c->frag_index.complete) ||
9493  start_pos + a.size == avio_size(pb))) {
9494  if (!(pb->seekable & AVIO_SEEKABLE_NORMAL) || c->fc->flags & AVFMT_FLAG_IGNIDX || c->frag_index.complete)
9495  c->next_root_atom = start_pos + a.size;
9496  c->atom_depth --;
9497  return 0;
9498  }
9499  left = a.size - avio_tell(pb) + start_pos;
9500  if (left > 0) /* skip garbage at atom end */
9501  avio_skip(pb, left);
9502  else if (left < 0) {
9503  av_log(c->fc, AV_LOG_WARNING,
9504  "overread end of atom '%s' by %"PRId64" bytes\n",
9505  av_fourcc2str(a.type), -left);
9506  avio_seek(pb, left, SEEK_CUR);
9507  }
9508  }
9509 
9510  total_size += a.size;
9511  }
9512 
9513  if (total_size < atom.size && atom.size < 0x7ffff)
9514  avio_skip(pb, atom.size - total_size);
9515 
9516  c->atom_depth --;
9517  return 0;
9518 }
9519 
9520 static int mov_probe(const AVProbeData *p)
9521 {
9522  int64_t offset;
9523  uint32_t tag;
9524  int score = 0;
9525  int moov_offset = -1;
9526 
9527  /* check file header */
9528  offset = 0;
9529  for (;;) {
9530  int64_t size;
9531  int minsize = 8;
9532  /* ignore invalid offset */
9533  if ((offset + 8ULL) > (unsigned int)p->buf_size)
9534  break;
9535  size = AV_RB32(p->buf + offset);
9536  if (size == 1 && offset + 16 <= (unsigned int)p->buf_size) {
9537  size = AV_RB64(p->buf+offset + 8);
9538  minsize = 16;
9539  } else if (size == 0) {
9540  size = p->buf_size - offset;
9541  }
9542  if (size < minsize) {
9543  offset += 4;
9544  continue;
9545  }
9546  tag = AV_RL32(p->buf + offset + 4);
9547  switch(tag) {
9548  /* check for obvious tags */
9549  case MKTAG('m','o','o','v'):
9550  moov_offset = offset + 4;
9551  case MKTAG('m','d','a','t'):
9552  case MKTAG('p','n','o','t'): /* detect movs with preview pics like ew.mov and april.mov */
9553  case MKTAG('u','d','t','a'): /* Packet Video PVAuthor adds this and a lot of more junk */
9554  case MKTAG('f','t','y','p'):
9555  if (tag == MKTAG('f','t','y','p') &&
9556  ( AV_RL32(p->buf + offset + 8) == MKTAG('j','p','2',' ')
9557  || AV_RL32(p->buf + offset + 8) == MKTAG('j','p','x',' ')
9558  || AV_RL32(p->buf + offset + 8) == MKTAG('j','x','l',' ')
9559  )) {
9560  score = FFMAX(score, 5);
9561  } else {
9562  score = AVPROBE_SCORE_MAX;
9563  }
9564  break;
9565  /* those are more common words, so rate then a bit less */
9566  case MKTAG('e','d','i','w'): /* xdcam files have reverted first tags */
9567  case MKTAG('w','i','d','e'):
9568  case MKTAG('f','r','e','e'):
9569  case MKTAG('j','u','n','k'):
9570  case MKTAG('p','i','c','t'):
9571  score = FFMAX(score, AVPROBE_SCORE_MAX - 5);
9572  break;
9573  case MKTAG(0x82,0x82,0x7f,0x7d):
9574  score = FFMAX(score, AVPROBE_SCORE_EXTENSION - 5);
9575  break;
9576  case MKTAG('s','k','i','p'):
9577  case MKTAG('u','u','i','d'):
9578  case MKTAG('p','r','f','l'):
9579  /* if we only find those cause probedata is too small at least rate them */
9580  score = FFMAX(score, AVPROBE_SCORE_EXTENSION);
9581  break;
9582  }
9583  if (size > INT64_MAX - offset)
9584  break;
9585  offset += size;
9586  }
9587  if (score > AVPROBE_SCORE_MAX - 50 && moov_offset != -1) {
9588  /* moov atom in the header - we should make sure that this is not a
9589  * MOV-packed MPEG-PS */
9590  offset = moov_offset;
9591 
9592  while (offset < (p->buf_size - 16)) { /* Sufficient space */
9593  /* We found an actual hdlr atom */
9594  if (AV_RL32(p->buf + offset ) == MKTAG('h','d','l','r') &&
9595  AV_RL32(p->buf + offset + 8) == MKTAG('m','h','l','r') &&
9596  AV_RL32(p->buf + offset + 12) == MKTAG('M','P','E','G')) {
9597  av_log(NULL, AV_LOG_WARNING, "Found media data tag MPEG indicating this is a MOV-packed MPEG-PS.\n");
9598  /* We found a media handler reference atom describing an
9599  * MPEG-PS-in-MOV, return a
9600  * low score to force expanding the probe window until
9601  * mpegps_probe finds what it needs */
9602  return 5;
9603  } else {
9604  /* Keep looking */
9605  offset += 2;
9606  }
9607  }
9608  }
9609 
9610  return score;
9611 }
9612 
9613 // must be done after parsing all trak because there's no order requirement
9615 {
9616  MOVContext *mov = s->priv_data;
9617  MOVStreamContext *sc;
9618  int64_t cur_pos;
9619  int i, j;
9620  int chapter_track;
9621 
9622  for (j = 0; j < mov->nb_chapter_tracks; j++) {
9623  AVStream *st = NULL;
9624  FFStream *sti = NULL;
9625  chapter_track = mov->chapter_tracks[j];
9626  for (i = 0; i < s->nb_streams; i++) {
9627  sc = mov->fc->streams[i]->priv_data;
9628  if (sc->id == chapter_track) {
9629  st = s->streams[i];
9630  break;
9631  }
9632  }
9633  if (!st) {
9634  av_log(s, AV_LOG_ERROR, "Referenced QT chapter track not found\n");
9635  continue;
9636  }
9637  sti = ffstream(st);
9638 
9639  sc = st->priv_data;
9640  cur_pos = avio_tell(sc->pb);
9641 
9642  if (st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO) {
9644  if (!st->attached_pic.data && sti->nb_index_entries) {
9645  // Retrieve the first frame, if possible
9646  AVIndexEntry *sample = &sti->index_entries[0];
9647  if (avio_seek(sc->pb, sample->pos, SEEK_SET) != sample->pos) {
9648  av_log(s, AV_LOG_ERROR, "Failed to retrieve first frame\n");
9649  goto finish;
9650  }
9651 
9652  if (ff_add_attached_pic(s, st, sc->pb, NULL, sample->size) < 0)
9653  goto finish;
9654  }
9655  } else {
9658  st->discard = AVDISCARD_ALL;
9659  for (int i = 0; i < sti->nb_index_entries; i++) {
9660  AVIndexEntry *sample = &sti->index_entries[i];
9661  int64_t end = i+1 < sti->nb_index_entries ? sti->index_entries[i+1].timestamp : st->duration;
9662  uint8_t *title;
9663  uint16_t ch;
9664  int len, title_len;
9665 
9666  if (end < sample->timestamp) {
9667  av_log(s, AV_LOG_WARNING, "ignoring stream duration which is shorter than chapters\n");
9668  end = AV_NOPTS_VALUE;
9669  }
9670 
9671  if (avio_seek(sc->pb, sample->pos, SEEK_SET) != sample->pos) {
9672  av_log(s, AV_LOG_ERROR, "Chapter %d not found in file\n", i);
9673  goto finish;
9674  }
9675 
9676  // the first two bytes are the length of the title
9677  len = avio_rb16(sc->pb);
9678  if (len > sample->size-2)
9679  continue;
9680  title_len = 2*len + 1;
9681  if (!(title = av_mallocz(title_len)))
9682  goto finish;
9683 
9684  // The samples could theoretically be in any encoding if there's an encd
9685  // atom following, but in practice are only utf-8 or utf-16, distinguished
9686  // instead by the presence of a BOM
9687  if (!len) {
9688  title[0] = 0;
9689  } else {
9690  ch = avio_rb16(sc->pb);
9691  if (ch == 0xfeff)
9692  avio_get_str16be(sc->pb, len, title, title_len);
9693  else if (ch == 0xfffe)
9694  avio_get_str16le(sc->pb, len, title, title_len);
9695  else {
9696  AV_WB16(title, ch);
9697  if (len == 1 || len == 2)
9698  title[len] = 0;
9699  else
9700  avio_get_str(sc->pb, INT_MAX, title + 2, len - 1);
9701  }
9702  }
9703 
9704  avpriv_new_chapter(s, i, st->time_base, sample->timestamp, end, title);
9705  av_freep(&title);
9706  }
9707  }
9708 finish:
9709  avio_seek(sc->pb, cur_pos, SEEK_SET);
9710  }
9711 }
9712 
9714  int64_t value, int flags)
9715 {
9716  AVTimecode tc;
9717  char buf[AV_TIMECODE_STR_SIZE];
9718  AVRational rate = st->avg_frame_rate;
9719  int ret = av_timecode_init(&tc, rate, flags, 0, s);
9720  if (ret < 0)
9721  return ret;
9722  av_dict_set(&st->metadata, "timecode",
9723  av_timecode_make_string(&tc, buf, value), 0);
9724  return 0;
9725 }
9726 
9728 {
9729  MOVStreamContext *sc = st->priv_data;
9730  FFStream *const sti = ffstream(st);
9731  char buf[AV_TIMECODE_STR_SIZE];
9732  int64_t cur_pos = avio_tell(sc->pb);
9733  int hh, mm, ss, ff, drop;
9734 
9735  if (!sti->nb_index_entries)
9736  return -1;
9737 
9738  avio_seek(sc->pb, sti->index_entries->pos, SEEK_SET);
9739  avio_skip(s->pb, 13);
9740  hh = avio_r8(s->pb);
9741  mm = avio_r8(s->pb);
9742  ss = avio_r8(s->pb);
9743  drop = avio_r8(s->pb);
9744  ff = avio_r8(s->pb);
9745  snprintf(buf, AV_TIMECODE_STR_SIZE, "%02d:%02d:%02d%c%02d",
9746  hh, mm, ss, drop ? ';' : ':', ff);
9747  av_dict_set(&st->metadata, "timecode", buf, 0);
9748 
9749  avio_seek(sc->pb, cur_pos, SEEK_SET);
9750  return 0;
9751 }
9752 
9754 {
9755  MOVStreamContext *sc = st->priv_data;
9756  FFStream *const sti = ffstream(st);
9757  int flags = 0;
9758  int64_t cur_pos = avio_tell(sc->pb);
9759  int64_t value;
9760  AVRational tc_rate = st->avg_frame_rate;
9761  int tmcd_nb_frames = sc->tmcd_nb_frames;
9762  int rounded_tc_rate;
9763 
9764  if (!sti->nb_index_entries)
9765  return -1;
9766 
9767  if (!tc_rate.num || !tc_rate.den || !tmcd_nb_frames)
9768  return -1;
9769 
9770  avio_seek(sc->pb, sti->index_entries->pos, SEEK_SET);
9771  value = avio_rb32(s->pb);
9772 
9773  if (sc->tmcd_flags & 0x0001) flags |= AV_TIMECODE_FLAG_DROPFRAME;
9774  if (sc->tmcd_flags & 0x0002) flags |= AV_TIMECODE_FLAG_24HOURSMAX;
9775  if (sc->tmcd_flags & 0x0004) flags |= AV_TIMECODE_FLAG_ALLOWNEGATIVE;
9776 
9777  /* Assume Counter flag is set to 1 in tmcd track (even though it is likely
9778  * not the case) and thus assume "frame number format" instead of QT one.
9779  * No sample with tmcd track can be found with a QT timecode at the moment,
9780  * despite what the tmcd track "suggests" (Counter flag set to 0 means QT
9781  * format). */
9782 
9783  /* 60 fps content have tmcd_nb_frames set to 30 but tc_rate set to 60, so
9784  * we multiply the frame number with the quotient.
9785  * See tickets #9492, #9710. */
9786  rounded_tc_rate = (tc_rate.num + tc_rate.den / 2LL) / tc_rate.den;
9787  /* Work around files where tmcd_nb_frames is rounded down from frame rate
9788  * instead of up. See ticket #5978. */
9789  if (tmcd_nb_frames == tc_rate.num / tc_rate.den &&
9790  s->strict_std_compliance < FF_COMPLIANCE_STRICT)
9791  tmcd_nb_frames = rounded_tc_rate;
9792  value = av_rescale(value, rounded_tc_rate, tmcd_nb_frames);
9793 
9795 
9796  avio_seek(sc->pb, cur_pos, SEEK_SET);
9797  return 0;
9798 }
9799 
9801  int i;
9802  if (!index || !*index) return;
9803  for (i = 0; i < (*index)->nb_encrypted_samples; i++) {
9804  av_encryption_info_free((*index)->encrypted_samples[i]);
9805  }
9806  av_freep(&(*index)->encrypted_samples);
9807  av_freep(&(*index)->auxiliary_info_sizes);
9808  av_freep(&(*index)->auxiliary_offsets);
9809  av_freep(index);
9810 }
9811 
9813 {
9814  MOVStreamContext *sc = st->priv_data;
9815 
9816  if (!sc || --sc->refcount) {
9817  st->priv_data = NULL;
9818  return;
9819  }
9820 
9821  av_freep(&sc->ctts_data);
9822  for (int i = 0; i < sc->drefs_count; i++) {
9823  av_freep(&sc->drefs[i].path);
9824  av_freep(&sc->drefs[i].dir);
9825  }
9826  av_freep(&sc->drefs);
9827 
9828  sc->drefs_count = 0;
9829 
9830  if (!sc->pb_is_copied)
9831  ff_format_io_close(s, &sc->pb);
9832 
9833  sc->pb = NULL;
9834  av_freep(&sc->chunk_offsets);
9835  av_freep(&sc->stsc_data);
9836  av_freep(&sc->sample_sizes);
9837  av_freep(&sc->keyframes);
9838  av_freep(&sc->stts_data);
9839  av_freep(&sc->sdtp_data);
9840  av_freep(&sc->stps_data);
9841  av_freep(&sc->elst_data);
9842  av_freep(&sc->rap_group);
9843  av_freep(&sc->sync_group);
9844  av_freep(&sc->sgpd_sync);
9845  av_freep(&sc->sample_offsets);
9846  av_freep(&sc->open_key_samples);
9847  av_freep(&sc->display_matrix);
9848  av_freep(&sc->index_ranges);
9849 
9850  if (sc->extradata)
9851  for (int i = 0; i < sc->stsd_count; i++)
9852  av_free(sc->extradata[i]);
9853  av_freep(&sc->extradata);
9854  av_freep(&sc->extradata_size);
9855 
9859 
9860  av_freep(&sc->stereo3d);
9861  av_freep(&sc->spherical);
9862  av_freep(&sc->mastering);
9863  av_freep(&sc->coll);
9864  av_freep(&sc->ambient);
9865 
9866 #if CONFIG_IAMFDEC
9867  if (sc->iamf)
9869 #endif
9870  av_freep(&sc->iamf);
9871 }
9872 
9874 {
9875  MOVContext *mov = s->priv_data;
9876  int i, j;
9877 
9878  for (i = 0; i < s->nb_streams; i++) {
9879  AVStream *st = s->streams[i];
9880 
9882  }
9883 
9884  av_freep(&mov->dv_demux);
9886  mov->dv_fctx = NULL;
9887 
9888  if (mov->meta_keys) {
9889  for (i = 1; i < mov->meta_keys_count; i++) {
9890  av_freep(&mov->meta_keys[i]);
9891  }
9892  av_freep(&mov->meta_keys);
9893  }
9894 
9895  av_freep(&mov->trex_data);
9896  av_freep(&mov->bitrates);
9897 
9898  for (i = 0; i < mov->frag_index.nb_items; i++) {
9900  for (j = 0; j < mov->frag_index.item[i].nb_stream_info; j++) {
9901  mov_free_encryption_index(&frag[j].encryption_index);
9902  }
9904  }
9905  av_freep(&mov->frag_index.item);
9906 
9907  av_freep(&mov->aes_decrypt);
9908  av_freep(&mov->chapter_tracks);
9909  for (i = 0; i < mov->nb_heif_item; i++) {
9910  if (!mov->heif_item[i])
9911  continue;
9912  av_freep(&mov->heif_item[i]->name);
9913  av_freep(&mov->heif_item[i]->icc_profile);
9914  av_freep(&mov->heif_item[i]);
9915  }
9916  av_freep(&mov->heif_item);
9917  for (i = 0; i < mov->nb_heif_grid; i++) {
9918  av_freep(&mov->heif_grid[i].tile_id_list);
9920  }
9921  av_freep(&mov->heif_grid);
9922 
9923  return 0;
9924 }
9925 
9926 static int tmcd_is_referenced(AVFormatContext *s, int tmcd_id)
9927 {
9928  int i;
9929 
9930  for (i = 0; i < s->nb_streams; i++) {
9931  AVStream *st = s->streams[i];
9932  MOVStreamContext *sc = st->priv_data;
9933 
9934  if (st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO &&
9935  sc->timecode_track == tmcd_id)
9936  return 1;
9937  }
9938  return 0;
9939 }
9940 
9941 /* look for a tmcd track not referenced by any video track, and export it globally */
9943 {
9944  int i;
9945 
9946  for (i = 0; i < s->nb_streams; i++) {
9947  AVStream *st = s->streams[i];
9948 
9949  if (st->codecpar->codec_tag == MKTAG('t','m','c','d') &&
9950  !tmcd_is_referenced(s, i + 1)) {
9951  AVDictionaryEntry *tcr = av_dict_get(st->metadata, "timecode", NULL, 0);
9952  if (tcr) {
9953  av_dict_set(&s->metadata, "timecode", tcr->value, 0);
9954  break;
9955  }
9956  }
9957  }
9958 }
9959 
9960 static int read_tfra(MOVContext *mov, AVIOContext *f)
9961 {
9962  int version, fieldlength, i, j;
9963  int64_t pos = avio_tell(f);
9964  uint32_t size = avio_rb32(f);
9965  unsigned track_id, item_count;
9966 
9967  if (avio_rb32(f) != MKBETAG('t', 'f', 'r', 'a')) {
9968  return 1;
9969  }
9970  av_log(mov->fc, AV_LOG_VERBOSE, "found tfra\n");
9971 
9972  version = avio_r8(f);
9973  avio_rb24(f);
9974  track_id = avio_rb32(f);
9975  fieldlength = avio_rb32(f);
9976  item_count = avio_rb32(f);
9977  for (i = 0; i < item_count; i++) {
9978  int64_t time, offset;
9979  int index;
9980  MOVFragmentStreamInfo * frag_stream_info;
9981 
9982  if (avio_feof(f)) {
9983  return AVERROR_INVALIDDATA;
9984  }
9985 
9986  if (version == 1) {
9987  time = avio_rb64(f);
9988  offset = avio_rb64(f);
9989  } else {
9990  time = avio_rb32(f);
9991  offset = avio_rb32(f);
9992  }
9993 
9994  // The first sample of each stream in a fragment is always a random
9995  // access sample. So it's entry in the tfra can be used as the
9996  // initial PTS of the fragment.
9997  index = update_frag_index(mov, offset);
9998  frag_stream_info = get_frag_stream_info(&mov->frag_index, index, track_id);
9999  if (frag_stream_info &&
10000  frag_stream_info->first_tfra_pts == AV_NOPTS_VALUE)
10001  frag_stream_info->first_tfra_pts = time;
10002 
10003  for (j = 0; j < ((fieldlength >> 4) & 3) + 1; j++)
10004  avio_r8(f);
10005  for (j = 0; j < ((fieldlength >> 2) & 3) + 1; j++)
10006  avio_r8(f);
10007  for (j = 0; j < ((fieldlength >> 0) & 3) + 1; j++)
10008  avio_r8(f);
10009  }
10010 
10011  avio_seek(f, pos + size, SEEK_SET);
10012  return 0;
10013 }
10014 
10016 {
10017  int64_t stream_size = avio_size(f);
10018  int64_t original_pos = avio_tell(f);
10019  int64_t seek_ret;
10020  int ret = -1;
10021  if ((seek_ret = avio_seek(f, stream_size - 4, SEEK_SET)) < 0) {
10022  ret = seek_ret;
10023  goto fail;
10024  }
10025  c->mfra_size = avio_rb32(f);
10026  c->have_read_mfra_size = 1;
10027  if (!c->mfra_size || c->mfra_size > stream_size) {
10028  av_log(c->fc, AV_LOG_DEBUG, "doesn't look like mfra (unreasonable size)\n");
10029  goto fail;
10030  }
10031  if ((seek_ret = avio_seek(f, -((int64_t) c->mfra_size), SEEK_CUR)) < 0) {
10032  ret = seek_ret;
10033  goto fail;
10034  }
10035  if (avio_rb32(f) != c->mfra_size) {
10036  av_log(c->fc, AV_LOG_DEBUG, "doesn't look like mfra (size mismatch)\n");
10037  goto fail;
10038  }
10039  if (avio_rb32(f) != MKBETAG('m', 'f', 'r', 'a')) {
10040  av_log(c->fc, AV_LOG_DEBUG, "doesn't look like mfra (tag mismatch)\n");
10041  goto fail;
10042  }
10043  av_log(c->fc, AV_LOG_VERBOSE, "stream has mfra\n");
10044  do {
10045  ret = read_tfra(c, f);
10046  if (ret < 0)
10047  goto fail;
10048  } while (!ret);
10049  ret = 0;
10050  c->frag_index.complete = 1;
10051 fail:
10052  seek_ret = avio_seek(f, original_pos, SEEK_SET);
10053  if (seek_ret < 0) {
10054  av_log(c->fc, AV_LOG_ERROR,
10055  "failed to seek back after looking for mfra\n");
10056  ret = seek_ret;
10057  }
10058  return ret;
10059 }
10060 
10061 static int set_icc_profile_from_item(AVPacketSideData **coded_side_data, int *nb_coded_side_data,
10062  const HEIFItem *item)
10063 {
10064  AVPacketSideData *sd = av_packet_side_data_new(coded_side_data, nb_coded_side_data,
10066  item->icc_profile_size, 0);
10067  if (!sd)
10068  return AVERROR(ENOMEM);
10069 
10070  memcpy(sd->data, item->icc_profile, item->icc_profile_size);
10071 
10072  return 0;
10073 }
10074 
10075 static int set_display_matrix_from_item(AVPacketSideData **coded_side_data, int *nb_coded_side_data,
10076  const HEIFItem *item)
10077 {
10078  int32_t *matrix;
10079  AVPacketSideData *sd = av_packet_side_data_new(coded_side_data,
10080  nb_coded_side_data,
10082  9 * sizeof(*matrix), 0);
10083  if (!sd)
10084  return AVERROR(ENOMEM);
10085 
10086  matrix = (int32_t*)sd->data;
10087  /* rotation is in the counter-clockwise direction whereas
10088  * av_display_rotation_set() expects its argument to be
10089  * oriented clockwise, so we need to negate it. */
10091  av_display_matrix_flip(matrix, item->hflip, item->vflip);
10092 
10093  return 0;
10094 }
10095 
10096 static int read_image_grid(AVFormatContext *s, const HEIFGrid *grid,
10097  AVStreamGroupTileGrid *tile_grid)
10098 {
10099  MOVContext *c = s->priv_data;
10100  const HEIFItem *item = grid->item;
10101  int64_t offset = 0, pos = avio_tell(s->pb);
10102  int x = 0, y = 0, i = 0;
10103  int tile_rows, tile_cols;
10104  int flags, size;
10105 
10106  if (!(s->pb->seekable & AVIO_SEEKABLE_NORMAL)) {
10107  av_log(c->fc, AV_LOG_INFO, "grid box with non seekable input\n");
10108  return AVERROR_PATCHWELCOME;
10109  }
10110  if (item->is_idat_relative) {
10111  if (!c->idat_offset) {
10112  av_log(c->fc, AV_LOG_ERROR, "missing idat box required by the image grid\n");
10113  return AVERROR_INVALIDDATA;
10114  }
10115  offset = c->idat_offset;
10116  }
10117 
10118  avio_seek(s->pb, item->extent_offset + offset, SEEK_SET);
10119 
10120  avio_r8(s->pb); /* version */
10121  flags = avio_r8(s->pb);
10122 
10123  tile_rows = avio_r8(s->pb) + 1;
10124  tile_cols = avio_r8(s->pb) + 1;
10125  /* actual width and height of output image */
10126  tile_grid->width = (flags & 1) ? avio_rb32(s->pb) : avio_rb16(s->pb);
10127  tile_grid->height = (flags & 1) ? avio_rb32(s->pb) : avio_rb16(s->pb);
10128 
10129  /* ICC profile */
10130  if (item->icc_profile_size) {
10131  int ret = set_icc_profile_from_item(&tile_grid->coded_side_data,
10132  &tile_grid->nb_coded_side_data, item);
10133  if (ret < 0)
10134  return ret;
10135  }
10136  /* rotation */
10137  if (item->rotation || item->hflip || item->vflip) {
10139  &tile_grid->nb_coded_side_data, item);
10140  if (ret < 0)
10141  return ret;
10142  }
10143 
10144  av_log(c->fc, AV_LOG_TRACE, "grid: grid_rows %d grid_cols %d output_width %d output_height %d\n",
10145  tile_rows, tile_cols, tile_grid->width, tile_grid->height);
10146 
10147  avio_seek(s->pb, pos, SEEK_SET);
10148 
10149  size = tile_rows * tile_cols;
10150  tile_grid->nb_tiles = grid->nb_tiles;
10151 
10152  if (tile_grid->nb_tiles != size)
10153  return AVERROR_INVALIDDATA;
10154 
10155  for (int i = 0; i < tile_cols; i++)
10156  tile_grid->coded_width += grid->tile_item_list[i]->width;
10157  for (int i = 0; i < size; i += tile_cols)
10158  tile_grid->coded_height += grid->tile_item_list[i]->height;
10159 
10160  tile_grid->offsets = av_calloc(tile_grid->nb_tiles, sizeof(*tile_grid->offsets));
10161  if (!tile_grid->offsets)
10162  return AVERROR(ENOMEM);
10163 
10164  while (y < tile_grid->coded_height) {
10165  int left_col = i;
10166 
10167  while (x < tile_grid->coded_width) {
10168  if (i == tile_grid->nb_tiles)
10169  return AVERROR_INVALIDDATA;
10170 
10171  tile_grid->offsets[i].idx = i;
10172  tile_grid->offsets[i].horizontal = x;
10173  tile_grid->offsets[i].vertical = y;
10174 
10175  x += grid->tile_item_list[i++]->width;
10176  }
10177 
10178  if (x > tile_grid->coded_width) {
10179  av_log(c->fc, AV_LOG_ERROR, "Non uniform HEIF tiles\n");
10180  return AVERROR_INVALIDDATA;
10181  }
10182 
10183  x = 0;
10184  y += grid->tile_item_list[left_col]->height;
10185  }
10186 
10187  if (y > tile_grid->coded_height || i != tile_grid->nb_tiles) {
10188  av_log(c->fc, AV_LOG_ERROR, "Non uniform HEIF tiles\n");
10189  return AVERROR_INVALIDDATA;
10190  }
10191 
10192  return 0;
10193 }
10194 
10195 static int read_image_iovl(AVFormatContext *s, const HEIFGrid *grid,
10196  AVStreamGroupTileGrid *tile_grid)
10197 {
10198  MOVContext *c = s->priv_data;
10199  const HEIFItem *item = grid->item;
10200  uint16_t canvas_fill_value[4];
10201  int64_t offset = 0, pos = avio_tell(s->pb);
10202  int ret = 0, flags;
10203 
10204  if (!(s->pb->seekable & AVIO_SEEKABLE_NORMAL)) {
10205  av_log(c->fc, AV_LOG_INFO, "iovl box with non seekable input\n");
10206  return AVERROR_PATCHWELCOME;
10207  }
10208  if (item->is_idat_relative) {
10209  if (!c->idat_offset) {
10210  av_log(c->fc, AV_LOG_ERROR, "missing idat box required by the image overlay\n");
10211  return AVERROR_INVALIDDATA;
10212  }
10213  offset = c->idat_offset;
10214  }
10215 
10216  avio_seek(s->pb, item->extent_offset + offset, SEEK_SET);
10217 
10218  avio_r8(s->pb); /* version */
10219  flags = avio_r8(s->pb);
10220 
10221  for (int i = 0; i < 4; i++)
10222  canvas_fill_value[i] = avio_rb16(s->pb);
10223  av_log(c->fc, AV_LOG_TRACE, "iovl: canvas_fill_value { %u, %u, %u, %u }\n",
10224  canvas_fill_value[0], canvas_fill_value[1],
10225  canvas_fill_value[2], canvas_fill_value[3]);
10226  for (int i = 0; i < 4; i++)
10227  tile_grid->background[i] = canvas_fill_value[i];
10228 
10229  /* actual width and height of output image */
10230  tile_grid->width =
10231  tile_grid->coded_width = (flags & 1) ? avio_rb32(s->pb) : avio_rb16(s->pb);
10232  tile_grid->height =
10233  tile_grid->coded_height = (flags & 1) ? avio_rb32(s->pb) : avio_rb16(s->pb);
10234 
10235  /* rotation */
10236  if (item->rotation || item->hflip || item->vflip) {
10238  &tile_grid->nb_coded_side_data, item);
10239  if (ret < 0)
10240  return ret;
10241  }
10242 
10243  /* ICC profile */
10244  if (item->icc_profile_size) {
10245  int ret = set_icc_profile_from_item(&tile_grid->coded_side_data,
10246  &tile_grid->nb_coded_side_data, item);
10247  if (ret < 0)
10248  return ret;
10249  }
10250 
10251  av_log(c->fc, AV_LOG_TRACE, "iovl: output_width %d, output_height %d\n",
10252  tile_grid->width, tile_grid->height);
10253 
10254  tile_grid->nb_tiles = grid->nb_tiles;
10255  tile_grid->offsets = av_malloc_array(tile_grid->nb_tiles, sizeof(*tile_grid->offsets));
10256  if (!tile_grid->offsets) {
10257  ret = AVERROR(ENOMEM);
10258  goto fail;
10259  }
10260 
10261  for (int i = 0; i < tile_grid->nb_tiles; i++) {
10262  tile_grid->offsets[i].idx = grid->tile_item_list[i]->st->index;
10263  tile_grid->offsets[i].horizontal = (flags & 1) ? avio_rb32(s->pb) : avio_rb16(s->pb);
10264  tile_grid->offsets[i].vertical = (flags & 1) ? avio_rb32(s->pb) : avio_rb16(s->pb);
10265  av_log(c->fc, AV_LOG_TRACE, "iovl: stream_idx[%d] %u, "
10266  "horizontal_offset[%d] %d, vertical_offset[%d] %d\n",
10267  i, tile_grid->offsets[i].idx,
10268  i, tile_grid->offsets[i].horizontal, i, tile_grid->offsets[i].vertical);
10269  }
10270 
10271 fail:
10272  avio_seek(s->pb, pos, SEEK_SET);
10273 
10274  return ret;
10275 }
10276 
10278 {
10279  MOVContext *mov = s->priv_data;
10280 
10281  for (int i = 0; i < mov->nb_heif_grid; i++) {
10283  AVStreamGroupTileGrid *tile_grid;
10284  const HEIFGrid *grid = &mov->heif_grid[i];
10285  int err, loop = 1;
10286 
10287  if (!stg)
10288  return AVERROR(ENOMEM);
10289 
10290  stg->id = grid->item->item_id;
10291  tile_grid = stg->params.tile_grid;
10292 
10293  for (int j = 0; j < grid->nb_tiles; j++) {
10294  int tile_id = grid->tile_id_list[j];
10295  int k;
10296 
10297  for (k = 0; k < mov->nb_heif_item; k++) {
10298  HEIFItem *item = mov->heif_item[k];
10299  AVStream *st = item->st;
10300 
10301  if (!item || item->item_id != tile_id)
10302  continue;
10303  if (!st) {
10304  av_log(s, AV_LOG_WARNING, "HEIF item id %d from grid id %d doesn't "
10305  "reference a stream\n",
10306  tile_id, grid->item->item_id);
10307  ff_remove_stream_group(s, stg);
10308  loop = 0;
10309  break;
10310  }
10311 
10312  grid->tile_item_list[j] = item;
10313 
10314  err = avformat_stream_group_add_stream(stg, st);
10315  if (err < 0 && err != AVERROR(EEXIST))
10316  return err;
10317 
10318  if (item->item_id != mov->primary_item_id)
10320  break;
10321  }
10322 
10323  if (k == mov->nb_heif_item) {
10324  av_assert0(loop);
10325  av_log(s, AV_LOG_WARNING, "HEIF item id %d referenced by grid id %d doesn't "
10326  "exist\n",
10327  tile_id, grid->item->item_id);
10328  ff_remove_stream_group(s, stg);
10329  loop = 0;
10330  }
10331  if (!loop)
10332  break;
10333  }
10334 
10335  if (!loop)
10336  continue;
10337 
10338  switch (grid->item->type) {
10339  case MKTAG('g','r','i','d'):
10340  err = read_image_grid(s, grid, tile_grid);
10341  break;
10342  case MKTAG('i','o','v','l'):
10343  err = read_image_iovl(s, grid, tile_grid);
10344  break;
10345  default:
10346  av_assert0(0);
10347  }
10348  if (err < 0)
10349  return err;
10350 
10351 
10352  if (grid->item->name)
10353  av_dict_set(&stg->metadata, "title", grid->item->name, 0);
10354  if (grid->item->item_id == mov->primary_item_id)
10356  }
10357 
10358  return 0;
10359 }
10360 
10362 {
10363  MOVContext *mov = s->priv_data;
10364  int err;
10365 
10366  for (int i = 0; i < mov->nb_heif_item; i++) {
10367  HEIFItem *item = mov->heif_item[i];
10368  MOVStreamContext *sc;
10369  AVStream *st;
10370  int64_t offset = 0;
10371 
10372  if (!item)
10373  continue;
10374  if (!item->st) {
10375  if (item->item_id == mov->thmb_item_id) {
10376  av_log(s, AV_LOG_ERROR, "HEIF thumbnail doesn't reference a stream\n");
10377  return AVERROR_INVALIDDATA;
10378  }
10379  continue;
10380  }
10381  if (item->is_idat_relative) {
10382  if (!mov->idat_offset) {
10383  av_log(s, AV_LOG_ERROR, "Missing idat box for item %d\n", item->item_id);
10384  return AVERROR_INVALIDDATA;
10385  }
10386  offset = mov->idat_offset;
10387  }
10388 
10389  st = item->st;
10390  sc = st->priv_data;
10391  st->codecpar->width = item->width;
10392  st->codecpar->height = item->height;
10393 
10394  if (sc->sample_count != 1 || sc->chunk_count != 1)
10395  return AVERROR_INVALIDDATA;
10396 
10397  sc->sample_sizes[0] = item->extent_length;
10398  sc->chunk_offsets[0] = item->extent_offset + offset;
10399 
10400  if (item->item_id == mov->primary_item_id)
10402 
10403  if (item->rotation || item->hflip || item->vflip) {
10405  &st->codecpar->nb_coded_side_data, item);
10406  if (err < 0)
10407  return err;
10408  }
10409 
10410  mov_build_index(mov, st);
10411  }
10412 
10413  if (mov->nb_heif_grid) {
10414  err = mov_parse_tiles(s);
10415  if (err < 0)
10416  return err;
10417  }
10418 
10419  return 0;
10420 }
10421 
10423  int first_index)
10424 {
10425  MOVStreamContext *sc = st->priv_data;
10426 
10427  if (sc->tref_id < 0)
10428  return NULL;
10429 
10430  for (int i = first_index; i < s->nb_streams; i++)
10431  if (s->streams[i]->id == sc->tref_id)
10432  return s->streams[i];
10433 
10434  return NULL;
10435 }
10436 
10438 {
10439  int err;
10440 
10441  for (int i = 0; i < s->nb_streams; i++) {
10442  AVStreamGroup *stg;
10443  AVStream *st = s->streams[i];
10444  AVStream *st_base;
10445  MOVStreamContext *sc = st->priv_data;
10446  int j = 0;
10447 
10448  /* Find an enhancement stream. */
10449  if (st->codecpar->codec_id != AV_CODEC_ID_LCEVC ||
10451  continue;
10452 
10454 
10456  if (!stg)
10457  return AVERROR(ENOMEM);
10458 
10459  stg->id = st->id;
10460  stg->params.lcevc->width = st->codecpar->width;
10461  stg->params.lcevc->height = st->codecpar->height;
10462  st->codecpar->width = 0;
10463  st->codecpar->height = 0;
10464 
10465  while (st_base = mov_find_reference_track(s, st, j)) {
10466  err = avformat_stream_group_add_stream(stg, st_base);
10467  if (err < 0)
10468  return err;
10469 
10470  j = st_base->index + 1;
10471  }
10472  if (!j) {
10473  av_log(s, AV_LOG_ERROR, "Failed to find base stream for enhancement stream\n");
10474  return AVERROR_INVALIDDATA;
10475  }
10476 
10477  err = avformat_stream_group_add_stream(stg, st);
10478  if (err < 0)
10479  return err;
10480 
10481  stg->params.lcevc->lcevc_index = stg->nb_streams - 1;
10482  }
10483 
10484  return 0;
10485 }
10486 
10488 {
10489  MOVContext *mov = s->priv_data;
10490  AVIOContext *pb = s->pb;
10491  int j, err;
10492  MOVAtom atom = { AV_RL32("root") };
10493  int i;
10494 
10495  if (mov->decryption_key_len != 0 && mov->decryption_key_len != AES_CTR_KEY_SIZE) {
10496  av_log(s, AV_LOG_ERROR, "Invalid decryption key len %d expected %d\n",
10498  return AVERROR(EINVAL);
10499  }
10500 
10501  mov->fc = s;
10502  mov->trak_index = -1;
10503  mov->thmb_item_id = -1;
10504  mov->primary_item_id = -1;
10505  mov->cur_item_id = -1;
10506  /* .mov and .mp4 aren't streamable anyway (only progressive download if moov is before mdat) */
10507  if (pb->seekable & AVIO_SEEKABLE_NORMAL)
10508  atom.size = avio_size(pb);
10509  else
10510  atom.size = INT64_MAX;
10511 
10512  /* check MOV header */
10513  do {
10514  if (mov->moov_retry)
10515  avio_seek(pb, 0, SEEK_SET);
10516  if ((err = mov_read_default(mov, pb, atom)) < 0) {
10517  av_log(s, AV_LOG_ERROR, "error reading header\n");
10518  return err;
10519  }
10520  } while ((pb->seekable & AVIO_SEEKABLE_NORMAL) &&
10521  !mov->found_moov && (!mov->found_iloc || !mov->found_iinf) && !mov->moov_retry++);
10522  if (!mov->found_moov && !mov->found_iloc && !mov->found_iinf) {
10523  av_log(s, AV_LOG_ERROR, "moov atom not found\n");
10524  return AVERROR_INVALIDDATA;
10525  }
10526  av_log(mov->fc, AV_LOG_TRACE, "on_parse_exit_offset=%"PRId64"\n", avio_tell(pb));
10527 
10528  if (mov->found_iloc && mov->found_iinf) {
10529  err = mov_parse_heif_items(s);
10530  if (err < 0)
10531  return err;
10532  }
10533  // prevent iloc and iinf boxes from being parsed while reading packets.
10534  // this is needed because an iinf box may have been parsed but ignored
10535  // for having old infe boxes which create no streams.
10536  mov->found_iloc = mov->found_iinf = 1;
10537 
10538  if (pb->seekable & AVIO_SEEKABLE_NORMAL) {
10539  if (mov->nb_chapter_tracks > 0 && !mov->ignore_chapters)
10541  for (i = 0; i < s->nb_streams; i++)
10542  if (s->streams[i]->codecpar->codec_tag == AV_RL32("tmcd")) {
10543  mov_read_timecode_track(s, s->streams[i]);
10544  } else if (s->streams[i]->codecpar->codec_tag == AV_RL32("rtmd")) {
10545  mov_read_rtmd_track(s, s->streams[i]);
10546  }
10547  }
10548 
10549  /* copy timecode metadata from tmcd tracks to the related video streams */
10550  for (i = 0; i < s->nb_streams; i++) {
10551  AVStream *st = s->streams[i];
10552  MOVStreamContext *sc = st->priv_data;
10553  if (sc->timecode_track > 0) {
10554  AVDictionaryEntry *tcr;
10555  int tmcd_st_id = -1;
10556 
10557  for (j = 0; j < s->nb_streams; j++) {
10558  MOVStreamContext *sc2 = s->streams[j]->priv_data;
10559  if (sc2->id == sc->timecode_track)
10560  tmcd_st_id = j;
10561  }
10562 
10563  if (tmcd_st_id < 0 || tmcd_st_id == i)
10564  continue;
10565  tcr = av_dict_get(s->streams[tmcd_st_id]->metadata, "timecode", NULL, 0);
10566  if (tcr)
10567  av_dict_set(&st->metadata, "timecode", tcr->value, 0);
10568  }
10569  }
10571 
10572  /* Create LCEVC stream groups. */
10573  err = mov_parse_lcevc_streams(s);
10574  if (err < 0)
10575  return err;
10576 
10577  for (i = 0; i < s->nb_streams; i++) {
10578  AVStream *st = s->streams[i];
10579  FFStream *const sti = ffstream(st);
10580  MOVStreamContext *sc = st->priv_data;
10581  uint32_t dvdsub_clut[FF_DVDCLUT_CLUT_LEN] = {0};
10582  fix_timescale(mov, sc);
10583  if (st->codecpar->codec_type == AVMEDIA_TYPE_AUDIO &&
10584  st->codecpar->codec_id == AV_CODEC_ID_AAC) {
10585  sti->skip_samples = sc->start_pad;
10586  }
10587  if (st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO && sc->nb_frames_for_fps > 0 && sc->duration_for_fps > 0)
10589  sc->time_scale*(int64_t)sc->nb_frames_for_fps, sc->duration_for_fps, INT_MAX);
10591  if (st->codecpar->width <= 0 || st->codecpar->height <= 0) {
10592  st->codecpar->width = sc->width;
10593  st->codecpar->height = sc->height;
10594  }
10597 
10598  for (j = 0; j < FF_DVDCLUT_CLUT_LEN; j++)
10599  dvdsub_clut[j] = AV_RB32(st->codecpar->extradata + j * 4);
10600 
10601  err = ff_dvdclut_yuv_to_rgb(dvdsub_clut, FF_DVDCLUT_CLUT_SIZE);
10602  if (err < 0)
10603  return err;
10604 
10605  av_freep(&st->codecpar->extradata);
10606  st->codecpar->extradata_size = 0;
10607 
10609  st->codecpar);
10610  if (err < 0)
10611  return err;
10612  }
10613  }
10614  if (mov->handbrake_version &&
10615  mov->handbrake_version <= 1000000*0 + 1000*10 + 2 && // 0.10.2
10616  st->codecpar->codec_id == AV_CODEC_ID_MP3) {
10617  av_log(s, AV_LOG_VERBOSE, "Forcing full parsing for mp3 stream\n");
10619  }
10620  }
10621 
10622  if (mov->trex_data || mov->use_mfra_for > 0) {
10623  for (i = 0; i < s->nb_streams; i++) {
10624  AVStream *st = s->streams[i];
10625  MOVStreamContext *sc = st->priv_data;
10626  if (sc->duration_for_fps > 0) {
10627  /* Akin to sc->data_size * 8 * sc->time_scale / sc->duration_for_fps but accounting for overflows. */
10629  if (st->codecpar->bit_rate == INT64_MIN) {
10630  av_log(s, AV_LOG_WARNING, "Overflow during bit rate calculation %"PRId64" * 8 * %d\n",
10631  sc->data_size, sc->time_scale);
10632  st->codecpar->bit_rate = 0;
10633  if (s->error_recognition & AV_EF_EXPLODE)
10634  return AVERROR_INVALIDDATA;
10635  }
10636  }
10637  }
10638  }
10639 
10640  for (i = 0; i < mov->bitrates_count && i < s->nb_streams; i++) {
10641  if (mov->bitrates[i]) {
10642  s->streams[i]->codecpar->bit_rate = mov->bitrates[i];
10643  }
10644  }
10645 
10647 
10648  for (i = 0; i < s->nb_streams; i++) {
10649  AVStream *st = s->streams[i];
10650  MOVStreamContext *sc = st->priv_data;
10651 
10652  switch (st->codecpar->codec_type) {
10653  case AVMEDIA_TYPE_AUDIO:
10654  err = ff_replaygain_export(st, s->metadata);
10655  if (err < 0)
10656  return err;
10657  break;
10658  case AVMEDIA_TYPE_VIDEO:
10659  if (sc->display_matrix) {
10662  (uint8_t*)sc->display_matrix, sizeof(int32_t) * 9, 0))
10663  return AVERROR(ENOMEM);
10664 
10665  sc->display_matrix = NULL;
10666  }
10667  if (sc->stereo3d) {
10670  (uint8_t *)sc->stereo3d, sc->stereo3d_size, 0))
10671  return AVERROR(ENOMEM);
10672 
10673  sc->stereo3d = NULL;
10674  }
10675  if (sc->spherical) {
10678  (uint8_t *)sc->spherical, sc->spherical_size, 0))
10679  return AVERROR(ENOMEM);
10680 
10681  sc->spherical = NULL;
10682  }
10683  if (sc->mastering) {
10686  (uint8_t *)sc->mastering, sc->mastering_size, 0))
10687  return AVERROR(ENOMEM);
10688 
10689  sc->mastering = NULL;
10690  }
10691  if (sc->coll) {
10694  (uint8_t *)sc->coll, sc->coll_size, 0))
10695  return AVERROR(ENOMEM);
10696 
10697  sc->coll = NULL;
10698  }
10699  if (sc->ambient) {
10702  (uint8_t *) sc->ambient, sc->ambient_size, 0))
10703  return AVERROR(ENOMEM);
10704 
10705  sc->ambient = NULL;
10706  }
10707  break;
10708  }
10709  }
10711 
10712  for (i = 0; i < mov->frag_index.nb_items; i++)
10713  if (mov->frag_index.item[i].moof_offset <= mov->fragment.moof_offset)
10714  mov->frag_index.item[i].headers_read = 1;
10715 
10716  return 0;
10717 }
10718 
10720 {
10722  int64_t best_dts = INT64_MAX;
10723  int i;
10724  MOVContext *mov = s->priv_data;
10725  int no_interleave = !mov->interleaved_read || !(s->pb->seekable & AVIO_SEEKABLE_NORMAL);
10726  for (i = 0; i < s->nb_streams; i++) {
10727  AVStream *avst = s->streams[i];
10728  FFStream *const avsti = ffstream(avst);
10729  MOVStreamContext *msc = avst->priv_data;
10730  if (msc->pb && msc->current_sample < avsti->nb_index_entries) {
10731  AVIndexEntry *current_sample = &avsti->index_entries[msc->current_sample];
10732  int64_t dts = av_rescale(current_sample->timestamp, AV_TIME_BASE, msc->time_scale);
10733  uint64_t dtsdiff = best_dts > dts ? best_dts - (uint64_t)dts : ((uint64_t)dts - best_dts);
10734  av_log(s, AV_LOG_TRACE, "stream %d, sample %d, dts %"PRId64"\n", i, msc->current_sample, dts);
10735  if (!sample || (no_interleave && current_sample->pos < sample->pos) ||
10736  ((s->pb->seekable & AVIO_SEEKABLE_NORMAL) &&
10737  ((msc->pb != s->pb && dts < best_dts) || (msc->pb == s->pb && dts != AV_NOPTS_VALUE &&
10738  ((dtsdiff <= AV_TIME_BASE && current_sample->pos < sample->pos) ||
10739  (dtsdiff > AV_TIME_BASE && dts < best_dts)))))) {
10740  sample = current_sample;
10741  best_dts = dts;
10742  *st = avst;
10743  }
10744  }
10745  }
10746  return sample;
10747 }
10748 
10749 static int should_retry(AVIOContext *pb, int error_code) {
10750  if (error_code == AVERROR_EOF || avio_feof(pb))
10751  return 0;
10752 
10753  return 1;
10754 }
10755 
10756 static int mov_switch_root(AVFormatContext *s, int64_t target, int index)
10757 {
10758  int ret;
10759  MOVContext *mov = s->priv_data;
10760 
10761  if (index >= 0 && index < mov->frag_index.nb_items)
10762  target = mov->frag_index.item[index].moof_offset;
10763  if (target >= 0 && avio_seek(s->pb, target, SEEK_SET) != target) {
10764  av_log(mov->fc, AV_LOG_ERROR, "root atom offset 0x%"PRIx64": partial file\n", target);
10765  return AVERROR_INVALIDDATA;
10766  }
10767 
10768  mov->next_root_atom = 0;
10769  if ((index < 0 && target >= 0) || index >= mov->frag_index.nb_items)
10770  index = search_frag_moof_offset(&mov->frag_index, target);
10771  if (index >= 0 && index < mov->frag_index.nb_items &&
10772  mov->frag_index.item[index].moof_offset == target) {
10773  if (index + 1 < mov->frag_index.nb_items)
10774  mov->next_root_atom = mov->frag_index.item[index + 1].moof_offset;
10775  if (mov->frag_index.item[index].headers_read)
10776  return 0;
10777  mov->frag_index.item[index].headers_read = 1;
10778  }
10779 
10780  mov->found_mdat = 0;
10781 
10782  ret = mov_read_default(mov, s->pb, (MOVAtom){ AV_RL32("root"), INT64_MAX });
10783  if (ret < 0)
10784  return ret;
10785  if (avio_feof(s->pb))
10786  return AVERROR_EOF;
10787  av_log(s, AV_LOG_TRACE, "read fragments, offset 0x%"PRIx64"\n", avio_tell(s->pb));
10788 
10789  return 1;
10790 }
10791 
10793 {
10794  MOVStreamContext *sc = st->priv_data;
10795  uint8_t *side, *extradata;
10796  int extradata_size;
10797 
10798  /* Save the current index. */
10799  sc->last_stsd_index = sc->stsc_data[sc->stsc_index].id - 1;
10800 
10801  /* Notify the decoder that extradata changed. */
10802  extradata_size = sc->extradata_size[sc->last_stsd_index];
10803  extradata = sc->extradata[sc->last_stsd_index];
10804  if (st->discard != AVDISCARD_ALL && extradata_size > 0 && extradata) {
10807  extradata_size);
10808  if (!side)
10809  return AVERROR(ENOMEM);
10810  memcpy(side, extradata, extradata_size);
10811  }
10812 
10813  return 0;
10814 }
10815 
10817 {
10818  int new_size, ret;
10819 
10820  if (size <= 8)
10821  return AVERROR_INVALIDDATA;
10822  new_size = ((size - 8) / 2) * 3;
10823  ret = av_new_packet(pkt, new_size);
10824  if (ret < 0)
10825  return ret;
10826 
10827  avio_skip(pb, 8);
10828  for (int j = 0; j < new_size; j += 3) {
10829  pkt->data[j] = 0xFC;
10830  pkt->data[j+1] = avio_r8(pb);
10831  pkt->data[j+2] = avio_r8(pb);
10832  }
10833 
10834  return 0;
10835 }
10836 
10838  int64_t current_index, AVPacket *pkt)
10839 {
10840  MOVStreamContext *sc = st->priv_data;
10841 
10842  pkt->stream_index = sc->ffindex;
10843  pkt->dts = sample->timestamp;
10844  if (sample->flags & AVINDEX_DISCARD_FRAME) {
10846  }
10847  if (sc->stts_data && sc->stts_index < sc->stts_count) {
10849 
10850  /* update stts context */
10851  sc->stts_sample++;
10852  if (sc->stts_index < sc->stts_count &&
10853  sc->stts_data[sc->stts_index].count == sc->stts_sample) {
10854  sc->stts_index++;
10855  sc->stts_sample = 0;
10856  }
10857  }
10858  if (sc->ctts_data && sc->ctts_index < sc->ctts_count) {
10860 
10861  /* update ctts context */
10862  sc->ctts_sample++;
10863  if (sc->ctts_index < sc->ctts_count &&
10864  sc->ctts_data[sc->ctts_index].count == sc->ctts_sample) {
10865  sc->ctts_index++;
10866  sc->ctts_sample = 0;
10867  }
10868  } else {
10869  if (pkt->duration == 0) {
10870  int64_t next_dts = (sc->current_sample < ffstream(st)->nb_index_entries) ?
10872  if (next_dts >= pkt->dts)
10873  pkt->duration = next_dts - pkt->dts;
10874  }
10875  pkt->pts = pkt->dts;
10876  }
10877 
10878  if (sc->sdtp_data && sc->current_sample <= sc->sdtp_count) {
10879  uint8_t sample_flags = sc->sdtp_data[sc->current_sample - 1];
10880  uint8_t sample_is_depended_on = (sample_flags >> 2) & 0x3;
10881  pkt->flags |= sample_is_depended_on == MOV_SAMPLE_DEPENDENCY_NO ? AV_PKT_FLAG_DISPOSABLE : 0;
10882  }
10883  pkt->flags |= sample->flags & AVINDEX_KEYFRAME ? AV_PKT_FLAG_KEY : 0;
10884  pkt->pos = sample->pos;
10885 
10886  /* Multiple stsd handling. */
10887  if (sc->stsc_data) {
10888  if (sc->stsc_data[sc->stsc_index].id > 0 &&
10889  sc->stsc_data[sc->stsc_index].id - 1 < sc->stsd_count &&
10890  sc->stsc_data[sc->stsc_index].id - 1 != sc->last_stsd_index) {
10891  int ret = mov_change_extradata(st, pkt);
10892  if (ret < 0)
10893  return ret;
10894  }
10895 
10896  /* Update the stsc index for the next sample */
10897  sc->stsc_sample++;
10898  if (mov_stsc_index_valid(sc->stsc_index, sc->stsc_count) &&
10899  mov_get_stsc_samples(sc, sc->stsc_index) == sc->stsc_sample) {
10900  sc->stsc_index++;
10901  sc->stsc_sample = 0;
10902  }
10903  }
10904 
10905  return 0;
10906 }
10907 
10909 {
10910  MOVContext *mov = s->priv_data;
10911  MOVStreamContext *sc;
10913  AVStream *st = NULL;
10914  FFStream *avsti = NULL;
10915  int64_t current_index;
10916  int ret;
10917  int i;
10918  mov->fc = s;
10919  retry:
10920  if (s->pb->pos == 0) {
10921 
10922  // Discard current fragment index
10923  if (mov->frag_index.allocated_size > 0) {
10924  av_freep(&mov->frag_index.item);
10925  mov->frag_index.nb_items = 0;
10926  mov->frag_index.allocated_size = 0;
10927  mov->frag_index.current = -1;
10928  mov->frag_index.complete = 0;
10929  }
10930 
10931  for (i = 0; i < s->nb_streams; i++) {
10932  AVStream *avst = s->streams[i];
10933  MOVStreamContext *msc = avst->priv_data;
10934 
10935  // Clear current sample
10936  mov_current_sample_set(msc, 0);
10937  msc->ctts_index = 0;
10938 
10939  // Discard current index entries
10940  avsti = ffstream(avst);
10941  if (avsti->index_entries_allocated_size > 0) {
10942  av_freep(&avsti->index_entries);
10943  avsti->index_entries_allocated_size = 0;
10944  avsti->nb_index_entries = 0;
10945  }
10946  }
10947 
10948  if ((ret = mov_switch_root(s, -1, -1)) < 0)
10949  return ret;
10950  }
10951  sample = mov_find_next_sample(s, &st);
10952  if (!sample || (mov->next_root_atom && sample->pos > mov->next_root_atom)) {
10953  if (!mov->next_root_atom)
10954  return AVERROR_EOF;
10955  if ((ret = mov_switch_root(s, mov->next_root_atom, -1)) < 0)
10956  return ret;
10957  goto retry;
10958  }
10959  sc = st->priv_data;
10960  /* must be done just before reading, to avoid infinite loop on sample */
10961  current_index = sc->current_index;
10963 
10964  if (mov->next_root_atom) {
10965  sample->pos = FFMIN(sample->pos, mov->next_root_atom);
10966  sample->size = FFMIN(sample->size, (mov->next_root_atom - sample->pos));
10967  }
10968 
10969  if (st->discard != AVDISCARD_ALL) {
10970  int64_t ret64 = avio_seek(sc->pb, sample->pos, SEEK_SET);
10971  if (ret64 != sample->pos) {
10972  av_log(mov->fc, AV_LOG_ERROR, "stream %d, offset 0x%"PRIx64": partial file\n",
10973  sc->ffindex, sample->pos);
10974  if (should_retry(sc->pb, ret64)) {
10976  } else if (ret64 < 0) {
10977  return (int)ret64;
10978  }
10979  return AVERROR_INVALIDDATA;
10980  }
10981 
10982  if (st->discard == AVDISCARD_NONKEY && !(sample->flags & AVINDEX_KEYFRAME)) {
10983  av_log(mov->fc, AV_LOG_DEBUG, "Nonkey frame from stream %d discarded due to AVDISCARD_NONKEY\n", sc->ffindex);
10984  goto retry;
10985  }
10986 
10987  if (st->codecpar->codec_id == AV_CODEC_ID_EIA_608 && sample->size > 8)
10988  ret = get_eia608_packet(sc->pb, pkt, sample->size);
10989 #if CONFIG_IAMFDEC
10990  else if (sc->iamf) {
10991  int64_t pts, dts, pos, duration;
10992  int flags, size = sample->size;
10993  ret = mov_finalize_packet(s, st, sample, current_index, pkt);
10994  pts = pkt->pts; dts = pkt->dts;
10995  pos = pkt->pos; flags = pkt->flags;
10996  duration = pkt->duration;
10997  while (!ret && size > 0) {
10998  ret = ff_iamf_read_packet(s, sc->iamf, sc->pb, size, pkt);
10999  if (ret < 0) {
11000  if (should_retry(sc->pb, ret))
11002  return ret;
11003  }
11004  size -= ret;
11005  pkt->pts = pts; pkt->dts = dts;
11006  pkt->pos = pos; pkt->flags |= flags;
11007  pkt->duration = duration;
11008  ret = ff_buffer_packet(s, pkt);
11009  }
11010  if (!ret)
11011  return FFERROR_REDO;
11012  }
11013 #endif
11014  else
11015  ret = av_get_packet(sc->pb, pkt, sample->size);
11016  if (ret < 0) {
11017  if (should_retry(sc->pb, ret)) {
11019  }
11020  return ret;
11021  }
11022 #if CONFIG_DV_DEMUXER
11023  if (mov->dv_demux && sc->dv_audio_container) {
11026  if (ret < 0)
11027  return ret;
11029  if (ret < 0)
11030  return ret;
11031  }
11032 #endif
11033  if (sc->has_palette) {
11034  uint8_t *pal;
11035 
11037  if (!pal) {
11038  av_log(mov->fc, AV_LOG_ERROR, "Cannot append palette to packet\n");
11039  } else {
11040  memcpy(pal, sc->palette, AVPALETTE_SIZE);
11041  sc->has_palette = 0;
11042  }
11043  }
11044  if (st->codecpar->codec_id == AV_CODEC_ID_MP3 && !ffstream(st)->need_parsing && pkt->size > 4) {
11045  if (ff_mpa_check_header(AV_RB32(pkt->data)) < 0)
11047  }
11048  }
11049 
11050  ret = mov_finalize_packet(s, st, sample, current_index, pkt);
11051  if (ret < 0)
11052  return ret;
11053 
11054  if (st->discard == AVDISCARD_ALL)
11055  goto retry;
11056 
11057  if (mov->aax_mode)
11058  aax_filter(pkt->data, pkt->size, mov);
11059 
11060  ret = cenc_filter(mov, st, sc, pkt, current_index);
11061  if (ret < 0) {
11062  return ret;
11063  }
11064 
11065  return 0;
11066 }
11067 
11069 {
11070  MOVContext *mov = s->priv_data;
11071  int index;
11072 
11073  if (!mov->frag_index.complete)
11074  return 0;
11075 
11076  index = search_frag_timestamp(s, &mov->frag_index, st, timestamp);
11077  if (index < 0)
11078  index = 0;
11079  if (!mov->frag_index.item[index].headers_read)
11080  return mov_switch_root(s, -1, index);
11081  if (index + 1 < mov->frag_index.nb_items)
11082  mov->next_root_atom = mov->frag_index.item[index + 1].moof_offset;
11083 
11084  return 0;
11085 }
11086 
11087 static int is_open_key_sample(const MOVStreamContext *sc, int sample)
11088 {
11089  // TODO: a bisect search would scale much better
11090  for (int i = 0; i < sc->open_key_samples_count; i++) {
11091  const int oks = sc->open_key_samples[i];
11092  if (oks == sample)
11093  return 1;
11094  if (oks > sample) /* list is monotically increasing so we can stop early */
11095  break;
11096  }
11097  return 0;
11098 }
11099 
11100 /*
11101  * Some key sample may be key frames but not IDR frames, so a random access to
11102  * them may not be allowed.
11103  */
11104 static int can_seek_to_key_sample(AVStream *st, int sample, int64_t requested_pts)
11105 {
11106  MOVStreamContext *sc = st->priv_data;
11107  FFStream *const sti = ffstream(st);
11108  int64_t key_sample_dts, key_sample_pts;
11109 
11110  if (st->codecpar->codec_id != AV_CODEC_ID_HEVC)
11111  return 1;
11112 
11113  if (sample >= sc->sample_offsets_count)
11114  return 1;
11115 
11116  key_sample_dts = sti->index_entries[sample].timestamp;
11117  key_sample_pts = key_sample_dts + sc->sample_offsets[sample] + sc->dts_shift;
11118 
11119  /*
11120  * If the sample needs to be presented before an open key sample, they may
11121  * not be decodable properly, even though they come after in decoding
11122  * order.
11123  */
11124  if (is_open_key_sample(sc, sample) && key_sample_pts > requested_pts)
11125  return 0;
11126 
11127  return 1;
11128 }
11129 
11130 static int mov_seek_stream(AVFormatContext *s, AVStream *st, int64_t timestamp, int flags)
11131 {
11132  MOVStreamContext *sc = st->priv_data;
11133  FFStream *const sti = ffstream(st);
11134  int sample, time_sample, ret, next_ts, requested_sample;
11135  unsigned int i;
11136 
11137  // Here we consider timestamp to be PTS, hence try to offset it so that we
11138  // can search over the DTS timeline.
11139  timestamp -= (sc->min_corrected_pts + sc->dts_shift);
11140 
11141  ret = mov_seek_fragment(s, st, timestamp);
11142  if (ret < 0)
11143  return ret;
11144 
11145  for (;;) {
11146  sample = av_index_search_timestamp(st, timestamp, flags);
11147  av_log(s, AV_LOG_TRACE, "stream %d, timestamp %"PRId64", sample %d\n", st->index, timestamp, sample);
11148  if (sample < 0 && sti->nb_index_entries && timestamp < sti->index_entries[0].timestamp)
11149  sample = 0;
11150  if (sample < 0) /* not sure what to do */
11151  return AVERROR_INVALIDDATA;
11152 
11153  if (!sample || can_seek_to_key_sample(st, sample, timestamp))
11154  break;
11155 
11156  next_ts = timestamp - FFMAX(sc->min_sample_duration, 1);
11157  requested_sample = av_index_search_timestamp(st, next_ts, flags);
11158 
11159  // If we've reached a different sample trying to find a good pts to
11160  // seek to, give up searching because we'll end up seeking back to
11161  // sample 0 on every seek.
11162  if (sample != requested_sample && !can_seek_to_key_sample(st, requested_sample, next_ts))
11163  break;
11164 
11165  timestamp = next_ts;
11166  }
11167 
11169  av_log(s, AV_LOG_TRACE, "stream %d, found sample %d\n", st->index, sc->current_sample);
11170  /* adjust stts index */
11171  if (sc->stts_data) {
11172  time_sample = 0;
11173  for (i = 0; i < sc->stts_count; i++) {
11174  int next = time_sample + sc->stts_data[i].count;
11175  if (next > sc->current_sample) {
11176  sc->stts_index = i;
11177  sc->stts_sample = sc->current_sample - time_sample;
11178  break;
11179  }
11180  time_sample = next;
11181  }
11182  }
11183  /* adjust ctts index */
11184  if (sc->ctts_data) {
11185  time_sample = 0;
11186  for (i = 0; i < sc->ctts_count; i++) {
11187  int next = time_sample + sc->ctts_data[i].count;
11188  if (next > sc->current_sample) {
11189  sc->ctts_index = i;
11190  sc->ctts_sample = sc->current_sample - time_sample;
11191  break;
11192  }
11193  time_sample = next;
11194  }
11195  }
11196 
11197  /* adjust stsd index */
11198  if (sc->chunk_count) {
11199  time_sample = 0;
11200  for (i = 0; i < sc->stsc_count; i++) {
11201  int64_t next = time_sample + mov_get_stsc_samples(sc, i);
11202  if (next > sc->current_sample) {
11203  sc->stsc_index = i;
11204  sc->stsc_sample = sc->current_sample - time_sample;
11205  break;
11206  }
11207  av_assert0(next == (int)next);
11208  time_sample = next;
11209  }
11210  }
11211 
11212  return sample;
11213 }
11214 
11216 {
11217  MOVStreamContext *sc = st->priv_data;
11218  FFStream *const sti = ffstream(st);
11219  int64_t first_ts = sti->index_entries[0].timestamp;
11221  int64_t off;
11222 
11224  return 0;
11225 
11226  /* compute skip samples according to stream start_pad, seek ts and first ts */
11227  off = av_rescale_q(ts - first_ts, st->time_base,
11228  (AVRational){1, st->codecpar->sample_rate});
11229  return FFMAX(sc->start_pad - off, 0);
11230 }
11231 
11232 static int mov_read_seek(AVFormatContext *s, int stream_index, int64_t sample_time, int flags)
11233 {
11234  MOVContext *mc = s->priv_data;
11235  AVStream *st;
11236  FFStream *sti;
11237  int sample;
11238  int i;
11239 
11240  if (stream_index >= s->nb_streams)
11241  return AVERROR_INVALIDDATA;
11242 
11243  st = s->streams[stream_index];
11244  sti = ffstream(st);
11245  sample = mov_seek_stream(s, st, sample_time, flags);
11246  if (sample < 0)
11247  return sample;
11248 
11249  if (mc->seek_individually) {
11250  /* adjust seek timestamp to found sample timestamp */
11251  int64_t seek_timestamp = sti->index_entries[sample].timestamp;
11253 
11254  for (i = 0; i < s->nb_streams; i++) {
11255  AVStream *const st = s->streams[i];
11256  FFStream *const sti = ffstream(st);
11257  int64_t timestamp;
11258 
11259  if (stream_index == i)
11260  continue;
11261 
11262  timestamp = av_rescale_q(seek_timestamp, s->streams[stream_index]->time_base, st->time_base);
11263  sample = mov_seek_stream(s, st, timestamp, flags);
11264  if (sample >= 0)
11266  }
11267  } else {
11268  for (i = 0; i < s->nb_streams; i++) {
11269  MOVStreamContext *sc;
11270  st = s->streams[i];
11271  sc = st->priv_data;
11272  mov_current_sample_set(sc, 0);
11273  }
11274  while (1) {
11275  MOVStreamContext *sc;
11277  if (!entry)
11278  return AVERROR_INVALIDDATA;
11279  sc = st->priv_data;
11280  if (sc->ffindex == stream_index && sc->current_sample == sample)
11281  break;
11283  }
11284  }
11285  return 0;
11286 }
11287 
11288 #define OFFSET(x) offsetof(MOVContext, x)
11289 #define FLAGS AV_OPT_FLAG_VIDEO_PARAM | AV_OPT_FLAG_DECODING_PARAM
11290 static const AVOption mov_options[] = {
11291  {"use_absolute_path",
11292  "allow using absolute path when opening alias, this is a possible security issue",
11293  OFFSET(use_absolute_path), AV_OPT_TYPE_BOOL, {.i64 = 0},
11294  0, 1, FLAGS},
11295  {"seek_streams_individually",
11296  "Seek each stream individually to the closest point",
11297  OFFSET(seek_individually), AV_OPT_TYPE_BOOL, { .i64 = 1 },
11298  0, 1, FLAGS},
11299  {"ignore_editlist", "Ignore the edit list atom.", OFFSET(ignore_editlist), AV_OPT_TYPE_BOOL, {.i64 = 0},
11300  0, 1, FLAGS},
11301  {"advanced_editlist",
11302  "Modify the AVIndex according to the editlists. Use this option to decode in the order specified by the edits.",
11303  OFFSET(advanced_editlist), AV_OPT_TYPE_BOOL, {.i64 = 1},
11304  0, 1, FLAGS},
11305  {"ignore_chapters", "", OFFSET(ignore_chapters), AV_OPT_TYPE_BOOL, {.i64 = 0},
11306  0, 1, FLAGS},
11307  {"use_mfra_for",
11308  "use mfra for fragment timestamps",
11309  OFFSET(use_mfra_for), AV_OPT_TYPE_INT, {.i64 = FF_MOV_FLAG_MFRA_AUTO},
11311  .unit = "use_mfra_for"},
11312  {"auto", "auto", 0, AV_OPT_TYPE_CONST, {.i64 = FF_MOV_FLAG_MFRA_AUTO}, 0, 0,
11313  FLAGS, .unit = "use_mfra_for" },
11314  {"dts", "dts", 0, AV_OPT_TYPE_CONST, {.i64 = FF_MOV_FLAG_MFRA_DTS}, 0, 0,
11315  FLAGS, .unit = "use_mfra_for" },
11316  {"pts", "pts", 0, AV_OPT_TYPE_CONST, {.i64 = FF_MOV_FLAG_MFRA_PTS}, 0, 0,
11317  FLAGS, .unit = "use_mfra_for" },
11318  {"use_tfdt", "use tfdt for fragment timestamps", OFFSET(use_tfdt), AV_OPT_TYPE_BOOL, {.i64 = 1},
11319  0, 1, FLAGS},
11320  { "export_all", "Export unrecognized metadata entries", OFFSET(export_all),
11321  AV_OPT_TYPE_BOOL, { .i64 = 0 }, 0, 1, .flags = FLAGS },
11322  { "export_xmp", "Export full XMP metadata", OFFSET(export_xmp),
11323  AV_OPT_TYPE_BOOL, { .i64 = 0 }, 0, 1, .flags = FLAGS },
11324  { "activation_bytes", "Secret bytes for Audible AAX files", OFFSET(activation_bytes),
11326  { "audible_key", "AES-128 Key for Audible AAXC files", OFFSET(audible_key),
11328  { "audible_iv", "AES-128 IV for Audible AAXC files", OFFSET(audible_iv),
11330  { "audible_fixed_key", // extracted from libAAX_SDK.so and AAXSDKWin.dll files!
11331  "Fixed key used for handling Audible AAX files", OFFSET(audible_fixed_key),
11332  AV_OPT_TYPE_BINARY, {.str="77214d4b196a87cd520045fd20a51d67"},
11333  .flags = AV_OPT_FLAG_DECODING_PARAM },
11334  { "decryption_key", "The media decryption key (hex)", OFFSET(decryption_key), AV_OPT_TYPE_BINARY, .flags = AV_OPT_FLAG_DECODING_PARAM },
11335  { "enable_drefs", "Enable external track support.", OFFSET(enable_drefs), AV_OPT_TYPE_BOOL,
11336  {.i64 = 0}, 0, 1, FLAGS },
11337  { "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 },
11338  { "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 },
11339 
11340  { NULL },
11341 };
11342 
11343 static const AVClass mov_class = {
11344  .class_name = "mov,mp4,m4a,3gp,3g2,mj2",
11345  .item_name = av_default_item_name,
11346  .option = mov_options,
11347  .version = LIBAVUTIL_VERSION_INT,
11348 };
11349 
11351  .p.name = "mov,mp4,m4a,3gp,3g2,mj2",
11352  .p.long_name = NULL_IF_CONFIG_SMALL("QuickTime / MOV"),
11353  .p.priv_class = &mov_class,
11354  .p.extensions = "mov,mp4,m4a,3gp,3g2,mj2,psp,m4b,ism,ismv,isma,f4v,avif,heic,heif",
11356  .priv_data_size = sizeof(MOVContext),
11357  .flags_internal = FF_INFMT_FLAG_INIT_CLEANUP,
11358  .read_probe = mov_probe,
11363 };
AVStreamGroup::params
union AVStreamGroup::@366 params
Group type-specific parameters.
avpriv_new_chapter
AVChapter * avpriv_new_chapter(AVFormatContext *s, int64_t id, AVRational time_base, int64_t start, int64_t end, const char *title)
Add a new chapter.
Definition: demux_utils.c:43
MOVStreamContext::ctts_allocated_size
unsigned int ctts_allocated_size
Definition: isom.h:182
item_name
item_name
Definition: libkvazaar.c:319
AV_CODEC_ID_PCM_S16LE
@ AV_CODEC_ID_PCM_S16LE
Definition: codec_id.h:334
mov_read_chpl
static int mov_read_chpl(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:594
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:7309
mov_read_meta
static int mov_read_meta(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:5507
AV_CODEC_ID_EIA_608
@ AV_CODEC_ID_EIA_608
Definition: codec_id.h:567
AV_PKT_DATA_DISPLAYMATRIX
@ AV_PKT_DATA_DISPLAYMATRIX
This side data contains a 3x3 transformation matrix describing an affine transformation that needs to...
Definition: packet.h:105
av_packet_unref
void av_packet_unref(AVPacket *pkt)
Wipe the packet.
Definition: packet.c:430
MOVContext::found_iloc
int found_iloc
'iloc' atom has been found
Definition: isom.h:311
AV_CODEC_ID_MACE6
@ AV_CODEC_ID_MACE6
Definition: codec_id.h:457
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:2295
read_image_iovl
static int read_image_iovl(AVFormatContext *s, const HEIFGrid *grid, AVStreamGroupTileGrid *tile_grid)
Definition: mov.c:10195
AV_PRIMARY_EYE_RIGHT
@ AV_PRIMARY_EYE_RIGHT
Right eye.
Definition: stereo3d.h:188
mov_read_irot
static int mov_read_irot(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:9120
AVMEDIA_TYPE_SUBTITLE
@ AVMEDIA_TYPE_SUBTITLE
Definition: avutil.h:204
AVIAMFSubmix::elements
AVIAMFSubmixElement ** elements
Array of submix elements.
Definition: iamf.h:565
skip_bits_long
static void skip_bits_long(GetBitContext *s, int n)
Skips the specified number of bits.
Definition: get_bits.h:278
AV_LOG_WARNING
#define AV_LOG_WARNING
Something somehow does not look correct.
Definition: log.h:215
AV_BPRINT_SIZE_UNLIMITED
#define AV_BPRINT_SIZE_UNLIMITED
MOV_TFHD_DEFAULT_FLAGS
#define MOV_TFHD_DEFAULT_FLAGS
Definition: isom.h:391
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:354
FFStream::skip_samples
int skip_samples
Number of samples to skip at the start of the frame decoded from the next packet.
Definition: internal.h:212
MOVStreamContext::audio_cid
int16_t audio_cid
stsd audio compression id
Definition: isom.h:214
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:379
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:8376
can_seek_to_key_sample
static int can_seek_to_key_sample(AVStream *st, int sample, int64_t requested_pts)
Definition: mov.c:11104
AV_CODEC_ID_ADPCM_IMA_QT
@ AV_CODEC_ID_ADPCM_IMA_QT
Definition: codec_id.h:373
entry
#define entry
Definition: aom_film_grain_template.c:66
AVFMT_NO_BYTE_SEEK
#define AVFMT_NO_BYTE_SEEK
Format does not allow seeking by bytes.
Definition: avformat.h:487
AV_EF_EXPLODE
#define AV_EF_EXPLODE
abort decoding on minor error detection
Definition: defs.h:51
AVStreamGroup::id
int64_t id
Group type-specific group ID.
Definition: avformat.h:1153
AV_CODEC_ID_AC3
@ AV_CODEC_ID_AC3
Definition: codec_id.h:450
HEIFItem::name
char * name
Definition: isom.h:283
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:236
MOVStreamContext::height
int height
tkhd height
Definition: isom.h:222
MOVContext::moov_retry
int moov_retry
Definition: isom.h:339
MOV_TRUN_SAMPLE_FLAGS
#define MOV_TRUN_SAMPLE_FLAGS
Definition: isom.h:399
find_prev_closest_index
static int find_prev_closest_index(AVStream *st, AVIndexEntry *e_old, int nb_old, MOVStts *stts_data, int64_t stts_count, MOVCtts *ctts_data, int64_t ctts_count, int64_t timestamp_pts, int flag, int64_t *index, int64_t *stts_index, int64_t *stts_sample, 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:3869
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:327
mix
static int mix(int c0, int c1)
Definition: 4xm.c:716
MOVStreamContext::last_stsd_index
int last_stsd_index
Definition: isom.h:251
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:412
AVCodecParameters::codec_type
enum AVMediaType codec_type
General type of the encoded data.
Definition: codec_par.h:51
AVStreamGroup::tile_grid
struct AVStreamGroupTileGrid * tile_grid
Definition: avformat.h:1169
AVFMT_SHOW_IDS
#define AVFMT_SHOW_IDS
Show format stream IDs numbers.
Definition: avformat.h:477
AVSphericalMapping::projection
enum AVSphericalProjection projection
Projection type.
Definition: spherical.h:98
AV_WL32
#define AV_WL32(p, v)
Definition: intreadwrite.h:422
AV_STREAM_GROUP_PARAMS_LCEVC
@ AV_STREAM_GROUP_PARAMS_LCEVC
Definition: avformat.h:1128
MOVStreamContext::extradata
uint8_t ** extradata
extradata array (and size) for multiple stsd
Definition: isom.h:249
mov_class
static const AVClass mov_class
Definition: mov.c:11343
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:241
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:2266
mov_read_chnl
static int mov_read_chnl(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:1188
mov_read_moof
static int mov_read_moof(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:1803
av_bprint_init
void av_bprint_init(AVBPrint *buf, unsigned size_init, unsigned size_max)
Definition: bprint.c:69
ctype
#define ctype
Definition: afir_template.c:46
AV_PKT_DATA_FRAME_CROPPING
@ AV_PKT_DATA_FRAME_CROPPING
The number of pixels to discard from the top/bottom/left/right border of the decoded frame to obtain ...
Definition: packet.h:340
AVCodecParameters
This struct describes the properties of an encoded stream.
Definition: codec_par.h:47
HEIFItem::icc_profile
uint8_t * icc_profile
Definition: isom.h:294
AVFMT_FLAG_IGNIDX
#define AVFMT_FLAG_IGNIDX
Ignore index.
Definition: avformat.h:1453
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:9926
HEIFItem::hflip
int hflip
Definition: isom.h:290
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:11290
mov_codec_id
static int mov_codec_id(AVStream *st, uint32_t format)
Definition: mov.c:2615
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:239
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:8767
matrix
Definition: vc1dsp.c:43
AVMasteringDisplayMetadata::display_primaries
AVRational display_primaries[3][2]
CIE 1931 xy chromaticity coords of color primaries (r, g, b order).
Definition: mastering_display_metadata.h:42
AV_PKT_FLAG_DISCARD
#define AV_PKT_FLAG_DISCARD
Flag is used to discard packets which are required to maintain valid decoder state but are not requir...
Definition: packet.h:601
AVMasteringDisplayMetadata::has_luminance
int has_luminance
Flag indicating whether the luminance (min_ and max_) have been set.
Definition: mastering_display_metadata.h:67
get_bits_long
static unsigned int get_bits_long(GetBitContext *s, int n)
Read 0-32 bits.
Definition: get_bits.h: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:2238
test_same_origin
static int test_same_origin(const char *src, const char *ref)
Definition: mov.c:4988
cbcs_scheme_decrypt
static int cbcs_scheme_decrypt(MOVContext *c, MOVStreamContext *sc, AVEncryptionInfo *sample, uint8_t *input, int size)
Definition: mov.c:8199
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:369
MOVStreamContext::stsc_data
MOVStsc * stsc_data
Definition: isom.h:185
ff_buffer_packet
int ff_buffer_packet(AVFormatContext *s, AVPacket *pkt)
Definition: demux.c:612
IS_MATRIX_IDENT
#define IS_MATRIX_IDENT(matrix)
Definition: mov.c:5525
AVStreamGroup::disposition
int disposition
Stream group disposition - a combination of AV_DISPOSITION_* flags.
Definition: avformat.h:1211
dict_internal.h
av_unused
#define av_unused
Definition: attributes.h:131
AV_DISPOSITION_DEFAULT
#define AV_DISPOSITION_DEFAULT
The stream should be chosen by default among other streams of the same type, unless the user has expl...
Definition: avformat.h:621
mov_update_dts_shift
static void mov_update_dts_shift(MOVStreamContext *sc, int duration, void *logctx)
Definition: mov.c:3624
MOVStreamContext::spherical
AVSphericalMapping * spherical
Definition: isom.h:258
mask
int mask
Definition: mediacodecdec_common.c:154
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:2243
AV_RB32A
#define AV_RB32A(p)
Definition: intreadwrite.h:575
MOVContext::primary_item_id
int primary_item_id
Definition: isom.h:364
mode
Definition: swscale.c:52
MOVContext::found_moov
int found_moov
'moov' atom has been found
Definition: isom.h:310
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:5369
pixdesc.h
cleanup
static av_cold void cleanup(FlashSV2Context *s)
Definition: flashsv2enc.c:130
AVFormatContext::streams
AVStream ** streams
A list of all streams in the file.
Definition: avformat.h:1368
HEIFGrid::nb_tiles
int nb_tiles
Definition: isom.h:302
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:2212
AVCOL_RANGE_JPEG
@ AVCOL_RANGE_JPEG
Full range content.
Definition: pixfmt.h:717
mpegaudiodecheader.h
MOVStreamContext::rap_group_count
unsigned int rap_group_count
Definition: isom.h:233
av_display_matrix_flip
void av_display_matrix_flip(int32_t matrix[9], int hflip, int vflip)
Flip the input matrix horizontally and/or vertically.
Definition: display.c:66
av_sha_init
av_cold int av_sha_init(AVSHA *ctx, int bits)
Initialize SHA-1 or SHA-2 hashing.
Definition: sha.c:274
HEIFItem::type
int type
Definition: isom.h:292
mov_read_mvhd
static int mov_read_mvhd(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:1905
mov_read_idat
static int mov_read_idat(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:8761
AVPacket::data
uint8_t * data
Definition: packet.h:539
MOVContext::found_mdat
int found_mdat
'mdat' atom has been found
Definition: isom.h:313
MOVStreamContext::drefs_count
unsigned drefs_count
Definition: isom.h:215
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:2258
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:322
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:3281
MOVContext::bitrates
int * bitrates
bitrates read before streams creation
Definition: isom.h:337
b
#define b
Definition: input.c:41
AVCOL_TRC_UNSPECIFIED
@ AVCOL_TRC_UNSPECIFIED
Definition: pixfmt.h:614
MOVContext::interleaved_read
int interleaved_read
Definition: isom.h:372
mov_read_tkhd
static int mov_read_tkhd(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:5533
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:2059
data
const char data[16]
Definition: mxf.c:149
set_last_stream_little_endian
static void set_last_stream_little_endian(AVFormatContext *fc)
Definition: mov.c:1944
mov_read_strf
static int mov_read_strf(MOVContext *c, AVIOContext *pb, MOVAtom atom)
An strf atom is a BITMAPINFOHEADER struct.
Definition: mov.c:2528
AV_CODEC_ID_ALAC
@ AV_CODEC_ID_ALAC
Definition: codec_id.h:463
HEIFItem::st
AVStream * st
Definition: isom.h:282
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:428
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:7517
mov_seek_stream
static int mov_seek_stream(AVFormatContext *s, AVStream *st, int64_t timestamp, int flags)
Definition: mov.c:11130
mov_read_saio
static int mov_read_saio(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:7663
mov_get_stsc_samples
static int64_t mov_get_stsc_samples(MOVStreamContext *sc, unsigned int index)
Definition: mov.c:3266
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:225
ff_codec_wav_tags
const AVCodecTag ff_codec_wav_tags[]
Definition: riff.c:530
get_edit_list_entry
static int get_edit_list_entry(MOVContext *mov, const MOVStreamContext *msc, unsigned int edit_list_index, int64_t *edit_list_media_time, int64_t *edit_list_duration, int64_t global_timescale)
Get ith edit list entry (media time, duration).
Definition: mov.c:3823
MOVFragmentIndexItem::moof_offset
int64_t moof_offset
Definition: isom.h:147
MOVStreamContext::spherical_size
size_t spherical_size
Definition: isom.h:259
mov_change_extradata
static int mov_change_extradata(AVStream *st, AVPacket *pkt)
Definition: mov.c:10792
fc
#define fc(width, name, range_min, range_max)
Definition: cbs_av1.c:472
MOVStreamContext::tref_id
int tref_id
Definition: isom.h:219
MP4TrackKindMapping::scheme_uri
const char * scheme_uri
Definition: isom.h:474
AVINDEX_DISCARD_FRAME
#define AVINDEX_DISCARD_FRAME
Definition: avformat.h:611
av_display_rotation_set
void av_display_rotation_set(int32_t matrix[9], double angle)
Initialize a transformation matrix describing a pure clockwise rotation by the specified angle (in de...
Definition: display.c:51
AVPacket::duration
int64_t duration
Duration of this packet in AVStream->time_base units, 0 if unknown.
Definition: packet.h:557
AVCodecParameters::codec_tag
uint32_t codec_tag
Additional information about the codec (corresponds to the AVI FOURCC).
Definition: codec_par.h:59
AV_SPHERICAL_EQUIRECTANGULAR_TILE
@ AV_SPHERICAL_EQUIRECTANGULAR_TILE
Video represents a portion of a sphere mapped on a flat surface using equirectangular projection.
Definition: spherical.h:68
AVStereo3D::baseline
uint32_t baseline
The distance between the centres of the lenses of the camera system, in micrometers.
Definition: stereo3d.h:228
MOVDref::dir
char * dir
Definition: isom.h:82
mov_current_sample_set
static void mov_current_sample_set(MOVStreamContext *sc, int current_sample)
Definition: mov.c:4188
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:323
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
MOVStreamContext::stts_sample
int stts_sample
Definition: isom.h:193
mov_read_moov
static int mov_read_moov(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:1557
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:363
mov_read_esds
static int mov_read_esds(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:843
MOVStreamContext::sample_count
unsigned int sample_count
Definition: isom.h:198
MOVFragmentIndex::allocated_size
int allocated_size
Definition: isom.h:155
MOVTrackExt::flags
unsigned flags
Definition: isom.h:112
AVChannelLayout::nb_channels
int nb_channels
Number of channels in this layout.
Definition: channel_layout.h:328
HEIFItem::height
int height
Definition: isom.h:288
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:183
ff_dvdclut_yuv_to_rgb
int ff_dvdclut_yuv_to_rgb(uint32_t *clut, const size_t clut_size)
Definition: dvdclut.c:50
AV_CODEC_ID_R10K
@ AV_CODEC_ID_R10K
Definition: codec_id.h:197
heif_cur_item
static HEIFItem * heif_cur_item(MOVContext *c)
Get the current item in the parsing process.
Definition: mov.c:196
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:331
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:2550
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:7036
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:271
cenc_filter
static int cenc_filter(MOVContext *mov, AVStream *st, MOVStreamContext *sc, AVPacket *pkt, int current_index)
Definition: mov.c:8306
mov_read_sdtp
static int mov_read_sdtp(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:3590
mov_read_jp2h
static int mov_read_jp2h(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:2248
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:212
AV_CODEC_ID_AMR_WB
@ AV_CODEC_ID_AMR_WB
Definition: codec_id.h:429
mov_read_tfhd
static int mov_read_tfhd(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:5638
AV_CODEC_ID_BIN_DATA
@ AV_CODEC_ID_BIN_DATA
Definition: codec_id.h:597
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:6237
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:252
ff_mov_lang_to_iso639
int ff_mov_lang_to_iso639(unsigned code, char to[4])
Definition: isom.c:260
ff_generate_avci_extradata
int ff_generate_avci_extradata(AVStream *st)
Generate standard extradata for AVC-Intra based on width/height and field order.
Definition: demux_utils.c:203
ff_get_extradata
int ff_get_extradata(void *logctx, AVCodecParameters *par, AVIOContext *pb, int size)
Allocate extradata with additional AV_INPUT_BUFFER_PADDING_SIZE at end which is always set to 0 and f...
Definition: demux_utils.c:338
AVStereo3D::horizontal_field_of_view
AVRational horizontal_field_of_view
Horizontal field of view, in degrees.
Definition: stereo3d.h:239
skip_bits
static void skip_bits(GetBitContext *s, int n)
Definition: get_bits.h: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:184
MOVStreamContext::has_palette
int has_palette
Definition: isom.h:227
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:121
OFFSET
#define OFFSET(x)
Definition: mov.c:11288
HEIFGrid::tile_item_list
HEIFItem ** tile_item_list
Definition: isom.h:300
set_icc_profile_from_item
static int set_icc_profile_from_item(AVPacketSideData **coded_side_data, int *nb_coded_side_data, const HEIFItem *item)
Definition: mov.c:10061
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:245
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:867
FF_DVDCLUT_CLUT_LEN
#define FF_DVDCLUT_CLUT_LEN
Definition: dvdclut.h:28
AVEncryptionInfo::skip_byte_block
uint32_t skip_byte_block
Only used for pattern encryption.
Definition: encryption_info.h:57
finish
static void finish(void)
Definition: movenc.c:374
aax_filter
static int aax_filter(uint8_t *input, int size, MOVContext *c)
Definition: mov.c:1495
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:3546
av_packet_add_side_data
int av_packet_add_side_data(AVPacket *pkt, enum AVPacketSideDataType type, uint8_t *data, size_t size)
Wrap an existing array as a packet side data.
Definition: packet.c:198
MOVStreamContext::mastering
AVMasteringDisplayMetadata * mastering
Definition: isom.h:260
AV_CODEC_ID_SPEEX
@ AV_CODEC_ID_SPEEX
Definition: codec_id.h:482
AV_FOURCC_MAX_STRING_SIZE
#define AV_FOURCC_MAX_STRING_SIZE
Definition: avutil.h:346
AV_PKT_DATA_PALETTE
@ AV_PKT_DATA_PALETTE
An AV_PKT_DATA_PALETTE side data packet contains exactly AVPALETTE_SIZE bytes worth of palette.
Definition: packet.h:47
ffstream
static av_always_inline FFStream * ffstream(AVStream *st)
Definition: internal.h:358
MOVFragmentIndexItem::current
int current
Definition: isom.h: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:335
mov_read_mdhd
static int mov_read_mdhd(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:1859
mov_read_ctts
static int mov_read_ctts(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:3635
MOVTrackExt
Definition: isom.h:107
MOV_FRAG_SAMPLE_FLAG_IS_NON_SYNC
#define MOV_FRAG_SAMPLE_FLAG_IS_NON_SYNC
Definition: isom.h:403
fail
#define fail()
Definition: checkasm.h:193
mov_read_aclr
static int mov_read_aclr(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:2323
AVSEEK_FLAG_ANY
#define AVSEEK_FLAG_ANY
seek to any frame, even non-keyframes
Definition: avformat.h:2500
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:357
FF_DVDCLUT_CLUT_SIZE
#define FF_DVDCLUT_CLUT_SIZE
Definition: dvdclut.h:29
AV_STEREO3D_2D
@ AV_STEREO3D_2D
Video is not stereoscopic (and metadata has to be there).
Definition: stereo3d.h:52
read_seek
static int read_seek(AVFormatContext *ctx, int stream_index, int64_t timestamp, int flags)
Definition: libcdio.c:151
HEIFItem::item_id
int item_id
Definition: isom.h:284
timecode.h
get_current_frag_stream_info
static MOVFragmentStreamInfo * get_current_frag_stream_info(MOVFragmentIndex *frag_index)
Definition: mov.c:1614
MOVStreamContext::ctts_index
int ctts_index
Definition: isom.h:194
GetBitContext
Definition: get_bits.h:108
MOVStreamContext::mastering_size
size_t mastering_size
Definition: isom.h:261
AVStreamGroupTileGrid::coded_width
int coded_width
Width of the canvas.
Definition: avformat.h:1002
av_iamf_audio_element_free
void av_iamf_audio_element_free(AVIAMFAudioElement **paudio_element)
Free an AVIAMFAudioElement and all its contents.
Definition: iamf.c:336
FFStream::index_entries_allocated_size
unsigned int index_entries_allocated_size
Definition: internal.h:191
read_close
static av_cold int read_close(AVFormatContext *ctx)
Definition: libcdio.c:143
mov_read_amve
static int mov_read_amve(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:6591
mov_read_enda
static int mov_read_enda(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:1973
mov_read_chap
static int mov_read_chap(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:5685
MOVParseTableEntry
Definition: mov.c:82
avio_tell
static av_always_inline int64_t avio_tell(AVIOContext *s)
ftell() equivalent for AVIOContext.
Definition: avio.h:494
MOV_TRUN_SAMPLE_DURATION
#define MOV_TRUN_SAMPLE_DURATION
Definition: isom.h:397
val
static double val(void *priv, double ch)
Definition: aeval.c:77
set_display_matrix_from_item
static int set_display_matrix_from_item(AVPacketSideData **coded_side_data, int *nb_coded_side_data, const HEIFItem *item)
Definition: mov.c:10075
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:305
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:224
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:448
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:221
MOVContext::meta_keys
char ** meta_keys
Definition: isom.h:316
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:250
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:1727
AVRational::num
int num
Numerator.
Definition: rational.h:59
MOVStreamContext::keyframes
int * keyframes
Definition: isom.h:202
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:7579
MOV_FRAG_SAMPLE_FLAG_DEPENDS_YES
#define MOV_FRAG_SAMPLE_FLAG_DEPENDS_YES
Definition: isom.h:410
MOVContext::idat_offset
int64_t idat_offset
Definition: isom.h:371
MOV_TRUN_DATA_OFFSET
#define MOV_TRUN_DATA_OFFSET
Definition: isom.h:395
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:190
mov_read_ares
static int mov_read_ares(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:2280
mov_read_adrm
static int mov_read_adrm(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:1371
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
MOVStreamContext::stts_index
int stts_index
Definition: isom.h:192
AV_CODEC_ID_PCM_S8
@ AV_CODEC_ID_PCM_S8
Definition: codec_id.h:338
avassert.h
avio_rb32
unsigned int avio_rb32(AVIOContext *s)
Definition: aviobuf.c:761
AV_LOG_TRACE
#define AV_LOG_TRACE
Extremely verbose debugging, useful for libav* development.
Definition: log.h:235
MOVStreamContext::stsc_sample
int stsc_sample
Definition: isom.h:187
pkt
AVPacket * pkt
Definition: movenc.c:60
AV_LOG_ERROR
#define AV_LOG_ERROR
Something went wrong and cannot losslessly be recovered.
Definition: log.h:209
AV_CODEC_ID_MACE3
@ AV_CODEC_ID_MACE3
Definition: codec_id.h:456
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:9800
AV_CH_LOW_FREQUENCY
#define AV_CH_LOW_FREQUENCY
Definition: channel_layout.h:178
duration
int64_t duration
Definition: movenc.c:65
MOVEncryptionIndex::auxiliary_offsets
uint64_t * auxiliary_offsets
Absolute seek position.
Definition: isom.h: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:225
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:93
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:253
AV_STREAM_GROUP_PARAMS_IAMF_MIX_PRESENTATION
@ AV_STREAM_GROUP_PARAMS_IAMF_MIX_PRESENTATION
Definition: avformat.h:1126
ff_add_attached_pic
int ff_add_attached_pic(AVFormatContext *s, AVStream *st, AVIOContext *pb, AVBufferRef **buf, int size)
Add an attached pic to an AVStream.
Definition: demux_utils.c:119
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:447
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:6525
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:5145
IAMFSubStream::audio_substream_id
unsigned int audio_substream_id
Definition: iamf.h:83
MOVContext::fc
AVFormatContext * fc
Definition: isom.h:307
MOV_TFHD_DEFAULT_BASE_IS_MOOF
#define MOV_TFHD_DEFAULT_BASE_IS_MOOF
Definition: isom.h:393
av_new_packet
int av_new_packet(AVPacket *pkt, int size)
Allocate the payload of a packet and initialize its fields with default values.
Definition: packet.c:99
AV_CODEC_ID_BMP
@ AV_CODEC_ID_BMP
Definition: codec_id.h:130
AV_CODEC_ID_EVC
@ AV_CODEC_ID_EVC
Definition: codec_id.h:325
IAMFLayer::substream_count
unsigned int substream_count
Definition: iamf.h:78
MOV_TFHD_DEFAULT_DURATION
#define MOV_TFHD_DEFAULT_DURATION
Definition: isom.h:389
ALAC_EXTRADATA_SIZE
#define ALAC_EXTRADATA_SIZE
DRM_BLOB_SIZE
#define DRM_BLOB_SIZE
Definition: mov.c:1369
MOVStreamContext::sample_offsets_count
int sample_offsets_count
Definition: isom.h:240
MOVCtts::count
unsigned int count
Definition: isom.h:63
MOVStreamContext::drefs
MOVDref * drefs
Definition: isom.h:216
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:356
AVProbeData::buf
unsigned char * buf
Buffer must have AVPROBE_PADDING_SIZE of extra allocated bytes filled with zero.
Definition: avformat.h:453
AVSphericalMapping::bound_top
uint32_t bound_top
Distance from the top edge.
Definition: spherical.h:180
AVMEDIA_TYPE_AUDIO
@ AVMEDIA_TYPE_AUDIO
Definition: avutil.h:202
AV_CODEC_ID_VP9
@ AV_CODEC_ID_VP9
Definition: codec_id.h:222
MOVFragmentIndex::nb_items
int nb_items
Definition: isom.h:158
AVCodecParameters::width
int width
Video only.
Definition: codec_par.h:134
AVChannelLayout::u
union AVChannelLayout::@428 u
Details about which channels are present in this layout.
AV_CHANNEL_ORDER_UNSPEC
@ AV_CHANNEL_ORDER_UNSPEC
Only the channel count is specified, without any further information about the channel order.
Definition: channel_layout.h:119
AV_CODEC_ID_MP2
@ AV_CODEC_ID_MP2
Definition: codec_id.h:447
MOV_TRUN_FIRST_SAMPLE_FLAGS
#define MOV_TRUN_FIRST_SAMPLE_FLAGS
Definition: isom.h:396
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:251
MOVStreamContext::keyframe_absent
int keyframe_absent
Definition: isom.h:200
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:263
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:4108
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:205
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:179
dvdclut.h
mov_read_lhvc
static int mov_read_lhvc(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:8480
AV_LOG_DEBUG
#define AV_LOG_DEBUG
Stuff which is only useful for libav* developers.
Definition: log.h:230
AVPacketSideData::data
uint8_t * data
Definition: packet.h:391
ctx
AVFormatContext * ctx
Definition: movenc.c:49
hevc.h
get_bits.h
limits.h
mov_read_sidx
static int mov_read_sidx(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:6099
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:1075
FFStream::display_aspect_ratio
AVRational display_aspect_ratio
display aspect ratio (0 if unknown)
Definition: internal.h:307
IAMFContext::nb_mix_presentations
int nb_mix_presentations
Definition: iamf.h:134
mov_find_next_sample
static AVIndexEntry * mov_find_next_sample(AVFormatContext *s, AVStream **st)
Definition: mov.c:10719
AV_CODEC_ID_TARGA_Y216
@ AV_CODEC_ID_TARGA_Y216
Definition: codec_id.h:258
AVIndexEntry::min_distance
int min_distance
Minimum distance between this and the previous keyframe, used to avoid unneeded searching.
Definition: avformat.h:614
mov_read_dvcc_dvvc
static int mov_read_dvcc_dvvc(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:8460
MOVParseTableEntry::parse
int(* parse)(MOVContext *ctx, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:84
codec_id
enum AVCodecID codec_id
Definition: vaapi_decode.c:410
AV_CODEC_ID_SVQ3
@ AV_CODEC_ID_SVQ3
Definition: codec_id.h:75
key
const char * key
Definition: hwcontext_opencl.c:189
AVCodecParameters::nb_coded_side_data
int nb_coded_side_data
Amount of entries in coded_side_data.
Definition: codec_par.h:86
MOVStreamContext::sdtp_data
uint8_t * sdtp_data
Definition: isom.h:180
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:347
mov_read_stss
static int mov_read_stss(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:3322
mov_read_ddts
static int mov_read_ddts(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:1116
mov_read_uuid
static int mov_read_uuid(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:7182
AVCOL_PRI_UNSPECIFIED
@ AVCOL_PRI_UNSPECIFIED
Definition: pixfmt.h:589
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:206
MOVFragmentStreamInfo::sidx_pts
int64_t sidx_pts
Definition: isom.h:135
MAX_REORDER_DELAY
#define MAX_REORDER_DELAY
Definition: mov.c:4107
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:9873
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:453
AV_CODEC_ID_PNG
@ AV_CODEC_ID_PNG
Definition: codec_id.h:113
AV_CODEC_ID_AVUI
@ AV_CODEC_ID_AVUI
Definition: codec_id.h:257
if
if(ret)
Definition: filter_design.txt:179
mov_read_cmov
static int mov_read_cmov(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:6257
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:7407
FFStream::need_parsing
enum AVStreamParseType need_parsing
Definition: internal.h:325
MOVStreamContext::keyframe_count
unsigned int keyframe_count
Definition: isom.h:201
mov_read_SAND
static int mov_read_SAND(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:8708
IAMFAudioElement::audio_element_id
unsigned int audio_element_id
Definition: iamf.h:96
AVDISCARD_ALL
@ AVDISCARD_ALL
discard all
Definition: defs.h:221
AVFormatContext
Format I/O context.
Definition: avformat.h:1300
av_realloc_f
#define av_realloc_f(p, o, n)
Definition: tableprint_vlc.h:32
mov_read_stts
static int mov_read_stts(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:3470
MOVStreamContext::index_ranges
MOVIndexRange * index_ranges
Definition: isom.h:208
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:1120
set_frag_stream
static void set_frag_stream(MOVFragmentIndex *frag_index, int id)
Definition: mov.c:1594
mov_read_free
static int mov_read_free(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:7287
mov_realloc_extradata
static int mov_realloc_extradata(AVCodecParameters *par, MOVAtom atom)
Definition: mov.c:2175
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:2498
read_header
static int read_header(FFV1Context *f)
Definition: ffv1dec.c:540
aes.h
AVClass
Describe the class of an AVClass context structure.
Definition: log.h:75
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:329
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:284
MOVStreamContext::ctts_count
unsigned int ctts_count
Definition: isom.h:181
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:469
mov_read_ftyp
static int mov_read_ftyp(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:1509
AV_WB16
#define AV_WB16(p, v)
Definition: intreadwrite.h:401
MOVContext::nb_heif_grid
int nb_heif_grid
Definition: isom.h:369
read_image_grid
static int read_image_grid(AVFormatContext *s, const HEIFGrid *grid, AVStreamGroupTileGrid *tile_grid)
Definition: mov.c:10096
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
AVStreamGroupTileGrid::coded_side_data
AVPacketSideData * coded_side_data
Additional data associated with the grid.
Definition: avformat.h:1090
AVRational
Rational number (pair of numerator and denominator).
Definition: rational.h:58
AV_PRIMARY_EYE_LEFT
@ AV_PRIMARY_EYE_LEFT
Left eye.
Definition: stereo3d.h:183
mov_read_sgpd
static int mov_read_sgpd(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:3706
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:719
mov_probe
static int mov_probe(const AVProbeData *p)
Definition: mov.c:9520
AVPALETTE_SIZE
#define AVPALETTE_SIZE
Definition: pixfmt.h:32
FLAC_METADATA_TYPE_STREAMINFO
@ FLAC_METADATA_TYPE_STREAMINFO
Definition: flac.h:46
MOVDref::nlvl_to
int16_t nlvl_to
Definition: isom.h:85
AV_CODEC_ID_DVD_SUBTITLE
@ AV_CODEC_ID_DVD_SUBTITLE
Definition: codec_id.h:557
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:204
mov_read_smdm
static int mov_read_smdm(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:6434
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:209
mov_open_dref
static int mov_open_dref(MOVContext *c, AVIOContext **pb, const char *src, MOVDref *ref)
Definition: mov.c:5017
FFStream::nb_index_entries
int nb_index_entries
Definition: internal.h:190
AVProbeData
This structure contains the data a format has to probe a file.
Definition: avformat.h:451
av_aes_alloc
struct AVAES * av_aes_alloc(void)
Allocate an AVAES context.
Definition: aes.c:35
TAG_IS_AVCI
#define TAG_IS_AVCI(tag)
Definition: isom.h:423
IAMFSubStream
Definition: iamf.h:82
MOVStreamContext::timecode_track
int timecode_track
Definition: isom.h:220
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:7879
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:3504
FF_MOV_FLAG_MFRA_DTS
#define FF_MOV_FLAG_MFRA_DTS
Definition: isom.h:446
MOV_SAMPLE_DEPENDENCY_NO
#define MOV_SAMPLE_DEPENDENCY_NO
Definition: isom.h:419
mov_read_iref_thmb
static int mov_read_iref_thmb(MOVContext *c, AVIOContext *pb, int version)
Definition: mov.c:9036
MOVStreamContext::cenc
struct MOVStreamContext::@393 cenc
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:234
AV_CODEC_ID_QDM2
@ AV_CODEC_ID_QDM2
Definition: codec_id.h:466
mov_read_ilst
static int mov_read_ilst(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:5314
AV_CH_FRONT_CENTER
#define AV_CH_FRONT_CENTER
Definition: channel_layout.h:177
AVCodecParameters::ch_layout
AVChannelLayout ch_layout
Audio only.
Definition: codec_par.h:180
get_frag_stream_info_from_pkt
static MOVFragmentStreamInfo * get_frag_stream_info_from_pkt(MOVFragmentIndex *frag_index, AVPacket *pkt, int id)
Definition: mov.c:8281
get_sgpd_sync_index
static uint32_t get_sgpd_sync_index(const MOVStreamContext *sc, int nal_unit_type)
Definition: mov.c:4563
mov_read_fiel
static int mov_read_fiel(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:2141
MOV_MP4_TTML_TAG
#define MOV_MP4_TTML_TAG
Definition: isom.h:464
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:387
MOVFragmentStreamInfo::stsd_id
int stsd_id
Definition: isom.h:143
MOVStreamContext::open_key_samples_count
int open_key_samples_count
Definition: isom.h:242
HEIFItem
Definition: isom.h:281
ff_codec_movaudio_tags
const AVCodecTag ff_codec_movaudio_tags[]
Definition: isom_tags.c:303
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:1220
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:2830
cid
uint16_t cid
Definition: mxfenc.c:2269
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:2992
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:465
AVStream::nb_frames
int64_t nb_frames
number of frames in this stream if known or 0
Definition: avformat.h:809
AVCodecID
AVCodecID
Identify the syntax and semantics of the bitstream.
Definition: codec_id.h:49
av_packet_side_data_get
const AVPacketSideData * av_packet_side_data_get(const AVPacketSideData *sd, int nb_sd, enum AVPacketSideDataType type)
Get side information from a side data array.
Definition: packet.c:657
AVIAMFSubmixElement::audio_element_id
unsigned int audio_element_id
The id of the Audio Element this submix element references.
Definition: iamf.h:452
AV_CODEC_ID_EAC3
@ AV_CODEC_ID_EAC3
Definition: codec_id.h:487
should_retry
static int should_retry(AVIOContext *pb, int error_code)
Definition: mov.c:10749
avformat_stream_group_add_stream
int avformat_stream_group_add_stream(AVStreamGroup *stg, AVStream *st)
Add an already allocated stream to a stream group.
Definition: options.c:529
AV_PKT_DATA_SPHERICAL
@ AV_PKT_DATA_SPHERICAL
This side data should be associated with a video stream and corresponds to the AVSphericalMapping str...
Definition: packet.h:225
AVCodecParameters::extradata_size
int extradata_size
Size of the extradata content in bytes.
Definition: codec_par.h:73
AVIAMFSubmix
Submix layout as defined in section 3.7 of IAMF.
Definition: iamf.h:556
AV_WB32
#define AV_WB32(p, v)
Definition: intreadwrite.h:415
mov_read_pasp
static int mov_read_pasp(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:1339
MOVContext::dv_demux
DVDemuxContext * dv_demux
Definition: isom.h:318
AV_CODEC_ID_AAC
@ AV_CODEC_ID_AAC
Definition: codec_id.h:449
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:8618
mov_read_elst
static int mov_read_elst(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:6310
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:1127
IAMFAudioElement
Definition: iamf.h:89
AV_UUID_LEN
#define AV_UUID_LEN
Definition: uuid.h:57
av_sat_sub64
#define av_sat_sub64
Definition: common.h:142
mov_read_header
static int mov_read_header(AVFormatContext *s)
Definition: mov.c:10487
AV_CODEC_ID_QCELP
@ AV_CODEC_ID_QCELP
Definition: codec_id.h:471
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:8074
avio_rl32
unsigned int avio_rl32(AVIOContext *s)
Definition: aviobuf.c:730
MOVStreamContext::tref_flags
unsigned tref_flags
Definition: isom.h:218
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:346
mov_read_wave
static int mov_read_wave(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:2371
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:272
MOV_TREF_FLAG_ENHANCEMENT
#define MOV_TREF_FLAG_ENHANCEMENT
Definition: isom.h:421
cens_scheme_decrypt
static int cens_scheme_decrypt(MOVContext *c, MOVStreamContext *sc, AVEncryptionInfo *sample, uint8_t *input, int size)
Definition: mov.c:8134
MOVContext::handbrake_version
int handbrake_version
Definition: isom.h:325
mov_free_stream_context
static void mov_free_stream_context(AVFormatContext *s, AVStream *st)
Definition: mov.c:9812
AVPacket::size
int size
Definition: packet.h:540
MOVStreamContext::ctts_sample
int ctts_sample
Definition: isom.h:195
NULL_IF_CONFIG_SMALL
#define NULL_IF_CONFIG_SMALL(x)
Return NULL if CONFIG_SMALL is true, otherwise the argument without modification.
Definition: internal.h:94
ff_codec_get_id
enum AVCodecID ff_codec_get_id(const AVCodecTag *tags, unsigned int tag)
Definition: utils.c:133
avformat_alloc_context
AVFormatContext * avformat_alloc_context(void)
Allocate an AVFormatContext.
Definition: options.c:162
MOVFragmentIndexItem
Definition: isom.h: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:7356
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:318
FFStream
Definition: internal.h:132
mov_read_dref
static int mov_read_dref(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:633
mov_current_sample_dec
static void mov_current_sample_dec(MOVStreamContext *sc)
Definition: mov.c:4176
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
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:197
FF_MOV_FLAG_MFRA_AUTO
#define FF_MOV_FLAG_MFRA_AUTO
Definition: isom.h:445
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:237
start_time
static int64_t start_time
Definition: ffplay.c:326
uuid.h
ff_dvdclut_palette_extradata_cat
int ff_dvdclut_palette_extradata_cat(const uint32_t *clut, const size_t clut_size, AVCodecParameters *par)
Definition: dvdclut.c:28
mov_read_trun
static int mov_read_trun(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:5771
MOVStreamContext::stereo3d_size
size_t stereo3d_size
Definition: isom.h:257
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:9159
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:388
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:1169
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:3180
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:497
av_fourcc_make_string
char * av_fourcc_make_string(char *buf, uint32_t fourcc)
Fill the provided buffer with a string containing a FourCC (four-character code) representation.
Definition: utils.c:75
AV_RB32
uint64_t_TMPL AV_WL64 unsigned int_TMPL AV_WL32 unsigned int_TMPL AV_WL24 unsigned int_TMPL AV_WL16 uint64_t_TMPL AV_WB64 unsigned int_TMPL AV_RB32
Definition: bytestream.h:96
avpriv_report_missing_feature
void avpriv_report_missing_feature(void *avc, const char *msg,...) av_printf_format(2
Log a generic warning message about a missing feature.
av_aes_ctr_set_full_iv
void av_aes_ctr_set_full_iv(struct AVAESCTR *a, const uint8_t *iv)
Forcefully change the "full" 16-byte iv, including the counter.
Definition: aes_ctr.c:52
AVStreamGroup::iamf_audio_element
struct AVIAMFAudioElement * iamf_audio_element
Definition: avformat.h:1167
MOVStreamContext::coll
AVContentLightMetadata * coll
Definition: isom.h:262
aes_ctr.h
ff_format_io_close
int ff_format_io_close(AVFormatContext *s, AVIOContext **pb)
Definition: avformat.c:958
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:4080
mov_parse_heif_items
static int mov_parse_heif_items(AVFormatContext *s)
Definition: mov.c:10361
HEIFItem::is_idat_relative
int is_idat_relative
Definition: isom.h:293
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:3996
MOVDref::path
char * path
Definition: isom.h:81
mov_current_sample_inc
static void mov_current_sample_inc(MOVStreamContext *sc)
Definition: mov.c:4164
AVStream::sample_aspect_ratio
AVRational sample_aspect_ratio
sample aspect ratio (0 if unknown)
Definition: avformat.h:826
FFInputFormat::p
AVInputFormat p
The public AVInputFormat.
Definition: demux.h:46
dovi_isom.h
AVPacket::dts
int64_t dts
Decompression timestamp in AVStream->time_base units; the time at which the packet is decompressed.
Definition: packet.h:538
mov_read_vexu_proj
static int mov_read_vexu_proj(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:6800
fix_timescale
static void fix_timescale(MOVContext *c, MOVStreamContext *sc)
Definition: mov.c:5089
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:884
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:9398
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:465
ffio_ensure_seekback
int ffio_ensure_seekback(AVIOContext *s, int64_t buf_size)
Ensures that the requested seekback buffer size will be available.
Definition: aviobuf.c:1023
AVStreamGroupTileGrid::nb_tiles
unsigned int nb_tiles
Amount of tiles in the grid.
Definition: avformat.h:995
av_packet_side_data_add
AVPacketSideData * av_packet_side_data_add(AVPacketSideData **psd, int *pnb_sd, enum AVPacketSideDataType type, void *data, size_t size, int flags)
Wrap existing data as packet side data.
Definition: packet.c:700
mov_read_packet
static int mov_read_packet(AVFormatContext *s, AVPacket *pkt)
Definition: mov.c:10908
offset
it s the only field you need to keep assuming you have a context There is some magic you don t need to care about around this just let it vf offset
Definition: writing_filters.txt:86
AVStreamGroupLCEVC::lcevc_index
unsigned int lcevc_index
Index of the LCEVC data stream in AVStreamGroup.
Definition: avformat.h:1112
AVStreamGroup::lcevc
struct AVStreamGroupLCEVC * lcevc
Definition: avformat.h:1170
attributes.h
AV_CODEC_ID_LCEVC
@ AV_CODEC_ID_LCEVC
Definition: codec_id.h:599
MOVEncryptionIndex::auxiliary_offsets_count
size_t auxiliary_offsets_count
Definition: isom.h:130
HEIFItem::vflip
int vflip
Definition: isom.h:291
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:10422
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:1125
AVEncryptionInitInfo::next
struct AVEncryptionInitInfo * next
An optional pointer to the next initialization info in the list.
Definition: encryption_info.h:122
AV_STEREO3D_FLAG_INVERT
#define AV_STEREO3D_FLAG_INVERT
Inverted views, Right/Bottom represents the left view.
Definition: stereo3d.h:194
AVStreamGroup::streams
AVStream ** streams
A list of streams in the group.
Definition: avformat.h:1201
AVStreamGroupTileGrid::offsets
struct AVStreamGroupTileGrid::@365 * offsets
An nb_tiles sized array of offsets in pixels from the topleft edge of the canvas, indicating where ea...
ff_rfps_calculate
void ff_rfps_calculate(AVFormatContext *ic)
Definition: demux.c:2356
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:466
mov_read_clli
static int mov_read_clli(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:6562
MOVStreamContext::chunk_offsets
int64_t * chunk_offsets
Definition: isom.h:175
AVStreamGroup::iamf_mix_presentation
struct AVIAMFMixPresentation * iamf_mix_presentation
Definition: avformat.h:1168
MOVFragmentIndex::item
MOVFragmentIndexItem * item
Definition: isom.h:159
AV_LOG_INFO
#define AV_LOG_INFO
Standard information.
Definition: log.h:220
MOVStreamContext::iamf
struct IAMFDemuxContext * iamf
Definition: isom.h:278
FFERROR_REDO
#define FFERROR_REDO
Returned by demuxers to indicate that data was consumed but discarded (ignored streams or junk data).
Definition: demux.h:176
av_encryption_init_info_alloc
AVEncryptionInitInfo * av_encryption_init_info_alloc(uint32_t system_id_size, uint32_t num_key_ids, uint32_t key_id_size, uint32_t data_size)
Allocates an AVEncryptionInitInfo structure and sub-pointers to hold the given sizes.
Definition: encryption_info.c:178
av_channel_layout_custom_init
int av_channel_layout_custom_init(AVChannelLayout *channel_layout, int nb_channels)
Initialize a custom channel layout with the specified number of channels.
Definition: channel_layout.c:231
MOVContext::decryption_key_len
int decryption_key_len
Definition: isom.h:358
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:7981
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:9270
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
AVStreamGroupTileGrid::nb_coded_side_data
int nb_coded_side_data
Amount of entries in coded_side_data.
Definition: avformat.h:1095
mov_metadata_creation_time
static void mov_metadata_creation_time(MOVContext *c, AVIOContext *pb, AVDictionary **metadata, int version)
Definition: mov.c:1829
mov_metadata_hmmt
static int mov_metadata_hmmt(MOVContext *c, AVIOContext *pb, unsigned len)
Definition: mov.c:326
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:186
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:7910
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:3260
mov_finalize_packet
static int mov_finalize_packet(AVFormatContext *s, AVStream *st, AVIndexEntry *sample, int64_t current_index, AVPacket *pkt)
Definition: mov.c:10837
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:11232
bprint.h
MOVContext::advanced_editlist
int advanced_editlist
Definition: isom.h:330
MOVStreamContext::time_scale
int time_scale
Definition: isom.h:203
mlp_parse.h
mac_to_unicode
static const uint32_t mac_to_unicode[128]
Definition: mov.c:152
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:210
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
MOVCtts::offset
int offset
Definition: isom.h:64
mov_read_trex
static int mov_read_trex(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:5706
search_frag_timestamp
static int search_frag_timestamp(AVFormatContext *s, MOVFragmentIndex *frag_index, AVStream *st, int64_t timestamp)
Definition: mov.c:1702
HEIFItem::width
int width
Definition: isom.h:287
FLAGS
#define FLAGS
Definition: mov.c:11289
MOVStreamContext::stereo3d
AVStereo3D * stereo3d
Definition: isom.h:256
add_stts_entry
static int64_t add_stts_entry(MOVStts **stts_data, unsigned int *stts_count, unsigned int *allocated_size, int count, int duration)
Definition: mov.c:4049
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:4216
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:7758
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:3115
internal.h
AV_SPHERICAL_FISHEYE
@ AV_SPHERICAL_FISHEYE
Fisheye projection (Apple).
Definition: spherical.h:84
AVCodecParameters::height
int height
Definition: codec_par.h:135
AV_TIME_BASE
#define AV_TIME_BASE
Internal time base represented as integer.
Definition: avutil.h:254
MOVStreamContext::stps_count
unsigned int stps_count
Definition: isom.h:188
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:581
rb_size
static int rb_size(AVIOContext *pb, int64_t *value, int size)
Definition: mov.c:8734
AVStereo3DPrimaryEye
AVStereo3DPrimaryEye
List of possible primary eyes.
Definition: stereo3d.h:174
av_malloc_array
#define av_malloc_array(a, b)
Definition: tableprint_vlc.h:31
AV_CODEC_ID_CAVS
@ AV_CODEC_ID_CAVS
Definition: codec_id.h:139
display.h
ff_mov_read_stsd_entries
int ff_mov_read_stsd_entries(MOVContext *c, AVIOContext *pb, int entries)
Definition: mov.c:3018
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:613
ff_id3v1_genre_str
const char *const ff_id3v1_genre_str[ID3v1_GENRE_MAX+1]
ID3v1 genres.
Definition: id3v1.c:26
MOVStreamContext::sample_sizes
unsigned int * sample_sizes
Definition: isom.h:199
MOVContext::frag_index
MOVFragmentIndex frag_index
Definition: isom.h:343
mov_read_vpcc
static int mov_read_vpcc(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:6390
AV_CODEC_ID_PCM_F64BE
@ AV_CODEC_ID_PCM_F64BE
Definition: codec_id.h:356
AV_CODEC_ID_HEVC
@ AV_CODEC_ID_HEVC
Definition: codec_id.h:228
value
it s the only field you need to keep assuming you have a context There is some magic you don t need to care about around this just let it vf default value
Definition: writing_filters.txt:86
av_url_split
void av_url_split(char *proto, int proto_size, char *authorization, int authorization_size, char *hostname, int hostname_size, int *port_ptr, char *path, int path_size, const char *url)
Split a URL string into components.
Definition: utils.c:351
MOVStreamContext::dref_id
int dref_id
Definition: isom.h:217
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:1788
mov_finalize_stsd_codec
static int mov_finalize_stsd_codec(MOVContext *c, AVIOContext *pb, AVStream *st, MOVStreamContext *sc)
Definition: mov.c:2892
AV_CH_FRONT_LEFT
#define AV_CH_FRONT_LEFT
Definition: channel_layout.h:175
AV_CODEC_ID_PCM_S32BE
@ AV_CODEC_ID_PCM_S32BE
Definition: codec_id.h:343
mov_read_mdcv
static int mov_read_mdcv(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:6481
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:1361
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:5323
AVCodecParameters::color_range
enum AVColorRange color_range
Video only.
Definition: codec_par.h:166
AV_CH_SIDE_RIGHT
#define AV_CH_SIDE_RIGHT
Definition: channel_layout.h:185
len
int len
Definition: vorbis_enc_data.h:426
AV_CODEC_ID_JPEG2000
@ AV_CODEC_ID_JPEG2000
Definition: codec_id.h:140
MOVFragment::size
unsigned size
Definition: isom.h:103
MOV_TFHD_DEFAULT_SIZE
#define MOV_TFHD_DEFAULT_SIZE
Definition: isom.h:390
AVCOL_SPC_UNSPECIFIED
@ AVCOL_SPC_UNSPECIFIED
Definition: pixfmt.h:643
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:4634
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:2366
AVSHA
hash context
Definition: sha.c:35
AVCOL_RANGE_MPEG
@ AVCOL_RANGE_MPEG
Narrow or limited range content.
Definition: pixfmt.h:700
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:8917
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:1654
MP4TrackKindValueMapping
Definition: isom.h:468
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:4037
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:228
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:264
mov_read_tmcd
static int mov_read_tmcd(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:6379
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:265
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:203
HEIFItem::extent_length
int64_t extent_length
Definition: isom.h:285
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:7461
avio_seek
int64_t avio_seek(AVIOContext *s, int64_t offset, int whence)
fseek() equivalent for AVIOContext.
Definition: aviobuf.c:231
FFSWAP
#define FFSWAP(type, a, b)
Definition: macros.h:52
AVClass::class_name
const char * class_name
The name of the class; usually it is the same name as the context structure type to which the AVClass...
Definition: log.h:80
AVEncryptionInfo::key_id
uint8_t * key_id
The ID of the key used to encrypt the packet.
Definition: encryption_info.h:63
av_strlcat
size_t av_strlcat(char *dst, const char *src, size_t size)
Append the string src to the string dst, but to a total length of no more than size - 1 bytes,...
Definition: avstring.c:95
MOVStreamContext::stts_data
MOVStts * stts_data
Definition: isom.h:178
AVSphericalMapping::pitch
int32_t pitch
Rotation around the right vector [-90, 90].
Definition: spherical.h:139
AVStreamGroup::metadata
AVDictionary * metadata
Metadata that applies to the whole group.
Definition: avformat.h:1181
avio_rb16
unsigned int avio_rb16(AVIOContext *s)
Definition: aviobuf.c:746
AVStereo3D::type
enum AVStereo3DType type
How views are packed within the video.
Definition: stereo3d.h:207
MOVSbgp::index
unsigned int index
Definition: isom.h:117
HEIFItem::icc_profile_size
size_t icc_profile_size
Definition: isom.h:295
MOVContext::chapter_tracks
int * chapter_tracks
Definition: isom.h:326
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:707
AV_AUDIO_SERVICE_TYPE_KARAOKE
@ AV_AUDIO_SERVICE_TYPE_KARAOKE
Definition: defs.h:233
mov_read_dmlp
static int mov_read_dmlp(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:8425
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:213
MOVContext::time_scale
int time_scale
Definition: isom.h:308
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:5732
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:5450
search_frag_moof_offset
static int search_frag_moof_offset(MOVFragmentIndex *frag_index, int64_t offset)
Definition: mov.c:1630
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:10756
MOVContext::use_mfra_for
int use_mfra_for
Definition: isom.h:340
AVEncryptionInfo
This describes encryption info for a packet.
Definition: encryption_info.h:43
MOVStreamContext::encryption_index
MOVEncryptionIndex * encryption_index
Definition: isom.h:275
MIN_DATA_ENTRY_BOX_SIZE
#define MIN_DATA_ENTRY_BOX_SIZE
Definition: mov.c:632
AVStreamGroup
Definition: avformat.h:1134
av_get_media_type_string
const char * av_get_media_type_string(enum AVMediaType media_type)
Return a string describing the media_type enum, NULL if media_type is unknown.
Definition: utils.c:28
IAMFMixPresentation
Definition: iamf.h:107
AVStream::index
int index
stream index in AVFormatContext
Definition: avformat.h:754
avpriv_dv_init_demux
DVDemuxContext * avpriv_dv_init_demux(AVFormatContext *s)
Definition: dv.c:726
mov_seek_fragment
static int mov_seek_fragment(AVFormatContext *s, AVStream *st, int64_t timestamp)
Definition: mov.c:11068
ff_configure_buffers_for_index
void ff_configure_buffers_for_index(AVFormatContext *s, int64_t time_tolerance)
Definition: seek.c:175
mov_parse_stsd_video
static void mov_parse_stsd_video(MOVContext *c, AVIOContext *pb, AVStream *st, MOVStreamContext *sc)
Definition: mov.c:2655
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:223
mov_read_dec3
static int mov_read_dec3(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:1073
get_frag_time
static int64_t get_frag_time(AVFormatContext *s, AVStream *dst_st, MOVFragmentIndex *frag_index, int index)
Definition: mov.c:1664
MOVStreamContext::sample_size
unsigned int sample_size
may contain value calculated from stsd or value from stsz atom
Definition: isom.h:196
HEVC_NAL_CRA_NUT
@ HEVC_NAL_CRA_NUT
Definition: hevc.h:50
AVStreamGroup::nb_streams
unsigned int nb_streams
Number of elements in AVStreamGroup.streams.
Definition: avformat.h:1188
mlp_samplerate
static int mlp_samplerate(int in)
Definition: mlp_parse.h:87
channel_layout.h
MOVStreamContext::duration_for_fps
int64_t duration_for_fps
Definition: isom.h:246
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:3762
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:232
buffer
the frame and frame reference mechanism is intended to as much as expensive copies of that data while still allowing the filters to produce correct results The data is stored in buffers represented by AVFrame structures Several references can point to the same frame buffer
Definition: filter_design.txt:49
mov_read_glbl
static int mov_read_glbl(MOVContext *c, AVIOContext *pb, MOVAtom atom)
This function reads atom content and puts data in extradata without tag nor size unlike mov_read_extr...
Definition: mov.c:2428
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:7119
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:129
AV_OPT_TYPE_INT
@ AV_OPT_TYPE_INT
Underlying C type is int.
Definition: opt.h:259
MOVContext::dv_fctx
AVFormatContext * dv_fctx
Definition: isom.h:319
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:441
AV_CODEC_ID_DVAUDIO
@ AV_CODEC_ID_DVAUDIO
Definition: codec_id.h:453
avformat_free_context
void avformat_free_context(AVFormatContext *s)
Free an AVFormatContext and all its streams.
Definition: avformat.c:149
MOVContext::aax_mode
unsigned int aax_mode
'aax' file has been detected
Definition: isom.h:345
mov_read_sv3d
static int mov_read_sv3d(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:6663
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:1470
mov_get_skip_samples
static int64_t mov_get_skip_samples(AVStream *st, int sample)
Definition: mov.c:11215
MOVFragmentIndex
Definition: isom.h:154
mov_read_infe
static int mov_read_infe(MOVContext *c, AVIOContext *pb, MOVAtom atom, int idx)
Definition: mov.c:8852
AV_RB8
uint64_t_TMPL AV_WL64 unsigned int_TMPL AV_WL32 unsigned int_TMPL AV_WL24 unsigned int_TMPL AV_WL16 uint64_t_TMPL AV_WB64 unsigned int_TMPL AV_WB32 unsigned int_TMPL AV_WB24 unsigned int_TMPL AV_WB16 unsigned int_TMPL AV_RB8
Definition: bytestream.h:99
ref
static int ref[MAX_W *MAX_W]
Definition: jpeg2000dwt.c:117
AVStream::r_frame_rate
AVRational r_frame_rate
Real base framerate of the stream.
Definition: avformat.h:914
MOVStreamContext::track_end
int64_t track_end
used for dts generation in fragmented movie files
Definition: isom.h:231
MOVStreamContext::sgpd_sync_count
uint32_t sgpd_sync_count
Definition: isom.h:238
MOVContext::fragment
MOVFragment fragment
current fragment in moof atom
Definition: isom.h:321
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:113
AVStreamGroupLCEVC::width
int width
Width of the final stream for presentation.
Definition: avformat.h:1116
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:233
MOVParseTableEntry::type
uint32_t type
Definition: mov.c:83
AVMasteringDisplayMetadata::min_luminance
AVRational min_luminance
Min luminance of mastering display (cd/m^2).
Definition: mastering_display_metadata.h:52
MOVStreamContext::per_sample_iv_size
unsigned int per_sample_iv_size
Definition: isom.h:273
ff_codec_movsubtitle_tags
const AVCodecTag ff_codec_movsubtitle_tags[]
Definition: isom.c:75
av_mul_q
AVRational av_mul_q(AVRational b, AVRational c)
Multiply two rationals.
Definition: rational.c:80
AVPacket::stream_index
int stream_index
Definition: packet.h:541
MOVFragmentIndexItem::nb_stream_info
int nb_stream_info
Definition: isom.h: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:9942
mov_read_sbas
static int mov_read_sbas(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:2499
MOVStreamContext::has_sidx
int has_sidx
Definition: isom.h:269
AV_CH_FRONT_RIGHT
#define AV_CH_FRONT_RIGHT
Definition: channel_layout.h:176
av_aes_ctr_crypt
void av_aes_ctr_crypt(struct AVAESCTR *a, uint8_t *dst, const uint8_t *src, int count)
Process a buffer using a previously initialized context.
Definition: aes_ctr.c:107
mov_metadata_gnre
static int mov_metadata_gnre(MOVContext *c, AVIOContext *pb, unsigned len, const char *key)
Definition: mov.c:136
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:188
av_dict_set_int
int av_dict_set_int(AVDictionary **pm, const char *key, int64_t value, int flags)
Convenience wrapper for av_dict_set() that converts the value to a string and stores it.
Definition: dict.c:167
mov_read_dpxe
static int mov_read_dpxe(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:2253
AVIAMFSubmix::nb_elements
unsigned int nb_elements
Number of elements in the submix.
Definition: iamf.h:572
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:370
mov_read_rtmd_track
static int mov_read_rtmd_track(AVFormatContext *s, AVStream *st)
Definition: mov.c:9727
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:342
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:10277
mem.h
MOVElst::time
int64_t time
Definition: isom.h:75
HEIFGrid
Definition: isom.h:298
mov_read_iref_dimg
static int mov_read_iref_dimg(MOVContext *c, AVIOContext *pb, int version)
Definition: mov.c:8977
mov_read_pcmc
static int mov_read_pcmc(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:1982
build_open_gop_key_points
static int build_open_gop_key_points(AVStream *st)
Definition: mov.c:4571
mov_parse_stsd_audio
static void mov_parse_stsd_audio(MOVContext *c, AVIOContext *pb, AVStream *st, MOVStreamContext *sc)
Definition: mov.c:2713
IAMFContext::mix_presentations
IAMFMixPresentation ** mix_presentations
Definition: iamf.h:133
AV_CODEC_ID_PCM_U8
@ AV_CODEC_ID_PCM_U8
Definition: codec_id.h:339
MOVContext::trak_index
int trak_index
Index of the current 'trak'.
Definition: isom.h:315
mov_read_timecode_track
static int mov_read_timecode_track(AVFormatContext *s, AVStream *st)
Definition: mov.c:9753
HEIFGrid::item
HEIFItem * item
Definition: isom.h:299
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:171
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:301
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:449
AV_CHANNEL_LAYOUT_MONO
#define AV_CHANNEL_LAYOUT_MONO
Definition: channel_layout.h:393
AV_CODEC_ID_PCM_F64LE
@ AV_CODEC_ID_PCM_F64LE
Definition: codec_id.h:357
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:9960
av_free
#define av_free(p)
Definition: tableprint_vlc.h:33
AVDictionaryEntry
Definition: dict.h:89
av_add_q
AVRational av_add_q(AVRational b, AVRational c)
Add two rationals.
Definition: rational.c:93
AVCodecParameters::codec_id
enum AVCodecID codec_id
Specific type of the encoded data (the codec used).
Definition: codec_par.h:55
AVStereo3DView
AVStereo3DView
List of possible view types.
Definition: stereo3d.h:149
AVPacket
This structure stores compressed data.
Definition: packet.h:516
AVContentLightMetadata::MaxFALL
unsigned MaxFALL
Max average light level per frame (cd/m^2).
Definition: mastering_display_metadata.h:116
mov_parse_lcevc_streams
static int mov_parse_lcevc_streams(AVFormatContext *s)
Definition: mov.c:10437
mov_read_hfov
static int mov_read_hfov(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:7090
AV_OPT_TYPE_BOOL
@ AV_OPT_TYPE_BOOL
Underlying C type is int.
Definition: opt.h:327
MOVStreamContext::stps_data
unsigned * stps_data
partial sync sample for mpeg-2 open gop
Definition: isom.h:189
AV_CODEC_ID_ADPCM_IMA_WAV
@ AV_CODEC_ID_ADPCM_IMA_WAV
Definition: codec_id.h:374
MOVContext::nb_heif_item
int nb_heif_item
Definition: isom.h:367
av_freep
#define av_freep(p)
Definition: tableprint_vlc.h:34
av_dict_set
int av_dict_set(AVDictionary **pm, const char *key, const char *value, int flags)
Set the given entry in *pm, overwriting an existing entry.
Definition: dict.c:88
riff.h
av_dict_copy
int av_dict_copy(AVDictionary **dst, const AVDictionary *src, int flags)
Copy entries from one AVDictionary struct into another.
Definition: dict.c:237
av_encryption_info_alloc
AVEncryptionInfo * av_encryption_info_alloc(uint32_t subsample_count, uint32_t key_id_size, uint32_t iv_size)
Allocates an AVEncryptionInfo structure and sub-pointers to hold the given number of subsamples.
Definition: encryption_info.c:41
AVPacket::pos
int64_t pos
byte position in stream, -1 if unknown
Definition: packet.h:559
FFInputFormat
Definition: demux.h:42
mov_metadata_loci
static int mov_metadata_loci(MOVContext *c, AVIOContext *pb, unsigned len)
Definition: mov.c:276
mov_read_eyes
static int mov_read_eyes(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:6862
AV_CODEC_ID_ILBC
@ AV_CODEC_ID_ILBC
Definition: codec_id.h:506
AV_CHAN_AMBISONIC_BASE
@ AV_CHAN_AMBISONIC_BASE
Range of channels between AV_CHAN_AMBISONIC_BASE and AV_CHAN_AMBISONIC_END represent Ambisonic compon...
Definition: channel_layout.h:108
MOV_TRUN_SAMPLE_SIZE
#define MOV_TRUN_SAMPLE_SIZE
Definition: isom.h:398
MOVStreamContext::tmcd_flags
uint32_t tmcd_flags
tmcd track flags
Definition: isom.h:229
int32_t
int32_t
Definition: audioconvert.c:56
HEIFItem::rotation
int rotation
Definition: isom.h:289
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:9713
MOVStreamContext::tmcd_nb_frames
uint8_t tmcd_nb_frames
tmcd number of frames per tick / second
Definition: isom.h:230
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:232
MP4TrackKindValueMapping::value
const char * value
Definition: isom.h:470
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:355
ff_mov_demuxer
const FFInputFormat ff_mov_demuxer
Definition: mov.c:11350
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:255
MOVContext::heif_grid
HEIFGrid * heif_grid
Definition: isom.h:368
MOVStreamContext::min_sample_duration
uint32_t min_sample_duration
Definition: isom.h:243
MOVStreamContext::current_index
int64_t current_index
Definition: isom.h:207
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:215
MOVStreamContext::stts_allocated_size
unsigned int stts_allocated_size
Definition: isom.h:177
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:8265
MOVStreamContext::format
uint32_t format
Definition: isom.h:267
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:235
MOVContext::bitrates_count
int bitrates_count
Definition: isom.h:338
AV_CODEC_ID_VORBIS
@ AV_CODEC_ID_VORBIS
Definition: codec_id.h:452
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:211
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:9098
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:9060
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:1235
mov_read_mfra
static int mov_read_mfra(MOVContext *c, AVIOContext *f)
Definition: mov.c:10015
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:127
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:1575
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:8529
MOVContext::heif_item
HEIFItem ** heif_item
Definition: isom.h:366
MOVStreamContext::stts_count
unsigned int stts_count
Definition: isom.h:176
MOV_TRUN_SAMPLE_CTS
#define MOV_TRUN_SAMPLE_CTS
Definition: isom.h:400
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:463
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:347
get_eia608_packet
static int get_eia608_packet(AVIOContext *pb, AVPacket *pkt, int size)
Definition: mov.c:10816
mov_read_st3d
static int mov_read_st3d(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:6616
mov_read_imir
static int mov_read_imir(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:9140
is_open_key_sample
static int is_open_key_sample(const MOVStreamContext *sc, int sample)
Definition: mov.c:11087
mov_read_dvc1
static int mov_read_dvc1(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:2474
MOVStreamContext::elst_count
unsigned int elst_count
Definition: isom.h:191
av_color_transfer_name
const char * av_color_transfer_name(enum AVColorTransferCharacteristic transfer)
Definition: pixdesc.c:3525
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:283
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:2190
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:9614
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:274
MOVContext::cur_item_id
int cur_item_id
Definition: isom.h:365
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:1677
AV_DICT_DONT_STRDUP_KEY
#define AV_DICT_DONT_STRDUP_KEY
Take ownership of a key that's been allocated with av_malloc() or another memory allocation function.
Definition: dict.h:77
MOVContext::next_root_atom
int64_t next_root_atom
offset of the next root atom
Definition: isom.h:334
MOVContext::found_iinf
int found_iinf
'iinf' atom has been found
Definition: isom.h:312
MOVContext::meta_keys_count
unsigned meta_keys_count
Definition: isom.h:317
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:226
cenc_scheme_decrypt
static int cenc_scheme_decrypt(MOVContext *c, MOVStreamContext *sc, AVEncryptionInfo *sample, uint8_t *input, int size)
Definition: mov.c:8021
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:777
mov_parse_stsd_data
static int mov_parse_stsd_data(MOVContext *c, AVIOContext *pb, AVStream *st, MOVStreamContext *sc, int64_t size)
Definition: mov.c:2846
AV_CH_SIDE_LEFT
#define AV_CH_SIDE_LEFT
Definition: channel_layout.h:184
ff_iamf_read_deinit
void ff_iamf_read_deinit(IAMFDemuxContext *c)
Definition: iamf_reader.c:340
AV_RB16
uint64_t_TMPL AV_WL64 unsigned int_TMPL AV_WL32 unsigned int_TMPL AV_WL24 unsigned int_TMPL AV_WL16 uint64_t_TMPL AV_WB64 unsigned int_TMPL AV_WB32 unsigned int_TMPL AV_WB24 unsigned int_TMPL AV_RB16
Definition: bytestream.h:98
av_realloc
void * av_realloc(void *ptr, size_t size)
Allocate, reallocate, or free a block of memory.
Definition: mem.c:155
av_encryption_init_info_add_side_data
uint8_t * av_encryption_init_info_add_side_data(const AVEncryptionInitInfo *info, size_t *side_data_size)
Allocates and initializes side data that holds a copy of the given encryption init info.
Definition: encryption_info.c:292
av_fourcc2str
#define av_fourcc2str(fourcc)
Definition: avutil.h:348
ff_mov_read_chan
int ff_mov_read_chan(AVFormatContext *s, AVIOContext *pb, AVStream *st, int64_t size)
Read 'chan' tag from the input stream.
Definition: mov_chan.c:524
av_index_search_timestamp
int av_index_search_timestamp(AVStream *st, int64_t timestamp, int flags)
Get the index for a specific timestamp.
Definition: seek.c:245
mov_read_pitm
static int mov_read_pitm(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:8753
MOVContext::ignore_chapters
int ignore_chapters
Definition: isom.h:332
mov_read_dac3
static int mov_read_dac3(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:848
MP4TrackKindMapping
Definition: isom.h:473
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:286
mov_read_stsz
static int mov_read_stsz(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:3377