FFmpeg
mov.c
Go to the documentation of this file.
1 /*
2  * MOV demuxer
3  * Copyright (c) 2001 Fabrice Bellard
4  * Copyright (c) 2009 Baptiste Coudurier <baptiste dot coudurier at gmail dot com>
5  *
6  * first version by Francois Revol <revol@free.fr>
7  * seek function by Gael Chardon <gael.dev@4now.net>
8  *
9  * This file is part of FFmpeg.
10  *
11  * FFmpeg is free software; you can redistribute it and/or
12  * modify it under the terms of the GNU Lesser General Public
13  * License as published by the Free Software Foundation; either
14  * version 2.1 of the License, or (at your option) any later version.
15  *
16  * FFmpeg is distributed in the hope that it will be useful,
17  * but WITHOUT ANY WARRANTY; without even the implied warranty of
18  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
19  * Lesser General Public License for more details.
20  *
21  * You should have received a copy of the GNU Lesser General Public
22  * License along with FFmpeg; if not, write to the Free Software
23  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
24  */
25 
26 #include "config_components.h"
27 
28 #include <inttypes.h>
29 #include <limits.h>
30 #include <stdint.h>
31 
32 #include "libavutil/attributes.h"
33 #include "libavutil/bprint.h"
36 #include "libavutil/internal.h"
37 #include "libavutil/intreadwrite.h"
38 #include "libavutil/intfloat.h"
39 #include "libavutil/mathematics.h"
40 #include "libavutil/avassert.h"
41 #include "libavutil/avstring.h"
42 #include "libavutil/dict.h"
43 #include "libavutil/mem.h"
44 #include "libavutil/opt.h"
45 #include "libavutil/aes.h"
46 #include "libavutil/aes_ctr.h"
47 #include "libavutil/pixdesc.h"
48 #include "libavutil/sha.h"
49 #include "libavutil/spherical.h"
50 #include "libavutil/stereo3d.h"
51 #include "libavutil/timecode.h"
52 #include "libavutil/uuid.h"
53 #include "libavcodec/ac3tab.h"
54 #include "libavcodec/flac.h"
55 #include "libavcodec/hevc.h"
57 #include "libavcodec/mlp_parse.h"
58 #include "avformat.h"
59 #include "internal.h"
60 #include "avio_internal.h"
61 #include "demux.h"
62 #include "iamf_parse.h"
63 #include "iamf_reader.h"
64 #include "dovi_isom.h"
65 #include "riff.h"
66 #include "isom.h"
67 #include "libavcodec/get_bits.h"
68 #include "id3v1.h"
69 #include "mov_chan.h"
70 #include "replaygain.h"
71 
72 #if CONFIG_ZLIB
73 #include <zlib.h>
74 #endif
75 
76 #include "qtpalette.h"
77 
78 /* those functions parse an atom */
79 /* links atom IDs to parse functions */
80 typedef struct MOVParseTableEntry {
81  uint32_t type;
84 
85 static int mov_read_default(MOVContext *c, AVIOContext *pb, MOVAtom atom);
86 static int mov_read_mfra(MOVContext *c, AVIOContext *f);
88 static int64_t add_ctts_entry(MOVCtts** ctts_data, unsigned int* ctts_count, unsigned int* allocated_size,
89  int count, int duration);
90 
92  unsigned len, const char *key)
93 {
94  char buf[16];
95 
96  short current, total = 0;
97  avio_rb16(pb); // unknown
98  current = avio_rb16(pb);
99  if (len >= 6)
100  total = avio_rb16(pb);
101  if (!total)
102  snprintf(buf, sizeof(buf), "%d", current);
103  else
104  snprintf(buf, sizeof(buf), "%d/%d", current, total);
105  c->fc->event_flags |= AVFMT_EVENT_FLAG_METADATA_UPDATED;
106  av_dict_set(&c->fc->metadata, key, buf, 0);
107 
108  return 0;
109 }
110 
112  unsigned len, const char *key)
113 {
114  /* bypass padding bytes */
115  avio_r8(pb);
116  avio_r8(pb);
117  avio_r8(pb);
118 
119  c->fc->event_flags |= AVFMT_EVENT_FLAG_METADATA_UPDATED;
120  av_dict_set_int(&c->fc->metadata, key, avio_r8(pb), 0);
121 
122  return 0;
123 }
124 
126  unsigned len, const char *key)
127 {
128  c->fc->event_flags |= AVFMT_EVENT_FLAG_METADATA_UPDATED;
129  av_dict_set_int(&c->fc->metadata, key, avio_r8(pb), 0);
130 
131  return 0;
132 }
133 
135  unsigned len, const char *key)
136 {
137  short genre;
138 
139  avio_r8(pb); // unknown
140 
141  genre = avio_r8(pb);
142  if (genre < 1 || genre > ID3v1_GENRE_MAX)
143  return 0;
144  c->fc->event_flags |= AVFMT_EVENT_FLAG_METADATA_UPDATED;
145  av_dict_set(&c->fc->metadata, key, ff_id3v1_genre_str[genre-1], 0);
146 
147  return 0;
148 }
149 
150 static const uint32_t mac_to_unicode[128] = {
151  0x00C4,0x00C5,0x00C7,0x00C9,0x00D1,0x00D6,0x00DC,0x00E1,
152  0x00E0,0x00E2,0x00E4,0x00E3,0x00E5,0x00E7,0x00E9,0x00E8,
153  0x00EA,0x00EB,0x00ED,0x00EC,0x00EE,0x00EF,0x00F1,0x00F3,
154  0x00F2,0x00F4,0x00F6,0x00F5,0x00FA,0x00F9,0x00FB,0x00FC,
155  0x2020,0x00B0,0x00A2,0x00A3,0x00A7,0x2022,0x00B6,0x00DF,
156  0x00AE,0x00A9,0x2122,0x00B4,0x00A8,0x2260,0x00C6,0x00D8,
157  0x221E,0x00B1,0x2264,0x2265,0x00A5,0x00B5,0x2202,0x2211,
158  0x220F,0x03C0,0x222B,0x00AA,0x00BA,0x03A9,0x00E6,0x00F8,
159  0x00BF,0x00A1,0x00AC,0x221A,0x0192,0x2248,0x2206,0x00AB,
160  0x00BB,0x2026,0x00A0,0x00C0,0x00C3,0x00D5,0x0152,0x0153,
161  0x2013,0x2014,0x201C,0x201D,0x2018,0x2019,0x00F7,0x25CA,
162  0x00FF,0x0178,0x2044,0x20AC,0x2039,0x203A,0xFB01,0xFB02,
163  0x2021,0x00B7,0x201A,0x201E,0x2030,0x00C2,0x00CA,0x00C1,
164  0x00CB,0x00C8,0x00CD,0x00CE,0x00CF,0x00CC,0x00D3,0x00D4,
165  0xF8FF,0x00D2,0x00DA,0x00DB,0x00D9,0x0131,0x02C6,0x02DC,
166  0x00AF,0x02D8,0x02D9,0x02DA,0x00B8,0x02DD,0x02DB,0x02C7,
167 };
168 
170  char *dst, int dstlen)
171 {
172  char *p = dst;
173  char *end = dst+dstlen-1;
174  int i;
175 
176  for (i = 0; i < len; i++) {
177  uint8_t t, c = avio_r8(pb);
178 
179  if (p >= end)
180  continue;
181 
182  if (c < 0x80)
183  *p++ = c;
184  else if (p < end)
185  PUT_UTF8(mac_to_unicode[c-0x80], t, if (p < end) *p++ = t;);
186  }
187  *p = 0;
188  return p - dst;
189 }
190 
192 {
193  AVStream *st = NULL;
194 
195  if (c->fc->nb_streams < 1)
196  return NULL;
197 
198  for (int i = 0; i < c->nb_heif_item; i++) {
199  HEIFItem *item = &c->heif_item[i];
200 
201  if (!item->st)
202  continue;
203  if (item->st->id != c->cur_item_id)
204  continue;
205 
206  st = item->st;
207  break;
208  }
209  if (!st)
210  st = c->fc->streams[c->fc->nb_streams-1];
211 
212  return st;
213 }
214 
215 static int mov_read_covr(MOVContext *c, AVIOContext *pb, int type, int len)
216 {
217  AVStream *st;
218  MOVStreamContext *sc;
219  enum AVCodecID id;
220  int ret;
221 
222  switch (type) {
223  case 0xd: id = AV_CODEC_ID_MJPEG; break;
224  case 0xe: id = AV_CODEC_ID_PNG; break;
225  case 0x1b: id = AV_CODEC_ID_BMP; break;
226  default:
227  av_log(c->fc, AV_LOG_WARNING, "Unknown cover type: 0x%x.\n", type);
228  avio_skip(pb, len);
229  return 0;
230  }
231 
232  sc = av_mallocz(sizeof(*sc));
233  if (!sc)
234  return AVERROR(ENOMEM);
235  ret = ff_add_attached_pic(c->fc, NULL, pb, NULL, len);
236  if (ret < 0) {
237  av_free(sc);
238  return ret;
239  }
240  st = c->fc->streams[c->fc->nb_streams - 1];
241  st->priv_data = sc;
242  sc->id = st->id;
243  sc->refcount = 1;
244 
245  if (st->attached_pic.size >= 8 && id != AV_CODEC_ID_BMP) {
246  if (AV_RB64(st->attached_pic.data) == 0x89504e470d0a1a0a) {
247  id = AV_CODEC_ID_PNG;
248  } else {
249  id = AV_CODEC_ID_MJPEG;
250  }
251  }
252  st->codecpar->codec_id = id;
253 
254  return 0;
255 }
256 
257 // 3GPP TS 26.244
258 static int mov_metadata_loci(MOVContext *c, AVIOContext *pb, unsigned len)
259 {
260  char language[4] = { 0 };
261  char buf[200], place[100];
262  uint16_t langcode = 0;
263  double longitude, latitude, altitude;
264  const char *key = "location";
265 
266  if (len < 4 + 2 + 1 + 1 + 4 + 4 + 4) {
267  av_log(c->fc, AV_LOG_ERROR, "loci too short\n");
268  return AVERROR_INVALIDDATA;
269  }
270 
271  avio_skip(pb, 4); // version+flags
272  langcode = avio_rb16(pb);
273  ff_mov_lang_to_iso639(langcode, language);
274  len -= 6;
275 
276  len -= avio_get_str(pb, len, place, sizeof(place));
277  if (len < 1) {
278  av_log(c->fc, AV_LOG_ERROR, "place name too long\n");
279  return AVERROR_INVALIDDATA;
280  }
281  avio_skip(pb, 1); // role
282  len -= 1;
283 
284  if (len < 12) {
285  av_log(c->fc, AV_LOG_ERROR,
286  "loci too short (%u bytes left, need at least %d)\n", len, 12);
287  return AVERROR_INVALIDDATA;
288  }
289  longitude = ((int32_t) avio_rb32(pb)) / (float) (1 << 16);
290  latitude = ((int32_t) avio_rb32(pb)) / (float) (1 << 16);
291  altitude = ((int32_t) avio_rb32(pb)) / (float) (1 << 16);
292 
293  // Try to output in the same format as the ?xyz field
294  snprintf(buf, sizeof(buf), "%+08.4f%+09.4f", latitude, longitude);
295  if (altitude)
296  av_strlcatf(buf, sizeof(buf), "%+f", altitude);
297  av_strlcatf(buf, sizeof(buf), "/%s", place);
298 
299  if (*language && strcmp(language, "und")) {
300  char key2[16];
301  snprintf(key2, sizeof(key2), "%s-%s", key, language);
302  av_dict_set(&c->fc->metadata, key2, buf, 0);
303  }
304  c->fc->event_flags |= AVFMT_EVENT_FLAG_METADATA_UPDATED;
305  return av_dict_set(&c->fc->metadata, key, buf, 0);
306 }
307 
308 static int mov_metadata_hmmt(MOVContext *c, AVIOContext *pb, unsigned len)
309 {
310  int i, n_hmmt;
311 
312  if (len < 2)
313  return 0;
314  if (c->ignore_chapters)
315  return 0;
316 
317  n_hmmt = avio_rb32(pb);
318  if (n_hmmt > len / 4)
319  return AVERROR_INVALIDDATA;
320  for (i = 0; i < n_hmmt && !pb->eof_reached; i++) {
321  int moment_time = avio_rb32(pb);
322  avpriv_new_chapter(c->fc, i, av_make_q(1, 1000), moment_time, AV_NOPTS_VALUE, NULL);
323  }
324  if (avio_feof(pb))
325  return AVERROR_INVALIDDATA;
326  return 0;
327 }
328 
330 {
331  char tmp_key[AV_FOURCC_MAX_STRING_SIZE] = {0};
332  char key2[32], language[4] = {0};
333  char *str = NULL;
334  const char *key = NULL;
335  uint16_t langcode = 0;
336  uint32_t data_type = 0, str_size, str_size_alloc;
337  int (*parse)(MOVContext*, AVIOContext*, unsigned, const char*) = NULL;
338  int raw = 0;
339  int num = 0;
340 
341  switch (atom.type) {
342  case MKTAG( '@','P','R','M'): key = "premiere_version"; raw = 1; break;
343  case MKTAG( '@','P','R','Q'): key = "quicktime_version"; raw = 1; break;
344  case MKTAG( 'X','M','P','_'):
345  if (c->export_xmp) { key = "xmp"; raw = 1; } break;
346  case MKTAG( 'a','A','R','T'): key = "album_artist"; break;
347  case MKTAG( 'a','k','I','D'): key = "account_type";
349  case MKTAG( 'a','p','I','D'): key = "account_id"; break;
350  case MKTAG( 'c','a','t','g'): key = "category"; break;
351  case MKTAG( 'c','p','i','l'): key = "compilation";
353  case MKTAG( 'c','p','r','t'): key = "copyright"; break;
354  case MKTAG( 'd','e','s','c'): key = "description"; break;
355  case MKTAG( 'd','i','s','k'): key = "disc";
357  case MKTAG( 'e','g','i','d'): key = "episode_uid";
359  case MKTAG( 'F','I','R','M'): key = "firmware"; raw = 1; break;
360  case MKTAG( 'g','n','r','e'): key = "genre";
361  parse = mov_metadata_gnre; break;
362  case MKTAG( 'h','d','v','d'): key = "hd_video";
364  case MKTAG( 'H','M','M','T'):
365  return mov_metadata_hmmt(c, pb, atom.size);
366  case MKTAG( 'k','e','y','w'): key = "keywords"; break;
367  case MKTAG( 'l','d','e','s'): key = "synopsis"; break;
368  case MKTAG( 'l','o','c','i'):
369  return mov_metadata_loci(c, pb, atom.size);
370  case MKTAG( 'm','a','n','u'): key = "make"; break;
371  case MKTAG( 'm','o','d','l'): key = "model"; break;
372  case MKTAG( 'p','c','s','t'): key = "podcast";
374  case MKTAG( 'p','g','a','p'): key = "gapless_playback";
376  case MKTAG( 'p','u','r','d'): key = "purchase_date"; break;
377  case MKTAG( 'r','t','n','g'): key = "rating";
379  case MKTAG( 's','o','a','a'): key = "sort_album_artist"; break;
380  case MKTAG( 's','o','a','l'): key = "sort_album"; break;
381  case MKTAG( 's','o','a','r'): key = "sort_artist"; break;
382  case MKTAG( 's','o','c','o'): key = "sort_composer"; break;
383  case MKTAG( 's','o','n','m'): key = "sort_name"; break;
384  case MKTAG( 's','o','s','n'): key = "sort_show"; break;
385  case MKTAG( 's','t','i','k'): key = "media_type";
387  case MKTAG( 't','r','k','n'): key = "track";
389  case MKTAG( 't','v','e','n'): key = "episode_id"; break;
390  case MKTAG( 't','v','e','s'): key = "episode_sort";
392  case MKTAG( 't','v','n','n'): key = "network"; break;
393  case MKTAG( 't','v','s','h'): key = "show"; break;
394  case MKTAG( 't','v','s','n'): key = "season_number";
396  case MKTAG(0xa9,'A','R','T'): key = "artist"; break;
397  case MKTAG(0xa9,'P','R','D'): key = "producer"; break;
398  case MKTAG(0xa9,'a','l','b'): key = "album"; break;
399  case MKTAG(0xa9,'a','u','t'): key = "artist"; break;
400  case MKTAG(0xa9,'c','h','p'): key = "chapter"; break;
401  case MKTAG(0xa9,'c','m','t'): key = "comment"; break;
402  case MKTAG(0xa9,'c','o','m'): key = "composer"; break;
403  case MKTAG(0xa9,'c','p','y'): key = "copyright"; break;
404  case MKTAG(0xa9,'d','a','y'): key = "date"; break;
405  case MKTAG(0xa9,'d','i','r'): key = "director"; break;
406  case MKTAG(0xa9,'d','i','s'): key = "disclaimer"; break;
407  case MKTAG(0xa9,'e','d','1'): key = "edit_date"; break;
408  case MKTAG(0xa9,'e','n','c'): key = "encoder"; break;
409  case MKTAG(0xa9,'f','m','t'): key = "original_format"; break;
410  case MKTAG(0xa9,'g','e','n'): key = "genre"; break;
411  case MKTAG(0xa9,'g','r','p'): key = "grouping"; break;
412  case MKTAG(0xa9,'h','s','t'): key = "host_computer"; break;
413  case MKTAG(0xa9,'i','n','f'): key = "comment"; break;
414  case MKTAG(0xa9,'l','y','r'): key = "lyrics"; break;
415  case MKTAG(0xa9,'m','a','k'): key = "make"; break;
416  case MKTAG(0xa9,'m','o','d'): key = "model"; break;
417  case MKTAG(0xa9,'n','a','m'): key = "title"; break;
418  case MKTAG(0xa9,'o','p','e'): key = "original_artist"; break;
419  case MKTAG(0xa9,'p','r','d'): key = "producer"; break;
420  case MKTAG(0xa9,'p','r','f'): key = "performers"; break;
421  case MKTAG(0xa9,'r','e','q'): key = "playback_requirements"; break;
422  case MKTAG(0xa9,'s','r','c'): key = "original_source"; break;
423  case MKTAG(0xa9,'s','t','3'): key = "subtitle"; break;
424  case MKTAG(0xa9,'s','w','r'): key = "encoder"; break;
425  case MKTAG(0xa9,'t','o','o'): key = "encoder"; break;
426  case MKTAG(0xa9,'t','r','k'): key = "track"; break;
427  case MKTAG(0xa9,'u','r','l'): key = "URL"; break;
428  case MKTAG(0xa9,'w','r','n'): key = "warning"; break;
429  case MKTAG(0xa9,'w','r','t'): key = "composer"; break;
430  case MKTAG(0xa9,'x','y','z'): key = "location"; break;
431  }
432 retry:
433  if (c->itunes_metadata && atom.size > 8) {
434  int data_size = avio_rb32(pb);
435  int tag = avio_rl32(pb);
436  if (tag == MKTAG('d','a','t','a') && data_size <= atom.size && data_size >= 16) {
437  data_type = avio_rb32(pb); // type
438  avio_rb32(pb); // unknown
439  str_size = data_size - 16;
440  atom.size -= 16;
441 
442  if (!key && c->found_hdlr_mdta && c->meta_keys) {
443  uint32_t index = av_bswap32(atom.type); // BE number has been read as LE
444  if (index < c->meta_keys_count && index > 0) {
445  key = c->meta_keys[index];
446  } else if (atom.type != MKTAG('c', 'o', 'v', 'r')) {
447  av_log(c->fc, AV_LOG_WARNING,
448  "The index of 'data' is out of range: %"PRId32" < 1 or >= %d.\n",
449  index, c->meta_keys_count);
450  }
451  }
452  if (atom.type == MKTAG('c', 'o', 'v', 'r') ||
453  (key && !strcmp(key, "com.apple.quicktime.artwork"))) {
454  int ret = mov_read_covr(c, pb, data_type, str_size);
455  if (ret < 0) {
456  av_log(c->fc, AV_LOG_ERROR, "Error parsing cover art.\n");
457  return ret;
458  }
459  atom.size -= str_size;
460  if (atom.size > 8)
461  goto retry;
462  return ret;
463  }
464  } else return 0;
465  } else if (atom.size > 4 && key && !c->itunes_metadata && !raw) {
466  str_size = avio_rb16(pb); // string length
467  if (str_size > atom.size) {
468  raw = 1;
469  avio_seek(pb, -2, SEEK_CUR);
470  av_log(c->fc, AV_LOG_WARNING, "UDTA parsing failed retrying raw\n");
471  goto retry;
472  }
473  langcode = avio_rb16(pb);
474  ff_mov_lang_to_iso639(langcode, language);
475  atom.size -= 4;
476  } else
477  str_size = atom.size;
478 
479  if (c->export_all && !key) {
480  key = av_fourcc_make_string(tmp_key, atom.type);
481  }
482 
483  if (!key)
484  return 0;
485  if (atom.size < 0 || str_size >= INT_MAX/2)
486  return AVERROR_INVALIDDATA;
487 
488  // Allocates enough space if data_type is a int32 or float32 number, otherwise
489  // worst-case requirement for output string in case of utf8 coded input
490  num = (data_type >= 21 && data_type <= 23);
491  str_size_alloc = (num ? 512 : (raw ? str_size : str_size * 2)) + 1;
492  str = av_mallocz(str_size_alloc);
493  if (!str)
494  return AVERROR(ENOMEM);
495 
496  if (parse)
497  parse(c, pb, str_size, key);
498  else {
499  if (!raw && (data_type == 3 || (data_type == 0 && (langcode < 0x400 || langcode == 0x7fff)))) { // MAC Encoded
500  mov_read_mac_string(c, pb, str_size, str, str_size_alloc);
501  } else if (data_type == 21) { // BE signed integer, variable size
502  int val = 0;
503  if (str_size == 1)
504  val = (int8_t)avio_r8(pb);
505  else if (str_size == 2)
506  val = (int16_t)avio_rb16(pb);
507  else if (str_size == 3)
508  val = ((int32_t)(avio_rb24(pb)<<8))>>8;
509  else if (str_size == 4)
510  val = (int32_t)avio_rb32(pb);
511  if (snprintf(str, str_size_alloc, "%d", val) >= str_size_alloc) {
512  av_log(c->fc, AV_LOG_ERROR,
513  "Failed to store the number (%d) in string.\n", val);
514  av_free(str);
515  return AVERROR_INVALIDDATA;
516  }
517  } else if (data_type == 22) { // BE unsigned integer, variable size
518  unsigned int val = 0;
519  if (str_size == 1)
520  val = avio_r8(pb);
521  else if (str_size == 2)
522  val = avio_rb16(pb);
523  else if (str_size == 3)
524  val = avio_rb24(pb);
525  else if (str_size == 4)
526  val = avio_rb32(pb);
527  if (snprintf(str, str_size_alloc, "%u", val) >= str_size_alloc) {
528  av_log(c->fc, AV_LOG_ERROR,
529  "Failed to store the number (%u) in string.\n", val);
530  av_free(str);
531  return AVERROR_INVALIDDATA;
532  }
533  } else if (data_type == 23 && str_size >= 4) { // BE float32
534  float val = av_int2float(avio_rb32(pb));
535  if (snprintf(str, str_size_alloc, "%f", val) >= str_size_alloc) {
536  av_log(c->fc, AV_LOG_ERROR,
537  "Failed to store the float32 number (%f) in string.\n", val);
538  av_free(str);
539  return AVERROR_INVALIDDATA;
540  }
541  } else if (data_type > 1 && data_type != 4) {
542  // data_type can be 0 if not set at all above. data_type 1 means
543  // UTF8 and 4 means "UTF8 sort". For any other type (UTF16 or e.g.
544  // a picture), don't return it blindly in a string that is supposed
545  // to be UTF8 text.
546  av_log(c->fc, AV_LOG_WARNING, "Skipping unhandled metadata %s of type %d\n", key, data_type);
547  av_free(str);
548  return 0;
549  } else {
550  int ret = ffio_read_size(pb, str, str_size);
551  if (ret < 0) {
552  av_free(str);
553  return ret;
554  }
555  str[str_size] = 0;
556  }
557  c->fc->event_flags |= AVFMT_EVENT_FLAG_METADATA_UPDATED;
558  av_dict_set(&c->fc->metadata, key, str, 0);
559  if (*language && strcmp(language, "und")) {
560  snprintf(key2, sizeof(key2), "%s-%s", key, language);
561  av_dict_set(&c->fc->metadata, key2, str, 0);
562  }
563  if (!strcmp(key, "encoder")) {
564  int major, minor, micro;
565  if (sscanf(str, "HandBrake %d.%d.%d", &major, &minor, &micro) == 3) {
566  c->handbrake_version = 1000000*major + 1000*minor + micro;
567  }
568  }
569  }
570 
571  av_freep(&str);
572  return 0;
573 }
574 
576 {
577  int64_t start;
578  int i, nb_chapters, str_len, version;
579  char str[256+1];
580  int ret;
581 
582  if (c->ignore_chapters)
583  return 0;
584 
585  if ((atom.size -= 5) < 0)
586  return 0;
587 
588  version = avio_r8(pb);
589  avio_rb24(pb);
590  if (version)
591  avio_rb32(pb); // ???
592  nb_chapters = avio_r8(pb);
593 
594  for (i = 0; i < nb_chapters; i++) {
595  if (atom.size < 9)
596  return 0;
597 
598  start = avio_rb64(pb);
599  str_len = avio_r8(pb);
600 
601  if ((atom.size -= 9+str_len) < 0)
602  return 0;
603 
604  ret = ffio_read_size(pb, str, str_len);
605  if (ret < 0)
606  return ret;
607  str[str_len] = 0;
608  avpriv_new_chapter(c->fc, i, (AVRational){1,10000000}, start, AV_NOPTS_VALUE, str);
609  }
610  return 0;
611 }
612 
613 #define MIN_DATA_ENTRY_BOX_SIZE 12
615 {
616  AVStream *st;
617  MOVStreamContext *sc;
618  int entries, i, j;
619 
620  if (c->fc->nb_streams < 1)
621  return 0;
622  st = c->fc->streams[c->fc->nb_streams-1];
623  sc = st->priv_data;
624 
625  avio_rb32(pb); // version + flags
626  entries = avio_rb32(pb);
627  if (!entries ||
628  entries > (atom.size - 1) / MIN_DATA_ENTRY_BOX_SIZE + 1 ||
629  entries >= UINT_MAX / sizeof(*sc->drefs))
630  return AVERROR_INVALIDDATA;
631 
632  for (i = 0; i < sc->drefs_count; i++) {
633  MOVDref *dref = &sc->drefs[i];
634  av_freep(&dref->path);
635  av_freep(&dref->dir);
636  }
637  av_free(sc->drefs);
638  sc->drefs_count = 0;
639  sc->drefs = av_mallocz(entries * sizeof(*sc->drefs));
640  if (!sc->drefs)
641  return AVERROR(ENOMEM);
642  sc->drefs_count = entries;
643 
644  for (i = 0; i < entries; i++) {
645  MOVDref *dref = &sc->drefs[i];
646  uint32_t size = avio_rb32(pb);
647  int64_t next = avio_tell(pb);
648 
649  if (size < 12 || next < 0 || next > INT64_MAX - size)
650  return AVERROR_INVALIDDATA;
651 
652  next += size - 4;
653 
654  dref->type = avio_rl32(pb);
655  avio_rb32(pb); // version + flags
656 
657  if (dref->type == MKTAG('a','l','i','s') && size > 150) {
658  /* macintosh alias record */
659  uint16_t volume_len, len;
660  int16_t type;
661  int ret;
662 
663  avio_skip(pb, 10);
664 
665  volume_len = avio_r8(pb);
666  volume_len = FFMIN(volume_len, 27);
667  ret = ffio_read_size(pb, dref->volume, 27);
668  if (ret < 0)
669  return ret;
670  dref->volume[volume_len] = 0;
671  av_log(c->fc, AV_LOG_DEBUG, "volume %s, len %d\n", dref->volume, volume_len);
672 
673  avio_skip(pb, 12);
674 
675  len = avio_r8(pb);
676  len = FFMIN(len, 63);
677  ret = ffio_read_size(pb, dref->filename, 63);
678  if (ret < 0)
679  return ret;
680  dref->filename[len] = 0;
681  av_log(c->fc, AV_LOG_DEBUG, "filename %s, len %d\n", dref->filename, len);
682 
683  avio_skip(pb, 16);
684 
685  /* read next level up_from_alias/down_to_target */
686  dref->nlvl_from = avio_rb16(pb);
687  dref->nlvl_to = avio_rb16(pb);
688  av_log(c->fc, AV_LOG_DEBUG, "nlvl from %d, nlvl to %d\n",
689  dref->nlvl_from, dref->nlvl_to);
690 
691  avio_skip(pb, 16);
692 
693  for (type = 0; type != -1 && avio_tell(pb) < next; ) {
694  if (avio_feof(pb))
695  return AVERROR_EOF;
696  type = avio_rb16(pb);
697  len = avio_rb16(pb);
698  av_log(c->fc, AV_LOG_DEBUG, "type %d, len %d\n", type, len);
699  if (len&1)
700  len += 1;
701  if (type == 2) { // absolute path
702  av_free(dref->path);
703  dref->path = av_mallocz(len+1);
704  if (!dref->path)
705  return AVERROR(ENOMEM);
706 
707  ret = ffio_read_size(pb, dref->path, len);
708  if (ret < 0) {
709  av_freep(&dref->path);
710  return ret;
711  }
712  if (len > volume_len && !strncmp(dref->path, dref->volume, volume_len)) {
713  len -= volume_len;
714  memmove(dref->path, dref->path+volume_len, len);
715  dref->path[len] = 0;
716  }
717  // trim string of any ending zeros
718  for (j = len - 1; j >= 0; j--) {
719  if (dref->path[j] == 0)
720  len--;
721  else
722  break;
723  }
724  for (j = 0; j < len; j++)
725  if (dref->path[j] == ':' || dref->path[j] == 0)
726  dref->path[j] = '/';
727  av_log(c->fc, AV_LOG_DEBUG, "path %s\n", dref->path);
728  } else if (type == 0) { // directory name
729  av_free(dref->dir);
730  dref->dir = av_malloc(len+1);
731  if (!dref->dir)
732  return AVERROR(ENOMEM);
733 
734  ret = ffio_read_size(pb, dref->dir, len);
735  if (ret < 0) {
736  av_freep(&dref->dir);
737  return ret;
738  }
739  dref->dir[len] = 0;
740  for (j = 0; j < len; j++)
741  if (dref->dir[j] == ':')
742  dref->dir[j] = '/';
743  av_log(c->fc, AV_LOG_DEBUG, "dir %s\n", dref->dir);
744  } else
745  avio_skip(pb, len);
746  }
747  } else {
748  av_log(c->fc, AV_LOG_DEBUG, "Unknown dref type 0x%08"PRIx32" size %"PRIu32"\n",
749  dref->type, size);
750  entries--;
751  i--;
752  }
753  avio_seek(pb, next, SEEK_SET);
754  }
755  return 0;
756 }
757 
759 {
760  AVStream *st;
761  uint32_t type;
762  uint32_t ctype;
763  int64_t title_size;
764  char *title_str;
765  int ret;
766 
767  avio_r8(pb); /* version */
768  avio_rb24(pb); /* flags */
769 
770  /* component type */
771  ctype = avio_rl32(pb);
772  type = avio_rl32(pb); /* component subtype */
773 
774  av_log(c->fc, AV_LOG_TRACE, "ctype=%s\n", av_fourcc2str(ctype));
775  av_log(c->fc, AV_LOG_TRACE, "stype=%s\n", av_fourcc2str(type));
776 
777  if (c->trak_index < 0) { // meta not inside a trak
778  if (type == MKTAG('m','d','t','a')) {
779  c->found_hdlr_mdta = 1;
780  }
781  return 0;
782  }
783 
784  st = c->fc->streams[c->fc->nb_streams-1];
785 
786  if (type == MKTAG('v','i','d','e'))
788  else if (type == MKTAG('s','o','u','n'))
790  else if (type == MKTAG('m','1','a',' '))
792  else if ((type == MKTAG('s','u','b','p')) || (type == MKTAG('c','l','c','p')))
794 
795  avio_rb32(pb); /* component manufacture */
796  avio_rb32(pb); /* component flags */
797  avio_rb32(pb); /* component flags mask */
798 
799  title_size = atom.size - 24;
800  if (title_size > 0) {
801  if (title_size > FFMIN(INT_MAX, SIZE_MAX-1))
802  return AVERROR_INVALIDDATA;
803  title_str = av_malloc(title_size + 1); /* Add null terminator */
804  if (!title_str)
805  return AVERROR(ENOMEM);
806 
807  ret = ffio_read_size(pb, title_str, title_size);
808  if (ret < 0) {
809  av_freep(&title_str);
810  return ret;
811  }
812  title_str[title_size] = 0;
813  if (title_str[0]) {
814  int off = (!c->isom && title_str[0] == title_size - 1);
815  // flag added so as to not set stream handler name if already set from mdia->hdlr
816  av_dict_set(&st->metadata, "handler_name", title_str + off, AV_DICT_DONT_OVERWRITE);
817  }
818  av_freep(&title_str);
819  }
820 
821  return 0;
822 }
823 
825 {
826  return ff_mov_read_esds(c->fc, pb);
827 }
828 
830 {
831  AVStream *st;
832  AVPacketSideData *sd;
833  enum AVAudioServiceType *ast;
834  int ac3info, acmod, lfeon, bsmod;
835  uint64_t mask;
836 
837  if (c->fc->nb_streams < 1)
838  return 0;
839  st = c->fc->streams[c->fc->nb_streams-1];
840 
844  sizeof(*ast), 0);
845  if (!sd)
846  return AVERROR(ENOMEM);
847 
848  ast = (enum AVAudioServiceType*)sd->data;
849  ac3info = avio_rb24(pb);
850  bsmod = (ac3info >> 14) & 0x7;
851  acmod = (ac3info >> 11) & 0x7;
852  lfeon = (ac3info >> 10) & 0x1;
853 
855  if (lfeon)
859 
860  *ast = bsmod;
861  if (st->codecpar->ch_layout.nb_channels > 1 && bsmod == 0x7)
863 
864  return 0;
865 }
866 
867 #if CONFIG_IAMFDEC
868 static int mov_read_iacb(MOVContext *c, AVIOContext *pb, MOVAtom atom)
869 {
870  AVStream *st;
871  MOVStreamContext *sc;
872  FFIOContext b;
873  AVIOContext *descriptor_pb;
874  AVDictionary *metadata;
875  IAMFContext *iamf;
876  int64_t start_time, duration;
877  unsigned descriptors_size;
878  int nb_frames, disposition;
879  int version, ret;
880 
881  if (atom.size < 5)
882  return AVERROR_INVALIDDATA;
883 
884  if (c->fc->nb_streams < 1)
885  return 0;
886 
887  version = avio_r8(pb);
888  if (version != 1) {
889  av_log(c->fc, AV_LOG_ERROR, "%s configurationVersion %d",
890  version < 1 ? "invalid" : "unsupported", version);
891  return AVERROR_INVALIDDATA;
892  }
893 
894  descriptors_size = ffio_read_leb(pb);
895  if (!descriptors_size || descriptors_size > INT_MAX)
896  return AVERROR_INVALIDDATA;
897 
898  st = c->fc->streams[c->fc->nb_streams - 1];
899  sc = st->priv_data;
900 
901  sc->iamf = av_mallocz(sizeof(*sc->iamf));
902  if (!sc->iamf)
903  return AVERROR(ENOMEM);
904  iamf = &sc->iamf->iamf;
905 
906  st->codecpar->extradata = av_malloc(descriptors_size);
907  if (!st->codecpar->extradata)
908  return AVERROR(ENOMEM);
909  st->codecpar->extradata_size = descriptors_size;
910 
911  ret = avio_read(pb, st->codecpar->extradata, descriptors_size);
912  if (ret != descriptors_size)
913  return ret < 0 ? ret : AVERROR_INVALIDDATA;
914 
915  ffio_init_read_context(&b, st->codecpar->extradata, descriptors_size);
916  descriptor_pb = &b.pub;
917 
918  ret = ff_iamfdec_read_descriptors(iamf, descriptor_pb, descriptors_size, c->fc);
919  if (ret < 0)
920  return ret;
921 
922  metadata = st->metadata;
923  st->metadata = NULL;
924  start_time = st->start_time;
925  nb_frames = st->nb_frames;
926  duration = st->duration;
927  disposition = st->disposition;
928 
929  for (int i = 0; i < iamf->nb_audio_elements; i++) {
930  IAMFAudioElement *audio_element = iamf->audio_elements[i];
931  const AVIAMFAudioElement *element;
932  AVStreamGroup *stg =
934 
935  if (!stg) {
936  ret = AVERROR(ENOMEM);
937  goto fail;
938  }
939 
941  stg->id = audio_element->audio_element_id;
942  /* Transfer ownership */
943  element = stg->params.iamf_audio_element = audio_element->element;
944  audio_element->element = NULL;
945 
946  for (int j = 0; j < audio_element->nb_substreams; j++) {
947  IAMFSubStream *substream = &audio_element->substreams[j];
948  AVStream *stream;
949 
950  if (!i && !j) {
951  if (audio_element->layers[0].substream_count != 1)
952  disposition &= ~AV_DISPOSITION_DEFAULT;
953  stream = st;
954  } else
955  stream = avformat_new_stream(c->fc, NULL);
956  if (!stream) {
957  ret = AVERROR(ENOMEM);
958  goto fail;
959  }
960 
961  stream->start_time = start_time;
962  stream->nb_frames = nb_frames;
963  stream->duration = duration;
964  stream->disposition = disposition;
965  if (stream != st) {
966  stream->priv_data = sc;
967  sc->refcount++;
968  }
969 
972  if (i || j) {
974  if (audio_element->layers[0].substream_count == 1)
976  }
977 
978  ret = avcodec_parameters_copy(stream->codecpar, substream->codecpar);
979  if (ret < 0)
980  goto fail;
981 
982  stream->id = substream->audio_substream_id;
983 
984  avpriv_set_pts_info(st, 64, 1, sc->time_scale);
985 
986  ret = avformat_stream_group_add_stream(stg, stream);
987  if (ret < 0)
988  goto fail;
989  }
990 
991  ret = av_dict_copy(&stg->metadata, metadata, 0);
992  if (ret < 0)
993  goto fail;
994  }
995 
996  for (int i = 0; i < iamf->nb_mix_presentations; i++) {
997  IAMFMixPresentation *mix_presentation = iamf->mix_presentations[i];
998  const AVIAMFMixPresentation *mix = mix_presentation->cmix;
999  AVStreamGroup *stg =
1001 
1002  if (!stg) {
1003  ret = AVERROR(ENOMEM);
1004  goto fail;
1005  }
1006 
1008  stg->id = mix_presentation->mix_presentation_id;
1009  /* Transfer ownership */
1010  stg->params.iamf_mix_presentation = mix_presentation->mix;
1011  mix_presentation->mix = NULL;
1012 
1013  for (int j = 0; j < mix->nb_submixes; j++) {
1014  const AVIAMFSubmix *submix = mix->submixes[j];
1015 
1016  for (int k = 0; k < submix->nb_elements; k++) {
1017  const AVIAMFSubmixElement *submix_element = submix->elements[k];
1018  const AVStreamGroup *audio_element = NULL;
1019 
1020  for (int l = 0; l < c->fc->nb_stream_groups; l++)
1021  if (c->fc->stream_groups[l]->type == AV_STREAM_GROUP_PARAMS_IAMF_AUDIO_ELEMENT &&
1022  c->fc->stream_groups[l]->id == submix_element->audio_element_id) {
1023  audio_element = c->fc->stream_groups[l];
1024  break;
1025  }
1026  av_assert0(audio_element);
1027 
1028  for (int l = 0; l < audio_element->nb_streams; l++) {
1029  ret = avformat_stream_group_add_stream(stg, audio_element->streams[l]);
1030  if (ret < 0 && ret != AVERROR(EEXIST))
1031  goto fail;
1032  }
1033  }
1034  }
1035 
1036  ret = av_dict_copy(&stg->metadata, metadata, 0);
1037  if (ret < 0)
1038  goto fail;
1039  }
1040 
1041  ret = 0;
1042 fail:
1043  av_dict_free(&metadata);
1044 
1045  return ret;
1046 }
1047 #endif
1048 
1050 {
1051  AVStream *st;
1052  AVPacketSideData *sd;
1053  enum AVAudioServiceType *ast;
1054  int eac3info, acmod, lfeon, bsmod;
1055  uint64_t mask;
1056 
1057  if (c->fc->nb_streams < 1)
1058  return 0;
1059  st = c->fc->streams[c->fc->nb_streams-1];
1060 
1064  sizeof(*ast), 0);
1065  if (!sd)
1066  return AVERROR(ENOMEM);
1067 
1068  ast = (enum AVAudioServiceType*)sd->data;
1069 
1070  /* No need to parse fields for additional independent substreams and its
1071  * associated dependent substreams since libavcodec's E-AC-3 decoder
1072  * does not support them yet. */
1073  avio_rb16(pb); /* data_rate and num_ind_sub */
1074  eac3info = avio_rb24(pb);
1075  bsmod = (eac3info >> 12) & 0x1f;
1076  acmod = (eac3info >> 9) & 0x7;
1077  lfeon = (eac3info >> 8) & 0x1;
1078 
1080  if (lfeon)
1084 
1085  *ast = bsmod;
1086  if (st->codecpar->ch_layout.nb_channels > 1 && bsmod == 0x7)
1088 
1089  return 0;
1090 }
1091 
1093 {
1094 #define DDTS_SIZE 20
1095  uint8_t buf[DDTS_SIZE + AV_INPUT_BUFFER_PADDING_SIZE];
1096  AVStream *st = NULL;
1097  uint32_t frame_duration_code = 0;
1098  uint32_t channel_layout_code = 0;
1099  GetBitContext gb;
1100  int ret;
1101 
1102  if ((ret = ffio_read_size(pb, buf, DDTS_SIZE)) < 0)
1103  return ret;
1104 
1105  init_get_bits(&gb, buf, 8 * DDTS_SIZE);
1106 
1107  if (c->fc->nb_streams < 1) {
1108  return 0;
1109  }
1110  st = c->fc->streams[c->fc->nb_streams-1];
1111 
1112  st->codecpar->sample_rate = get_bits_long(&gb, 32);
1113  if (st->codecpar->sample_rate <= 0) {
1114  av_log(c->fc, AV_LOG_ERROR, "Invalid sample rate %d\n", st->codecpar->sample_rate);
1115  return AVERROR_INVALIDDATA;
1116  }
1117  skip_bits_long(&gb, 32); /* max bitrate */
1118  st->codecpar->bit_rate = get_bits_long(&gb, 32);
1119  st->codecpar->bits_per_coded_sample = get_bits(&gb, 8);
1120  frame_duration_code = get_bits(&gb, 2);
1121  skip_bits(&gb, 30); /* various fields */
1122  channel_layout_code = get_bits(&gb, 16);
1123 
1124  st->codecpar->frame_size =
1125  (frame_duration_code == 0) ? 512 :
1126  (frame_duration_code == 1) ? 1024 :
1127  (frame_duration_code == 2) ? 2048 :
1128  (frame_duration_code == 3) ? 4096 : 0;
1129 
1130  if (channel_layout_code > 0xff) {
1131  av_log(c->fc, AV_LOG_WARNING, "Unsupported DTS audio channel layout\n");
1132  }
1135  ((channel_layout_code & 0x1) ? AV_CH_FRONT_CENTER : 0) |
1136  ((channel_layout_code & 0x2) ? AV_CH_FRONT_LEFT : 0) |
1137  ((channel_layout_code & 0x2) ? AV_CH_FRONT_RIGHT : 0) |
1138  ((channel_layout_code & 0x4) ? AV_CH_SIDE_LEFT : 0) |
1139  ((channel_layout_code & 0x4) ? AV_CH_SIDE_RIGHT : 0) |
1140  ((channel_layout_code & 0x8) ? AV_CH_LOW_FREQUENCY : 0));
1141 
1142  return 0;
1143 }
1144 
1146 {
1147  AVStream *st;
1148 
1149  if (c->fc->nb_streams < 1)
1150  return 0;
1151  st = c->fc->streams[c->fc->nb_streams-1];
1152 
1153  if (atom.size < 16)
1154  return 0;
1155 
1156  /* skip version and flags */
1157  avio_skip(pb, 4);
1158 
1159  ff_mov_read_chan(c->fc, pb, st, atom.size - 4);
1160 
1161  return 0;
1162 }
1163 
1165 {
1166  int64_t end = av_sat_add64(avio_tell(pb), atom.size);
1167  int version, flags;
1168  int ret;
1169  AVStream *st;
1170 
1171  if (c->fc->nb_streams < 1)
1172  return 0;
1173  st = c->fc->streams[c->fc->nb_streams-1];
1174 
1175  version = avio_r8(pb);
1176  flags = avio_rb24(pb);
1177  if (version != 0 || flags != 0) {
1178  av_log(c->fc, AV_LOG_ERROR,
1179  "Unsupported 'chnl' box with version %d, flags: %#x",
1180  version, flags);
1181  return AVERROR_INVALIDDATA;
1182  }
1183 
1184  ret = ff_mov_read_chnl(c->fc, pb, st);
1185  if (ret < 0)
1186  return ret;
1187 
1188  if (avio_tell(pb) != end) {
1189  av_log(c->fc, AV_LOG_WARNING, "skip %" PRId64 " bytes of unknown data inside chnl\n",
1190  end - avio_tell(pb));
1191  avio_seek(pb, end, SEEK_SET);
1192  }
1193  return ret;
1194 }
1195 
1197 {
1198  AVStream *st;
1199  int ret;
1200 
1201  if (c->fc->nb_streams < 1)
1202  return 0;
1203  st = c->fc->streams[c->fc->nb_streams-1];
1204 
1205  if ((ret = ff_get_wav_header(c->fc, pb, st->codecpar, atom.size, 0)) < 0)
1206  av_log(c->fc, AV_LOG_WARNING, "get_wav_header failed\n");
1207 
1208  return ret;
1209 }
1210 
1211 /* This atom overrides any previously set aspect ratio */
1213 {
1214  const int num = avio_rb32(pb);
1215  const int den = avio_rb32(pb);
1216  AVStream *st;
1217 
1218  if (c->fc->nb_streams < 1)
1219  return 0;
1220  st = c->fc->streams[c->fc->nb_streams-1];
1221 
1222  if (den != 0) {
1224  num, den, 32767);
1225  }
1226  return 0;
1227 }
1228 
1229 /* this atom contains actual media data */
1231 {
1232  if (atom.size == 0) /* wrong one (MP4) */
1233  return 0;
1234  c->found_mdat=1;
1235  return 0; /* now go for moov */
1236 }
1237 
1238 #define DRM_BLOB_SIZE 56
1239 
1241 {
1242  uint8_t intermediate_key[20];
1243  uint8_t intermediate_iv[20];
1244  uint8_t input[64];
1245  uint8_t output[64];
1246  uint8_t file_checksum[20];
1247  uint8_t calculated_checksum[20];
1248  char checksum_string[2 * sizeof(file_checksum) + 1];
1249  struct AVSHA *sha;
1250  int i;
1251  int ret = 0;
1252  uint8_t *activation_bytes = c->activation_bytes;
1253  uint8_t *fixed_key = c->audible_fixed_key;
1254 
1255  c->aax_mode = 1;
1256 
1257  sha = av_sha_alloc();
1258  if (!sha)
1259  return AVERROR(ENOMEM);
1260  av_free(c->aes_decrypt);
1261  c->aes_decrypt = av_aes_alloc();
1262  if (!c->aes_decrypt) {
1263  ret = AVERROR(ENOMEM);
1264  goto fail;
1265  }
1266 
1267  /* drm blob processing */
1268  avio_read(pb, output, 8); // go to offset 8, absolute position 0x251
1270  avio_read(pb, output, 4); // go to offset 4, absolute position 0x28d
1271  avio_read(pb, file_checksum, 20);
1272 
1273  // required by external tools
1274  ff_data_to_hex(checksum_string, file_checksum, sizeof(file_checksum), 1);
1275  av_log(c->fc, AV_LOG_INFO, "[aax] file checksum == %s\n", checksum_string);
1276 
1277  /* verify activation data */
1278  if (!activation_bytes) {
1279  av_log(c->fc, AV_LOG_WARNING, "[aax] activation_bytes option is missing!\n");
1280  ret = 0; /* allow ffprobe to continue working on .aax files */
1281  goto fail;
1282  }
1283  if (c->activation_bytes_size != 4) {
1284  av_log(c->fc, AV_LOG_FATAL, "[aax] activation_bytes value needs to be 4 bytes!\n");
1285  ret = AVERROR(EINVAL);
1286  goto fail;
1287  }
1288 
1289  /* verify fixed key */
1290  if (c->audible_fixed_key_size != 16) {
1291  av_log(c->fc, AV_LOG_FATAL, "[aax] audible_fixed_key value needs to be 16 bytes!\n");
1292  ret = AVERROR(EINVAL);
1293  goto fail;
1294  }
1295 
1296  /* AAX (and AAX+) key derivation */
1297  av_sha_init(sha, 160);
1298  av_sha_update(sha, fixed_key, 16);
1299  av_sha_update(sha, activation_bytes, 4);
1300  av_sha_final(sha, intermediate_key);
1301  av_sha_init(sha, 160);
1302  av_sha_update(sha, fixed_key, 16);
1303  av_sha_update(sha, intermediate_key, 20);
1304  av_sha_update(sha, activation_bytes, 4);
1305  av_sha_final(sha, intermediate_iv);
1306  av_sha_init(sha, 160);
1307  av_sha_update(sha, intermediate_key, 16);
1308  av_sha_update(sha, intermediate_iv, 16);
1309  av_sha_final(sha, calculated_checksum);
1310  if (memcmp(calculated_checksum, file_checksum, 20)) { // critical error
1311  av_log(c->fc, AV_LOG_ERROR, "[aax] mismatch in checksums!\n");
1313  goto fail;
1314  }
1315  av_aes_init(c->aes_decrypt, intermediate_key, 128, 1);
1316  av_aes_crypt(c->aes_decrypt, output, input, DRM_BLOB_SIZE >> 4, intermediate_iv, 1);
1317  for (i = 0; i < 4; i++) {
1318  // file data (in output) is stored in big-endian mode
1319  if (activation_bytes[i] != output[3 - i]) { // critical error
1320  av_log(c->fc, AV_LOG_ERROR, "[aax] error in drm blob decryption!\n");
1322  goto fail;
1323  }
1324  }
1325  memcpy(c->file_key, output + 8, 16);
1326  memcpy(input, output + 26, 16);
1327  av_sha_init(sha, 160);
1328  av_sha_update(sha, input, 16);
1329  av_sha_update(sha, c->file_key, 16);
1330  av_sha_update(sha, fixed_key, 16);
1331  av_sha_final(sha, c->file_iv);
1332 
1333 fail:
1334  av_free(sha);
1335 
1336  return ret;
1337 }
1338 
1340 {
1341  if (c->audible_key_size != 16) {
1342  av_log(c->fc, AV_LOG_FATAL, "[aaxc] audible_key value needs to be 16 bytes!\n");
1343  return AVERROR(EINVAL);
1344  }
1345 
1346  if (c->audible_iv_size != 16) {
1347  av_log(c->fc, AV_LOG_FATAL, "[aaxc] audible_iv value needs to be 16 bytes!\n");
1348  return AVERROR(EINVAL);
1349  }
1350 
1351  c->aes_decrypt = av_aes_alloc();
1352  if (!c->aes_decrypt) {
1353  return AVERROR(ENOMEM);
1354  }
1355 
1356  memcpy(c->file_key, c->audible_key, 16);
1357  memcpy(c->file_iv, c->audible_iv, 16);
1358  c->aax_mode = 1;
1359 
1360  return 0;
1361 }
1362 
1363 // Audible AAX (and AAX+) bytestream decryption
1364 static int aax_filter(uint8_t *input, int size, MOVContext *c)
1365 {
1366  int blocks = 0;
1367  unsigned char iv[16];
1368 
1369  memcpy(iv, c->file_iv, 16); // iv is overwritten
1370  blocks = size >> 4; // trailing bytes are not encrypted!
1371  av_aes_init(c->aes_decrypt, c->file_key, 128, 1);
1372  av_aes_crypt(c->aes_decrypt, input, input, blocks, iv, 1);
1373 
1374  return 0;
1375 }
1376 
1377 /* read major brand, minor version and compatible brands and store them as metadata */
1379 {
1380  uint32_t minor_ver;
1381  int comp_brand_size;
1382  char* comp_brands_str;
1383  uint8_t type[5] = {0};
1384  int ret = ffio_read_size(pb, type, 4);
1385  if (ret < 0)
1386  return ret;
1387  if (c->fc->nb_streams) {
1388  if (c->fc->strict_std_compliance >= FF_COMPLIANCE_STRICT)
1389  return AVERROR_INVALIDDATA;
1390  av_log(c->fc, AV_LOG_DEBUG, "Ignoring duplicate FTYP\n");
1391  return 0;
1392  }
1393 
1394  if (strcmp(type, "qt "))
1395  c->isom = 1;
1396  av_log(c->fc, AV_LOG_DEBUG, "ISO: File Type Major Brand: %.4s\n",(char *)&type);
1397  av_dict_set(&c->fc->metadata, "major_brand", type, 0);
1398  minor_ver = avio_rb32(pb); /* minor version */
1399  av_dict_set_int(&c->fc->metadata, "minor_version", minor_ver, 0);
1400 
1401  comp_brand_size = atom.size - 8;
1402  if (comp_brand_size < 0 || comp_brand_size == INT_MAX)
1403  return AVERROR_INVALIDDATA;
1404  comp_brands_str = av_malloc(comp_brand_size + 1); /* Add null terminator */
1405  if (!comp_brands_str)
1406  return AVERROR(ENOMEM);
1407 
1408  ret = ffio_read_size(pb, comp_brands_str, comp_brand_size);
1409  if (ret < 0) {
1410  av_freep(&comp_brands_str);
1411  return ret;
1412  }
1413  comp_brands_str[comp_brand_size] = 0;
1414  av_dict_set(&c->fc->metadata, "compatible_brands",
1415  comp_brands_str, AV_DICT_DONT_STRDUP_VAL);
1416 
1417  // Logic for handling Audible's .aaxc files
1418  if (!strcmp(type, "aaxc")) {
1419  mov_aaxc_crypto(c);
1420  }
1421 
1422  return 0;
1423 }
1424 
1425 /* this atom should contain all header atoms */
1427 {
1428  int ret;
1429 
1430  if (c->found_moov) {
1431  av_log(c->fc, AV_LOG_WARNING, "Found duplicated MOOV Atom. Skipped it\n");
1432  avio_skip(pb, atom.size);
1433  return 0;
1434  }
1435 
1436  if ((ret = mov_read_default(c, pb, atom)) < 0)
1437  return ret;
1438  /* we parsed the 'moov' atom, we can terminate the parsing as soon as we find the 'mdat' */
1439  /* so we don't parse the whole file if over a network */
1440  c->found_moov=1;
1441  return 0; /* now go for mdat */
1442 }
1443 
1445  MOVFragmentIndex *frag_index,
1446  int index,
1447  int id)
1448 {
1449  int i;
1450  MOVFragmentIndexItem * item;
1451 
1452  if (index < 0 || index >= frag_index->nb_items)
1453  return NULL;
1454  item = &frag_index->item[index];
1455  for (i = 0; i < item->nb_stream_info; i++)
1456  if (item->stream_info[i].id == id)
1457  return &item->stream_info[i];
1458 
1459  // This shouldn't happen
1460  return NULL;
1461 }
1462 
1463 static void set_frag_stream(MOVFragmentIndex *frag_index, int id)
1464 {
1465  int i;
1466  MOVFragmentIndexItem * item;
1467 
1468  if (frag_index->current < 0 ||
1469  frag_index->current >= frag_index->nb_items)
1470  return;
1471 
1472  item = &frag_index->item[frag_index->current];
1473  for (i = 0; i < item->nb_stream_info; i++)
1474  if (item->stream_info[i].id == id) {
1475  item->current = i;
1476  return;
1477  }
1478 
1479  // id not found. This shouldn't happen.
1480  item->current = -1;
1481 }
1482 
1484  MOVFragmentIndex *frag_index)
1485 {
1486  MOVFragmentIndexItem *item;
1487  if (frag_index->current < 0 ||
1488  frag_index->current >= frag_index->nb_items)
1489  return NULL;
1490 
1491  item = &frag_index->item[frag_index->current];
1492  if (item->current >= 0 && item->current < item->nb_stream_info)
1493  return &item->stream_info[item->current];
1494 
1495  // This shouldn't happen
1496  return NULL;
1497 }
1498 
1499 static int search_frag_moof_offset(MOVFragmentIndex *frag_index, int64_t offset)
1500 {
1501  int a, b, m;
1502  int64_t moof_offset;
1503 
1504  // Optimize for appending new entries
1505  if (!frag_index->nb_items ||
1506  frag_index->item[frag_index->nb_items - 1].moof_offset < offset)
1507  return frag_index->nb_items;
1508 
1509  a = -1;
1510  b = frag_index->nb_items;
1511 
1512  while (b - a > 1) {
1513  m = (a + b) >> 1;
1514  moof_offset = frag_index->item[m].moof_offset;
1515  if (moof_offset >= offset)
1516  b = m;
1517  if (moof_offset <= offset)
1518  a = m;
1519  }
1520  return b;
1521 }
1522 
1523 static int64_t get_stream_info_time(MOVFragmentStreamInfo * frag_stream_info)
1524 {
1525  av_assert0(frag_stream_info);
1526  if (frag_stream_info->sidx_pts != AV_NOPTS_VALUE)
1527  return frag_stream_info->sidx_pts;
1528  if (frag_stream_info->first_tfra_pts != AV_NOPTS_VALUE)
1529  return frag_stream_info->first_tfra_pts;
1530  return frag_stream_info->tfdt_dts;
1531 }
1532 
1533 static int64_t get_frag_time(AVFormatContext *s, AVStream *dst_st,
1534  MOVFragmentIndex *frag_index, int index)
1535 {
1536  MOVFragmentStreamInfo * frag_stream_info;
1537  MOVStreamContext *sc = dst_st->priv_data;
1538  int64_t timestamp;
1539  int i, j;
1540 
1541  // If the stream is referenced by any sidx, limit the search
1542  // to fragments that referenced this stream in the sidx
1543  if (sc->has_sidx) {
1544  frag_stream_info = get_frag_stream_info(frag_index, index, sc->id);
1545  if (frag_stream_info->sidx_pts != AV_NOPTS_VALUE)
1546  return frag_stream_info->sidx_pts;
1547  if (frag_stream_info->first_tfra_pts != AV_NOPTS_VALUE)
1548  return frag_stream_info->first_tfra_pts;
1549  return frag_stream_info->sidx_pts;
1550  }
1551 
1552  for (i = 0; i < frag_index->item[index].nb_stream_info; i++) {
1553  AVStream *frag_stream = NULL;
1554  frag_stream_info = &frag_index->item[index].stream_info[i];
1555  for (j = 0; j < s->nb_streams; j++) {
1556  MOVStreamContext *sc2 = s->streams[j]->priv_data;
1557  if (sc2->id == frag_stream_info->id)
1558  frag_stream = s->streams[j];
1559  }
1560  if (!frag_stream) {
1561  av_log(s, AV_LOG_WARNING, "No stream matching sidx ID found.\n");
1562  continue;
1563  }
1564  timestamp = get_stream_info_time(frag_stream_info);
1565  if (timestamp != AV_NOPTS_VALUE)
1566  return av_rescale_q(timestamp, frag_stream->time_base, dst_st->time_base);
1567  }
1568  return AV_NOPTS_VALUE;
1569 }
1570 
1572  AVStream *st, int64_t timestamp)
1573 {
1574  int a, b, m, m0;
1575  int64_t frag_time;
1576 
1577  a = -1;
1578  b = frag_index->nb_items;
1579 
1580  while (b - a > 1) {
1581  m0 = m = (a + b) >> 1;
1582 
1583  while (m < b &&
1584  (frag_time = get_frag_time(s, st, frag_index, m)) == AV_NOPTS_VALUE)
1585  m++;
1586 
1587  if (m < b && frag_time <= timestamp)
1588  a = m;
1589  else
1590  b = m0;
1591  }
1592 
1593  return a;
1594 }
1595 
1596 static int update_frag_index(MOVContext *c, int64_t offset)
1597 {
1598  int index, i;
1599  MOVFragmentIndexItem * item;
1600  MOVFragmentStreamInfo * frag_stream_info;
1601 
1602  // If moof_offset already exists in frag_index, return index to it
1603  index = search_frag_moof_offset(&c->frag_index, offset);
1604  if (index < c->frag_index.nb_items &&
1605  c->frag_index.item[index].moof_offset == offset)
1606  return index;
1607 
1608  // offset is not yet in frag index.
1609  // Insert new item at index (sorted by moof offset)
1610  item = av_fast_realloc(c->frag_index.item,
1611  &c->frag_index.allocated_size,
1612  (c->frag_index.nb_items + 1) *
1613  sizeof(*c->frag_index.item));
1614  if (!item)
1615  return -1;
1616  c->frag_index.item = item;
1617 
1618  frag_stream_info = av_realloc_array(NULL, c->fc->nb_streams,
1619  sizeof(*item->stream_info));
1620  if (!frag_stream_info)
1621  return -1;
1622 
1623  for (i = 0; i < c->fc->nb_streams; i++) {
1624  // Avoid building frag index if streams lack track id.
1625  MOVStreamContext *sc = c->fc->streams[i]->priv_data;
1626  if (sc->id < 0) {
1627  av_free(frag_stream_info);
1628  return AVERROR_INVALIDDATA;
1629  }
1630 
1631  frag_stream_info[i].id = sc->id;
1632  frag_stream_info[i].sidx_pts = AV_NOPTS_VALUE;
1633  frag_stream_info[i].tfdt_dts = AV_NOPTS_VALUE;
1634  frag_stream_info[i].next_trun_dts = AV_NOPTS_VALUE;
1635  frag_stream_info[i].first_tfra_pts = AV_NOPTS_VALUE;
1636  frag_stream_info[i].index_base = -1;
1637  frag_stream_info[i].index_entry = -1;
1638  frag_stream_info[i].encryption_index = NULL;
1639  frag_stream_info[i].stsd_id = -1;
1640  }
1641 
1642  if (index < c->frag_index.nb_items)
1643  memmove(c->frag_index.item + index + 1, c->frag_index.item + index,
1644  (c->frag_index.nb_items - index) * sizeof(*c->frag_index.item));
1645 
1646  item = &c->frag_index.item[index];
1647  item->headers_read = 0;
1648  item->current = 0;
1649  item->nb_stream_info = c->fc->nb_streams;
1650  item->moof_offset = offset;
1651  item->stream_info = frag_stream_info;
1652  c->frag_index.nb_items++;
1653 
1654  return index;
1655 }
1656 
1657 static void fix_frag_index_entries(MOVFragmentIndex *frag_index, int index,
1658  int id, int entries)
1659 {
1660  int i;
1661  MOVFragmentStreamInfo * frag_stream_info;
1662 
1663  if (index < 0)
1664  return;
1665  for (i = index; i < frag_index->nb_items; i++) {
1666  frag_stream_info = get_frag_stream_info(frag_index, i, id);
1667  if (frag_stream_info && frag_stream_info->index_entry >= 0)
1668  frag_stream_info->index_entry += entries;
1669  }
1670 }
1671 
1673 {
1674  // Set by mov_read_tfhd(). mov_read_trun() will reject files missing tfhd.
1675  c->fragment.found_tfhd = 0;
1676 
1677  if (!c->has_looked_for_mfra && c->use_mfra_for > 0) {
1678  c->has_looked_for_mfra = 1;
1679  if (pb->seekable & AVIO_SEEKABLE_NORMAL) {
1680  int ret;
1681  av_log(c->fc, AV_LOG_VERBOSE, "stream has moof boxes, will look "
1682  "for a mfra\n");
1683  if ((ret = mov_read_mfra(c, pb)) < 0) {
1684  av_log(c->fc, AV_LOG_VERBOSE, "found a moof box but failed to "
1685  "read the mfra (may be a live ismv)\n");
1686  }
1687  } else {
1688  av_log(c->fc, AV_LOG_VERBOSE, "found a moof box but stream is not "
1689  "seekable, can not look for mfra\n");
1690  }
1691  }
1692  c->fragment.moof_offset = c->fragment.implicit_offset = avio_tell(pb) - 8;
1693  av_log(c->fc, AV_LOG_TRACE, "moof offset %"PRIx64"\n", c->fragment.moof_offset);
1694  c->frag_index.current = update_frag_index(c, c->fragment.moof_offset);
1695  return mov_read_default(c, pb, atom);
1696 }
1697 
1699 {
1700  int64_t time;
1701  if (version == 1) {
1702  time = avio_rb64(pb);
1703  avio_rb64(pb);
1704  if (time < 0) {
1705  av_log(c->fc, AV_LOG_DEBUG, "creation_time is negative\n");
1706  return;
1707  }
1708  } else {
1709  time = avio_rb32(pb);
1710  avio_rb32(pb); /* modification time */
1711  if (time > 0 && time < 2082844800) {
1712  av_log(c->fc, AV_LOG_WARNING, "Detected creation time before 1970, parsing as unix timestamp.\n");
1713  time += 2082844800;
1714  }
1715  }
1716  if (time) {
1717  time -= 2082844800; /* seconds between 1904-01-01 and Epoch */
1718 
1719  if ((int64_t)(time * 1000000ULL) / 1000000 != time) {
1720  av_log(c->fc, AV_LOG_DEBUG, "creation_time is not representable\n");
1721  return;
1722  }
1723 
1724  avpriv_dict_set_timestamp(metadata, "creation_time", time * 1000000);
1725  }
1726 }
1727 
1729 {
1730  AVStream *st;
1731  MOVStreamContext *sc;
1732  int version;
1733  char language[4] = {0};
1734  unsigned lang;
1735 
1736  if (c->fc->nb_streams < 1)
1737  return 0;
1738  st = c->fc->streams[c->fc->nb_streams-1];
1739  sc = st->priv_data;
1740 
1741  if (sc->time_scale) {
1742  av_log(c->fc, AV_LOG_ERROR, "Multiple mdhd?\n");
1743  return AVERROR_INVALIDDATA;
1744  }
1745 
1746  version = avio_r8(pb);
1747  if (version > 1) {
1748  avpriv_request_sample(c->fc, "Version %d", version);
1749  return AVERROR_PATCHWELCOME;
1750  }
1751  avio_rb24(pb); /* flags */
1753 
1754  sc->time_scale = avio_rb32(pb);
1755  if (sc->time_scale <= 0) {
1756  av_log(c->fc, AV_LOG_ERROR, "Invalid mdhd time scale %d, defaulting to 1\n", sc->time_scale);
1757  sc->time_scale = 1;
1758  }
1759  st->duration = (version == 1) ? avio_rb64(pb) : avio_rb32(pb); /* duration */
1760 
1761  if ((version == 1 && st->duration == UINT64_MAX) ||
1762  (version != 1 && st->duration == UINT32_MAX)) {
1763  st->duration = 0;
1764  }
1765 
1766  lang = avio_rb16(pb); /* language */
1767  if (ff_mov_lang_to_iso639(lang, language))
1768  av_dict_set(&st->metadata, "language", language, 0);
1769  avio_rb16(pb); /* quality */
1770 
1771  return 0;
1772 }
1773 
1775 {
1776  int i;
1777  int version = avio_r8(pb); /* version */
1778  avio_rb24(pb); /* flags */
1779 
1780  mov_metadata_creation_time(c, pb, &c->fc->metadata, version);
1781  c->time_scale = avio_rb32(pb); /* time scale */
1782  if (c->time_scale <= 0) {
1783  av_log(c->fc, AV_LOG_ERROR, "Invalid mvhd time scale %d, defaulting to 1\n", c->time_scale);
1784  c->time_scale = 1;
1785  }
1786  av_log(c->fc, AV_LOG_TRACE, "time scale = %i\n", c->time_scale);
1787 
1788  c->duration = (version == 1) ? avio_rb64(pb) : avio_rb32(pb); /* duration */
1789  avio_rb32(pb); /* preferred scale */
1790 
1791  avio_rb16(pb); /* preferred volume */
1792 
1793  avio_skip(pb, 10); /* reserved */
1794 
1795  /* movie display matrix, store it in main context and use it later on */
1796  for (i = 0; i < 3; i++) {
1797  c->movie_display_matrix[i][0] = avio_rb32(pb); // 16.16 fixed point
1798  c->movie_display_matrix[i][1] = avio_rb32(pb); // 16.16 fixed point
1799  c->movie_display_matrix[i][2] = avio_rb32(pb); // 2.30 fixed point
1800  }
1801 
1802  avio_rb32(pb); /* preview time */
1803  avio_rb32(pb); /* preview duration */
1804  avio_rb32(pb); /* poster time */
1805  avio_rb32(pb); /* selection time */
1806  avio_rb32(pb); /* selection duration */
1807  avio_rb32(pb); /* current time */
1808  avio_rb32(pb); /* next track ID */
1809 
1810  return 0;
1811 }
1812 
1814 {
1815  AVStream *st;
1816 
1817  if (fc->nb_streams < 1)
1818  return;
1819  st = fc->streams[fc->nb_streams-1];
1820 
1821  switch (st->codecpar->codec_id) {
1822  case AV_CODEC_ID_PCM_S16BE:
1824  break;
1825  case AV_CODEC_ID_PCM_S24BE:
1827  break;
1828  case AV_CODEC_ID_PCM_S32BE:
1830  break;
1831  case AV_CODEC_ID_PCM_F32BE:
1833  break;
1834  case AV_CODEC_ID_PCM_F64BE:
1836  break;
1837  default:
1838  break;
1839  }
1840 }
1841 
1843 {
1844  int little_endian = avio_rb16(pb) & 0xFF;
1845  av_log(c->fc, AV_LOG_TRACE, "enda %d\n", little_endian);
1846  if (little_endian == 1)
1848  return 0;
1849 }
1850 
1852 {
1853  int format_flags;
1854  int version, flags;
1855  int pcm_sample_size;
1856  AVFormatContext *fc = c->fc;
1857  AVStream *st;
1858  MOVStreamContext *sc;
1859 
1860  if (atom.size < 6) {
1861  av_log(c->fc, AV_LOG_ERROR, "Empty pcmC box\n");
1862  return AVERROR_INVALIDDATA;
1863  }
1864 
1865  version = avio_r8(pb);
1866  flags = avio_rb24(pb);
1867 
1868  if (version != 0 || flags != 0) {
1869  av_log(c->fc, AV_LOG_ERROR,
1870  "Unsupported 'pcmC' box with version %d, flags: %x",
1871  version, flags);
1872  return AVERROR_INVALIDDATA;
1873  }
1874 
1875  format_flags = avio_r8(pb);
1876  pcm_sample_size = avio_r8(pb);
1877 
1878  if (fc->nb_streams < 1)
1879  return AVERROR_INVALIDDATA;
1880 
1881  st = fc->streams[fc->nb_streams - 1];
1882  sc = st->priv_data;
1883 
1884  if (sc->format == MOV_MP4_FPCM_TAG) {
1885  switch (pcm_sample_size) {
1886  case 32:
1888  break;
1889  case 64:
1891  break;
1892  default:
1893  av_log(fc, AV_LOG_ERROR, "invalid pcm_sample_size %d for %s\n",
1894  pcm_sample_size,
1895  av_fourcc2str(sc->format));
1896  return AVERROR_INVALIDDATA;
1897  }
1898  } else if (sc->format == MOV_MP4_IPCM_TAG) {
1899  switch (pcm_sample_size) {
1900  case 16:
1902  break;
1903  case 24:
1905  break;
1906  case 32:
1908  break;
1909  default:
1910  av_log(fc, AV_LOG_ERROR, "invalid pcm_sample_size %d for %s\n",
1911  pcm_sample_size,
1912  av_fourcc2str(sc->format));
1913  return AVERROR_INVALIDDATA;
1914  }
1915  } else {
1916  av_log(fc, AV_LOG_ERROR, "'pcmC' with invalid sample entry '%s'\n",
1917  av_fourcc2str(sc->format));
1918  return AVERROR_INVALIDDATA;
1919  }
1920 
1921  if (format_flags & 1) // indicates little-endian format. If not present, big-endian format is used
1924 
1925  return 0;
1926 }
1927 
1929 {
1930  AVStream *st;
1931  char color_parameter_type[5] = { 0 };
1932  uint16_t color_primaries, color_trc, color_matrix;
1933  int ret;
1934 
1935  st = get_curr_st(c);
1936  if (!st)
1937  return 0;
1938 
1939  ret = ffio_read_size(pb, color_parameter_type, 4);
1940  if (ret < 0)
1941  return ret;
1942  if (strncmp(color_parameter_type, "nclx", 4) &&
1943  strncmp(color_parameter_type, "nclc", 4) &&
1944  strncmp(color_parameter_type, "prof", 4)) {
1945  av_log(c->fc, AV_LOG_WARNING, "unsupported color_parameter_type %s\n",
1946  color_parameter_type);
1947  return 0;
1948  }
1949 
1950  if (!strncmp(color_parameter_type, "prof", 4)) {
1954  atom.size - 4, 0);
1955  if (!sd)
1956  return AVERROR(ENOMEM);
1957  ret = ffio_read_size(pb, sd->data, atom.size - 4);
1958  if (ret < 0)
1959  return ret;
1960  } else {
1961  color_primaries = avio_rb16(pb);
1962  color_trc = avio_rb16(pb);
1963  color_matrix = avio_rb16(pb);
1964 
1965  av_log(c->fc, AV_LOG_TRACE,
1966  "%s: pri %d trc %d matrix %d",
1967  color_parameter_type, color_primaries, color_trc, color_matrix);
1968 
1969  if (!strncmp(color_parameter_type, "nclx", 4)) {
1970  uint8_t color_range = avio_r8(pb) >> 7;
1971  av_log(c->fc, AV_LOG_TRACE, " full %"PRIu8"", color_range);
1972  if (color_range)
1974  else
1976  }
1977 
1980  if (!av_color_transfer_name(color_trc))
1981  color_trc = AVCOL_TRC_UNSPECIFIED;
1982  if (!av_color_space_name(color_matrix))
1983  color_matrix = AVCOL_SPC_UNSPECIFIED;
1984 
1986  st->codecpar->color_trc = color_trc;
1987  st->codecpar->color_space = color_matrix;
1988  av_log(c->fc, AV_LOG_TRACE, "\n");
1989  }
1990  return 0;
1991 }
1992 
1994 {
1995  AVStream *st;
1996  unsigned mov_field_order;
1997  enum AVFieldOrder decoded_field_order = AV_FIELD_UNKNOWN;
1998 
1999  if (c->fc->nb_streams < 1) // will happen with jp2 files
2000  return 0;
2001  st = c->fc->streams[c->fc->nb_streams-1];
2002  if (atom.size < 2)
2003  return AVERROR_INVALIDDATA;
2004  mov_field_order = avio_rb16(pb);
2005  if ((mov_field_order & 0xFF00) == 0x0100)
2006  decoded_field_order = AV_FIELD_PROGRESSIVE;
2007  else if ((mov_field_order & 0xFF00) == 0x0200) {
2008  switch (mov_field_order & 0xFF) {
2009  case 0x01: decoded_field_order = AV_FIELD_TT;
2010  break;
2011  case 0x06: decoded_field_order = AV_FIELD_BB;
2012  break;
2013  case 0x09: decoded_field_order = AV_FIELD_TB;
2014  break;
2015  case 0x0E: decoded_field_order = AV_FIELD_BT;
2016  break;
2017  }
2018  }
2019  if (decoded_field_order == AV_FIELD_UNKNOWN && mov_field_order) {
2020  av_log(c->fc, AV_LOG_ERROR, "Unknown MOV field order 0x%04x\n", mov_field_order);
2021  }
2022  st->codecpar->field_order = decoded_field_order;
2023 
2024  return 0;
2025 }
2026 
2028 {
2029  int err = 0;
2030  uint64_t size = (uint64_t)par->extradata_size + atom.size + 8 + AV_INPUT_BUFFER_PADDING_SIZE;
2031  if (size > INT_MAX || (uint64_t)atom.size > INT_MAX)
2032  return AVERROR_INVALIDDATA;
2033  if ((err = av_reallocp(&par->extradata, size)) < 0) {
2034  par->extradata_size = 0;
2035  return err;
2036  }
2038  return 0;
2039 }
2040 
2041 /* Read a whole atom into the extradata return the size of the atom read, possibly truncated if != atom.size */
2043  AVCodecParameters *par, uint8_t *buf)
2044 {
2045  int64_t result = atom.size;
2046  int err;
2047 
2048  AV_WB32(buf , atom.size + 8);
2049  AV_WL32(buf + 4, atom.type);
2050  err = ffio_read_size(pb, buf + 8, atom.size);
2051  if (err < 0) {
2052  par->extradata_size -= atom.size;
2053  return err;
2054  } else if (err < atom.size) {
2055  av_log(c->fc, AV_LOG_WARNING, "truncated extradata\n");
2056  par->extradata_size -= atom.size - err;
2057  result = err;
2058  }
2059  memset(buf + 8 + err, 0, AV_INPUT_BUFFER_PADDING_SIZE);
2060  return result;
2061 }
2062 
2063 /* FIXME modify QDM2/SVQ3/H.264 decoders to take full atom as extradata */
2065  enum AVCodecID codec_id)
2066 {
2067  AVStream *st;
2068  uint64_t original_size;
2069  int err;
2070 
2071  if (c->fc->nb_streams < 1) // will happen with jp2 files
2072  return 0;
2073  st = c->fc->streams[c->fc->nb_streams-1];
2074 
2075  if (st->codecpar->codec_id != codec_id)
2076  return 0; /* unexpected codec_id - don't mess with extradata */
2077 
2078  original_size = st->codecpar->extradata_size;
2079  err = mov_realloc_extradata(st->codecpar, atom);
2080  if (err)
2081  return err;
2082 
2083  err = mov_read_atom_into_extradata(c, pb, atom, st->codecpar, st->codecpar->extradata + original_size);
2084  if (err < 0)
2085  return err;
2086  return 0; // Note: this is the original behavior to ignore truncation.
2087 }
2088 
2089 /* wrapper functions for reading ALAC/AVS/MJPEG/MJPEG2000 extradata atoms only for those codecs */
2091 {
2092  return mov_read_extradata(c, pb, atom, AV_CODEC_ID_ALAC);
2093 }
2094 
2096 {
2097  return mov_read_extradata(c, pb, atom, AV_CODEC_ID_CAVS);
2098 }
2099 
2101 {
2102  return mov_read_extradata(c, pb, atom, AV_CODEC_ID_JPEG2000);
2103 }
2104 
2106 {
2107  return mov_read_extradata(c, pb, atom, AV_CODEC_ID_R10K);
2108 }
2109 
2111 {
2112  int ret = mov_read_extradata(c, pb, atom, AV_CODEC_ID_AVUI);
2113  if (!ret)
2114  ret = mov_read_extradata(c, pb, atom, AV_CODEC_ID_DNXHD);
2115  return ret;
2116 }
2117 
2119 {
2120  int ret = mov_read_extradata(c, pb, atom, AV_CODEC_ID_TARGA_Y216);
2121 
2122  if (!ret && c->fc->nb_streams >= 1) {
2123  AVCodecParameters *par = c->fc->streams[c->fc->nb_streams-1]->codecpar;
2124  if (par->extradata_size >= 40) {
2125  par->height = AV_RB16(&par->extradata[36]);
2126  par->width = AV_RB16(&par->extradata[38]);
2127  }
2128  }
2129  return ret;
2130 }
2131 
2133 {
2134  if (c->fc->nb_streams >= 1) {
2135  AVStream *const st = c->fc->streams[c->fc->nb_streams - 1];
2136  FFStream *const sti = ffstream(st);
2137  AVCodecParameters *par = st->codecpar;
2138 
2139  if (par->codec_tag == MKTAG('A', 'V', 'i', 'n') &&
2140  par->codec_id == AV_CODEC_ID_H264 &&
2141  atom.size > 11) {
2142  int cid;
2143  avio_skip(pb, 10);
2144  cid = avio_rb16(pb);
2145  /* For AVID AVCI50, force width of 1440 to be able to select the correct SPS and PPS */
2146  if (cid == 0xd4d || cid == 0xd4e)
2147  par->width = 1440;
2148  return 0;
2149  } else if ((par->codec_tag == MKTAG('A', 'V', 'd', '1') ||
2150  par->codec_tag == MKTAG('A', 'V', 'j', '2') ||
2151  par->codec_tag == MKTAG('A', 'V', 'd', 'n')) &&
2152  atom.size >= 24) {
2153  int num, den;
2154  avio_skip(pb, 12);
2155  num = avio_rb32(pb);
2156  den = avio_rb32(pb);
2157  if (num <= 0 || den <= 0)
2158  return 0;
2159  switch (avio_rb32(pb)) {
2160  case 2:
2161  if (den >= INT_MAX / 2)
2162  return 0;
2163  den *= 2;
2164  case 1:
2165  sti->display_aspect_ratio = (AVRational){ num, den };
2166  default:
2167  return 0;
2168  }
2169  }
2170  }
2171 
2172  return mov_read_avid(c, pb, atom);
2173 }
2174 
2176 {
2177  int ret = 0;
2178  int length = 0;
2179  uint64_t original_size;
2180  if (c->fc->nb_streams >= 1) {
2181  AVCodecParameters *par = c->fc->streams[c->fc->nb_streams-1]->codecpar;
2182  if (par->codec_id == AV_CODEC_ID_H264)
2183  return 0;
2184  if (atom.size == 16) {
2185  original_size = par->extradata_size;
2186  ret = mov_realloc_extradata(par, atom);
2187  if (!ret) {
2188  length = mov_read_atom_into_extradata(c, pb, atom, par, par->extradata + original_size);
2189  if (length == atom.size) {
2190  const uint8_t range_value = par->extradata[original_size + 19];
2191  switch (range_value) {
2192  case 1:
2194  break;
2195  case 2:
2197  break;
2198  default:
2199  av_log(c->fc, AV_LOG_WARNING, "ignored unknown aclr value (%d)\n", range_value);
2200  break;
2201  }
2202  ff_dlog(c->fc, "color_range: %d\n", par->color_range);
2203  } else {
2204  /* For some reason the whole atom was not added to the extradata */
2205  av_log(c->fc, AV_LOG_ERROR, "aclr not decoded - incomplete atom\n");
2206  }
2207  } else {
2208  av_log(c->fc, AV_LOG_ERROR, "aclr not decoded - unable to add atom to extradata\n");
2209  }
2210  } else {
2211  av_log(c->fc, AV_LOG_WARNING, "aclr not decoded - unexpected size %"PRId64"\n", atom.size);
2212  }
2213  }
2214 
2215  return ret;
2216 }
2217 
2219 {
2220  return mov_read_extradata(c, pb, atom, AV_CODEC_ID_SVQ3);
2221 }
2222 
2224 {
2225  AVStream *st;
2226  int ret;
2227 
2228  if (c->fc->nb_streams < 1)
2229  return 0;
2230  st = c->fc->streams[c->fc->nb_streams-1];
2231 
2232  if ((uint64_t)atom.size > (1<<30))
2233  return AVERROR_INVALIDDATA;
2234 
2235  if (st->codecpar->codec_id == AV_CODEC_ID_QDM2 ||
2238  // pass all frma atom to codec, needed at least for QDMC and QDM2
2239  ret = ff_get_extradata(c->fc, st->codecpar, pb, atom.size);
2240  if (ret < 0)
2241  return ret;
2242  } else if (atom.size > 8) { /* to read frma, esds atoms */
2243  if (st->codecpar->codec_id == AV_CODEC_ID_ALAC && atom.size >= 24) {
2244  uint64_t buffer;
2245  ret = ffio_ensure_seekback(pb, 8);
2246  if (ret < 0)
2247  return ret;
2248  buffer = avio_rb64(pb);
2249  atom.size -= 8;
2250  if ( (buffer & 0xFFFFFFFF) == MKBETAG('f','r','m','a')
2251  && buffer >> 32 <= atom.size
2252  && buffer >> 32 >= 8) {
2253  avio_skip(pb, -8);
2254  atom.size += 8;
2255  } else if (!st->codecpar->extradata_size) {
2256 #define ALAC_EXTRADATA_SIZE 36
2258  if (!st->codecpar->extradata)
2259  return AVERROR(ENOMEM);
2262  AV_WB32(st->codecpar->extradata + 4, MKTAG('a','l','a','c'));
2263  AV_WB64(st->codecpar->extradata + 12, buffer);
2264  avio_read(pb, st->codecpar->extradata + 20, 16);
2265  avio_skip(pb, atom.size - 24);
2266  return 0;
2267  }
2268  }
2269  if ((ret = mov_read_default(c, pb, atom)) < 0)
2270  return ret;
2271  } else
2272  avio_skip(pb, atom.size);
2273  return 0;
2274 }
2275 
2276 /**
2277  * This function reads atom content and puts data in extradata without tag
2278  * nor size unlike mov_read_extradata.
2279  */
2281 {
2282  AVStream *st;
2283  int ret;
2284 
2285  st = get_curr_st(c);
2286  if (!st)
2287  return 0;
2288 
2289  if ((uint64_t)atom.size > (1<<30))
2290  return AVERROR_INVALIDDATA;
2291 
2292  if (atom.type == MKTAG('v','v','c','C')) {
2293  avio_skip(pb, 4);
2294  atom.size -= 4;
2295  }
2296 
2297  if (atom.size >= 10) {
2298  // Broken files created by legacy versions of libavformat will
2299  // wrap a whole fiel atom inside of a glbl atom.
2300  unsigned size = avio_rb32(pb);
2301  unsigned type = avio_rl32(pb);
2302  if (avio_feof(pb))
2303  return AVERROR_INVALIDDATA;
2304  avio_seek(pb, -8, SEEK_CUR);
2305  if (type == MKTAG('f','i','e','l') && size == atom.size)
2306  return mov_read_default(c, pb, atom);
2307  }
2308  if (st->codecpar->extradata_size > 1 && st->codecpar->extradata) {
2309  av_log(c->fc, AV_LOG_WARNING, "ignoring multiple glbl\n");
2310  return 0;
2311  }
2312  ret = ff_get_extradata(c->fc, st->codecpar, pb, atom.size);
2313  if (ret < 0)
2314  return ret;
2315  if (atom.type == MKTAG('h','v','c','C') && st->codecpar->codec_tag == MKTAG('d','v','h','1'))
2316  /* HEVC-based Dolby Vision derived from hvc1.
2317  Happens to match with an identifier
2318  previously utilized for DV. Thus, if we have
2319  the hvcC extradata box available as specified,
2320  set codec to HEVC */
2322 
2323  return 0;
2324 }
2325 
2327 {
2328  AVStream *st;
2329  uint8_t profile_level;
2330  int ret;
2331 
2332  if (c->fc->nb_streams < 1)
2333  return 0;
2334  st = c->fc->streams[c->fc->nb_streams-1];
2335 
2336  if (atom.size >= (1<<28) || atom.size < 7)
2337  return AVERROR_INVALIDDATA;
2338 
2339  profile_level = avio_r8(pb);
2340  if ((profile_level & 0xf0) != 0xc0)
2341  return 0;
2342 
2343  avio_seek(pb, 6, SEEK_CUR);
2344  ret = ff_get_extradata(c->fc, st->codecpar, pb, atom.size - 7);
2345  if (ret < 0)
2346  return ret;
2347 
2348  return 0;
2349 }
2350 
2351 /**
2352  * An strf atom is a BITMAPINFOHEADER struct. This struct is 40 bytes itself,
2353  * but can have extradata appended at the end after the 40 bytes belonging
2354  * to the struct.
2355  */
2357 {
2358  AVStream *st;
2359  int ret;
2360 
2361  if (c->fc->nb_streams < 1)
2362  return 0;
2363  if (atom.size <= 40)
2364  return 0;
2365  st = c->fc->streams[c->fc->nb_streams-1];
2366 
2367  if ((uint64_t)atom.size > (1<<30))
2368  return AVERROR_INVALIDDATA;
2369 
2370  avio_skip(pb, 40);
2371  ret = ff_get_extradata(c->fc, st->codecpar, pb, atom.size - 40);
2372  if (ret < 0)
2373  return ret;
2374 
2375  return 0;
2376 }
2377 
2379 {
2380  AVStream *st;
2381  MOVStreamContext *sc;
2382  unsigned int i, entries;
2383 
2384  if (c->trak_index < 0) {
2385  av_log(c->fc, AV_LOG_WARNING, "STCO outside TRAK\n");
2386  return 0;
2387  }
2388  if (c->fc->nb_streams < 1)
2389  return 0;
2390  st = c->fc->streams[c->fc->nb_streams-1];
2391  sc = st->priv_data;
2392 
2393  avio_r8(pb); /* version */
2394  avio_rb24(pb); /* flags */
2395 
2396  // Clamp allocation size for `chunk_offsets` -- don't throw an error for an
2397  // invalid count since the EOF path doesn't throw either.
2398  entries = avio_rb32(pb);
2399  entries =
2400  FFMIN(entries,
2401  FFMAX(0, (atom.size - 8) /
2402  (atom.type == MKTAG('s', 't', 'c', 'o') ? 4 : 8)));
2403 
2404  if (!entries)
2405  return 0;
2406 
2407  if (sc->chunk_offsets) {
2408  av_log(c->fc, AV_LOG_WARNING, "Ignoring duplicated STCO atom\n");
2409  return 0;
2410  }
2411 
2412  av_free(sc->chunk_offsets);
2413  sc->chunk_count = 0;
2414  sc->chunk_offsets = av_malloc_array(entries, sizeof(*sc->chunk_offsets));
2415  if (!sc->chunk_offsets)
2416  return AVERROR(ENOMEM);
2417  sc->chunk_count = entries;
2418 
2419  if (atom.type == MKTAG('s','t','c','o'))
2420  for (i = 0; i < entries && !pb->eof_reached; i++)
2421  sc->chunk_offsets[i] = avio_rb32(pb);
2422  else if (atom.type == MKTAG('c','o','6','4'))
2423  for (i = 0; i < entries && !pb->eof_reached; i++) {
2424  sc->chunk_offsets[i] = avio_rb64(pb);
2425  if (sc->chunk_offsets[i] < 0) {
2426  av_log(c->fc, AV_LOG_WARNING, "Impossible chunk_offset\n");
2427  sc->chunk_offsets[i] = 0;
2428  }
2429  }
2430  else
2431  return AVERROR_INVALIDDATA;
2432 
2433  sc->chunk_count = i;
2434 
2435  if (pb->eof_reached) {
2436  av_log(c->fc, AV_LOG_WARNING, "reached eof, corrupted STCO atom\n");
2437  return AVERROR_EOF;
2438  }
2439 
2440  return 0;
2441 }
2442 
2443 static int mov_codec_id(AVStream *st, uint32_t format)
2444 {
2446 
2447  if (id <= 0 &&
2448  ((format & 0xFFFF) == 'm' + ('s' << 8) ||
2449  (format & 0xFFFF) == 'T' + ('S' << 8)))
2451 
2452  if (st->codecpar->codec_type != AVMEDIA_TYPE_VIDEO && id > 0) {
2454  } else if (st->codecpar->codec_type != AVMEDIA_TYPE_AUDIO &&
2455  /* skip old ASF MPEG-4 tag */
2456  format && format != MKTAG('m','p','4','s')) {
2458  if (id <= 0)
2460  if (id > 0)
2462  else if (st->codecpar->codec_type == AVMEDIA_TYPE_DATA ||
2464  st->codecpar->codec_id == AV_CODEC_ID_NONE)) {
2466  if (id <= 0) {
2468  AV_CODEC_ID_TTML : id;
2469  }
2470 
2471  if (id > 0)
2473  else
2475  }
2476  }
2477 
2478  st->codecpar->codec_tag = format;
2479 
2480  return id;
2481 }
2482 
2484  AVStream *st, MOVStreamContext *sc)
2485 {
2486  uint8_t codec_name[32] = { 0 };
2487  int64_t stsd_start;
2488  unsigned int len;
2489  uint32_t id = 0;
2490 
2491  /* The first 16 bytes of the video sample description are already
2492  * read in ff_mov_read_stsd_entries() */
2493  stsd_start = avio_tell(pb) - 16;
2494 
2495  avio_rb16(pb); /* version */
2496  avio_rb16(pb); /* revision level */
2497  id = avio_rl32(pb); /* vendor */
2498  av_dict_set(&st->metadata, "vendor_id", av_fourcc2str(id), 0);
2499  avio_rb32(pb); /* temporal quality */
2500  avio_rb32(pb); /* spatial quality */
2501 
2502  st->codecpar->width = avio_rb16(pb); /* width */
2503  st->codecpar->height = avio_rb16(pb); /* height */
2504 
2505  avio_rb32(pb); /* horiz resolution */
2506  avio_rb32(pb); /* vert resolution */
2507  avio_rb32(pb); /* data size, always 0 */
2508  avio_rb16(pb); /* frames per samples */
2509 
2510  len = avio_r8(pb); /* codec name, pascal string */
2511  if (len > 31)
2512  len = 31;
2513  mov_read_mac_string(c, pb, len, codec_name, sizeof(codec_name));
2514  if (len < 31)
2515  avio_skip(pb, 31 - len);
2516 
2517  if (codec_name[0])
2518  av_dict_set(&st->metadata, "encoder", codec_name, 0);
2519 
2520  /* codec_tag YV12 triggers an UV swap in rawdec.c */
2521  if (!strncmp(codec_name, "Planar Y'CbCr 8-bit 4:2:0", 25)) {
2522  st->codecpar->codec_tag = MKTAG('I', '4', '2', '0');
2523  st->codecpar->width &= ~1;
2524  st->codecpar->height &= ~1;
2525  }
2526  /* Flash Media Server uses tag H.263 with Sorenson Spark */
2527  if (st->codecpar->codec_tag == MKTAG('H','2','6','3') &&
2528  !strncmp(codec_name, "Sorenson H263", 13))
2530 
2531  st->codecpar->bits_per_coded_sample = avio_rb16(pb); /* depth */
2532 
2533  avio_seek(pb, stsd_start, SEEK_SET);
2534 
2535  if (ff_get_qtpalette(st->codecpar->codec_id, pb, sc->palette)) {
2536  st->codecpar->bits_per_coded_sample &= 0x1F;
2537  sc->has_palette = 1;
2538  }
2539 }
2540 
2542  AVStream *st, MOVStreamContext *sc)
2543 {
2544  int bits_per_sample, flags;
2545  uint16_t version = avio_rb16(pb);
2546  uint32_t id = 0;
2547  AVDictionaryEntry *compatible_brands = av_dict_get(c->fc->metadata, "compatible_brands", NULL, AV_DICT_MATCH_CASE);
2548  int channel_count;
2549 
2550  avio_rb16(pb); /* revision level */
2551  id = avio_rl32(pb); /* vendor */
2552  av_dict_set(&st->metadata, "vendor_id", av_fourcc2str(id), 0);
2553 
2554  channel_count = avio_rb16(pb);
2555 
2557  st->codecpar->ch_layout.nb_channels = channel_count;
2558  st->codecpar->bits_per_coded_sample = avio_rb16(pb); /* sample size */
2559  av_log(c->fc, AV_LOG_TRACE, "audio channels %d\n", channel_count);
2560 
2561  sc->audio_cid = avio_rb16(pb);
2562  avio_rb16(pb); /* packet size = 0 */
2563 
2564  st->codecpar->sample_rate = ((avio_rb32(pb) >> 16));
2565 
2566  // Read QT version 1 fields. In version 0 these do not exist.
2567  av_log(c->fc, AV_LOG_TRACE, "version =%d, isom =%d\n", version, c->isom);
2568  if (!c->isom ||
2569  (compatible_brands && strstr(compatible_brands->value, "qt ")) ||
2570  (sc->stsd_version == 0 && version > 0)) {
2571  if (version == 1) {
2572  sc->samples_per_frame = avio_rb32(pb);
2573  avio_rb32(pb); /* bytes per packet */
2574  sc->bytes_per_frame = avio_rb32(pb);
2575  avio_rb32(pb); /* bytes per sample */
2576  } else if (version == 2) {
2577  avio_rb32(pb); /* sizeof struct only */
2579  channel_count = avio_rb32(pb);
2581  st->codecpar->ch_layout.nb_channels = channel_count;
2582  avio_rb32(pb); /* always 0x7F000000 */
2584 
2585  flags = avio_rb32(pb); /* lpcm format specific flag */
2586  sc->bytes_per_frame = avio_rb32(pb);
2587  sc->samples_per_frame = avio_rb32(pb);
2588  if (st->codecpar->codec_tag == MKTAG('l','p','c','m'))
2589  st->codecpar->codec_id =
2591  flags);
2592  }
2593  if (version == 0 || (version == 1 && sc->audio_cid != -2)) {
2594  /* can't correctly handle variable sized packet as audio unit */
2595  switch (st->codecpar->codec_id) {
2596  case AV_CODEC_ID_MP2:
2597  case AV_CODEC_ID_MP3:
2599  break;
2600  }
2601  }
2602  }
2603 
2604  if (sc->format == 0) {
2605  if (st->codecpar->bits_per_coded_sample == 8)
2606  st->codecpar->codec_id = mov_codec_id(st, MKTAG('r','a','w',' '));
2607  else if (st->codecpar->bits_per_coded_sample == 16)
2608  st->codecpar->codec_id = mov_codec_id(st, MKTAG('t','w','o','s'));
2609  }
2610 
2611  switch (st->codecpar->codec_id) {
2612  case AV_CODEC_ID_PCM_S8:
2613  case AV_CODEC_ID_PCM_U8:
2614  if (st->codecpar->bits_per_coded_sample == 16)
2616  break;
2617  case AV_CODEC_ID_PCM_S16LE:
2618  case AV_CODEC_ID_PCM_S16BE:
2619  if (st->codecpar->bits_per_coded_sample == 8)
2621  else if (st->codecpar->bits_per_coded_sample == 24)
2622  st->codecpar->codec_id =
2625  else if (st->codecpar->bits_per_coded_sample == 32)
2626  st->codecpar->codec_id =
2629  break;
2630  /* set values for old format before stsd version 1 appeared */
2631  case AV_CODEC_ID_MACE3:
2632  sc->samples_per_frame = 6;
2634  break;
2635  case AV_CODEC_ID_MACE6:
2636  sc->samples_per_frame = 6;
2638  break;
2640  sc->samples_per_frame = 64;
2642  break;
2643  case AV_CODEC_ID_GSM:
2644  sc->samples_per_frame = 160;
2645  sc->bytes_per_frame = 33;
2646  break;
2647  default:
2648  break;
2649  }
2650 
2651  bits_per_sample = av_get_bits_per_sample(st->codecpar->codec_id);
2652  if (bits_per_sample && (bits_per_sample >> 3) * (uint64_t)st->codecpar->ch_layout.nb_channels <= INT_MAX) {
2653  st->codecpar->bits_per_coded_sample = bits_per_sample;
2654  sc->sample_size = (bits_per_sample >> 3) * st->codecpar->ch_layout.nb_channels;
2655  }
2656 }
2657 
2659  AVStream *st, MOVStreamContext *sc,
2660  int64_t size)
2661 {
2662  // ttxt stsd contains display flags, justification, background
2663  // color, fonts, and default styles, so fake an atom to read it
2664  MOVAtom fake_atom = { .size = size };
2665  // mp4s contains a regular esds atom, dfxp ISMV TTML has no content
2666  // in extradata unlike stpp MP4 TTML.
2667  if (st->codecpar->codec_tag != AV_RL32("mp4s") &&
2669  mov_read_glbl(c, pb, fake_atom);
2670  st->codecpar->width = sc->width;
2671  st->codecpar->height = sc->height;
2672 }
2673 
2674 static uint32_t yuv_to_rgba(uint32_t ycbcr)
2675 {
2676  uint8_t r, g, b;
2677  int y, cb, cr;
2678 
2679  y = (ycbcr >> 16) & 0xFF;
2680  cr = (ycbcr >> 8) & 0xFF;
2681  cb = ycbcr & 0xFF;
2682 
2683  b = av_clip_uint8((1164 * (y - 16) + 2018 * (cb - 128)) / 1000);
2684  g = av_clip_uint8((1164 * (y - 16) - 813 * (cr - 128) - 391 * (cb - 128)) / 1000);
2685  r = av_clip_uint8((1164 * (y - 16) + 1596 * (cr - 128) ) / 1000);
2686 
2687  return (r << 16) | (g << 8) | b;
2688 }
2689 
2691 {
2692  char buf[256] = {0};
2693  uint8_t *src = st->codecpar->extradata;
2694  int i, ret;
2695 
2696  if (st->codecpar->extradata_size != 64)
2697  return 0;
2698 
2699  if (st->codecpar->width > 0 && st->codecpar->height > 0)
2700  snprintf(buf, sizeof(buf), "size: %dx%d\n",
2701  st->codecpar->width, st->codecpar->height);
2702  av_strlcat(buf, "palette: ", sizeof(buf));
2703 
2704  for (i = 0; i < 16; i++) {
2705  uint32_t yuv = AV_RB32(src + i * 4);
2706  uint32_t rgba = yuv_to_rgba(yuv);
2707 
2708  av_strlcatf(buf, sizeof(buf), "%06"PRIx32"%s", rgba, i != 15 ? ", " : "");
2709  }
2710 
2711  if (av_strlcat(buf, "\n", sizeof(buf)) >= sizeof(buf))
2712  return 0;
2713 
2714  ret = ff_alloc_extradata(st->codecpar, strlen(buf));
2715  if (ret < 0)
2716  return ret;
2717  memcpy(st->codecpar->extradata, buf, st->codecpar->extradata_size);
2718 
2719  return 0;
2720 }
2721 
2723  AVStream *st, MOVStreamContext *sc,
2724  int64_t size)
2725 {
2726  int ret;
2727 
2728  if (st->codecpar->codec_tag == MKTAG('t','m','c','d')) {
2729  if ((int)size != size)
2730  return AVERROR(ENOMEM);
2731 
2732  ret = ff_get_extradata(c->fc, st->codecpar, pb, size);
2733  if (ret < 0)
2734  return ret;
2735  if (size > 16) {
2736  MOVStreamContext *tmcd_ctx = st->priv_data;
2737  int val;
2738  val = AV_RB32(st->codecpar->extradata + 4);
2739  tmcd_ctx->tmcd_flags = val;
2740  st->avg_frame_rate.num = AV_RB32(st->codecpar->extradata + 8); /* timescale */
2741  st->avg_frame_rate.den = AV_RB32(st->codecpar->extradata + 12); /* frameDuration */
2742  tmcd_ctx->tmcd_nb_frames = st->codecpar->extradata[16]; /* number of frames */
2743  if (size > 30) {
2744  uint32_t len = AV_RB32(st->codecpar->extradata + 18); /* name atom length */
2745  uint32_t format = AV_RB32(st->codecpar->extradata + 22);
2746  if (format == AV_RB32("name") && (int64_t)size >= (int64_t)len + 18) {
2747  uint16_t str_size = AV_RB16(st->codecpar->extradata + 26); /* string length */
2748  if (str_size > 0 && size >= (int)str_size + 30 &&
2749  st->codecpar->extradata[30] /* Don't add empty string */) {
2750  char *reel_name = av_malloc(str_size + 1);
2751  if (!reel_name)
2752  return AVERROR(ENOMEM);
2753  memcpy(reel_name, st->codecpar->extradata + 30, str_size);
2754  reel_name[str_size] = 0; /* Add null terminator */
2755  av_dict_set(&st->metadata, "reel_name", reel_name,
2757  }
2758  }
2759  }
2760  }
2761  } else {
2762  /* other codec type, just skip (rtp, mp4s ...) */
2763  avio_skip(pb, size);
2764  }
2765  return 0;
2766 }
2767 
2769  AVStream *st, MOVStreamContext *sc)
2770 {
2771  FFStream *const sti = ffstream(st);
2772 
2773  if (st->codecpar->codec_type == AVMEDIA_TYPE_AUDIO &&
2774  !st->codecpar->sample_rate && sc->time_scale > 1)
2775  st->codecpar->sample_rate = sc->time_scale;
2776 
2777  /* special codec parameters handling */
2778  switch (st->codecpar->codec_id) {
2779 #if CONFIG_DV_DEMUXER
2780  case AV_CODEC_ID_DVAUDIO:
2781  if (c->dv_fctx) {
2782  avpriv_request_sample(c->fc, "multiple DV audio streams");
2783  return AVERROR(ENOSYS);
2784  }
2785 
2786  c->dv_fctx = avformat_alloc_context();
2787  if (!c->dv_fctx) {
2788  av_log(c->fc, AV_LOG_ERROR, "dv demux context alloc error\n");
2789  return AVERROR(ENOMEM);
2790  }
2791  c->dv_demux = avpriv_dv_init_demux(c->dv_fctx);
2792  if (!c->dv_demux) {
2793  av_log(c->fc, AV_LOG_ERROR, "dv demux context init error\n");
2794  return AVERROR(ENOMEM);
2795  }
2796  sc->dv_audio_container = 1;
2798  break;
2799 #endif
2800  /* no ifdef since parameters are always those */
2801  case AV_CODEC_ID_QCELP:
2804  // force sample rate for qcelp when not stored in mov
2805  if (st->codecpar->codec_tag != MKTAG('Q','c','l','p'))
2806  st->codecpar->sample_rate = 8000;
2807  // FIXME: Why is the following needed for some files?
2808  sc->samples_per_frame = 160;
2809  if (!sc->bytes_per_frame)
2810  sc->bytes_per_frame = 35;
2811  break;
2812  case AV_CODEC_ID_AMR_NB:
2815  /* force sample rate for amr, stsd in 3gp does not store sample rate */
2816  st->codecpar->sample_rate = 8000;
2817  break;
2818  case AV_CODEC_ID_AMR_WB:
2821  st->codecpar->sample_rate = 16000;
2822  break;
2823  case AV_CODEC_ID_MP2:
2824  case AV_CODEC_ID_MP3:
2825  /* force type after stsd for m1a hdlr */
2827  break;
2828  case AV_CODEC_ID_GSM:
2829  case AV_CODEC_ID_ADPCM_MS:
2831  case AV_CODEC_ID_ILBC:
2832  case AV_CODEC_ID_MACE3:
2833  case AV_CODEC_ID_MACE6:
2834  case AV_CODEC_ID_QDM2:
2836  break;
2837  case AV_CODEC_ID_ALAC:
2838  if (st->codecpar->extradata_size == 36) {
2839  int channel_count = AV_RB8(st->codecpar->extradata + 21);
2840  if (st->codecpar->ch_layout.nb_channels != channel_count) {
2843  st->codecpar->ch_layout.nb_channels = channel_count;
2844  }
2845  st->codecpar->sample_rate = AV_RB32(st->codecpar->extradata + 32);
2846  }
2847  break;
2848  case AV_CODEC_ID_AC3:
2849  case AV_CODEC_ID_EAC3:
2851  case AV_CODEC_ID_VC1:
2852  case AV_CODEC_ID_VP8:
2853  case AV_CODEC_ID_VP9:
2855  break;
2856  case AV_CODEC_ID_EVC:
2857  case AV_CODEC_ID_AV1:
2858  /* field_order detection of H264 requires parsing */
2859  case AV_CODEC_ID_H264:
2861  break;
2862  default:
2863  break;
2864  }
2865  return 0;
2866 }
2867 
2869  int codec_tag, int format,
2870  int64_t size)
2871 {
2872  if (codec_tag &&
2873  (codec_tag != format &&
2874  // AVID 1:1 samples with differing data format and codec tag exist
2875  (codec_tag != AV_RL32("AV1x") || format != AV_RL32("AVup")) &&
2876  // prores is allowed to have differing data format and codec tag
2877  codec_tag != AV_RL32("apcn") && codec_tag != AV_RL32("apch") &&
2878  // so is dv (sigh)
2879  codec_tag != AV_RL32("dvpp") && codec_tag != AV_RL32("dvcp") &&
2880  (c->fc->video_codec_id ? ff_codec_get_id(ff_codec_movvideo_tags, format) != c->fc->video_codec_id
2881  : codec_tag != MKTAG('j','p','e','g')))) {
2882  /* Multiple fourcc, we skip JPEG. This is not correct, we should
2883  * export it as a separate AVStream but this needs a few changes
2884  * in the MOV demuxer, patch welcome. */
2885 
2886  av_log(c->fc, AV_LOG_WARNING, "multiple fourcc not supported\n");
2887  avio_skip(pb, size);
2888  return 1;
2889  }
2890 
2891  return 0;
2892 }
2893 
2895 {
2896  AVStream *st;
2897  MOVStreamContext *sc;
2898  int pseudo_stream_id;
2899 
2900  av_assert0 (c->fc->nb_streams >= 1);
2901  st = c->fc->streams[c->fc->nb_streams-1];
2902  sc = st->priv_data;
2903 
2904  for (pseudo_stream_id = 0;
2905  pseudo_stream_id < entries && !pb->eof_reached;
2906  pseudo_stream_id++) {
2907  //Parsing Sample description table
2908  enum AVCodecID id;
2909  int ret, dref_id = 1;
2910  MOVAtom a = { AV_RL32("stsd") };
2911  int64_t start_pos = avio_tell(pb);
2912  int64_t size = avio_rb32(pb); /* size */
2913  uint32_t format = avio_rl32(pb); /* data format */
2914 
2915  if (size >= 16) {
2916  avio_rb32(pb); /* reserved */
2917  avio_rb16(pb); /* reserved */
2918  dref_id = avio_rb16(pb);
2919  } else if (size <= 7) {
2920  av_log(c->fc, AV_LOG_ERROR,
2921  "invalid size %"PRId64" in stsd\n", size);
2922  return AVERROR_INVALIDDATA;
2923  }
2924 
2926  size - (avio_tell(pb) - start_pos))) {
2927  sc->stsd_count++;
2928  continue;
2929  }
2930 
2931  sc->pseudo_stream_id = st->codecpar->codec_tag ? -1 : pseudo_stream_id;
2932  sc->dref_id= dref_id;
2933  sc->format = format;
2934 
2935  id = mov_codec_id(st, format);
2936 
2937  av_log(c->fc, AV_LOG_TRACE,
2938  "size=%"PRId64" 4CC=%s codec_type=%d\n", size,
2940 
2941  st->codecpar->codec_id = id;
2943  mov_parse_stsd_video(c, pb, st, sc);
2944  } else if (st->codecpar->codec_type==AVMEDIA_TYPE_AUDIO) {
2945  mov_parse_stsd_audio(c, pb, st, sc);
2946  if (st->codecpar->sample_rate < 0) {
2947  av_log(c->fc, AV_LOG_ERROR, "Invalid sample rate %d\n", st->codecpar->sample_rate);
2948  return AVERROR_INVALIDDATA;
2949  }
2950  if (st->codecpar->ch_layout.nb_channels < 0) {
2951  av_log(c->fc, AV_LOG_ERROR, "Invalid channels %d\n", st->codecpar->ch_layout.nb_channels);
2952  return AVERROR_INVALIDDATA;
2953  }
2954  } else if (st->codecpar->codec_type==AVMEDIA_TYPE_SUBTITLE){
2955  mov_parse_stsd_subtitle(c, pb, st, sc,
2956  size - (avio_tell(pb) - start_pos));
2957  } else {
2958  ret = mov_parse_stsd_data(c, pb, st, sc,
2959  size - (avio_tell(pb) - start_pos));
2960  if (ret < 0)
2961  return ret;
2962  }
2963  /* this will read extra atoms at the end (wave, alac, damr, avcC, hvcC, SMI ...) */
2964  a.size = size - (avio_tell(pb) - start_pos);
2965  if (a.size > 8) {
2966  if ((ret = mov_read_default(c, pb, a)) < 0)
2967  return ret;
2968  } else if (a.size > 0)
2969  avio_skip(pb, a.size);
2970 
2971  if (sc->extradata && st->codecpar->extradata) {
2972  int extra_size = st->codecpar->extradata_size;
2973 
2974  /* Move the current stream extradata to the stream context one. */
2975  sc->extradata_size[pseudo_stream_id] = extra_size;
2976  sc->extradata[pseudo_stream_id] = st->codecpar->extradata;
2977  st->codecpar->extradata = NULL;
2978  st->codecpar->extradata_size = 0;
2979  }
2980  sc->stsd_count++;
2981  }
2982 
2983  if (pb->eof_reached) {
2984  av_log(c->fc, AV_LOG_WARNING, "reached eof, corrupted STSD atom\n");
2985  return AVERROR_EOF;
2986  }
2987 
2988  return 0;
2989 }
2990 
2992 {
2993  AVStream *st;
2994  MOVStreamContext *sc;
2995  int ret, entries;
2996 
2997  if (c->fc->nb_streams < 1)
2998  return 0;
2999  st = c->fc->streams[c->fc->nb_streams - 1];
3000  sc = st->priv_data;
3001 
3002  sc->stsd_version = avio_r8(pb);
3003  avio_rb24(pb); /* flags */
3004  entries = avio_rb32(pb);
3005 
3006  /* Each entry contains a size (4 bytes) and format (4 bytes). */
3007  if (entries <= 0 || entries > atom.size / 8 || entries > 1024) {
3008  av_log(c->fc, AV_LOG_ERROR, "invalid STSD entries %d\n", entries);
3009  return AVERROR_INVALIDDATA;
3010  }
3011 
3012  if (sc->extradata) {
3013  av_log(c->fc, AV_LOG_ERROR,
3014  "Duplicate stsd found in this track.\n");
3015  return AVERROR_INVALIDDATA;
3016  }
3017 
3018  /* Prepare space for hosting multiple extradata. */
3019  sc->extradata = av_calloc(entries, sizeof(*sc->extradata));
3020  if (!sc->extradata)
3021  return AVERROR(ENOMEM);
3022 
3023  sc->extradata_size = av_calloc(entries, sizeof(*sc->extradata_size));
3024  if (!sc->extradata_size) {
3025  ret = AVERROR(ENOMEM);
3026  goto fail;
3027  }
3028 
3029  ret = ff_mov_read_stsd_entries(c, pb, entries);
3030  if (ret < 0)
3031  goto fail;
3032 
3033  /* Restore back the primary extradata. */
3034  av_freep(&st->codecpar->extradata);
3035  st->codecpar->extradata_size = sc->extradata_size[0];
3036  if (sc->extradata_size[0]) {
3038  if (!st->codecpar->extradata)
3039  return AVERROR(ENOMEM);
3040  memcpy(st->codecpar->extradata, sc->extradata[0], sc->extradata_size[0]);
3041  }
3042 
3043  return mov_finalize_stsd_codec(c, pb, st, sc);
3044 fail:
3045  if (sc->extradata) {
3046  int j;
3047  for (j = 0; j < sc->stsd_count; j++)
3048  av_freep(&sc->extradata[j]);
3049  }
3050 
3051  av_freep(&sc->extradata);
3052  av_freep(&sc->extradata_size);
3053  return ret;
3054 }
3055 
3057 {
3058  AVStream *st;
3059  MOVStreamContext *sc;
3060  unsigned int i, entries;
3061 
3062  if (c->fc->nb_streams < 1)
3063  return 0;
3064  st = c->fc->streams[c->fc->nb_streams-1];
3065  sc = st->priv_data;
3066 
3067  avio_r8(pb); /* version */
3068  avio_rb24(pb); /* flags */
3069 
3070  entries = avio_rb32(pb);
3071  if ((uint64_t)entries * 12 + 4 > atom.size)
3072  return AVERROR_INVALIDDATA;
3073 
3074  av_log(c->fc, AV_LOG_TRACE, "track[%u].stsc.entries = %u\n", c->fc->nb_streams - 1, entries);
3075 
3076  if (!entries)
3077  return 0;
3078  if (sc->stsc_data) {
3079  av_log(c->fc, AV_LOG_WARNING, "Ignoring duplicated STSC atom\n");
3080  return 0;
3081  }
3082  av_free(sc->stsc_data);
3083  sc->stsc_count = 0;
3084  sc->stsc_data = av_malloc_array(entries, sizeof(*sc->stsc_data));
3085  if (!sc->stsc_data)
3086  return AVERROR(ENOMEM);
3087 
3088  for (i = 0; i < entries && !pb->eof_reached; i++) {
3089  sc->stsc_data[i].first = avio_rb32(pb);
3090  sc->stsc_data[i].count = avio_rb32(pb);
3091  sc->stsc_data[i].id = avio_rb32(pb);
3092  }
3093 
3094  sc->stsc_count = i;
3095  for (i = sc->stsc_count - 1; i < UINT_MAX; i--) {
3096  int64_t first_min = i + 1;
3097  if ((i+1 < sc->stsc_count && sc->stsc_data[i].first >= sc->stsc_data[i+1].first) ||
3098  (i > 0 && sc->stsc_data[i].first <= sc->stsc_data[i-1].first) ||
3099  sc->stsc_data[i].first < first_min ||
3100  sc->stsc_data[i].count < 1 ||
3101  sc->stsc_data[i].id < 1) {
3102  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);
3103  if (i+1 >= sc->stsc_count) {
3104  if (sc->stsc_data[i].count == 0 && i > 0) {
3105  sc->stsc_count --;
3106  continue;
3107  }
3108  sc->stsc_data[i].first = FFMAX(sc->stsc_data[i].first, first_min);
3109  if (i > 0 && sc->stsc_data[i].first <= sc->stsc_data[i-1].first)
3110  sc->stsc_data[i].first = FFMIN(sc->stsc_data[i-1].first + 1LL, INT_MAX);
3111  sc->stsc_data[i].count = FFMAX(sc->stsc_data[i].count, 1);
3112  sc->stsc_data[i].id = FFMAX(sc->stsc_data[i].id, 1);
3113  continue;
3114  }
3115  av_assert0(sc->stsc_data[i+1].first >= 2);
3116  // We replace this entry by the next valid
3117  sc->stsc_data[i].first = sc->stsc_data[i+1].first - 1;
3118  sc->stsc_data[i].count = sc->stsc_data[i+1].count;
3119  sc->stsc_data[i].id = sc->stsc_data[i+1].id;
3120  }
3121  }
3122 
3123  if (pb->eof_reached) {
3124  av_log(c->fc, AV_LOG_WARNING, "reached eof, corrupted STSC atom\n");
3125  return AVERROR_EOF;
3126  }
3127 
3128  return 0;
3129 }
3130 
3131 static inline int mov_stsc_index_valid(unsigned int index, unsigned int count)
3132 {
3133  return index < count - 1;
3134 }
3135 
3136 /* Compute the samples value for the stsc entry at the given index. */
3137 static inline int64_t mov_get_stsc_samples(MOVStreamContext *sc, unsigned int index)
3138 {
3139  int chunk_count;
3140 
3142  chunk_count = sc->stsc_data[index + 1].first - sc->stsc_data[index].first;
3143  else {
3144  // Validation for stsc / stco happens earlier in mov_read_stsc + mov_read_trak.
3146  chunk_count = sc->chunk_count - (sc->stsc_data[index].first - 1);
3147  }
3148 
3149  return sc->stsc_data[index].count * (int64_t)chunk_count;
3150 }
3151 
3153 {
3154  AVStream *st;
3155  MOVStreamContext *sc;
3156  unsigned i, entries;
3157 
3158  if (c->fc->nb_streams < 1)
3159  return 0;
3160  st = c->fc->streams[c->fc->nb_streams-1];
3161  sc = st->priv_data;
3162 
3163  avio_rb32(pb); // version + flags
3164 
3165  entries = avio_rb32(pb);
3166  if (sc->stps_data)
3167  av_log(c->fc, AV_LOG_WARNING, "Duplicated STPS atom\n");
3168  av_free(sc->stps_data);
3169  sc->stps_count = 0;
3170  sc->stps_data = av_malloc_array(entries, sizeof(*sc->stps_data));
3171  if (!sc->stps_data)
3172  return AVERROR(ENOMEM);
3173 
3174  for (i = 0; i < entries && !pb->eof_reached; i++) {
3175  sc->stps_data[i] = avio_rb32(pb);
3176  }
3177 
3178  sc->stps_count = i;
3179 
3180  if (pb->eof_reached) {
3181  av_log(c->fc, AV_LOG_WARNING, "reached eof, corrupted STPS atom\n");
3182  return AVERROR_EOF;
3183  }
3184 
3185  return 0;
3186 }
3187 
3189 {
3190  AVStream *st;
3191  FFStream *sti;
3192  MOVStreamContext *sc;
3193  unsigned int i, entries;
3194 
3195  if (c->fc->nb_streams < 1)
3196  return 0;
3197  st = c->fc->streams[c->fc->nb_streams-1];
3198  sti = ffstream(st);
3199  sc = st->priv_data;
3200 
3201  avio_r8(pb); /* version */
3202  avio_rb24(pb); /* flags */
3203 
3204  entries = avio_rb32(pb);
3205 
3206  av_log(c->fc, AV_LOG_TRACE, "keyframe_count = %u\n", entries);
3207 
3208  if (!entries) {
3209  sc->keyframe_absent = 1;
3210  if (!sti->need_parsing && st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO)
3212  return 0;
3213  }
3214  if (sc->keyframes)
3215  av_log(c->fc, AV_LOG_WARNING, "Duplicated STSS atom\n");
3216  if (entries >= UINT_MAX / sizeof(int))
3217  return AVERROR_INVALIDDATA;
3218  av_freep(&sc->keyframes);
3219  sc->keyframe_count = 0;
3220  sc->keyframes = av_malloc_array(entries, sizeof(*sc->keyframes));
3221  if (!sc->keyframes)
3222  return AVERROR(ENOMEM);
3223 
3224  for (i = 0; i < entries && !pb->eof_reached; i++) {
3225  sc->keyframes[i] = avio_rb32(pb);
3226  }
3227 
3228  sc->keyframe_count = i;
3229 
3230  if (pb->eof_reached) {
3231  av_log(c->fc, AV_LOG_WARNING, "reached eof, corrupted STSS atom\n");
3232  return AVERROR_EOF;
3233  }
3234 
3235  return 0;
3236 }
3237 
3239 {
3240  AVStream *st;
3241  MOVStreamContext *sc;
3242  unsigned int i, entries, sample_size, field_size, num_bytes;
3243  GetBitContext gb;
3244  unsigned char* buf;
3245  int ret;
3246 
3247  if (c->fc->nb_streams < 1)
3248  return 0;
3249  st = c->fc->streams[c->fc->nb_streams-1];
3250  sc = st->priv_data;
3251 
3252  avio_r8(pb); /* version */
3253  avio_rb24(pb); /* flags */
3254 
3255  if (atom.type == MKTAG('s','t','s','z')) {
3256  sample_size = avio_rb32(pb);
3257  if (!sc->sample_size) /* do not overwrite value computed in stsd */
3258  sc->sample_size = sample_size;
3259  sc->stsz_sample_size = sample_size;
3260  field_size = 32;
3261  } else {
3262  sample_size = 0;
3263  avio_rb24(pb); /* reserved */
3264  field_size = avio_r8(pb);
3265  }
3266  entries = avio_rb32(pb);
3267 
3268  av_log(c->fc, AV_LOG_TRACE, "sample_size = %u sample_count = %u\n", sc->sample_size, entries);
3269 
3270  sc->sample_count = entries;
3271  if (sample_size)
3272  return 0;
3273 
3274  if (field_size != 4 && field_size != 8 && field_size != 16 && field_size != 32) {
3275  av_log(c->fc, AV_LOG_ERROR, "Invalid sample field size %u\n", field_size);
3276  return AVERROR_INVALIDDATA;
3277  }
3278 
3279  if (!entries)
3280  return 0;
3281  if (entries >= (INT_MAX - 4 - 8 * AV_INPUT_BUFFER_PADDING_SIZE) / field_size)
3282  return AVERROR_INVALIDDATA;
3283  if (sc->sample_sizes)
3284  av_log(c->fc, AV_LOG_WARNING, "Duplicated STSZ atom\n");
3285  av_free(sc->sample_sizes);
3286  sc->sample_count = 0;
3287  sc->sample_sizes = av_malloc_array(entries, sizeof(*sc->sample_sizes));
3288  if (!sc->sample_sizes)
3289  return AVERROR(ENOMEM);
3290 
3291  num_bytes = (entries*field_size+4)>>3;
3292 
3293  buf = av_malloc(num_bytes+AV_INPUT_BUFFER_PADDING_SIZE);
3294  if (!buf) {
3295  av_freep(&sc->sample_sizes);
3296  return AVERROR(ENOMEM);
3297  }
3298 
3299  ret = ffio_read_size(pb, buf, num_bytes);
3300  if (ret < 0) {
3301  av_freep(&sc->sample_sizes);
3302  av_free(buf);
3303  av_log(c->fc, AV_LOG_WARNING, "STSZ atom truncated\n");
3304  return 0;
3305  }
3306 
3307  init_get_bits(&gb, buf, 8*num_bytes);
3308 
3309  for (i = 0; i < entries; i++) {
3310  sc->sample_sizes[i] = get_bits_long(&gb, field_size);
3311  if (sc->sample_sizes[i] < 0) {
3312  av_free(buf);
3313  av_log(c->fc, AV_LOG_ERROR, "Invalid sample size %d\n", sc->sample_sizes[i]);
3314  return AVERROR_INVALIDDATA;
3315  }
3316  sc->data_size += sc->sample_sizes[i];
3317  }
3318 
3319  sc->sample_count = i;
3320 
3321  av_free(buf);
3322 
3323  return 0;
3324 }
3325 
3327 {
3328  AVStream *st;
3329  MOVStreamContext *sc;
3330  unsigned int i, entries, alloc_size = 0;
3331  int64_t duration = 0;
3332  int64_t total_sample_count = 0;
3333  int64_t current_dts = 0;
3334  int64_t corrected_dts = 0;
3335 
3336  if (c->fc->nb_streams < 1)
3337  return 0;
3338  st = c->fc->streams[c->fc->nb_streams-1];
3339  sc = st->priv_data;
3340 
3341  avio_r8(pb); /* version */
3342  avio_rb24(pb); /* flags */
3343  entries = avio_rb32(pb);
3344 
3345  av_log(c->fc, AV_LOG_TRACE, "track[%u].stts.entries = %u\n",
3346  c->fc->nb_streams-1, entries);
3347 
3348  if (sc->stts_data)
3349  av_log(c->fc, AV_LOG_WARNING, "Duplicated STTS atom\n");
3350  av_freep(&sc->stts_data);
3351  sc->stts_count = 0;
3352  if (entries >= INT_MAX / sizeof(*sc->stts_data))
3353  return AVERROR(ENOMEM);
3354 
3355  for (i = 0; i < entries && !pb->eof_reached; i++) {
3356  unsigned int sample_duration;
3357  unsigned int sample_count;
3358  unsigned int min_entries = FFMIN(FFMAX(i + 1, 1024 * 1024), entries);
3359  MOVStts *stts_data = av_fast_realloc(sc->stts_data, &alloc_size,
3360  min_entries * sizeof(*sc->stts_data));
3361  if (!stts_data) {
3362  av_freep(&sc->stts_data);
3363  sc->stts_count = 0;
3364  return AVERROR(ENOMEM);
3365  }
3366  sc->stts_count = min_entries;
3367  sc->stts_data = stts_data;
3368 
3369  sample_count = avio_rb32(pb);
3370  sample_duration = avio_rb32(pb);
3371 
3372  sc->stts_data[i].count= sample_count;
3373  sc->stts_data[i].duration= sample_duration;
3374 
3375  av_log(c->fc, AV_LOG_TRACE, "sample_count=%u, sample_duration=%u\n",
3376  sample_count, sample_duration);
3377 
3378  /* STTS sample offsets are uint32 but some files store it as int32
3379  * with negative values used to correct DTS delays.
3380  There may be abnormally large values as well. */
3381  if (sample_duration > c->max_stts_delta) {
3382  // assume high delta is a correction if negative when cast as int32
3383  int32_t delta_magnitude = (int32_t)sample_duration;
3384  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",
3385  sample_duration, i, sample_count, st->index);
3386  sc->stts_data[i].duration = 1;
3387  corrected_dts += (delta_magnitude < 0 ? (int64_t)delta_magnitude : 1) * sample_count;
3388  } else {
3389  corrected_dts += sample_duration * sample_count;
3390  }
3391 
3392  current_dts += sc->stts_data[i].duration * sample_count;
3393 
3394  if (current_dts > corrected_dts) {
3395  int64_t drift = (current_dts - corrected_dts)/FFMAX(sample_count, 1);
3396  uint32_t correction = (sc->stts_data[i].duration > drift) ? drift : sc->stts_data[i].duration - 1;
3397  current_dts -= correction * sample_count;
3398  sc->stts_data[i].duration -= correction;
3399  }
3400 
3401  duration+=(int64_t)sc->stts_data[i].duration*(uint64_t)sc->stts_data[i].count;
3402  total_sample_count+=sc->stts_data[i].count;
3403  }
3404 
3405  sc->stts_count = i;
3406 
3407  if (duration > 0 &&
3408  duration <= INT64_MAX - sc->duration_for_fps &&
3409  total_sample_count <= INT_MAX - sc->nb_frames_for_fps) {
3410  sc->duration_for_fps += duration;
3411  sc->nb_frames_for_fps += total_sample_count;
3412  }
3413 
3414  if (pb->eof_reached) {
3415  av_log(c->fc, AV_LOG_WARNING, "reached eof, corrupted STTS atom\n");
3416  return AVERROR_EOF;
3417  }
3418 
3419  st->nb_frames= total_sample_count;
3420  if (duration)
3421  st->duration= FFMIN(st->duration, duration);
3422 
3423  // All samples have zero duration. They have higher chance be chose by
3424  // mov_find_next_sample, which leads to seek again and again.
3425  //
3426  // It's AVERROR_INVALIDDATA actually, but such files exist in the wild.
3427  // So only mark data stream as discarded for safety.
3428  if (!duration && sc->stts_count &&
3430  av_log(c->fc, AV_LOG_WARNING,
3431  "All samples in data stream index:id [%d:%d] have zero "
3432  "duration, stream set to be discarded by default. Override "
3433  "using AVStream->discard or -discard for ffmpeg command.\n",
3434  st->index, sc->id);
3435  st->discard = AVDISCARD_ALL;
3436  }
3437  sc->track_end = duration;
3438  return 0;
3439 }
3440 
3442 {
3443  AVStream *st;
3444  MOVStreamContext *sc;
3445  int64_t i, entries;
3446 
3447  if (c->fc->nb_streams < 1)
3448  return 0;
3449  st = c->fc->streams[c->fc->nb_streams - 1];
3450  sc = st->priv_data;
3451 
3452  avio_r8(pb); /* version */
3453  avio_rb24(pb); /* flags */
3454  entries = atom.size - 4;
3455 
3456  av_log(c->fc, AV_LOG_TRACE, "track[%u].sdtp.entries = %" PRId64 "\n",
3457  c->fc->nb_streams - 1, entries);
3458 
3459  if (sc->sdtp_data)
3460  av_log(c->fc, AV_LOG_WARNING, "Duplicated SDTP atom\n");
3461  av_freep(&sc->sdtp_data);
3462  sc->sdtp_count = 0;
3463 
3464  sc->sdtp_data = av_malloc(entries);
3465  if (!sc->sdtp_data)
3466  return AVERROR(ENOMEM);
3467 
3468  for (i = 0; i < entries && !pb->eof_reached; i++)
3469  sc->sdtp_data[i] = avio_r8(pb);
3470  sc->sdtp_count = i;
3471 
3472  return 0;
3473 }
3474 
3475 static void mov_update_dts_shift(MOVStreamContext *sc, int duration, void *logctx)
3476 {
3477  if (duration < 0) {
3478  if (duration == INT_MIN) {
3479  av_log(logctx, AV_LOG_WARNING, "mov_update_dts_shift(): dts_shift set to %d\n", INT_MAX);
3480  duration++;
3481  }
3482  sc->dts_shift = FFMAX(sc->dts_shift, -duration);
3483  }
3484 }
3485 
3487 {
3488  AVStream *st;
3489  MOVStreamContext *sc;
3490  unsigned int i, entries, ctts_count = 0;
3491 
3492  if (c->fc->nb_streams < 1)
3493  return 0;
3494  st = c->fc->streams[c->fc->nb_streams-1];
3495  sc = st->priv_data;
3496 
3497  avio_r8(pb); /* version */
3498  avio_rb24(pb); /* flags */
3499  entries = avio_rb32(pb);
3500 
3501  av_log(c->fc, AV_LOG_TRACE, "track[%u].ctts.entries = %u\n", c->fc->nb_streams - 1, entries);
3502 
3503  if (!entries)
3504  return 0;
3505  if (entries >= UINT_MAX / sizeof(*sc->ctts_data))
3506  return AVERROR_INVALIDDATA;
3507  av_freep(&sc->ctts_data);
3508  sc->ctts_data = av_fast_realloc(NULL, &sc->ctts_allocated_size, entries * sizeof(*sc->ctts_data));
3509  if (!sc->ctts_data)
3510  return AVERROR(ENOMEM);
3511 
3512  for (i = 0; i < entries && !pb->eof_reached; i++) {
3513  int count = avio_rb32(pb);
3514  int duration = avio_rb32(pb);
3515 
3516  if (count <= 0) {
3517  av_log(c->fc, AV_LOG_TRACE,
3518  "ignoring CTTS entry with count=%d duration=%d\n",
3519  count, duration);
3520  continue;
3521  }
3522 
3523  add_ctts_entry(&sc->ctts_data, &ctts_count, &sc->ctts_allocated_size,
3524  count, duration);
3525 
3526  av_log(c->fc, AV_LOG_TRACE, "count=%d, duration=%d\n",
3527  count, duration);
3528 
3529  if (FFNABS(duration) < -(1<<28) && i+2<entries) {
3530  av_log(c->fc, AV_LOG_WARNING, "CTTS invalid\n");
3531  av_freep(&sc->ctts_data);
3532  sc->ctts_count = 0;
3533  return 0;
3534  }
3535 
3536  if (i+2<entries)
3537  mov_update_dts_shift(sc, duration, c->fc);
3538  }
3539 
3540  sc->ctts_count = ctts_count;
3541 
3542  if (pb->eof_reached) {
3543  av_log(c->fc, AV_LOG_WARNING, "reached eof, corrupted CTTS atom\n");
3544  return AVERROR_EOF;
3545  }
3546 
3547  av_log(c->fc, AV_LOG_TRACE, "dts shift %d\n", sc->dts_shift);
3548 
3549  return 0;
3550 }
3551 
3553 {
3554  AVStream *st;
3555  MOVStreamContext *sc;
3556  uint8_t version;
3557  uint32_t grouping_type;
3558  uint32_t default_length;
3559  av_unused uint32_t default_group_description_index;
3560  uint32_t entry_count;
3561 
3562  if (c->fc->nb_streams < 1)
3563  return 0;
3564  st = c->fc->streams[c->fc->nb_streams - 1];
3565  sc = st->priv_data;
3566 
3567  version = avio_r8(pb); /* version */
3568  avio_rb24(pb); /* flags */
3569  grouping_type = avio_rl32(pb);
3570 
3571  /*
3572  * This function only supports "sync" boxes, but the code is able to parse
3573  * other boxes (such as "tscl", "tsas" and "stsa")
3574  */
3575  if (grouping_type != MKTAG('s','y','n','c'))
3576  return 0;
3577 
3578  default_length = version >= 1 ? avio_rb32(pb) : 0;
3579  default_group_description_index = version >= 2 ? avio_rb32(pb) : 0;
3580  entry_count = avio_rb32(pb);
3581 
3582  av_freep(&sc->sgpd_sync);
3583  sc->sgpd_sync_count = entry_count;
3584  sc->sgpd_sync = av_calloc(entry_count, sizeof(*sc->sgpd_sync));
3585  if (!sc->sgpd_sync)
3586  return AVERROR(ENOMEM);
3587 
3588  for (uint32_t i = 0; i < entry_count && !pb->eof_reached; i++) {
3589  uint32_t description_length = default_length;
3590  if (version >= 1 && default_length == 0)
3591  description_length = avio_rb32(pb);
3592  if (grouping_type == MKTAG('s','y','n','c')) {
3593  const uint8_t nal_unit_type = avio_r8(pb) & 0x3f;
3594  sc->sgpd_sync[i] = nal_unit_type;
3595  description_length -= 1;
3596  }
3597  avio_skip(pb, description_length);
3598  }
3599 
3600  if (pb->eof_reached) {
3601  av_log(c->fc, AV_LOG_WARNING, "reached eof, corrupted SGPD atom\n");
3602  return AVERROR_EOF;
3603  }
3604 
3605  return 0;
3606 }
3607 
3609 {
3610  AVStream *st;
3611  MOVStreamContext *sc;
3612  unsigned int i, entries;
3613  uint8_t version;
3614  uint32_t grouping_type;
3615  MOVSbgp *table, **tablep;
3616  int *table_count;
3617 
3618  if (c->fc->nb_streams < 1)
3619  return 0;
3620  st = c->fc->streams[c->fc->nb_streams-1];
3621  sc = st->priv_data;
3622 
3623  version = avio_r8(pb); /* version */
3624  avio_rb24(pb); /* flags */
3625  grouping_type = avio_rl32(pb);
3626 
3627  if (grouping_type == MKTAG('r','a','p',' ')) {
3628  tablep = &sc->rap_group;
3629  table_count = &sc->rap_group_count;
3630  } else if (grouping_type == MKTAG('s','y','n','c')) {
3631  tablep = &sc->sync_group;
3632  table_count = &sc->sync_group_count;
3633  } else {
3634  return 0;
3635  }
3636 
3637  if (version == 1)
3638  avio_rb32(pb); /* grouping_type_parameter */
3639 
3640  entries = avio_rb32(pb);
3641  if (!entries)
3642  return 0;
3643  if (*tablep)
3644  av_log(c->fc, AV_LOG_WARNING, "Duplicated SBGP %s atom\n", av_fourcc2str(grouping_type));
3645  av_freep(tablep);
3646  table = av_malloc_array(entries, sizeof(*table));
3647  if (!table)
3648  return AVERROR(ENOMEM);
3649  *tablep = table;
3650 
3651  for (i = 0; i < entries && !pb->eof_reached; i++) {
3652  table[i].count = avio_rb32(pb); /* sample_count */
3653  table[i].index = avio_rb32(pb); /* group_description_index */
3654  }
3655 
3656  *table_count = i;
3657 
3658  if (pb->eof_reached) {
3659  av_log(c->fc, AV_LOG_WARNING, "reached eof, corrupted SBGP atom\n");
3660  return AVERROR_EOF;
3661  }
3662 
3663  return 0;
3664 }
3665 
3666 /**
3667  * Get ith edit list entry (media time, duration).
3668  */
3670  const MOVStreamContext *msc,
3671  unsigned int edit_list_index,
3672  int64_t *edit_list_media_time,
3673  int64_t *edit_list_duration,
3674  int64_t global_timescale)
3675 {
3676  if (edit_list_index == msc->elst_count) {
3677  return 0;
3678  }
3679  *edit_list_media_time = msc->elst_data[edit_list_index].time;
3680  *edit_list_duration = msc->elst_data[edit_list_index].duration;
3681 
3682  /* duration is in global timescale units;convert to msc timescale */
3683  if (global_timescale == 0) {
3684  avpriv_request_sample(mov->fc, "Support for mvhd.timescale = 0 with editlists");
3685  return 0;
3686  }
3687  *edit_list_duration = av_rescale(*edit_list_duration, msc->time_scale,
3688  global_timescale);
3689  return 1;
3690 }
3691 
3692 /**
3693  * Find the closest previous frame to the timestamp_pts, in e_old index
3694  * entries. Searching for just any frame / just key frames can be controlled by
3695  * last argument 'flag'.
3696  * Note that if ctts_data is not NULL, we will always search for a key frame
3697  * irrespective of the value of 'flag'. If we don't find any keyframe, we will
3698  * return the first frame of the video.
3699  *
3700  * Here the timestamp_pts is considered to be a presentation timestamp and
3701  * the timestamp of index entries are considered to be decoding timestamps.
3702  *
3703  * Returns 0 if successful in finding a frame, else returns -1.
3704  * Places the found index corresponding output arg.
3705  *
3706  * If ctts_old is not NULL, then refines the searched entry by searching
3707  * backwards from the found timestamp, to find the frame with correct PTS.
3708  *
3709  * Places the found ctts_index and ctts_sample in corresponding output args.
3710  */
3712  AVIndexEntry *e_old,
3713  int nb_old,
3714  MOVCtts* ctts_data,
3715  int64_t ctts_count,
3716  int64_t timestamp_pts,
3717  int flag,
3718  int64_t* index,
3719  int64_t* ctts_index,
3720  int64_t* ctts_sample)
3721 {
3722  MOVStreamContext *msc = st->priv_data;
3723  FFStream *const sti = ffstream(st);
3724  AVIndexEntry *e_keep = sti->index_entries;
3725  int nb_keep = sti->nb_index_entries;
3726  int64_t i = 0;
3727  int64_t index_ctts_count;
3728 
3729  av_assert0(index);
3730 
3731  // If dts_shift > 0, then all the index timestamps will have to be offset by
3732  // at least dts_shift amount to obtain PTS.
3733  // Hence we decrement the searched timestamp_pts by dts_shift to find the closest index element.
3734  if (msc->dts_shift > 0) {
3735  timestamp_pts -= msc->dts_shift;
3736  }
3737 
3738  sti->index_entries = e_old;
3739  sti->nb_index_entries = nb_old;
3740  *index = av_index_search_timestamp(st, timestamp_pts, flag | AVSEEK_FLAG_BACKWARD);
3741 
3742  // Keep going backwards in the index entries until the timestamp is the same.
3743  if (*index >= 0) {
3744  for (i = *index; i > 0 && e_old[i].timestamp == e_old[i - 1].timestamp;
3745  i--) {
3746  if ((flag & AVSEEK_FLAG_ANY) ||
3747  (e_old[i - 1].flags & AVINDEX_KEYFRAME)) {
3748  *index = i - 1;
3749  }
3750  }
3751  }
3752 
3753  // If we have CTTS then refine the search, by searching backwards over PTS
3754  // computed by adding corresponding CTTS durations to index timestamps.
3755  if (ctts_data && *index >= 0) {
3756  av_assert0(ctts_index);
3757  av_assert0(ctts_sample);
3758  // Find out the ctts_index for the found frame.
3759  *ctts_index = 0;
3760  *ctts_sample = 0;
3761  for (index_ctts_count = 0; index_ctts_count < *index; index_ctts_count++) {
3762  if (*ctts_index < ctts_count) {
3763  (*ctts_sample)++;
3764  if (ctts_data[*ctts_index].count == *ctts_sample) {
3765  (*ctts_index)++;
3766  *ctts_sample = 0;
3767  }
3768  }
3769  }
3770 
3771  while (*index >= 0 && (*ctts_index) >= 0 && (*ctts_index) < ctts_count) {
3772  // Find a "key frame" with PTS <= timestamp_pts (So that we can decode B-frames correctly).
3773  // No need to add dts_shift to the timestamp here becase timestamp_pts has already been
3774  // compensated by dts_shift above.
3775  if ((e_old[*index].timestamp + ctts_data[*ctts_index].duration) <= timestamp_pts &&
3776  (e_old[*index].flags & AVINDEX_KEYFRAME)) {
3777  break;
3778  }
3779 
3780  (*index)--;
3781  if (*ctts_sample == 0) {
3782  (*ctts_index)--;
3783  if (*ctts_index >= 0)
3784  *ctts_sample = ctts_data[*ctts_index].count - 1;
3785  } else {
3786  (*ctts_sample)--;
3787  }
3788  }
3789  }
3790 
3791  /* restore AVStream state*/
3792  sti->index_entries = e_keep;
3793  sti->nb_index_entries = nb_keep;
3794  return *index >= 0 ? 0 : -1;
3795 }
3796 
3797 /**
3798  * Add index entry with the given values, to the end of ffstream(st)->index_entries.
3799  * Returns the new size ffstream(st)->index_entries if successful, else returns -1.
3800  *
3801  * This function is similar to ff_add_index_entry in libavformat/utils.c
3802  * except that here we are always unconditionally adding an index entry to
3803  * the end, instead of searching the entries list and skipping the add if
3804  * there is an existing entry with the same timestamp.
3805  * This is needed because the mov_fix_index calls this func with the same
3806  * unincremented timestamp for successive discarded frames.
3807  */
3808 static int64_t add_index_entry(AVStream *st, int64_t pos, int64_t timestamp,
3809  int size, int distance, int flags)
3810 {
3811  FFStream *const sti = ffstream(st);
3812  AVIndexEntry *entries, *ie;
3813  int64_t index = -1;
3814  const size_t min_size_needed = (sti->nb_index_entries + 1) * sizeof(AVIndexEntry);
3815 
3816  // Double the allocation each time, to lower memory fragmentation.
3817  // Another difference from ff_add_index_entry function.
3818  const size_t requested_size =
3819  min_size_needed > sti->index_entries_allocated_size ?
3820  FFMAX(min_size_needed, 2 * sti->index_entries_allocated_size) :
3821  min_size_needed;
3822 
3823  if (sti->nb_index_entries + 1U >= UINT_MAX / sizeof(AVIndexEntry))
3824  return -1;
3825 
3826  entries = av_fast_realloc(sti->index_entries,
3828  requested_size);
3829  if (!entries)
3830  return -1;
3831 
3832  sti->index_entries = entries;
3833 
3834  index = sti->nb_index_entries++;
3835  ie= &entries[index];
3836 
3837  ie->pos = pos;
3838  ie->timestamp = timestamp;
3839  ie->min_distance= distance;
3840  ie->size= size;
3841  ie->flags = flags;
3842  return index;
3843 }
3844 
3845 /**
3846  * Rewrite timestamps of index entries in the range [end_index - frame_duration_buffer_size, end_index)
3847  * by subtracting end_ts successively by the amounts given in frame_duration_buffer.
3848  */
3849 static void fix_index_entry_timestamps(AVStream* st, int end_index, int64_t end_ts,
3850  int64_t* frame_duration_buffer,
3851  int frame_duration_buffer_size) {
3852  FFStream *const sti = ffstream(st);
3853  int i = 0;
3854  av_assert0(end_index >= 0 && end_index <= sti->nb_index_entries);
3855  for (i = 0; i < frame_duration_buffer_size; i++) {
3856  end_ts -= frame_duration_buffer[frame_duration_buffer_size - 1 - i];
3857  sti->index_entries[end_index - 1 - i].timestamp = end_ts;
3858  }
3859 }
3860 
3861 /**
3862  * Append a new ctts entry to ctts_data.
3863  * Returns the new ctts_count if successful, else returns -1.
3864  */
3865 static int64_t add_ctts_entry(MOVCtts** ctts_data, unsigned int* ctts_count, unsigned int* allocated_size,
3866  int count, int duration)
3867 {
3868  MOVCtts *ctts_buf_new;
3869  const size_t min_size_needed = (*ctts_count + 1) * sizeof(MOVCtts);
3870  const size_t requested_size =
3871  min_size_needed > *allocated_size ?
3872  FFMAX(min_size_needed, 2 * (*allocated_size)) :
3873  min_size_needed;
3874 
3875  if ((unsigned)(*ctts_count) >= UINT_MAX / sizeof(MOVCtts) - 1)
3876  return -1;
3877 
3878  ctts_buf_new = av_fast_realloc(*ctts_data, allocated_size, requested_size);
3879 
3880  if (!ctts_buf_new)
3881  return -1;
3882 
3883  *ctts_data = ctts_buf_new;
3884 
3885  ctts_buf_new[*ctts_count].count = count;
3886  ctts_buf_new[*ctts_count].duration = duration;
3887 
3888  *ctts_count = (*ctts_count) + 1;
3889  return *ctts_count;
3890 }
3891 
3892 #define MAX_REORDER_DELAY 16
3894 {
3895  MOVStreamContext *msc = st->priv_data;
3896  FFStream *const sti = ffstream(st);
3897  int ctts_ind = 0;
3898  int ctts_sample = 0;
3899  int64_t pts_buf[MAX_REORDER_DELAY + 1]; // Circular buffer to sort pts.
3900  int buf_start = 0;
3901  int j, r, num_swaps;
3902 
3903  for (j = 0; j < MAX_REORDER_DELAY + 1; j++)
3904  pts_buf[j] = INT64_MIN;
3905 
3906  if (st->codecpar->video_delay <= 0 && msc->ctts_data &&
3908  st->codecpar->video_delay = 0;
3909  for (int ind = 0; ind < sti->nb_index_entries && ctts_ind < msc->ctts_count; ++ind) {
3910  // Point j to the last elem of the buffer and insert the current pts there.
3911  j = buf_start;
3912  buf_start = (buf_start + 1);
3913  if (buf_start == MAX_REORDER_DELAY + 1)
3914  buf_start = 0;
3915 
3916  pts_buf[j] = sti->index_entries[ind].timestamp + msc->ctts_data[ctts_ind].duration;
3917 
3918  // The timestamps that are already in the sorted buffer, and are greater than the
3919  // current pts, are exactly the timestamps that need to be buffered to output PTS
3920  // in correct sorted order.
3921  // Hence the video delay (which is the buffer size used to sort DTS and output PTS),
3922  // can be computed as the maximum no. of swaps any particular timestamp needs to
3923  // go through, to keep this buffer in sorted order.
3924  num_swaps = 0;
3925  while (j != buf_start) {
3926  r = j - 1;
3927  if (r < 0) r = MAX_REORDER_DELAY;
3928  if (pts_buf[j] < pts_buf[r]) {
3929  FFSWAP(int64_t, pts_buf[j], pts_buf[r]);
3930  ++num_swaps;
3931  } else {
3932  break;
3933  }
3934  j = r;
3935  }
3936  st->codecpar->video_delay = FFMAX(st->codecpar->video_delay, num_swaps);
3937 
3938  ctts_sample++;
3939  if (ctts_sample == msc->ctts_data[ctts_ind].count) {
3940  ctts_ind++;
3941  ctts_sample = 0;
3942  }
3943  }
3944  av_log(c->fc, AV_LOG_DEBUG, "Setting codecpar->delay to %d for stream st: %d\n",
3945  st->codecpar->video_delay, st->index);
3946  }
3947 }
3948 
3950 {
3951  sc->current_sample++;
3952  sc->current_index++;
3953  if (sc->index_ranges &&
3954  sc->current_index >= sc->current_index_range->end &&
3955  sc->current_index_range->end) {
3956  sc->current_index_range++;
3958  }
3959 }
3960 
3962 {
3963  sc->current_sample--;
3964  sc->current_index--;
3965  if (sc->index_ranges &&
3967  sc->current_index_range > sc->index_ranges) {
3968  sc->current_index_range--;
3969  sc->current_index = sc->current_index_range->end - 1;
3970  }
3971 }
3972 
3973 static void mov_current_sample_set(MOVStreamContext *sc, int current_sample)
3974 {
3975  int64_t range_size;
3976 
3977  sc->current_sample = current_sample;
3978  sc->current_index = current_sample;
3979  if (!sc->index_ranges) {
3980  return;
3981  }
3982 
3983  for (sc->current_index_range = sc->index_ranges;
3984  sc->current_index_range->end;
3985  sc->current_index_range++) {
3986  range_size = sc->current_index_range->end - sc->current_index_range->start;
3987  if (range_size > current_sample) {
3988  sc->current_index = sc->current_index_range->start + current_sample;
3989  break;
3990  }
3991  current_sample -= range_size;
3992  }
3993 }
3994 
3995 /**
3996  * Fix ffstream(st)->index_entries, so that it contains only the entries (and the entries
3997  * which are needed to decode them) that fall in the edit list time ranges.
3998  * Also fixes the timestamps of the index entries to match the timeline
3999  * specified the edit lists.
4000  */
4001 static void mov_fix_index(MOVContext *mov, AVStream *st)
4002 {
4003  MOVStreamContext *msc = st->priv_data;
4004  FFStream *const sti = ffstream(st);
4005  AVIndexEntry *e_old = sti->index_entries;
4006  int nb_old = sti->nb_index_entries;
4007  const AVIndexEntry *e_old_end = e_old + nb_old;
4008  const AVIndexEntry *current = NULL;
4009  MOVCtts *ctts_data_old = msc->ctts_data;
4010  int64_t ctts_index_old = 0;
4011  int64_t ctts_sample_old = 0;
4012  int64_t ctts_count_old = msc->ctts_count;
4013  int64_t edit_list_media_time = 0;
4014  int64_t edit_list_duration = 0;
4015  int64_t frame_duration = 0;
4016  int64_t edit_list_dts_counter = 0;
4017  int64_t edit_list_dts_entry_end = 0;
4018  int64_t edit_list_start_ctts_sample = 0;
4019  int64_t curr_cts;
4020  int64_t curr_ctts = 0;
4021  int64_t empty_edits_sum_duration = 0;
4022  int64_t edit_list_index = 0;
4023  int64_t index;
4024  int flags;
4025  int64_t start_dts = 0;
4026  int64_t edit_list_start_encountered = 0;
4027  int64_t search_timestamp = 0;
4028  int64_t* frame_duration_buffer = NULL;
4029  int num_discarded_begin = 0;
4030  int first_non_zero_audio_edit = -1;
4031  int packet_skip_samples = 0;
4032  MOVIndexRange *current_index_range = NULL;
4033  int found_keyframe_after_edit = 0;
4034  int found_non_empty_edit = 0;
4035 
4036  if (!msc->elst_data || msc->elst_count <= 0 || nb_old <= 0) {
4037  return;
4038  }
4039 
4040  // allocate the index ranges array
4041  msc->index_ranges = av_malloc_array(msc->elst_count + 1,
4042  sizeof(msc->index_ranges[0]));
4043  if (!msc->index_ranges) {
4044  av_log(mov->fc, AV_LOG_ERROR, "Cannot allocate index ranges buffer\n");
4045  return;
4046  }
4047  msc->current_index_range = msc->index_ranges;
4048 
4049  // Clean AVStream from traces of old index
4050  sti->index_entries = NULL;
4052  sti->nb_index_entries = 0;
4053 
4054  // Clean ctts fields of MOVStreamContext
4055  msc->ctts_data = NULL;
4056  msc->ctts_count = 0;
4057  msc->ctts_index = 0;
4058  msc->ctts_sample = 0;
4059  msc->ctts_allocated_size = 0;
4060 
4061  // Reinitialize min_corrected_pts so that it can be computed again.
4062  msc->min_corrected_pts = -1;
4063 
4064  // If the dts_shift is positive (in case of negative ctts values in mov),
4065  // then negate the DTS by dts_shift
4066  if (msc->dts_shift > 0) {
4067  edit_list_dts_entry_end -= msc->dts_shift;
4068  av_log(mov->fc, AV_LOG_DEBUG, "Shifting DTS by %d because of negative CTTS.\n", msc->dts_shift);
4069  }
4070 
4071  start_dts = edit_list_dts_entry_end;
4072 
4073  while (get_edit_list_entry(mov, msc, edit_list_index, &edit_list_media_time,
4074  &edit_list_duration, mov->time_scale)) {
4075  av_log(mov->fc, AV_LOG_DEBUG, "Processing st: %d, edit list %"PRId64" - media time: %"PRId64", duration: %"PRId64"\n",
4076  st->index, edit_list_index, edit_list_media_time, edit_list_duration);
4077  edit_list_index++;
4078  edit_list_dts_counter = edit_list_dts_entry_end;
4079  edit_list_dts_entry_end += edit_list_duration;
4080  num_discarded_begin = 0;
4081  if (!found_non_empty_edit && edit_list_media_time == -1) {
4082  empty_edits_sum_duration += edit_list_duration;
4083  continue;
4084  }
4085  found_non_empty_edit = 1;
4086 
4087  // If we encounter a non-negative edit list reset the skip_samples/start_pad fields and set them
4088  // according to the edit list below.
4089  if (st->codecpar->codec_type == AVMEDIA_TYPE_AUDIO) {
4090  if (first_non_zero_audio_edit < 0) {
4091  first_non_zero_audio_edit = 1;
4092  } else {
4093  first_non_zero_audio_edit = 0;
4094  }
4095 
4096  if (first_non_zero_audio_edit > 0)
4097  sti->skip_samples = msc->start_pad = 0;
4098  }
4099 
4100  // While reordering frame index according to edit list we must handle properly
4101  // the scenario when edit list entry starts from none key frame.
4102  // We find closest previous key frame and preserve it and consequent frames in index.
4103  // All frames which are outside edit list entry time boundaries will be dropped after decoding.
4104  search_timestamp = edit_list_media_time;
4105  if (st->codecpar->codec_type == AVMEDIA_TYPE_AUDIO) {
4106  // Audio decoders like AAC need need a decoder delay samples previous to the current sample,
4107  // to correctly decode this frame. Hence for audio we seek to a frame 1 sec. before the
4108  // edit_list_media_time to cover the decoder delay.
4109  search_timestamp = FFMAX(search_timestamp - msc->time_scale, e_old[0].timestamp);
4110  }
4111 
4112  if (find_prev_closest_index(st, e_old, nb_old, ctts_data_old, ctts_count_old, search_timestamp, 0,
4113  &index, &ctts_index_old, &ctts_sample_old) < 0) {
4114  av_log(mov->fc, AV_LOG_WARNING,
4115  "st: %d edit list: %"PRId64" Missing key frame while searching for timestamp: %"PRId64"\n",
4116  st->index, edit_list_index, search_timestamp);
4117  if (find_prev_closest_index(st, e_old, nb_old, ctts_data_old, ctts_count_old, search_timestamp, AVSEEK_FLAG_ANY,
4118  &index, &ctts_index_old, &ctts_sample_old) < 0) {
4119  av_log(mov->fc, AV_LOG_WARNING,
4120  "st: %d edit list %"PRId64" Cannot find an index entry before timestamp: %"PRId64".\n",
4121  st->index, edit_list_index, search_timestamp);
4122  index = 0;
4123  ctts_index_old = 0;
4124  ctts_sample_old = 0;
4125  }
4126  }
4127  current = e_old + index;
4128  edit_list_start_ctts_sample = ctts_sample_old;
4129 
4130  // Iterate over index and arrange it according to edit list
4131  edit_list_start_encountered = 0;
4132  found_keyframe_after_edit = 0;
4133  for (; current < e_old_end; current++, index++) {
4134  // check if frame outside edit list mark it for discard
4135  frame_duration = (current + 1 < e_old_end) ?
4136  ((current + 1)->timestamp - current->timestamp) : edit_list_duration;
4137 
4138  flags = current->flags;
4139 
4140  // frames (pts) before or after edit list
4141  curr_cts = current->timestamp + msc->dts_shift;
4142  curr_ctts = 0;
4143 
4144  if (ctts_data_old && ctts_index_old < ctts_count_old) {
4145  curr_ctts = ctts_data_old[ctts_index_old].duration;
4146  av_log(mov->fc, AV_LOG_TRACE, "stts: %"PRId64" ctts: %"PRId64", ctts_index: %"PRId64", ctts_count: %"PRId64"\n",
4147  curr_cts, curr_ctts, ctts_index_old, ctts_count_old);
4148  curr_cts += curr_ctts;
4149  ctts_sample_old++;
4150  if (ctts_sample_old == ctts_data_old[ctts_index_old].count) {
4151  if (add_ctts_entry(&msc->ctts_data, &msc->ctts_count,
4152  &msc->ctts_allocated_size,
4153  ctts_data_old[ctts_index_old].count - edit_list_start_ctts_sample,
4154  ctts_data_old[ctts_index_old].duration) == -1) {
4155  av_log(mov->fc, AV_LOG_ERROR, "Cannot add CTTS entry %"PRId64" - {%"PRId64", %d}\n",
4156  ctts_index_old,
4157  ctts_data_old[ctts_index_old].count - edit_list_start_ctts_sample,
4158  ctts_data_old[ctts_index_old].duration);
4159  break;
4160  }
4161  ctts_index_old++;
4162  ctts_sample_old = 0;
4163  edit_list_start_ctts_sample = 0;
4164  }
4165  }
4166 
4167  if (curr_cts < edit_list_media_time || curr_cts >= (edit_list_duration + edit_list_media_time)) {
4169  curr_cts < edit_list_media_time && curr_cts + frame_duration > edit_list_media_time &&
4170  first_non_zero_audio_edit > 0) {
4171  packet_skip_samples = edit_list_media_time - curr_cts;
4172  sti->skip_samples += packet_skip_samples;
4173 
4174  // Shift the index entry timestamp by packet_skip_samples to be correct.
4175  edit_list_dts_counter -= packet_skip_samples;
4176  if (edit_list_start_encountered == 0) {
4177  edit_list_start_encountered = 1;
4178  // Make timestamps strictly monotonically increasing for audio, by rewriting timestamps for
4179  // discarded packets.
4180  if (frame_duration_buffer) {
4181  fix_index_entry_timestamps(st, sti->nb_index_entries, edit_list_dts_counter,
4182  frame_duration_buffer, num_discarded_begin);
4183  av_freep(&frame_duration_buffer);
4184  }
4185  }
4186 
4187  av_log(mov->fc, AV_LOG_DEBUG, "skip %d audio samples from curr_cts: %"PRId64"\n", packet_skip_samples, curr_cts);
4188  } else {
4190  av_log(mov->fc, AV_LOG_DEBUG, "drop a frame at curr_cts: %"PRId64" @ %"PRId64"\n", curr_cts, index);
4191 
4192  if (edit_list_start_encountered == 0) {
4193  num_discarded_begin++;
4194  frame_duration_buffer = av_realloc(frame_duration_buffer,
4195  num_discarded_begin * sizeof(int64_t));
4196  if (!frame_duration_buffer) {
4197  av_log(mov->fc, AV_LOG_ERROR, "Cannot reallocate frame duration buffer\n");
4198  break;
4199  }
4200  frame_duration_buffer[num_discarded_begin - 1] = frame_duration;
4201 
4202  // Increment skip_samples for the first non-zero audio edit list
4203  if (st->codecpar->codec_type == AVMEDIA_TYPE_AUDIO &&
4204  first_non_zero_audio_edit > 0 && st->codecpar->codec_id != AV_CODEC_ID_VORBIS) {
4205  sti->skip_samples += frame_duration;
4206  }
4207  }
4208  }
4209  } else {
4210  if (msc->min_corrected_pts < 0) {
4211  msc->min_corrected_pts = edit_list_dts_counter + curr_ctts + msc->dts_shift;
4212  } else {
4213  msc->min_corrected_pts = FFMIN(msc->min_corrected_pts, edit_list_dts_counter + curr_ctts + msc->dts_shift);
4214  }
4215  if (edit_list_start_encountered == 0) {
4216  edit_list_start_encountered = 1;
4217  // Make timestamps strictly monotonically increasing by rewriting timestamps for
4218  // discarded packets.
4219  if (frame_duration_buffer) {
4220  fix_index_entry_timestamps(st, sti->nb_index_entries, edit_list_dts_counter,
4221  frame_duration_buffer, num_discarded_begin);
4222  av_freep(&frame_duration_buffer);
4223  }
4224  }
4225  }
4226 
4227  if (add_index_entry(st, current->pos, edit_list_dts_counter, current->size,
4228  current->min_distance, flags) == -1) {
4229  av_log(mov->fc, AV_LOG_ERROR, "Cannot add index entry\n");
4230  break;
4231  }
4232 
4233  // Update the index ranges array
4234  if (!current_index_range || index != current_index_range->end) {
4235  current_index_range = current_index_range ? current_index_range + 1
4236  : msc->index_ranges;
4237  current_index_range->start = index;
4238  }
4239  current_index_range->end = index + 1;
4240 
4241  // Only start incrementing DTS in frame_duration amounts, when we encounter a frame in edit list.
4242  if (edit_list_start_encountered > 0) {
4243  edit_list_dts_counter = edit_list_dts_counter + frame_duration;
4244  }
4245 
4246  // Break when found first key frame after edit entry completion
4247  if ((curr_cts + frame_duration >= (edit_list_duration + edit_list_media_time)) &&
4249  if (ctts_data_old) {
4250  // If we have CTTS and this is the first keyframe after edit elist,
4251  // wait for one more, because there might be trailing B-frames after this I-frame
4252  // that do belong to the edit.
4253  if (st->codecpar->codec_type != AVMEDIA_TYPE_AUDIO && found_keyframe_after_edit == 0) {
4254  found_keyframe_after_edit = 1;
4255  continue;
4256  }
4257  if (ctts_sample_old != 0) {
4258  if (add_ctts_entry(&msc->ctts_data, &msc->ctts_count,
4259  &msc->ctts_allocated_size,
4260  ctts_sample_old - edit_list_start_ctts_sample,
4261  ctts_data_old[ctts_index_old].duration) == -1) {
4262  av_log(mov->fc, AV_LOG_ERROR, "Cannot add CTTS entry %"PRId64" - {%"PRId64", %d}\n",
4263  ctts_index_old, ctts_sample_old - edit_list_start_ctts_sample,
4264  ctts_data_old[ctts_index_old].duration);
4265  break;
4266  }
4267  }
4268  }
4269  break;
4270  }
4271  }
4272  }
4273  // If there are empty edits, then msc->min_corrected_pts might be positive
4274  // intentionally. So we subtract the sum duration of emtpy edits here.
4275  msc->min_corrected_pts -= empty_edits_sum_duration;
4276 
4277  // If the minimum pts turns out to be greater than zero after fixing the index, then we subtract the
4278  // dts by that amount to make the first pts zero.
4279  if (st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO) {
4280  if (msc->min_corrected_pts > 0) {
4281  av_log(mov->fc, AV_LOG_DEBUG, "Offset DTS by %"PRId64" to make first pts zero.\n", msc->min_corrected_pts);
4282  for (int i = 0; i < sti->nb_index_entries; ++i)
4284  }
4285  }
4286  // Start time should be equal to zero or the duration of any empty edits.
4287  st->start_time = empty_edits_sum_duration;
4288 
4289  // Update av stream length, if it ends up shorter than the track's media duration
4290  st->duration = FFMIN(st->duration, edit_list_dts_entry_end - start_dts);
4291  msc->start_pad = sti->skip_samples;
4292 
4293  // Free the old index and the old CTTS structures
4294  av_free(e_old);
4295  av_free(ctts_data_old);
4296  av_freep(&frame_duration_buffer);
4297 
4298  // Null terminate the index ranges array
4299  current_index_range = current_index_range ? current_index_range + 1
4300  : msc->index_ranges;
4301  current_index_range->start = 0;
4302  current_index_range->end = 0;
4303  msc->current_index = msc->index_ranges[0].start;
4304 }
4305 
4306 static uint32_t get_sgpd_sync_index(const MOVStreamContext *sc, int nal_unit_type)
4307 {
4308  for (uint32_t i = 0; i < sc->sgpd_sync_count; i++)
4309  if (sc->sgpd_sync[i] == HEVC_NAL_CRA_NUT)
4310  return i + 1;
4311  return 0;
4312 }
4313 
4315 {
4316  int k;
4317  int sample_id = 0;
4318  uint32_t cra_index;
4319  MOVStreamContext *sc = st->priv_data;
4320 
4321  if (st->codecpar->codec_id != AV_CODEC_ID_HEVC || !sc->sync_group_count)
4322  return 0;
4323 
4324  /* Build an unrolled index of the samples */
4325  sc->sample_offsets_count = 0;
4326  for (uint32_t i = 0; i < sc->ctts_count; i++) {
4327  if (sc->ctts_data[i].count > INT_MAX - sc->sample_offsets_count)
4328  return AVERROR(ENOMEM);
4329  sc->sample_offsets_count += sc->ctts_data[i].count;
4330  }
4331  av_freep(&sc->sample_offsets);
4333  if (!sc->sample_offsets)
4334  return AVERROR(ENOMEM);
4335  k = 0;
4336  for (uint32_t i = 0; i < sc->ctts_count; i++)
4337  for (int j = 0; j < sc->ctts_data[i].count; j++)
4338  sc->sample_offsets[k++] = sc->ctts_data[i].duration;
4339 
4340  /* The following HEVC NAL type reveal the use of open GOP sync points
4341  * (TODO: BLA types may also be concerned) */
4342  cra_index = get_sgpd_sync_index(sc, HEVC_NAL_CRA_NUT); /* Clean Random Access */
4343  if (!cra_index)
4344  return 0;
4345 
4346  /* Build a list of open-GOP key samples */
4347  sc->open_key_samples_count = 0;
4348  for (uint32_t i = 0; i < sc->sync_group_count; i++)
4349  if (sc->sync_group[i].index == cra_index) {
4350  if (sc->sync_group[i].count > INT_MAX - sc->open_key_samples_count)
4351  return AVERROR(ENOMEM);
4353  }
4354  av_freep(&sc->open_key_samples);
4356  if (!sc->open_key_samples)
4357  return AVERROR(ENOMEM);
4358  k = 0;
4359  for (uint32_t i = 0; i < sc->sync_group_count; i++) {
4360  const MOVSbgp *sg = &sc->sync_group[i];
4361  if (sg->index == cra_index)
4362  for (uint32_t j = 0; j < sg->count; j++)
4363  sc->open_key_samples[k++] = sample_id;
4364  if (sg->count > INT_MAX - sample_id)
4365  return AVERROR_PATCHWELCOME;
4366  sample_id += sg->count;
4367  }
4368 
4369  /* Identify the minimal time step between samples */
4370  sc->min_sample_duration = UINT_MAX;
4371  for (uint32_t i = 0; i < sc->stts_count; i++)
4373 
4374  return 0;
4375 }
4376 
4377 static void mov_build_index(MOVContext *mov, AVStream *st)
4378 {
4379  MOVStreamContext *sc = st->priv_data;
4380  FFStream *const sti = ffstream(st);
4381  int64_t current_offset;
4382  int64_t current_dts = 0;
4383  unsigned int stts_index = 0;
4384  unsigned int stsc_index = 0;
4385  unsigned int stss_index = 0;
4386  unsigned int stps_index = 0;
4387  unsigned int i, j;
4388  uint64_t stream_size = 0;
4389  MOVCtts *ctts_data_old = sc->ctts_data;
4390  unsigned int ctts_count_old = sc->ctts_count;
4391 
4392  int ret = build_open_gop_key_points(st);
4393  if (ret < 0)
4394  return;
4395 
4396  if (sc->elst_count) {
4397  int i, edit_start_index = 0, multiple_edits = 0;
4398  int64_t empty_duration = 0; // empty duration of the first edit list entry
4399  int64_t start_time = 0; // start time of the media
4400 
4401  for (i = 0; i < sc->elst_count; i++) {
4402  const MOVElst *e = &sc->elst_data[i];
4403  if (i == 0 && e->time == -1) {
4404  /* if empty, the first entry is the start time of the stream
4405  * relative to the presentation itself */
4406  empty_duration = e->duration;
4407  edit_start_index = 1;
4408  } else if (i == edit_start_index && e->time >= 0) {
4409  start_time = e->time;
4410  } else {
4411  multiple_edits = 1;
4412  }
4413  }
4414 
4415  if (multiple_edits && !mov->advanced_editlist) {
4417  av_log(mov->fc, AV_LOG_WARNING, "multiple edit list entries, "
4418  "not supported in fragmented MP4 files\n");
4419  else
4420  av_log(mov->fc, AV_LOG_WARNING, "multiple edit list entries, "
4421  "Use -advanced_editlist to correctly decode otherwise "
4422  "a/v desync might occur\n");
4423  }
4424 
4425  /* adjust first dts according to edit list */
4426  if ((empty_duration || start_time) && mov->time_scale > 0) {
4427  if (empty_duration)
4428  empty_duration = av_rescale(empty_duration, sc->time_scale, mov->time_scale);
4429 
4430  if (av_sat_sub64(start_time, empty_duration) != start_time - (uint64_t)empty_duration)
4431  av_log(mov->fc, AV_LOG_WARNING, "start_time - empty_duration is not representable\n");
4432 
4433  sc->time_offset = start_time - (uint64_t)empty_duration;
4435  if (!mov->advanced_editlist)
4436  current_dts = -sc->time_offset;
4437  }
4438 
4439  if (!multiple_edits && !mov->advanced_editlist &&
4441  sc->start_pad = start_time;
4442  }
4443 
4444  /* only use old uncompressed audio chunk demuxing when stts specifies it */
4445  if (!(st->codecpar->codec_type == AVMEDIA_TYPE_AUDIO &&
4446  sc->stts_count == 1 && sc->stts_data[0].duration == 1)) {
4447  unsigned int current_sample = 0;
4448  unsigned int stts_sample = 0;
4449  unsigned int sample_size;
4450  unsigned int distance = 0;
4451  unsigned int rap_group_index = 0;
4452  unsigned int rap_group_sample = 0;
4453  int rap_group_present = sc->rap_group_count && sc->rap_group;
4454  int key_off = (sc->keyframe_count && sc->keyframes[0] > 0) || (sc->stps_count && sc->stps_data[0] > 0);
4455 
4456  current_dts -= sc->dts_shift;
4457 
4458  if (!sc->sample_count || sti->nb_index_entries)
4459  return;
4460  if (sc->sample_count >= UINT_MAX / sizeof(*sti->index_entries) - sti->nb_index_entries)
4461  return;
4462  if (av_reallocp_array(&sti->index_entries,
4463  sti->nb_index_entries + sc->sample_count,
4464  sizeof(*sti->index_entries)) < 0) {
4465  sti->nb_index_entries = 0;
4466  return;
4467  }
4468  sti->index_entries_allocated_size = (sti->nb_index_entries + sc->sample_count) * sizeof(*sti->index_entries);
4469 
4470  if (ctts_data_old) {
4471  // Expand ctts entries such that we have a 1-1 mapping with samples
4472  if (sc->sample_count >= UINT_MAX / sizeof(*sc->ctts_data))
4473  return;
4474  sc->ctts_count = 0;
4475  sc->ctts_allocated_size = 0;
4477  sc->sample_count * sizeof(*sc->ctts_data));
4478  if (!sc->ctts_data) {
4479  av_free(ctts_data_old);
4480  return;
4481  }
4482 
4483  memset((uint8_t*)(sc->ctts_data), 0, sc->ctts_allocated_size);
4484 
4485  for (i = 0; i < ctts_count_old &&
4486  sc->ctts_count < sc->sample_count; i++)
4487  for (j = 0; j < ctts_data_old[i].count &&
4488  sc->ctts_count < sc->sample_count; j++)
4489  add_ctts_entry(&sc->ctts_data, &sc->ctts_count,
4490  &sc->ctts_allocated_size, 1,
4491  ctts_data_old[i].duration);
4492  av_free(ctts_data_old);
4493  }
4494 
4495  for (i = 0; i < sc->chunk_count; i++) {
4496  int64_t next_offset = i+1 < sc->chunk_count ? sc->chunk_offsets[i+1] : INT64_MAX;
4497  current_offset = sc->chunk_offsets[i];
4498  while (mov_stsc_index_valid(stsc_index, sc->stsc_count) &&
4499  i + 1 == sc->stsc_data[stsc_index + 1].first)
4500  stsc_index++;
4501 
4502  if (next_offset > current_offset && sc->sample_size>0 && sc->sample_size < sc->stsz_sample_size &&
4503  sc->stsc_data[stsc_index].count * (int64_t)sc->stsz_sample_size > next_offset - current_offset) {
4504  av_log(mov->fc, AV_LOG_WARNING, "STSZ sample size %d invalid (too large), ignoring\n", sc->stsz_sample_size);
4505  sc->stsz_sample_size = sc->sample_size;
4506  }
4507  if (sc->stsz_sample_size>0 && sc->stsz_sample_size < sc->sample_size) {
4508  av_log(mov->fc, AV_LOG_WARNING, "STSZ sample size %d invalid (too small), ignoring\n", sc->stsz_sample_size);
4509  sc->stsz_sample_size = sc->sample_size;
4510  }
4511 
4512  for (j = 0; j < sc->stsc_data[stsc_index].count; j++) {
4513  int keyframe = 0;
4514  if (current_sample >= sc->sample_count) {
4515  av_log(mov->fc, AV_LOG_ERROR, "wrong sample count\n");
4516  return;
4517  }
4518 
4519  if (!sc->keyframe_absent && (!sc->keyframe_count || current_sample+key_off == sc->keyframes[stss_index])) {
4520  keyframe = 1;
4521  if (stss_index + 1 < sc->keyframe_count)
4522  stss_index++;
4523  } else if (sc->stps_count && current_sample+key_off == sc->stps_data[stps_index]) {
4524  keyframe = 1;
4525  if (stps_index + 1 < sc->stps_count)
4526  stps_index++;
4527  }
4528  if (rap_group_present && rap_group_index < sc->rap_group_count) {
4529  if (sc->rap_group[rap_group_index].index > 0)
4530  keyframe = 1;
4531  if (++rap_group_sample == sc->rap_group[rap_group_index].count) {
4532  rap_group_sample = 0;
4533  rap_group_index++;
4534  }
4535  }
4536  if (sc->keyframe_absent
4537  && !sc->stps_count
4538  && !rap_group_present
4539  && (st->codecpar->codec_type == AVMEDIA_TYPE_AUDIO || (i==0 && j==0)))
4540  keyframe = 1;
4541  if (keyframe)
4542  distance = 0;
4543  sample_size = sc->stsz_sample_size > 0 ? sc->stsz_sample_size : sc->sample_sizes[current_sample];
4544  if (current_offset > INT64_MAX - sample_size) {
4545  av_log(mov->fc, AV_LOG_ERROR, "Current offset %"PRId64" or sample size %u is too large\n",
4546  current_offset,
4547  sample_size);
4548  return;
4549  }
4550 
4551  if (sc->pseudo_stream_id == -1 ||
4552  sc->stsc_data[stsc_index].id - 1 == sc->pseudo_stream_id) {
4553  AVIndexEntry *e;
4554  if (sample_size > 0x3FFFFFFF) {
4555  av_log(mov->fc, AV_LOG_ERROR, "Sample size %u is too large\n", sample_size);
4556  return;
4557  }
4558  e = &sti->index_entries[sti->nb_index_entries++];
4559  e->pos = current_offset;
4560  e->timestamp = current_dts;
4561  e->size = sample_size;
4562  e->min_distance = distance;
4563  e->flags = keyframe ? AVINDEX_KEYFRAME : 0;
4564  av_log(mov->fc, AV_LOG_TRACE, "AVIndex stream %d, sample %u, offset %"PRIx64", dts %"PRId64", "
4565  "size %u, distance %u, keyframe %d\n", st->index, current_sample,
4566  current_offset, current_dts, sample_size, distance, keyframe);
4567  if (st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO && sti->nb_index_entries < 100)
4568  ff_rfps_add_frame(mov->fc, st, current_dts);
4569  }
4570 
4571  current_offset += sample_size;
4572  stream_size += sample_size;
4573 
4574  current_dts += sc->stts_data[stts_index].duration;
4575 
4576  distance++;
4577  stts_sample++;
4578  current_sample++;
4579  if (stts_index + 1 < sc->stts_count && stts_sample == sc->stts_data[stts_index].count) {
4580  stts_sample = 0;
4581  stts_index++;
4582  }
4583  }
4584  }
4585  if (st->duration > 0)
4586  st->codecpar->bit_rate = stream_size*8*sc->time_scale/st->duration;
4587  } else {
4588  unsigned chunk_samples, total = 0;
4589 
4590  if (!sc->chunk_count)
4591  return;
4592 
4593  // compute total chunk count
4594  for (i = 0; i < sc->stsc_count; i++) {
4595  unsigned count, chunk_count;
4596 
4597  chunk_samples = sc->stsc_data[i].count;
4598  if (i != sc->stsc_count - 1 &&
4599  sc->samples_per_frame && chunk_samples % sc->samples_per_frame) {
4600  av_log(mov->fc, AV_LOG_ERROR, "error unaligned chunk\n");
4601  return;
4602  }
4603 
4604  if (sc->samples_per_frame >= 160) { // gsm
4605  count = chunk_samples / sc->samples_per_frame;
4606  } else if (sc->samples_per_frame > 1) {
4607  unsigned samples = (1024/sc->samples_per_frame)*sc->samples_per_frame;
4608  count = (chunk_samples+samples-1) / samples;
4609  } else {
4610  count = (chunk_samples+1023) / 1024;
4611  }
4612 
4613  if (mov_stsc_index_valid(i, sc->stsc_count))
4614  chunk_count = sc->stsc_data[i+1].first - sc->stsc_data[i].first;
4615  else
4616  chunk_count = sc->chunk_count - (sc->stsc_data[i].first - 1);
4617  total += chunk_count * count;
4618  }
4619 
4620  av_log(mov->fc, AV_LOG_TRACE, "chunk count %u\n", total);
4621  if (total >= UINT_MAX / sizeof(*sti->index_entries) - sti->nb_index_entries)
4622  return;
4623  if (av_reallocp_array(&sti->index_entries,
4624  sti->nb_index_entries + total,
4625  sizeof(*sti->index_entries)) < 0) {
4626  sti->nb_index_entries = 0;
4627  return;
4628  }
4629  sti->index_entries_allocated_size = (sti->nb_index_entries + total) * sizeof(*sti->index_entries);
4630 
4631  // populate index
4632  for (i = 0; i < sc->chunk_count; i++) {
4633  current_offset = sc->chunk_offsets[i];
4634  if (mov_stsc_index_valid(stsc_index, sc->stsc_count) &&
4635  i + 1 == sc->stsc_data[stsc_index + 1].first)
4636  stsc_index++;
4637  chunk_samples = sc->stsc_data[stsc_index].count;
4638 
4639  while (chunk_samples > 0) {
4640  AVIndexEntry *e;
4641  unsigned size, samples;
4642 
4643  if (sc->samples_per_frame > 1 && !sc->bytes_per_frame) {
4645  "Zero bytes per frame, but %d samples per frame",
4646  sc->samples_per_frame);
4647  return;
4648  }
4649 
4650  if (sc->samples_per_frame >= 160) { // gsm
4651  samples = sc->samples_per_frame;
4652  size = sc->bytes_per_frame;
4653  } else {
4654  if (sc->samples_per_frame > 1) {
4655  samples = FFMIN((1024 / sc->samples_per_frame)*
4656  sc->samples_per_frame, chunk_samples);
4658  } else {
4659  samples = FFMIN(1024, chunk_samples);
4660  size = samples * sc->sample_size;
4661  }
4662  }
4663 
4664  if (sti->nb_index_entries >= total) {
4665  av_log(mov->fc, AV_LOG_ERROR, "wrong chunk count %u\n", total);
4666  return;
4667  }
4668  if (size > 0x3FFFFFFF) {
4669  av_log(mov->fc, AV_LOG_ERROR, "Sample size %u is too large\n", size);
4670  return;
4671  }
4672  e = &sti->index_entries[sti->nb_index_entries++];
4673  e->pos = current_offset;
4674  e->timestamp = current_dts;
4675  e->size = size;
4676  e->min_distance = 0;
4677  e->flags = AVINDEX_KEYFRAME;
4678  av_log(mov->fc, AV_LOG_TRACE, "AVIndex stream %d, chunk %u, offset %"PRIx64", dts %"PRId64", "
4679  "size %u, duration %u\n", st->index, i, current_offset, current_dts,
4680  size, samples);
4681 
4682  current_offset += size;
4683  current_dts += samples;
4684  chunk_samples -= samples;
4685  }
4686  }
4687  }
4688 
4689  if (!mov->ignore_editlist && mov->advanced_editlist) {
4690  // Fix index according to edit lists.
4691  mov_fix_index(mov, st);
4692  }
4693 
4694  // Update start time of the stream.
4696  st->start_time = sti->index_entries[0].timestamp + sc->dts_shift;
4697  if (sc->ctts_data) {
4698  st->start_time += sc->ctts_data[0].duration;
4699  }
4700  }
4701 
4702  mov_estimate_video_delay(mov, st);
4703 }
4704 
4705 static int test_same_origin(const char *src, const char *ref) {
4706  char src_proto[64];
4707  char ref_proto[64];
4708  char src_auth[256];
4709  char ref_auth[256];
4710  char src_host[256];
4711  char ref_host[256];
4712  int src_port=-1;
4713  int ref_port=-1;
4714 
4715  av_url_split(src_proto, sizeof(src_proto), src_auth, sizeof(src_auth), src_host, sizeof(src_host), &src_port, NULL, 0, src);
4716  av_url_split(ref_proto, sizeof(ref_proto), ref_auth, sizeof(ref_auth), ref_host, sizeof(ref_host), &ref_port, NULL, 0, ref);
4717 
4718  if (strlen(src) == 0) {
4719  return -1;
4720  } else if (strlen(src_auth) + 1 >= sizeof(src_auth) ||
4721  strlen(ref_auth) + 1 >= sizeof(ref_auth) ||
4722  strlen(src_host) + 1 >= sizeof(src_host) ||
4723  strlen(ref_host) + 1 >= sizeof(ref_host)) {
4724  return 0;
4725  } else if (strcmp(src_proto, ref_proto) ||
4726  strcmp(src_auth, ref_auth) ||
4727  strcmp(src_host, ref_host) ||
4728  src_port != ref_port) {
4729  return 0;
4730  } else
4731  return 1;
4732 }
4733 
4734 static int mov_open_dref(MOVContext *c, AVIOContext **pb, const char *src, MOVDref *ref)
4735 {
4736  /* try relative path, we do not try the absolute because it can leak information about our
4737  system to an attacker */
4738  if (ref->nlvl_to > 0 && ref->nlvl_from > 0) {
4739  char filename[1025];
4740  const char *src_path;
4741  int i, l;
4742 
4743  /* find a source dir */
4744  src_path = strrchr(src, '/');
4745  if (src_path)
4746  src_path++;
4747  else
4748  src_path = src;
4749 
4750  /* find a next level down to target */
4751  for (i = 0, l = strlen(ref->path) - 1; l >= 0; l--)
4752  if (ref->path[l] == '/') {
4753  if (i == ref->nlvl_to - 1)
4754  break;
4755  else
4756  i++;
4757  }
4758 
4759  /* compose filename if next level down to target was found */
4760  if (i == ref->nlvl_to - 1 && src_path - src < sizeof(filename)) {
4761  memcpy(filename, src, src_path - src);
4762  filename[src_path - src] = 0;
4763 
4764  for (i = 1; i < ref->nlvl_from; i++)
4765  av_strlcat(filename, "../", sizeof(filename));
4766 
4767  av_strlcat(filename, ref->path + l + 1, sizeof(filename));
4768  if (!c->use_absolute_path) {
4769  int same_origin = test_same_origin(src, filename);
4770 
4771  if (!same_origin) {
4772  av_log(c->fc, AV_LOG_ERROR,
4773  "Reference with mismatching origin, %s not tried for security reasons, "
4774  "set demuxer option use_absolute_path to allow it anyway\n",
4775  ref->path);
4776  return AVERROR(ENOENT);
4777  }
4778 
4779  if (strstr(ref->path + l + 1, "..") ||
4780  strstr(ref->path + l + 1, ":") ||
4781  (ref->nlvl_from > 1 && same_origin < 0) ||
4782  (filename[0] == '/' && src_path == src))
4783  return AVERROR(ENOENT);
4784  }
4785 
4786  if (strlen(filename) + 1 == sizeof(filename))
4787  return AVERROR(ENOENT);
4788  if (!c->fc->io_open(c->fc, pb, filename, AVIO_FLAG_READ, NULL))
4789  return 0;
4790  }
4791  } else if (c->use_absolute_path) {
4792  av_log(c->fc, AV_LOG_WARNING, "Using absolute path on user request, "
4793  "this is a possible security issue\n");
4794  if (!c->fc->io_open(c->fc, pb, ref->path, AVIO_FLAG_READ, NULL))
4795  return 0;
4796  } else {
4797  av_log(c->fc, AV_LOG_ERROR,
4798  "Absolute path %s not tried for security reasons, "
4799  "set demuxer option use_absolute_path to allow absolute paths\n",
4800  ref->path);
4801  }
4802 
4803  return AVERROR(ENOENT);
4804 }
4805 
4807 {
4808  if (sc->time_scale <= 0) {
4809  av_log(c->fc, AV_LOG_WARNING, "stream %d, timescale not set\n", sc->ffindex);
4810  sc->time_scale = c->time_scale;
4811  if (sc->time_scale <= 0)
4812  sc->time_scale = 1;
4813  }
4814 }
4815 
4816 #if CONFIG_IAMFDEC
4817 static int mov_update_iamf_streams(MOVContext *c, const AVStream *st)
4818 {
4819  const MOVStreamContext *sc = st->priv_data;
4820  const IAMFContext *iamf = &sc->iamf->iamf;
4821 
4822  for (int i = 0; i < iamf->nb_audio_elements; i++) {
4823  const AVStreamGroup *stg = NULL;
4824 
4825  for (int j = 0; j < c->fc->nb_stream_groups; j++)
4826  if (c->fc->stream_groups[j]->id == iamf->audio_elements[i]->audio_element_id)
4827  stg = c->fc->stream_groups[j];
4828  av_assert0(stg);
4829 
4830  for (int j = 0; j < stg->nb_streams; j++) {
4831  const FFStream *sti = cffstream(st);
4832  AVStream *out = stg->streams[j];
4833  FFStream *out_sti = ffstream(stg->streams[j]);
4834 
4835  out->codecpar->bit_rate = 0;
4836 
4837  if (out == st)
4838  continue;
4839 
4840  out->time_base = st->time_base;
4841  out->start_time = st->start_time;
4842  out->duration = st->duration;
4843  out->nb_frames = st->nb_frames;
4844  out->discard = st->discard;
4845 
4846  av_assert0(!out_sti->index_entries);
4848  if (!out_sti->index_entries)
4849  return AVERROR(ENOMEM);
4850 
4852  out_sti->nb_index_entries = sti->nb_index_entries;
4853  out_sti->skip_samples = sti->skip_samples;
4854  memcpy(out_sti->index_entries, sti->index_entries, sti->index_entries_allocated_size);
4855  }
4856  }
4857 
4858  return 0;
4859 }
4860 #endif
4861 
4863 {
4864  AVStream *st;
4865  MOVStreamContext *sc;
4866  int ret;
4867 
4868  st = avformat_new_stream(c->fc, NULL);
4869  if (!st) return AVERROR(ENOMEM);
4870  st->id = -1;
4871  sc = av_mallocz(sizeof(MOVStreamContext));
4872  if (!sc) return AVERROR(ENOMEM);
4873 
4874  st->priv_data = sc;
4876  sc->ffindex = st->index;
4877  c->trak_index = st->index;
4878  sc->refcount = 1;
4879 
4880  if ((ret = mov_read_default(c, pb, atom)) < 0)
4881  return ret;
4882 
4883  c->trak_index = -1;
4884 
4885  // Here stsc refers to a chunk not described in stco. This is technically invalid,
4886  // but we can overlook it (clearing stsc) whenever stts_count == 0 (indicating no samples).
4887  if (!sc->chunk_count && !sc->stts_count && sc->stsc_count) {
4888  sc->stsc_count = 0;
4889  av_freep(&sc->stsc_data);
4890  }
4891 
4892  /* sanity checks */
4893  if ((sc->chunk_count && (!sc->stts_count || !sc->stsc_count ||
4894  (!sc->sample_size && !sc->sample_count))) ||
4895  (!sc->chunk_count && sc->sample_count)) {
4896  av_log(c->fc, AV_LOG_ERROR, "stream %d, missing mandatory atoms, broken header\n",
4897  st->index);
4898  return 0;
4899  }
4900  if (sc->stsc_count && sc->stsc_data[ sc->stsc_count - 1 ].first > sc->chunk_count) {
4901  av_log(c->fc, AV_LOG_ERROR, "stream %d, contradictionary STSC and STCO\n",
4902  st->index);
4903  return AVERROR_INVALIDDATA;
4904  }
4905 
4906  fix_timescale(c, sc);
4907 
4908  avpriv_set_pts_info(st, 64, 1, sc->time_scale);
4909 
4910  /*
4911  * Advanced edit list support does not work with fragemented MP4s, which
4912  * have stsc, stsz, stco, and stts with zero entries in the moov atom.
4913  * In these files, trun atoms may be streamed in.
4914  */
4915  if (!sc->stts_count && c->advanced_editlist) {
4916 
4917  av_log(c->fc, AV_LOG_VERBOSE, "advanced_editlist does not work with fragmented "
4918  "MP4. disabling.\n");
4919  c->advanced_editlist = 0;
4920  c->advanced_editlist_autodisabled = 1;
4921  }
4922 
4923  mov_build_index(c, st);
4924 
4925 #if CONFIG_IAMFDEC
4926  if (sc->iamf) {
4927  ret = mov_update_iamf_streams(c, st);
4928  if (ret < 0)
4929  return ret;
4930  }
4931 #endif
4932 
4933  if (sc->dref_id-1 < sc->drefs_count && sc->drefs[sc->dref_id-1].path) {
4934  MOVDref *dref = &sc->drefs[sc->dref_id - 1];
4935  if (c->enable_drefs) {
4936  if (mov_open_dref(c, &sc->pb, c->fc->url, dref) < 0)
4937  av_log(c->fc, AV_LOG_ERROR,
4938  "stream %d, error opening alias: path='%s', dir='%s', "
4939  "filename='%s', volume='%s', nlvl_from=%d, nlvl_to=%d\n",
4940  st->index, dref->path, dref->dir, dref->filename,
4941  dref->volume, dref->nlvl_from, dref->nlvl_to);
4942  } else {
4943  av_log(c->fc, AV_LOG_WARNING,
4944  "Skipped opening external track: "
4945  "stream %d, alias: path='%s', dir='%s', "
4946  "filename='%s', volume='%s', nlvl_from=%d, nlvl_to=%d."
4947  "Set enable_drefs to allow this.\n",
4948  st->index, dref->path, dref->dir, dref->filename,
4949  dref->volume, dref->nlvl_from, dref->nlvl_to);
4950  }
4951  } else {
4952  sc->pb = c->fc->pb;
4953  sc->pb_is_copied = 1;
4954  }
4955 
4956  if (st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO) {
4957  if (!st->sample_aspect_ratio.num && st->codecpar->width && st->codecpar->height &&
4958  sc->height && sc->width &&
4959  (st->codecpar->width != sc->width || st->codecpar->height != sc->height)) {
4960  st->sample_aspect_ratio = av_d2q(((double)st->codecpar->height * sc->width) /
4961  ((double)st->codecpar->width * sc->height), INT_MAX);
4962  }
4963 
4964 #if FF_API_R_FRAME_RATE
4965  if (sc->stts_count == 1 || (sc->stts_count == 2 && sc->stts_data[1].count == 1))
4967  sc->time_scale, sc->stts_data[0].duration, INT_MAX);
4968 #endif
4969  }
4970 
4971  // done for ai5q, ai52, ai55, ai1q, ai12 and ai15.
4972  if (!st->codecpar->extradata_size && st->codecpar->codec_id == AV_CODEC_ID_H264 &&
4973  TAG_IS_AVCI(st->codecpar->codec_tag)) {
4975  if (ret < 0)
4976  return ret;
4977  }
4978 
4979  switch (st->codecpar->codec_id) {
4980 #if CONFIG_H261_DECODER
4981  case AV_CODEC_ID_H261:
4982 #endif
4983 #if CONFIG_H263_DECODER
4984  case AV_CODEC_ID_H263:
4985 #endif
4986 #if CONFIG_MPEG4_DECODER
4987  case AV_CODEC_ID_MPEG4:
4988 #endif
4989  st->codecpar->width = 0; /* let decoder init width/height */
4990  st->codecpar->height= 0;
4991  break;
4992  }
4993 
4994  // If the duration of the mp3 packets is not constant, then they could need a parser
4995  if (st->codecpar->codec_id == AV_CODEC_ID_MP3
4996  && sc->stts_count > 3
4997  && sc->stts_count*10 > st->nb_frames
4998  && sc->time_scale == st->codecpar->sample_rate) {
5000  }
5001  /* Do not need those anymore. */
5002  av_freep(&sc->chunk_offsets);
5003  av_freep(&sc->sample_sizes);
5004  av_freep(&sc->keyframes);
5005  av_freep(&sc->stts_data);
5006  av_freep(&sc->stps_data);
5007  av_freep(&sc->elst_data);
5008  av_freep(&sc->rap_group);
5009  av_freep(&sc->sync_group);
5010  av_freep(&sc->sgpd_sync);
5011 
5012  return 0;
5013 }
5014 
5016 {
5017  int ret;
5018  c->itunes_metadata = 1;
5019  ret = mov_read_default(c, pb, atom);
5020  c->itunes_metadata = 0;
5021  return ret;
5022 }
5023 
5025 {
5026  uint32_t count;
5027  uint32_t i;
5028 
5029  if (atom.size < 8)
5030  return 0;
5031 
5032  avio_skip(pb, 4);
5033  count = avio_rb32(pb);
5034  atom.size -= 8;
5035  if (count >= UINT_MAX / sizeof(*c->meta_keys)) {
5036  av_log(c->fc, AV_LOG_ERROR,
5037  "The 'keys' atom with the invalid key count: %"PRIu32"\n", count);
5038  return AVERROR_INVALIDDATA;
5039  }
5040 
5041  c->meta_keys_count = count + 1;
5042  c->meta_keys = av_mallocz(c->meta_keys_count * sizeof(*c->meta_keys));
5043  if (!c->meta_keys)
5044  return AVERROR(ENOMEM);
5045 
5046  for (i = 1; i <= count; ++i) {
5047  uint32_t key_size = avio_rb32(pb);
5048  uint32_t type = avio_rl32(pb);
5049  if (key_size < 8 || key_size > atom.size) {
5050  av_log(c->fc, AV_LOG_ERROR,
5051  "The key# %"PRIu32" in meta has invalid size:"
5052  "%"PRIu32"\n", i, key_size);
5053  return AVERROR_INVALIDDATA;
5054  }
5055  atom.size -= key_size;
5056  key_size -= 8;
5057  if (type != MKTAG('m','d','t','a')) {
5058  avio_skip(pb, key_size);
5059  continue;
5060  }
5061  c->meta_keys[i] = av_mallocz(key_size + 1);
5062  if (!c->meta_keys[i])
5063  return AVERROR(ENOMEM);
5064  avio_read(pb, c->meta_keys[i], key_size);
5065  }
5066 
5067  return 0;
5068 }
5069 
5071 {
5072  int64_t end = av_sat_add64(avio_tell(pb), atom.size);
5073  uint8_t *key = NULL, *val = NULL, *mean = NULL;
5074  int i;
5075  int ret = 0;
5076  AVStream *st;
5077  MOVStreamContext *sc;
5078 
5079  if (c->fc->nb_streams < 1)
5080  return 0;
5081  st = c->fc->streams[c->fc->nb_streams-1];
5082  sc = st->priv_data;
5083 
5084  for (i = 0; i < 3; i++) {
5085  uint8_t **p;
5086  uint32_t len, tag;
5087 
5088  if (end - avio_tell(pb) <= 12)
5089  break;
5090 
5091  len = avio_rb32(pb);
5092  tag = avio_rl32(pb);
5093  avio_skip(pb, 4); // flags
5094 
5095  if (len < 12 || len - 12 > end - avio_tell(pb))
5096  break;
5097  len -= 12;
5098 
5099  if (tag == MKTAG('m', 'e', 'a', 'n'))
5100  p = &mean;
5101  else if (tag == MKTAG('n', 'a', 'm', 'e'))
5102  p = &key;
5103  else if (tag == MKTAG('d', 'a', 't', 'a') && len > 4) {
5104  avio_skip(pb, 4);
5105  len -= 4;
5106  p = &val;
5107  } else
5108  break;
5109 
5110  if (*p)
5111  break;
5112 
5113  *p = av_malloc(len + 1);
5114  if (!*p) {
5115  ret = AVERROR(ENOMEM);
5116  break;
5117  }
5118  ret = ffio_read_size(pb, *p, len);
5119  if (ret < 0) {
5120  av_freep(p);
5121  break;
5122  }
5123  (*p)[len] = 0;
5124  }
5125 
5126  if (mean && key && val) {
5127  if (strcmp(key, "iTunSMPB") == 0) {
5128  int priming, remainder, samples;
5129  if(sscanf(val, "%*X %X %X %X", &priming, &remainder, &samples) == 3){
5130  if(priming>0 && priming<16384)
5131  sc->start_pad = priming;
5132  }
5133  }
5134  if (strcmp(key, "cdec") != 0) {
5135  av_dict_set(&c->fc->metadata, key, val,
5137  key = val = NULL;
5138  }
5139  } else {
5140  av_log(c->fc, AV_LOG_VERBOSE,
5141  "Unhandled or malformed custom metadata of size %"PRId64"\n", atom.size);
5142  }
5143 
5144  avio_seek(pb, end, SEEK_SET);
5145  av_freep(&key);
5146  av_freep(&val);
5147  av_freep(&mean);
5148  return ret;
5149 }
5150 
5152 {
5153  MOVStreamContext *sc;
5154  AVStream *st;
5155 
5156  st = avformat_new_stream(c->fc, NULL);
5157  if (!st)
5158  return AVERROR(ENOMEM);
5159  sc = av_mallocz(sizeof(MOVStreamContext));
5160  if (!sc)
5161  return AVERROR(ENOMEM);
5162 
5163  item->st = st;
5164  st->id = item->item_id;
5165  st->priv_data = sc;
5167  st->codecpar->codec_id = mov_codec_id(st, item->type);
5168  sc->id = st->id;
5169  sc->ffindex = st->index;
5170  st->avg_frame_rate.num = st->avg_frame_rate.den = 1;
5171  st->time_base.num = st->time_base.den = 1;
5172  st->nb_frames = 1;
5173  sc->time_scale = 1;
5174  sc->pb = c->fc->pb;
5175  sc->pb_is_copied = 1;
5176  sc->refcount = 1;
5177 
5178  if (item->name)
5179  av_dict_set(&st->metadata, "title", item->name, 0);
5180 
5181  // Populate the necessary fields used by mov_build_index.
5182  sc->stsc_count = 1;
5183  sc->stsc_data = av_malloc_array(1, sizeof(*sc->stsc_data));
5184  if (!sc->stsc_data)
5185  return AVERROR(ENOMEM);
5186  sc->stsc_data[0].first = 1;
5187  sc->stsc_data[0].count = 1;
5188  sc->stsc_data[0].id = 1;
5189  sc->chunk_count = 1;
5190  sc->chunk_offsets = av_malloc_array(1, sizeof(*sc->chunk_offsets));
5191  if (!sc->chunk_offsets)
5192  return AVERROR(ENOMEM);
5193  sc->sample_count = 1;
5194  sc->sample_sizes = av_malloc_array(1, sizeof(*sc->sample_sizes));
5195  if (!sc->sample_sizes)
5196  return AVERROR(ENOMEM);
5197  sc->stts_count = 1;
5198  sc->stts_data = av_malloc_array(1, sizeof(*sc->stts_data));
5199  if (!sc->stts_data)
5200  return AVERROR(ENOMEM);
5201  sc->stts_data[0].count = 1;
5202  // Not used for still images. But needed by mov_build_index.
5203  sc->stts_data[0].duration = 0;
5204 
5205  return 0;
5206 }
5207 
5209 {
5210  while (atom.size > 8) {
5211  uint32_t tag;
5212  if (avio_feof(pb))
5213  return AVERROR_EOF;
5214  tag = avio_rl32(pb);
5215  atom.size -= 4;
5216  if (tag == MKTAG('h','d','l','r')) {
5217  avio_seek(pb, -8, SEEK_CUR);
5218  atom.size += 8;
5219  return mov_read_default(c, pb, atom);
5220  }
5221  }
5222  return 0;
5223 }
5224 
5225 // return 1 when matrix is identity, 0 otherwise
5226 #define IS_MATRIX_IDENT(matrix) \
5227  ( (matrix)[0][0] == (1 << 16) && \
5228  (matrix)[1][1] == (1 << 16) && \
5229  (matrix)[2][2] == (1 << 30) && \
5230  !(matrix)[0][1] && !(matrix)[0][2] && \
5231  !(matrix)[1][0] && !(matrix)[1][2] && \
5232  !(matrix)[2][0] && !(matrix)[2][1])
5233 
5235 {
5236  int i, j, e;
5237  int width;
5238  int height;
5239  int display_matrix[3][3];
5240  int res_display_matrix[3][3] = { { 0 } };
5241  AVStream *st;
5242  MOVStreamContext *sc;
5243  int version;
5244  int flags;
5245 
5246  if (c->fc->nb_streams < 1)
5247  return 0;
5248  st = c->fc->streams[c->fc->nb_streams-1];
5249  sc = st->priv_data;
5250 
5251  // Each stream (trak) should have exactly 1 tkhd. This catches bad files and
5252  // avoids corrupting AVStreams mapped to an earlier tkhd.
5253  if (st->id != -1)
5254  return AVERROR_INVALIDDATA;
5255 
5256  version = avio_r8(pb);
5257  flags = avio_rb24(pb);
5259 
5260  if (version == 1) {
5261  avio_rb64(pb);
5262  avio_rb64(pb);
5263  } else {
5264  avio_rb32(pb); /* creation time */
5265  avio_rb32(pb); /* modification time */
5266  }
5267  st->id = (int)avio_rb32(pb); /* track id (NOT 0 !)*/
5268  sc->id = st->id;
5269  avio_rb32(pb); /* reserved */
5270 
5271  /* highlevel (considering edits) duration in movie timebase */
5272  (version == 1) ? avio_rb64(pb) : avio_rb32(pb);
5273  avio_rb32(pb); /* reserved */
5274  avio_rb32(pb); /* reserved */
5275 
5276  avio_rb16(pb); /* layer */
5277  avio_rb16(pb); /* alternate group */
5278  avio_rb16(pb); /* volume */
5279  avio_rb16(pb); /* reserved */
5280 
5281  //read in the display matrix (outlined in ISO 14496-12, Section 6.2.2)
5282  // they're kept in fixed point format through all calculations
5283  // save u,v,z to store the whole matrix in the AV_PKT_DATA_DISPLAYMATRIX
5284  // side data, but the scale factor is not needed to calculate aspect ratio
5285  for (i = 0; i < 3; i++) {
5286  display_matrix[i][0] = avio_rb32(pb); // 16.16 fixed point
5287  display_matrix[i][1] = avio_rb32(pb); // 16.16 fixed point
5288  display_matrix[i][2] = avio_rb32(pb); // 2.30 fixed point
5289  }
5290 
5291  width = avio_rb32(pb); // 16.16 fixed point track width
5292  height = avio_rb32(pb); // 16.16 fixed point track height
5293  sc->width = width >> 16;
5294  sc->height = height >> 16;
5295 
5296  // apply the moov display matrix (after the tkhd one)
5297  for (i = 0; i < 3; i++) {
5298  const int sh[3] = { 16, 16, 30 };
5299  for (j = 0; j < 3; j++) {
5300  for (e = 0; e < 3; e++) {
5301  res_display_matrix[i][j] +=
5302  ((int64_t) display_matrix[i][e] *
5303  c->movie_display_matrix[e][j]) >> sh[e];
5304  }
5305  }
5306  }
5307 
5308  // save the matrix when it is not the default identity
5309  if (!IS_MATRIX_IDENT(res_display_matrix)) {
5310  av_freep(&sc->display_matrix);
5311  sc->display_matrix = av_malloc(sizeof(int32_t) * 9);
5312  if (!sc->display_matrix)
5313  return AVERROR(ENOMEM);
5314 
5315  for (i = 0; i < 3; i++)
5316  for (j = 0; j < 3; j++)
5317  sc->display_matrix[i * 3 + j] = res_display_matrix[i][j];
5318  }
5319 
5320  // transform the display width/height according to the matrix
5321  // to keep the same scale, use [width height 1<<16]
5322  if (width && height && sc->display_matrix) {
5323  double disp_transform[2];
5324 
5325  for (i = 0; i < 2; i++)
5326  disp_transform[i] = hypot(sc->display_matrix[0 + i],
5327  sc->display_matrix[3 + i]);
5328 
5329  if (disp_transform[0] > 1 && disp_transform[1] > 1 &&
5330  disp_transform[0] < (1<<24) && disp_transform[1] < (1<<24) &&
5331  fabs((disp_transform[0] / disp_transform[1]) - 1.0) > 0.01)
5333  disp_transform[0] / disp_transform[1],
5334  INT_MAX);
5335  }
5336  return 0;
5337 }
5338 
5340 {
5341  MOVFragment *frag = &c->fragment;
5342  MOVTrackExt *trex = NULL;
5343  int flags, track_id, i;
5344  MOVFragmentStreamInfo * frag_stream_info;
5345 
5346  avio_r8(pb); /* version */
5347  flags = avio_rb24(pb);
5348 
5349  track_id = avio_rb32(pb);
5350  if (!track_id)
5351  return AVERROR_INVALIDDATA;
5352  for (i = 0; i < c->trex_count; i++)
5353  if (c->trex_data[i].track_id == track_id) {
5354  trex = &c->trex_data[i];
5355  break;
5356  }
5357  if (!trex) {
5358  av_log(c->fc, AV_LOG_WARNING, "could not find corresponding trex (id %u)\n", track_id);
5359  return 0;
5360  }
5361  c->fragment.found_tfhd = 1;
5362  frag->track_id = track_id;
5363  set_frag_stream(&c->frag_index, track_id);
5364 
5367  frag->moof_offset : frag->implicit_offset;
5368  frag->stsd_id = flags & MOV_TFHD_STSD_ID ? avio_rb32(pb) : trex->stsd_id;
5369 
5371  avio_rb32(pb) : trex->duration;
5372  frag->size = flags & MOV_TFHD_DEFAULT_SIZE ?
5373  avio_rb32(pb) : trex->size;
5374  frag->flags = flags & MOV_TFHD_DEFAULT_FLAGS ?
5375  avio_rb32(pb) : trex->flags;
5376  av_log(c->fc, AV_LOG_TRACE, "frag flags 0x%x\n", frag->flags);
5377 
5378  frag_stream_info = get_current_frag_stream_info(&c->frag_index);
5379  if (frag_stream_info) {
5380  frag_stream_info->next_trun_dts = AV_NOPTS_VALUE;
5381  frag_stream_info->stsd_id = frag->stsd_id;
5382  }
5383  return 0;
5384 }
5385 
5387 {
5388  unsigned i, num;
5389  void *new_tracks;
5390 
5391  num = atom.size / 4;
5392  if (!(new_tracks = av_malloc_array(num, sizeof(int))))
5393  return AVERROR(ENOMEM);
5394 
5395  av_free(c->chapter_tracks);
5396  c->chapter_tracks = new_tracks;
5397  c->nb_chapter_tracks = num;
5398 
5399  for (i = 0; i < num && !pb->eof_reached; i++)
5400  c->chapter_tracks[i] = avio_rb32(pb);
5401 
5402  c->nb_chapter_tracks = i;
5403 
5404  return 0;
5405 }
5406 
5408 {
5409  MOVTrackExt *trex;
5410  int err;
5411 
5412  if ((uint64_t)c->trex_count+1 >= UINT_MAX / sizeof(*c->trex_data))
5413  return AVERROR_INVALIDDATA;
5414  if ((err = av_reallocp_array(&c->trex_data, c->trex_count + 1,
5415  sizeof(*c->trex_data))) < 0) {
5416  c->trex_count = 0;
5417  return err;
5418  }
5419 
5420  c->fc->duration = AV_NOPTS_VALUE; // the duration from mvhd is not representing the whole file when fragments are used.
5421 
5422  trex = &c->trex_data[c->trex_count++];
5423  avio_r8(pb); /* version */
5424  avio_rb24(pb); /* flags */
5425  trex->track_id = avio_rb32(pb);
5426  trex->stsd_id = avio_rb32(pb);
5427  trex->duration = avio_rb32(pb);
5428  trex->size = avio_rb32(pb);
5429  trex->flags = avio_rb32(pb);
5430  return 0;
5431 }
5432 
5434 {
5435  MOVFragment *frag = &c->fragment;
5436  AVStream *st = NULL;
5437  MOVStreamContext *sc;
5438  int version, i;
5439  MOVFragmentStreamInfo * frag_stream_info;
5440  int64_t base_media_decode_time;
5441 
5442  for (i = 0; i < c->fc->nb_streams; i++) {
5443  sc = c->fc->streams[i]->priv_data;
5444  if (sc->id == frag->track_id) {
5445  st = c->fc->streams[i];
5446  break;
5447  }
5448  }
5449  if (!st) {
5450  av_log(c->fc, AV_LOG_WARNING, "could not find corresponding track id %u\n", frag->track_id);
5451  return 0;
5452  }
5453  sc = st->priv_data;
5454  if (sc->pseudo_stream_id + 1 != frag->stsd_id && sc->pseudo_stream_id != -1)
5455  return 0;
5456  version = avio_r8(pb);
5457  avio_rb24(pb); /* flags */
5458  if (version) {
5459  base_media_decode_time = avio_rb64(pb);
5460  } else {
5461  base_media_decode_time = avio_rb32(pb);
5462  }
5463 
5464  frag_stream_info = get_current_frag_stream_info(&c->frag_index);
5465  if (frag_stream_info)
5466  frag_stream_info->tfdt_dts = base_media_decode_time;
5467  sc->track_end = base_media_decode_time;
5468 
5469  return 0;
5470 }
5471 
5473 {
5474  MOVFragment *frag = &c->fragment;
5475  AVStream *st = NULL;
5476  FFStream *sti = NULL;
5477  MOVStreamContext *sc;
5478  MOVCtts *ctts_data;
5479  uint64_t offset;
5480  int64_t dts, pts = AV_NOPTS_VALUE;
5481  int data_offset = 0;
5482  unsigned entries, first_sample_flags = frag->flags;
5483  int flags, distance, i;
5484  int64_t prev_dts = AV_NOPTS_VALUE;
5485  int next_frag_index = -1, index_entry_pos;
5486  size_t requested_size;
5487  size_t old_ctts_allocated_size;
5488  AVIndexEntry *new_entries;
5489  MOVFragmentStreamInfo * frag_stream_info;
5490 
5491  if (!frag->found_tfhd) {
5492  av_log(c->fc, AV_LOG_ERROR, "trun track id unknown, no tfhd was found\n");
5493  return AVERROR_INVALIDDATA;
5494  }
5495 
5496  for (i = 0; i < c->fc->nb_streams; i++) {
5497  sc = c->fc->streams[i]->priv_data;
5498  if (sc->id == frag->track_id) {
5499  st = c->fc->streams[i];
5500  sti = ffstream(st);
5501  break;
5502  }
5503  }
5504  if (!st) {
5505  av_log(c->fc, AV_LOG_WARNING, "could not find corresponding track id %u\n", frag->track_id);
5506  return 0;
5507  }
5508  sc = st->priv_data;
5509  if (sc->pseudo_stream_id+1 != frag->stsd_id && sc->pseudo_stream_id != -1)
5510  return 0;
5511 
5512  // Find the next frag_index index that has a valid index_entry for
5513  // the current track_id.
5514  //
5515  // A valid index_entry means the trun for the fragment was read
5516  // and it's samples are in index_entries at the given position.
5517  // New index entries will be inserted before the index_entry found.
5518  index_entry_pos = sti->nb_index_entries;
5519  for (i = c->frag_index.current + 1; i < c->frag_index.nb_items; i++) {
5520  frag_stream_info = get_frag_stream_info(&c->frag_index, i, frag->track_id);
5521  if (frag_stream_info && frag_stream_info->index_entry >= 0) {
5522  next_frag_index = i;
5523  index_entry_pos = frag_stream_info->index_entry;
5524  break;
5525  }
5526  }
5527  av_assert0(index_entry_pos <= sti->nb_index_entries);
5528 
5529  avio_r8(pb); /* version */
5530  flags = avio_rb24(pb);
5531  entries = avio_rb32(pb);
5532  av_log(c->fc, AV_LOG_TRACE, "flags 0x%x entries %u\n", flags, entries);
5533 
5534  if ((uint64_t)entries+sc->ctts_count >= UINT_MAX/sizeof(*sc->ctts_data))
5535  return AVERROR_INVALIDDATA;
5536  if (flags & MOV_TRUN_DATA_OFFSET) data_offset = avio_rb32(pb);
5537  if (flags & MOV_TRUN_FIRST_SAMPLE_FLAGS) first_sample_flags = avio_rb32(pb);
5538 
5539  frag_stream_info = get_current_frag_stream_info(&c->frag_index);
5540  if (frag_stream_info) {
5541  if (frag_stream_info->next_trun_dts != AV_NOPTS_VALUE) {
5542  dts = frag_stream_info->next_trun_dts - sc->time_offset;
5543  } else if (frag_stream_info->first_tfra_pts != AV_NOPTS_VALUE &&
5544  c->use_mfra_for == FF_MOV_FLAG_MFRA_PTS) {
5545  pts = frag_stream_info->first_tfra_pts;
5546  av_log(c->fc, AV_LOG_DEBUG, "found mfra time %"PRId64
5547  ", using it for pts\n", pts);
5548  } else if (frag_stream_info->first_tfra_pts != AV_NOPTS_VALUE &&
5549  c->use_mfra_for == FF_MOV_FLAG_MFRA_DTS) {
5550  dts = frag_stream_info->first_tfra_pts;
5551  av_log(c->fc, AV_LOG_DEBUG, "found mfra time %"PRId64
5552  ", using it for dts\n", pts);
5553  } else {
5554  int has_tfdt = frag_stream_info->tfdt_dts != AV_NOPTS_VALUE;
5555  int has_sidx = frag_stream_info->sidx_pts != AV_NOPTS_VALUE;
5556  int fallback_tfdt = !c->use_tfdt && !has_sidx && has_tfdt;
5557  int fallback_sidx = c->use_tfdt && !has_tfdt && has_sidx;
5558 
5559  if (fallback_sidx) {
5560  av_log(c->fc, AV_LOG_DEBUG, "use_tfdt set but no tfdt found, using sidx instead\n");
5561  }
5562  if (fallback_tfdt) {
5563  av_log(c->fc, AV_LOG_DEBUG, "use_tfdt not set but no sidx found, using tfdt instead\n");
5564  }
5565 
5566  if (has_tfdt && c->use_tfdt || fallback_tfdt) {
5567  dts = frag_stream_info->tfdt_dts - sc->time_offset;
5568  av_log(c->fc, AV_LOG_DEBUG, "found tfdt time %"PRId64
5569  ", using it for dts\n", dts);
5570  } else if (has_sidx && !c->use_tfdt || fallback_sidx) {
5571  // FIXME: sidx earliest_presentation_time is *PTS*, s.b.
5572  // pts = frag_stream_info->sidx_pts;
5573  dts = frag_stream_info->sidx_pts - sc->time_offset;
5574  av_log(c->fc, AV_LOG_DEBUG, "found sidx time %"PRId64
5575  ", using it for dts\n", frag_stream_info->sidx_pts);
5576  } else {
5577  dts = sc->track_end - sc->time_offset;
5578  av_log(c->fc, AV_LOG_DEBUG, "found track end time %"PRId64
5579  ", using it for dts\n", dts);
5580  }
5581  }
5582  } else {
5583  dts = sc->track_end - sc->time_offset;
5584  av_log(c->fc, AV_LOG_DEBUG, "found track end time %"PRId64
5585  ", using it for dts\n", dts);
5586  }
5587  offset = frag->base_data_offset + data_offset;
5588  distance = 0;
5589  av_log(c->fc, AV_LOG_TRACE, "first sample flags 0x%x\n", first_sample_flags);
5590 
5591  // realloc space for new index entries
5592  if ((uint64_t)sti->nb_index_entries + entries >= UINT_MAX / sizeof(AVIndexEntry)) {
5593  entries = UINT_MAX / sizeof(AVIndexEntry) - sti->nb_index_entries;
5594  av_log(c->fc, AV_LOG_ERROR, "Failed to add index entry\n");
5595  }
5596  if (entries == 0)
5597  return 0;
5598 
5599  requested_size = (sti->nb_index_entries + entries) * sizeof(AVIndexEntry);
5600  new_entries = av_fast_realloc(sti->index_entries,
5602  requested_size);
5603  if (!new_entries)
5604  return AVERROR(ENOMEM);
5605  sti->index_entries= new_entries;
5606 
5607  requested_size = (sti->nb_index_entries + entries) * sizeof(*sc->ctts_data);
5608  old_ctts_allocated_size = sc->ctts_allocated_size;
5609  ctts_data = av_fast_realloc(sc->ctts_data, &sc->ctts_allocated_size,
5610  requested_size);
5611  if (!ctts_data)
5612  return AVERROR(ENOMEM);
5613  sc->ctts_data = ctts_data;
5614 
5615  // In case there were samples without ctts entries, ensure they get
5616  // zero valued entries. This ensures clips which mix boxes with and
5617  // without ctts entries don't pickup uninitialized data.
5618  memset((uint8_t*)(sc->ctts_data) + old_ctts_allocated_size, 0,
5619  sc->ctts_allocated_size - old_ctts_allocated_size);
5620 
5621  if (index_entry_pos < sti->nb_index_entries) {
5622  // Make hole in index_entries and ctts_data for new samples
5623  memmove(sti->index_entries + index_entry_pos + entries,
5624  sti->index_entries + index_entry_pos,
5625  sizeof(*sti->index_entries) *
5626  (sti->nb_index_entries - index_entry_pos));
5627  memmove(sc->ctts_data + index_entry_pos + entries,
5628  sc->ctts_data + index_entry_pos,
5629  sizeof(*sc->ctts_data) * (sc->ctts_count - index_entry_pos));
5630  if (index_entry_pos < sc->current_sample) {
5631  sc->current_sample += entries;
5632  }
5633  }
5634 
5635  sti->nb_index_entries += entries;
5636  sc->ctts_count = sti->nb_index_entries;
5637 
5638  // Record the index_entry position in frag_index of this fragment
5639  if (frag_stream_info) {
5640  frag_stream_info->index_entry = index_entry_pos;
5641  if (frag_stream_info->index_base < 0)
5642  frag_stream_info->index_base = index_entry_pos;
5643  }
5644 
5645  if (index_entry_pos > 0)
5646  prev_dts = sti->index_entries[index_entry_pos-1].timestamp;
5647 
5648  for (i = 0; i < entries && !pb->eof_reached; i++) {
5649  unsigned sample_size = frag->size;
5650  int sample_flags = i ? frag->flags : first_sample_flags;
5651  unsigned sample_duration = frag->duration;
5652  unsigned ctts_duration = 0;
5653  int keyframe = 0;
5654  int index_entry_flags = 0;
5655 
5656  if (flags & MOV_TRUN_SAMPLE_DURATION) sample_duration = avio_rb32(pb);
5657  if (flags & MOV_TRUN_SAMPLE_SIZE) sample_size = avio_rb32(pb);
5658  if (flags & MOV_TRUN_SAMPLE_FLAGS) sample_flags = avio_rb32(pb);
5659  if (flags & MOV_TRUN_SAMPLE_CTS) ctts_duration = avio_rb32(pb);
5660 
5661  mov_update_dts_shift(sc, ctts_duration, c->fc);
5662  if (pts != AV_NOPTS_VALUE) {
5663  dts = pts - sc->dts_shift;
5664  if (flags & MOV_TRUN_SAMPLE_CTS) {
5665  dts -= ctts_duration;
5666  } else {
5667  dts -= sc->time_offset;
5668  }
5669  av_log(c->fc, AV_LOG_DEBUG,
5670  "pts %"PRId64" calculated dts %"PRId64
5671  " sc->dts_shift %d ctts.duration %d"
5672  " sc->time_offset %"PRId64
5673  " flags & MOV_TRUN_SAMPLE_CTS %d\n",
5674  pts, dts,
5675  sc->dts_shift, ctts_duration,
5677  pts = AV_NOPTS_VALUE;
5678  }
5679 
5681  keyframe = 1;
5682  else
5683  keyframe =
5684  !(sample_flags & (MOV_FRAG_SAMPLE_FLAG_IS_NON_SYNC |
5686  if (keyframe) {
5687  distance = 0;
5688  index_entry_flags |= AVINDEX_KEYFRAME;
5689  }
5690  // Fragments can overlap in time. Discard overlapping frames after
5691  // decoding.
5692  if (prev_dts >= dts)
5693  index_entry_flags |= AVINDEX_DISCARD_FRAME;
5694 
5695  sti->index_entries[index_entry_pos].pos = offset;
5696  sti->index_entries[index_entry_pos].timestamp = dts;
5697  sti->index_entries[index_entry_pos].size = sample_size;
5698  sti->index_entries[index_entry_pos].min_distance = distance;
5699  sti->index_entries[index_entry_pos].flags = index_entry_flags;
5700 
5701  sc->ctts_data[index_entry_pos].count = 1;
5702  sc->ctts_data[index_entry_pos].duration = ctts_duration;
5703  index_entry_pos++;
5704 
5705  av_log(c->fc, AV_LOG_TRACE, "AVIndex stream %d, sample %d, offset %"PRIx64", dts %"PRId64", "
5706  "size %u, distance %d, keyframe %d\n", st->index,
5707  index_entry_pos, offset, dts, sample_size, distance, keyframe);
5708  distance++;
5709  if (av_sat_add64(dts, sample_duration) != dts + (uint64_t)sample_duration)
5710  return AVERROR_INVALIDDATA;
5711  if (!sample_size)
5712  return AVERROR_INVALIDDATA;
5713  dts += sample_duration;
5714  offset += sample_size;
5715  sc->data_size += sample_size;
5716 
5717  if (sample_duration <= INT64_MAX - sc->duration_for_fps &&
5718  1 <= INT_MAX - sc->nb_frames_for_fps
5719  ) {
5720  sc->duration_for_fps += sample_duration;
5721  sc->nb_frames_for_fps ++;
5722  }
5723  }
5724  if (frag_stream_info)
5725  frag_stream_info->next_trun_dts = dts + sc->time_offset;
5726  if (i < entries) {
5727  // EOF found before reading all entries. Fix the hole this would
5728  // leave in index_entries and ctts_data
5729  int gap = entries - i;
5730  memmove(sti->index_entries + index_entry_pos,
5731  sti->index_entries + index_entry_pos + gap,
5732  sizeof(*sti->index_entries) *
5733  (sti->nb_index_entries - (index_entry_pos + gap)));
5734  memmove(sc->ctts_data + index_entry_pos,
5735  sc->ctts_data + index_entry_pos + gap,
5736  sizeof(*sc->ctts_data) *
5737  (sc->ctts_count - (index_entry_pos + gap)));
5738 
5739  sti->nb_index_entries -= gap;
5740  sc->ctts_count -= gap;
5741  if (index_entry_pos < sc->current_sample) {
5742  sc->current_sample -= gap;
5743  }
5744  entries = i;
5745  }
5746 
5747  // The end of this new fragment may overlap in time with the start
5748  // of the next fragment in index_entries. Mark the samples in the next
5749  // fragment that overlap with AVINDEX_DISCARD_FRAME
5750  prev_dts = AV_NOPTS_VALUE;
5751  if (index_entry_pos > 0)
5752  prev_dts = sti->index_entries[index_entry_pos-1].timestamp;
5753  for (int i = index_entry_pos; i < sti->nb_index_entries; i++) {
5754  if (prev_dts < sti->index_entries[i].timestamp)
5755  break;
5757  }
5758 
5759  // If a hole was created to insert the new index_entries into,
5760  // the index_entry recorded for all subsequent moof must
5761  // be incremented by the number of entries inserted.
5762  fix_frag_index_entries(&c->frag_index, next_frag_index,
5763  frag->track_id, entries);
5764 
5765  if (pb->eof_reached) {
5766  av_log(c->fc, AV_LOG_WARNING, "reached eof, corrupted TRUN atom\n");
5767  return AVERROR_EOF;
5768  }
5769 
5770  frag->implicit_offset = offset;
5771 
5772  sc->track_end = dts + sc->time_offset;
5773  if (st->duration < sc->track_end)
5774  st->duration = sc->track_end;
5775 
5776  return 0;
5777 }
5778 
5780 {
5781  int64_t stream_size = avio_size(pb);
5782  int64_t offset = av_sat_add64(avio_tell(pb), atom.size), pts, timestamp;
5783  uint8_t version, is_complete;
5784  int64_t offadd;
5785  unsigned i, j, track_id, item_count;
5786  AVStream *st = NULL;
5787  AVStream *ref_st = NULL;
5788  MOVStreamContext *sc, *ref_sc = NULL;
5789  AVRational timescale;
5790 
5791  version = avio_r8(pb);
5792  if (version > 1) {
5793  avpriv_request_sample(c->fc, "sidx version %u", version);
5794  return 0;
5795  }
5796 
5797  avio_rb24(pb); // flags
5798 
5799  track_id = avio_rb32(pb); // Reference ID
5800  for (i = 0; i < c->fc->nb_streams; i++) {
5801  sc = c->fc->streams[i]->priv_data;
5802  if (sc->id == track_id) {
5803  st = c->fc->streams[i];
5804  break;
5805  }
5806  }
5807  if (!st) {
5808  av_log(c->fc, AV_LOG_WARNING, "could not find corresponding track id %d\n", track_id);
5809  return 0;
5810  }
5811 
5812  sc = st->priv_data;
5813 
5814  timescale = av_make_q(1, avio_rb32(pb));
5815 
5816  if (timescale.den <= 0) {
5817  av_log(c->fc, AV_LOG_ERROR, "Invalid sidx timescale 1/%d\n", timescale.den);
5818  return AVERROR_INVALIDDATA;
5819  }
5820 
5821  if (version == 0) {
5822  pts = avio_rb32(pb);
5823  offadd= avio_rb32(pb);
5824  } else {
5825  pts = avio_rb64(pb);
5826  offadd= avio_rb64(pb);
5827  }
5828  if (av_sat_add64(offset, offadd) != offset + (uint64_t)offadd)
5829  return AVERROR_INVALIDDATA;
5830 
5831  offset += (uint64_t)offadd;
5832 
5833  avio_rb16(pb); // reserved
5834 
5835  item_count = avio_rb16(pb);
5836  if (item_count == 0)
5837  return AVERROR_INVALIDDATA;
5838 
5839  for (i = 0; i < item_count; i++) {
5840  int index;
5841  MOVFragmentStreamInfo * frag_stream_info;
5842  uint32_t size = avio_rb32(pb);
5843  uint32_t duration = avio_rb32(pb);
5844  if (size & 0x80000000) {
5845  avpriv_request_sample(c->fc, "sidx reference_type 1");
5846  return AVERROR_PATCHWELCOME;
5847  }
5848  avio_rb32(pb); // sap_flags
5849  timestamp = av_rescale_q(pts, timescale, st->time_base);
5850 
5852  frag_stream_info = get_frag_stream_info(&c->frag_index, index, track_id);
5853  if (frag_stream_info)
5854  frag_stream_info->sidx_pts = timestamp;
5855 
5856  if (av_sat_add64(offset, size) != offset + (uint64_t)size ||
5857  av_sat_add64(pts, duration) != pts + (uint64_t)duration
5858  )
5859  return AVERROR_INVALIDDATA;
5860  offset += size;
5861  pts += duration;
5862  }
5863 
5864  st->duration = sc->track_end = pts;
5865 
5866  sc->has_sidx = 1;
5867 
5868  // See if the remaining bytes are just an mfra which we can ignore.
5869  is_complete = offset == stream_size;
5870  if (!is_complete && (pb->seekable & AVIO_SEEKABLE_NORMAL) && stream_size > 0 ) {
5871  int64_t ret;
5872  int64_t original_pos = avio_tell(pb);
5873  if (!c->have_read_mfra_size) {
5874  if ((ret = avio_seek(pb, stream_size - 4, SEEK_SET)) < 0)
5875  return ret;
5876  c->mfra_size = avio_rb32(pb);
5877  c->have_read_mfra_size = 1;
5878  if ((ret = avio_seek(pb, original_pos, SEEK_SET)) < 0)
5879  return ret;
5880  }
5881  if (offset == stream_size - c->mfra_size)
5882  is_complete = 1;
5883  }
5884 
5885  if (is_complete) {
5886  // Find first entry in fragment index that came from an sidx.
5887  // This will pretty much always be the first entry.
5888  for (i = 0; i < c->frag_index.nb_items; i++) {
5889  MOVFragmentIndexItem * item = &c->frag_index.item[i];
5890  for (j = 0; ref_st == NULL && j < item->nb_stream_info; j++) {
5891  MOVFragmentStreamInfo * si;
5892  si = &item->stream_info[j];
5893  if (si->sidx_pts != AV_NOPTS_VALUE) {
5894  ref_st = c->fc->streams[j];
5895  ref_sc = ref_st->priv_data;
5896  break;
5897  }
5898  }
5899  }
5900  if (ref_st) for (i = 0; i < c->fc->nb_streams; i++) {
5901  st = c->fc->streams[i];
5902  sc = st->priv_data;
5903  if (!sc->has_sidx) {
5904  st->duration = sc->track_end = av_rescale(ref_st->duration, sc->time_scale, ref_sc->time_scale);
5905  }
5906  }
5907 
5908  c->frag_index.complete = 1;
5909  }
5910 
5911  return 0;
5912 }
5913 
5914 /* this atom should be null (from specs), but some buggy files put the 'moov' atom inside it... */
5915 /* like the files created with Adobe Premiere 5.0, for samples see */
5916 /* http://graphics.tudelft.nl/~wouter/publications/soundtests/ */
5918 {
5919  int err;
5920 
5921  if (atom.size < 8)
5922  return 0; /* continue */
5923  if (avio_rb32(pb) != 0) { /* 0 sized mdat atom... use the 'wide' atom size */
5924  avio_skip(pb, atom.size - 4);
5925  return 0;
5926  }
5927  atom.type = avio_rl32(pb);
5928  atom.size -= 8;
5929  if (atom.type != MKTAG('m','d','a','t')) {
5930  avio_skip(pb, atom.size);
5931  return 0;
5932  }
5933  err = mov_read_mdat(c, pb, atom);
5934  return err;
5935 }
5936 
5938 {
5939 #if CONFIG_ZLIB
5940  FFIOContext ctx;
5941  uint8_t *cmov_data;
5942  uint8_t *moov_data; /* uncompressed data */
5943  long cmov_len, moov_len;
5944  int ret = -1;
5945 
5946  avio_rb32(pb); /* dcom atom */
5947  if (avio_rl32(pb) != MKTAG('d','c','o','m'))
5948  return AVERROR_INVALIDDATA;
5949  if (avio_rl32(pb) != MKTAG('z','l','i','b')) {
5950  av_log(c->fc, AV_LOG_ERROR, "unknown compression for cmov atom !\n");
5951  return AVERROR_INVALIDDATA;
5952  }
5953  avio_rb32(pb); /* cmvd atom */
5954  if (avio_rl32(pb) != MKTAG('c','m','v','d'))
5955  return AVERROR_INVALIDDATA;
5956  moov_len = avio_rb32(pb); /* uncompressed size */
5957  cmov_len = atom.size - 6 * 4;
5958 
5959  cmov_data = av_malloc(cmov_len);
5960  if (!cmov_data)
5961  return AVERROR(ENOMEM);
5962  moov_data = av_malloc(moov_len);
5963  if (!moov_data) {
5964  av_free(cmov_data);
5965  return AVERROR(ENOMEM);
5966  }
5967  ret = ffio_read_size(pb, cmov_data, cmov_len);
5968  if (ret < 0)
5969  goto free_and_return;
5970 
5972  if (uncompress (moov_data, (uLongf *) &moov_len, (const Bytef *)cmov_data, cmov_len) != Z_OK)
5973  goto free_and_return;
5974  ffio_init_read_context(&ctx, moov_data, moov_len);
5975  ctx.pub.seekable = AVIO_SEEKABLE_NORMAL;
5976  atom.type = MKTAG('m','o','o','v');
5977  atom.size = moov_len;
5978  ret = mov_read_default(c, &ctx.pub, atom);
5979 free_and_return:
5980  av_free(moov_data);
5981  av_free(cmov_data);
5982  return ret;
5983 #else
5984  av_log(c->fc, AV_LOG_ERROR, "this file requires zlib support compiled in\n");
5985  return AVERROR(ENOSYS);
5986 #endif
5987 }
5988 
5989 /* edit list atom */
5991 {
5992  MOVStreamContext *sc;
5993  int i, edit_count, version;
5994  int64_t elst_entry_size;
5995 
5996  if (c->fc->nb_streams < 1 || c->ignore_editlist)
5997  return 0;
5998  sc = c->fc->streams[c->fc->nb_streams-1]->priv_data;
5999 
6000  version = avio_r8(pb); /* version */
6001  avio_rb24(pb); /* flags */
6002  edit_count = avio_rb32(pb); /* entries */
6003  atom.size -= 8;
6004 
6005  elst_entry_size = version == 1 ? 20 : 12;
6006  if (atom.size != edit_count * elst_entry_size) {
6007  if (c->fc->strict_std_compliance >= FF_COMPLIANCE_STRICT) {
6008  av_log(c->fc, AV_LOG_ERROR, "Invalid edit list entry_count: %d for elst atom of size: %"PRId64" bytes.\n",
6009  edit_count, atom.size + 8);
6010  return AVERROR_INVALIDDATA;
6011  } else {
6012  edit_count = atom.size / elst_entry_size;
6013  if (edit_count * elst_entry_size != atom.size) {
6014  av_log(c->fc, AV_LOG_WARNING, "ELST atom of %"PRId64" bytes, bigger than %d entries.\n", atom.size, edit_count);
6015  }
6016  }
6017  }
6018 
6019  if (!edit_count)
6020  return 0;
6021  if (sc->elst_data)
6022  av_log(c->fc, AV_LOG_WARNING, "Duplicated ELST atom\n");
6023  av_free(sc->elst_data);
6024  sc->elst_count = 0;
6025  sc->elst_data = av_malloc_array(edit_count, sizeof(*sc->elst_data));
6026  if (!sc->elst_data)
6027  return AVERROR(ENOMEM);
6028 
6029  av_log(c->fc, AV_LOG_TRACE, "track[%u].edit_count = %i\n", c->fc->nb_streams - 1, edit_count);
6030  for (i = 0; i < edit_count && atom.size > 0 && !pb->eof_reached; i++) {
6031  MOVElst *e = &sc->elst_data[i];
6032 
6033  if (version == 1) {
6034  e->duration = avio_rb64(pb);
6035  e->time = avio_rb64(pb);
6036  atom.size -= 16;
6037  } else {
6038  e->duration = avio_rb32(pb); /* segment duration */
6039  e->time = (int32_t)avio_rb32(pb); /* media time */
6040  atom.size -= 8;
6041  }
6042  e->rate = avio_rb32(pb) / 65536.0;
6043  atom.size -= 4;
6044  av_log(c->fc, AV_LOG_TRACE, "duration=%"PRId64" time=%"PRId64" rate=%f\n",
6045  e->duration, e->time, e->rate);
6046 
6047  if (e->time < 0 && e->time != -1 &&
6048  c->fc->strict_std_compliance >= FF_COMPLIANCE_STRICT) {
6049  av_log(c->fc, AV_LOG_ERROR, "Track %d, edit %d: Invalid edit list media time=%"PRId64"\n",
6050  c->fc->nb_streams-1, i, e->time);
6051  return AVERROR_INVALIDDATA;
6052  }
6053  }
6054  sc->elst_count = i;
6055 
6056  return 0;
6057 }
6058 
6060 {
6061  MOVStreamContext *sc;
6062 
6063  if (c->fc->nb_streams < 1)
6064  return AVERROR_INVALIDDATA;
6065  sc = c->fc->streams[c->fc->nb_streams - 1]->priv_data;
6066  sc->timecode_track = avio_rb32(pb);
6067  return 0;
6068 }
6069 
6071 {
6072  AVStream *st;
6073  int version, color_range, color_primaries, color_trc, color_space;
6074 
6075  if (c->fc->nb_streams < 1)
6076  return 0;
6077  st = c->fc->streams[c->fc->nb_streams - 1];
6078 
6079  if (atom.size < 5) {
6080  av_log(c->fc, AV_LOG_ERROR, "Empty VP Codec Configuration box\n");
6081  return AVERROR_INVALIDDATA;
6082  }
6083 
6084  version = avio_r8(pb);
6085  if (version != 1) {
6086  av_log(c->fc, AV_LOG_WARNING, "Unsupported VP Codec Configuration box version %d\n", version);
6087  return 0;
6088  }
6089  avio_skip(pb, 3); /* flags */
6090 
6091  avio_skip(pb, 2); /* profile + level */
6092  color_range = avio_r8(pb); /* bitDepth, chromaSubsampling, videoFullRangeFlag */
6093  color_primaries = avio_r8(pb);
6094  color_trc = avio_r8(pb);
6095  color_space = avio_r8(pb);
6096  if (avio_rb16(pb)) /* codecIntializationDataSize */
6097  return AVERROR_INVALIDDATA;
6098 
6101  if (!av_color_transfer_name(color_trc))
6102  color_trc = AVCOL_TRC_UNSPECIFIED;
6103  if (!av_color_space_name(color_space))
6104  color_space = AVCOL_SPC_UNSPECIFIED;
6105 
6108  st->codecpar->color_trc = color_trc;
6109  st->codecpar->color_space = color_space;
6110 
6111  return 0;
6112 }
6113 
6115 {
6116  MOVStreamContext *sc;
6117  int i, version;
6118 
6119  if (c->fc->nb_streams < 1)
6120  return AVERROR_INVALIDDATA;
6121 
6122  sc = c->fc->streams[c->fc->nb_streams - 1]->priv_data;
6123 
6124  if (atom.size < 5) {
6125  av_log(c->fc, AV_LOG_ERROR, "Empty Mastering Display Metadata box\n");
6126  return AVERROR_INVALIDDATA;
6127  }
6128 
6129  version = avio_r8(pb);
6130  if (version) {
6131  av_log(c->fc, AV_LOG_WARNING, "Unsupported Mastering Display Metadata box version %d\n", version);
6132  return 0;
6133  }
6134  if (sc->mastering) {
6135  av_log(c->fc, AV_LOG_WARNING, "Ignoring duplicate Mastering Display Metadata\n");
6136  return 0;
6137  }
6138 
6139  avio_skip(pb, 3); /* flags */
6140 
6142  if (!sc->mastering)
6143  return AVERROR(ENOMEM);
6144 
6145  for (i = 0; i < 3; i++) {
6146  sc->mastering->display_primaries[i][0] = av_make_q(avio_rb16(pb), 1 << 16);
6147  sc->mastering->display_primaries[i][1] = av_make_q(avio_rb16(pb), 1 << 16);
6148  }
6149  sc->mastering->white_point[0] = av_make_q(avio_rb16(pb), 1 << 16);
6150  sc->mastering->white_point[1] = av_make_q(avio_rb16(pb), 1 << 16);
6151 
6152  sc->mastering->max_luminance = av_make_q(avio_rb32(pb), 1 << 8);
6153  sc->mastering->min_luminance = av_make_q(avio_rb32(pb), 1 << 14);
6154 
6155  sc->mastering->has_primaries = 1;
6156  sc->mastering->has_luminance = 1;
6157 
6158  return 0;
6159 }
6160 
6162 {
6163  MOVStreamContext *sc;
6164  const int mapping[3] = {1, 2, 0};
6165  const int chroma_den = 50000;
6166  const int luma_den = 10000;
6167  int i;
6168 
6169  if (c->fc->nb_streams < 1)
6170  return AVERROR_INVALIDDATA;
6171 
6172  sc = c->fc->streams[c->fc->nb_streams - 1]->priv_data;
6173 
6174  if (atom.size < 24) {
6175  av_log(c->fc, AV_LOG_ERROR, "Invalid Mastering Display Color Volume box\n");
6176  return AVERROR_INVALIDDATA;
6177  }
6178 
6179  if (sc->mastering) {
6180  av_log(c->fc, AV_LOG_WARNING, "Ignoring duplicate Mastering Display Color Volume\n");
6181  return 0;
6182  }
6183 
6185  if (!sc->mastering)
6186  return AVERROR(ENOMEM);
6187 
6188  for (i = 0; i < 3; i++) {
6189  const int j = mapping[i];
6190  sc->mastering->display_primaries[j][0] = av_make_q(avio_rb16(pb), chroma_den);
6191  sc->mastering->display_primaries[j][1] = av_make_q(avio_rb16(pb), chroma_den);
6192  }
6193  sc->mastering->white_point[0] = av_make_q(avio_rb16(pb), chroma_den);
6194  sc->mastering->white_point[1] = av_make_q(avio_rb16(pb), chroma_den);
6195 
6196  sc->mastering->max_luminance = av_make_q(avio_rb32(pb), luma_den);
6197  sc->mastering->min_luminance = av_make_q(avio_rb32(pb), luma_den);
6198 
6199  sc->mastering->has_luminance = 1;
6200  sc->mastering->has_primaries = 1;
6201 
6202  return 0;
6203 }
6204 
6206 {
6207  MOVStreamContext *sc;
6208  int version;
6209 
6210  if (c->fc->nb_streams < 1)
6211  return AVERROR_INVALIDDATA;
6212 
6213  sc = c->fc->streams[c->fc->nb_streams - 1]->priv_data;
6214 
6215  if (atom.size < 5) {
6216  av_log(c->fc, AV_LOG_ERROR, "Empty Content Light Level box\n");
6217  return AVERROR_INVALIDDATA;
6218  }
6219 
6220  version = avio_r8(pb);
6221  if (version) {
6222  av_log(c->fc, AV_LOG_WARNING, "Unsupported Content Light Level box version %d\n", version);
6223  return 0;
6224  }
6225  avio_skip(pb, 3); /* flags */
6226 
6227  if (sc->coll){
6228  av_log(c->fc, AV_LOG_WARNING, "Ignoring duplicate COLL\n");
6229  return 0;
6230  }
6231 
6233  if (!sc->coll)
6234  return AVERROR(ENOMEM);
6235 
6236  sc->coll->MaxCLL = avio_rb16(pb);
6237  sc->coll->MaxFALL = avio_rb16(pb);
6238 
6239  return 0;
6240 }
6241 
6243 {
6244  MOVStreamContext *sc;
6245 
6246  if (c->fc->nb_streams < 1)
6247  return AVERROR_INVALIDDATA;
6248 
6249  sc = c->fc->streams[c->fc->nb_streams - 1]->priv_data;
6250 
6251  if (atom.size < 4) {
6252  av_log(c->fc, AV_LOG_ERROR, "Empty Content Light Level Info box\n");
6253  return AVERROR_INVALIDDATA;
6254  }
6255 
6256  if (sc->coll){
6257  av_log(c->fc, AV_LOG_WARNING, "Ignoring duplicate CLLI/COLL\n");
6258  return 0;
6259  }
6260 
6262  if (!sc->coll)
6263  return AVERROR(ENOMEM);
6264 
6265  sc->coll->MaxCLL = avio_rb16(pb);
6266  sc->coll->MaxFALL = avio_rb16(pb);
6267 
6268  return 0;
6269 }
6270 
6272 {
6273  MOVStreamContext *sc;
6274  const int illuminance_den = 10000;
6275  const int ambient_den = 50000;
6276  if (c->fc->nb_streams < 1)
6277  return AVERROR_INVALIDDATA;
6278  sc = c->fc->streams[c->fc->nb_streams - 1]->priv_data;
6279  if (atom.size < 6) {
6280  av_log(c->fc, AV_LOG_ERROR, "Empty Ambient Viewing Environment Info box\n");
6281  return AVERROR_INVALIDDATA;
6282  }
6283  if (sc->ambient){
6284  av_log(c->fc, AV_LOG_WARNING, "Ignoring duplicate AMVE\n");
6285  return 0;
6286  }
6288  if (!sc->ambient)
6289  return AVERROR(ENOMEM);
6290  sc->ambient->ambient_illuminance = av_make_q(avio_rb32(pb), illuminance_den);
6291  sc->ambient->ambient_light_x = av_make_q(avio_rb16(pb), ambient_den);
6292  sc->ambient->ambient_light_y = av_make_q(avio_rb16(pb), ambient_den);
6293  return 0;
6294 }
6295 
6297 {
6298  AVStream *st;
6299  MOVStreamContext *sc;
6300  enum AVStereo3DType type;
6301  int mode;
6302 
6303  if (c->fc->nb_streams < 1)
6304  return 0;
6305 
6306  st = c->fc->streams[c->fc->nb_streams - 1];
6307  sc = st->priv_data;
6308 
6309  if (atom.size < 5) {
6310  av_log(c->fc, AV_LOG_ERROR, "Empty stereoscopic video box\n");
6311  return AVERROR_INVALIDDATA;
6312  }
6313 
6314  if (sc->stereo3d)
6315  return AVERROR_INVALIDDATA;
6316 
6317  avio_skip(pb, 4); /* version + flags */
6318 
6319  mode = avio_r8(pb);
6320  switch (mode) {
6321  case 0:
6322  type = AV_STEREO3D_2D;
6323  break;
6324  case 1:
6326  break;
6327  case 2:
6329  break;
6330  default:
6331  av_log(c->fc, AV_LOG_WARNING, "Unknown st3d mode value %d\n", mode);
6332  return 0;
6333  }
6334 
6335  sc->stereo3d = av_stereo3d_alloc();
6336  if (!sc->stereo3d)
6337  return AVERROR(ENOMEM);
6338 
6339  sc->stereo3d->type = type;
6340  return 0;
6341 }
6342 
6344 {
6345  AVStream *st;
6346  MOVStreamContext *sc;
6347  int size, version, layout;
6348  int32_t yaw, pitch, roll;
6349  uint32_t l = 0, t = 0, r = 0, b = 0;
6350  uint32_t tag, padding = 0;
6351  enum AVSphericalProjection projection;
6352 
6353  if (c->fc->nb_streams < 1)
6354  return 0;
6355 
6356  st = c->fc->streams[c->fc->nb_streams - 1];
6357  sc = st->priv_data;
6358 
6359  if (atom.size < 8) {
6360  av_log(c->fc, AV_LOG_ERROR, "Empty spherical video box\n");
6361  return AVERROR_INVALIDDATA;
6362  }
6363 
6364  size = avio_rb32(pb);
6365  if (size <= 12 || size > atom.size)
6366  return AVERROR_INVALIDDATA;
6367 
6368  tag = avio_rl32(pb);
6369  if (tag != MKTAG('s','v','h','d')) {
6370  av_log(c->fc, AV_LOG_ERROR, "Missing spherical video header\n");
6371  return 0;
6372  }
6373  version = avio_r8(pb);
6374  if (version != 0) {
6375  av_log(c->fc, AV_LOG_WARNING, "Unknown spherical version %d\n",
6376  version);
6377  return 0;
6378  }
6379  avio_skip(pb, 3); /* flags */
6380  avio_skip(pb, size - 12); /* metadata_source */
6381 
6382  size = avio_rb32(pb);
6383  if (size > atom.size)
6384  return AVERROR_INVALIDDATA;
6385 
6386  tag = avio_rl32(pb);
6387  if (tag != MKTAG('p','r','o','j')) {
6388  av_log(c->fc, AV_LOG_ERROR, "Missing projection box\n");
6389  return 0;
6390  }
6391 
6392  size = avio_rb32(pb);
6393  if (size > atom.size)
6394  return AVERROR_INVALIDDATA;
6395 
6396  tag = avio_rl32(pb);
6397  if (tag != MKTAG('p','r','h','d')) {
6398  av_log(c->fc, AV_LOG_ERROR, "Missing projection header box\n");
6399  return 0;
6400  }
6401  version = avio_r8(pb);
6402  if (version != 0) {
6403  av_log(c->fc, AV_LOG_WARNING, "Unknown spherical version %d\n",
6404  version);
6405  return 0;
6406  }
6407  avio_skip(pb, 3); /* flags */
6408 
6409  /* 16.16 fixed point */
6410  yaw = avio_rb32(pb);
6411  pitch = avio_rb32(pb);
6412  roll = avio_rb32(pb);
6413 
6414  size = avio_rb32(pb);
6415  if (size > atom.size)
6416  return AVERROR_INVALIDDATA;
6417 
6418  tag = avio_rl32(pb);
6419  version = avio_r8(pb);
6420  if (version != 0) {
6421  av_log(c->fc, AV_LOG_WARNING, "Unknown spherical version %d\n",
6422  version);
6423  return 0;
6424  }
6425  avio_skip(pb, 3); /* flags */
6426  switch (tag) {
6427  case MKTAG('c','b','m','p'):
6428  layout = avio_rb32(pb);
6429  if (layout) {
6430  av_log(c->fc, AV_LOG_WARNING,
6431  "Unsupported cubemap layout %d\n", layout);
6432  return 0;
6433  }
6434  projection = AV_SPHERICAL_CUBEMAP;
6435  padding = avio_rb32(pb);
6436  break;
6437  case MKTAG('e','q','u','i'):
6438  t = avio_rb32(pb);
6439  b = avio_rb32(pb);
6440  l = avio_rb32(pb);
6441  r = avio_rb32(pb);
6442 
6443  if (b >= UINT_MAX - t || r >= UINT_MAX - l) {
6444  av_log(c->fc, AV_LOG_ERROR,
6445  "Invalid bounding rectangle coordinates "
6446  "%"PRIu32",%"PRIu32",%"PRIu32",%"PRIu32"\n", l, t, r, b);
6447  return AVERROR_INVALIDDATA;
6448  }
6449 
6450  if (l || t || r || b)
6451  projection = AV_SPHERICAL_EQUIRECTANGULAR_TILE;
6452  else
6453  projection = AV_SPHERICAL_EQUIRECTANGULAR;
6454  break;
6455  default:
6456  av_log(c->fc, AV_LOG_ERROR, "Unknown projection type: %s\n", av_fourcc2str(tag));
6457  return 0;
6458  }
6459 
6461  if (!sc->spherical)
6462  return AVERROR(ENOMEM);
6463 
6464  sc->spherical->projection = projection;
6465 
6466  sc->spherical->yaw = yaw;
6467  sc->spherical->pitch = pitch;
6468  sc->spherical->roll = roll;
6469 
6470  sc->spherical->padding = padding;
6471 
6472  sc->spherical->bound_left = l;
6473  sc->spherical->bound_top = t;
6474  sc->spherical->bound_right = r;
6475  sc->spherical->bound_bottom = b;
6476 
6477  return 0;
6478 }
6479 
6481 {
6482  int ret = 0;
6483  uint8_t *buffer = av_malloc(len + 1);
6484  const char *val;
6485 
6486  if (!buffer)
6487  return AVERROR(ENOMEM);
6488  buffer[len] = '\0';
6489 
6490  ret = ffio_read_size(pb, buffer, len);
6491  if (ret < 0)
6492  goto out;
6493 
6494  /* Check for mandatory keys and values, try to support XML as best-effort */
6495  if (!sc->spherical &&
6496  av_stristr(buffer, "<GSpherical:StitchingSoftware>") &&
6497  (val = av_stristr(buffer, "<GSpherical:Spherical>")) &&
6498  av_stristr(val, "true") &&
6499  (val = av_stristr(buffer, "<GSpherical:Stitched>")) &&
6500  av_stristr(val, "true") &&
6501  (val = av_stristr(buffer, "<GSpherical:ProjectionType>")) &&
6502  av_stristr(val, "equirectangular")) {
6504  if (!sc->spherical)
6505  goto out;
6506 
6508 
6509  if (av_stristr(buffer, "<GSpherical:StereoMode>") && !sc->stereo3d) {
6510  enum AVStereo3DType mode;
6511 
6512  if (av_stristr(buffer, "left-right"))
6514  else if (av_stristr(buffer, "top-bottom"))
6516  else
6517  mode = AV_STEREO3D_2D;
6518 
6519  sc->stereo3d = av_stereo3d_alloc();
6520  if (!sc->stereo3d)
6521  goto out;
6522 
6523  sc->stereo3d->type = mode;
6524  }
6525 
6526  /* orientation */
6527  val = av_stristr(buffer, "<GSpherical:InitialViewHeadingDegrees>");
6528  if (val)
6529  sc->spherical->yaw = strtol(val, NULL, 10) * (1 << 16);
6530  val = av_stristr(buffer, "<GSpherical:InitialViewPitchDegrees>");
6531  if (val)
6532  sc->spherical->pitch = strtol(val, NULL, 10) * (1 << 16);
6533  val = av_stristr(buffer, "<GSpherical:InitialViewRollDegrees>");
6534  if (val)
6535  sc->spherical->roll = strtol(val, NULL, 10) * (1 << 16);
6536  }
6537 
6538 out:
6539  av_free(buffer);
6540  return ret;
6541 }
6542 
6544 {
6545  AVStream *st;
6546  MOVStreamContext *sc;
6547  int64_t ret;
6548  AVUUID uuid;
6549  static const AVUUID uuid_isml_manifest = {
6550  0xa5, 0xd4, 0x0b, 0x30, 0xe8, 0x14, 0x11, 0xdd,
6551  0xba, 0x2f, 0x08, 0x00, 0x20, 0x0c, 0x9a, 0x66
6552  };
6553  static const AVUUID uuid_xmp = {
6554  0xbe, 0x7a, 0xcf, 0xcb, 0x97, 0xa9, 0x42, 0xe8,
6555  0x9c, 0x71, 0x99, 0x94, 0x91, 0xe3, 0xaf, 0xac
6556  };
6557  static const AVUUID uuid_spherical = {
6558  0xff, 0xcc, 0x82, 0x63, 0xf8, 0x55, 0x4a, 0x93,
6559  0x88, 0x14, 0x58, 0x7a, 0x02, 0x52, 0x1f, 0xdd,
6560  };
6561 
6562  if (atom.size < AV_UUID_LEN || atom.size >= FFMIN(INT_MAX, SIZE_MAX))
6563  return AVERROR_INVALIDDATA;
6564 
6565  if (c->fc->nb_streams < 1)
6566  return 0;
6567  st = c->fc->streams[c->fc->nb_streams - 1];
6568  sc = st->priv_data;
6569 
6570  ret = ffio_read_size(pb, uuid, AV_UUID_LEN);
6571  if (ret < 0)
6572  return ret;
6573  if (av_uuid_equal(uuid, uuid_isml_manifest)) {
6574  uint8_t *buffer, *ptr;
6575  char *endptr;
6576  size_t len = atom.size - AV_UUID_LEN;
6577 
6578  if (len < 4) {
6579  return AVERROR_INVALIDDATA;
6580  }
6581  ret = avio_skip(pb, 4); // zeroes
6582  len -= 4;
6583 
6584  buffer = av_mallocz(len + 1);
6585  if (!buffer) {
6586  return AVERROR(ENOMEM);
6587  }
6588  ret = ffio_read_size(pb, buffer, len);
6589  if (ret < 0) {
6590  av_free(buffer);
6591  return ret;
6592  }
6593 
6594  ptr = buffer;
6595  while ((ptr = av_stristr(ptr, "systemBitrate=\""))) {
6596  ptr += sizeof("systemBitrate=\"") - 1;
6597  c->bitrates_count++;
6598  c->bitrates = av_realloc_f(c->bitrates, c->bitrates_count, sizeof(*c->bitrates));
6599  if (!c->bitrates) {
6600  c->bitrates_count = 0;
6601  av_free(buffer);
6602  return AVERROR(ENOMEM);
6603  }
6604  errno = 0;
6605  ret = strtol(ptr, &endptr, 10);
6606  if (ret < 0 || errno || *endptr != '"') {
6607  c->bitrates[c->bitrates_count - 1] = 0;
6608  } else {
6609  c->bitrates[c->bitrates_count - 1] = ret;
6610  }
6611  }
6612 
6613  av_free(buffer);
6614  } else if (av_uuid_equal(uuid, uuid_xmp)) {
6615  uint8_t *buffer;
6616  size_t len = atom.size - AV_UUID_LEN;
6617  if (c->export_xmp) {
6618  buffer = av_mallocz(len + 1);
6619  if (!buffer) {
6620  return AVERROR(ENOMEM);
6621  }
6622  ret = ffio_read_size(pb, buffer, len);
6623  if (ret < 0) {
6624  av_free(buffer);
6625  return ret;
6626  }
6627  buffer[len] = '\0';
6628  av_dict_set(&c->fc->metadata, "xmp",
6630  } else {
6631  // skip all uuid atom, which makes it fast for long uuid-xmp file
6632  ret = avio_skip(pb, len);
6633  if (ret < 0)
6634  return ret;
6635  }
6636  } else if (av_uuid_equal(uuid, uuid_spherical)) {
6637  size_t len = atom.size - AV_UUID_LEN;
6638  ret = mov_parse_uuid_spherical(sc, pb, len);
6639  if (ret < 0)
6640  return ret;
6641  if (!sc->spherical)
6642  av_log(c->fc, AV_LOG_WARNING, "Invalid spherical metadata found\n");
6643  }
6644 
6645  return 0;
6646 }
6647 
6649 {
6650  int ret;
6651  uint8_t content[16];
6652 
6653  if (atom.size < 8)
6654  return 0;
6655 
6656  ret = avio_read(pb, content, FFMIN(sizeof(content), atom.size));
6657  if (ret < 0)
6658  return ret;
6659 
6660  if ( !c->found_moov
6661  && !c->found_mdat
6662  && !memcmp(content, "Anevia\x1A\x1A", 8)
6663  && c->use_mfra_for == FF_MOV_FLAG_MFRA_AUTO) {
6664  c->use_mfra_for = FF_MOV_FLAG_MFRA_PTS;
6665  }
6666 
6667  return 0;
6668 }
6669 
6671 {
6672  uint32_t format = avio_rl32(pb);
6673  MOVStreamContext *sc;
6674  enum AVCodecID id;
6675  AVStream *st;
6676 
6677  if (c->fc->nb_streams < 1)
6678  return 0;
6679  st = c->fc->streams[c->fc->nb_streams - 1];
6680  sc = st->priv_data;
6681 
6682  switch (sc->format)
6683  {
6684  case MKTAG('e','n','c','v'): // encrypted video
6685  case MKTAG('e','n','c','a'): // encrypted audio
6686  id = mov_codec_id(st, format);
6687  if (st->codecpar->codec_id != AV_CODEC_ID_NONE &&
6688  st->codecpar->codec_id != id) {
6689  av_log(c->fc, AV_LOG_WARNING,
6690  "ignoring 'frma' atom of '%.4s', stream has codec id %d\n",
6691  (char*)&format, st->codecpar->codec_id);
6692  break;
6693  }
6694 
6695  st->codecpar->codec_id = id;
6696  sc->format = format;
6697  break;
6698 
6699  default:
6700  if (format != sc->format) {
6701  av_log(c->fc, AV_LOG_WARNING,
6702  "ignoring 'frma' atom of '%.4s', stream format is '%.4s'\n",
6703  (char*)&format, (char*)&sc->format);
6704  }
6705  break;
6706  }
6707 
6708  return 0;
6709 }
6710 
6711 /**
6712  * Gets the current encryption info and associated current stream context. If
6713  * we are parsing a track fragment, this will return the specific encryption
6714  * info for this fragment; otherwise this will return the global encryption
6715  * info for the current stream.
6716  */
6718 {
6719  MOVFragmentStreamInfo *frag_stream_info;
6720  AVStream *st;
6721  int i;
6722 
6723  frag_stream_info = get_current_frag_stream_info(&c->frag_index);
6724  if (frag_stream_info) {
6725  for (i = 0; i < c->fc->nb_streams; i++) {
6726  *sc = c->fc->streams[i]->priv_data;
6727  if ((*sc)->id == frag_stream_info->id) {
6728  st = c->fc->streams[i];
6729  break;
6730  }
6731  }
6732  if (i == c->fc->nb_streams)
6733  return 0;
6734  *sc = st->priv_data;
6735 
6736  if (!frag_stream_info->encryption_index) {
6737  // If this stream isn't encrypted, don't create the index.
6738  if (!(*sc)->cenc.default_encrypted_sample)
6739  return 0;
6740  frag_stream_info->encryption_index = av_mallocz(sizeof(*frag_stream_info->encryption_index));
6741  if (!frag_stream_info->encryption_index)
6742  return AVERROR(ENOMEM);
6743  }
6744  *encryption_index = frag_stream_info->encryption_index;
6745  return 1;
6746  } else {
6747  // No current track fragment, using stream level encryption info.
6748 
6749  if (c->fc->nb_streams < 1)
6750  return 0;
6751  st = c->fc->streams[c->fc->nb_streams - 1];
6752  *sc = st->priv_data;
6753 
6754  if (!(*sc)->cenc.encryption_index) {
6755  // If this stream isn't encrypted, don't create the index.
6756  if (!(*sc)->cenc.default_encrypted_sample)
6757  return 0;
6758  (*sc)->cenc.encryption_index = av_mallocz(sizeof(*frag_stream_info->encryption_index));
6759  if (!(*sc)->cenc.encryption_index)
6760  return AVERROR(ENOMEM);
6761  }
6762 
6763  *encryption_index = (*sc)->cenc.encryption_index;
6764  return 1;
6765  }
6766 }
6767 
6769 {
6770  int i, ret;
6771  unsigned int subsample_count;
6772  AVSubsampleEncryptionInfo *subsamples;
6773 
6774  if (!sc->cenc.default_encrypted_sample) {
6775  av_log(c->fc, AV_LOG_ERROR, "Missing schm or tenc\n");
6776  return AVERROR_INVALIDDATA;
6777  }
6778 
6779  if (sc->cenc.per_sample_iv_size || use_subsamples) {
6781  if (!*sample)
6782  return AVERROR(ENOMEM);
6783  } else
6784  *sample = NULL;
6785 
6786  if (sc->cenc.per_sample_iv_size != 0) {
6787  if ((ret = ffio_read_size(pb, (*sample)->iv, sc->cenc.per_sample_iv_size)) < 0) {
6788  av_log(c->fc, AV_LOG_ERROR, "failed to read the initialization vector\n");
6790  *sample = NULL;
6791  return ret;
6792  }
6793  }
6794 
6795  if (use_subsamples) {
6796  subsample_count = avio_rb16(pb);
6797  av_free((*sample)->subsamples);
6798  (*sample)->subsamples = av_calloc(subsample_count, sizeof(*subsamples));
6799  if (!(*sample)->subsamples) {
6801  *sample = NULL;
6802  return AVERROR(ENOMEM);
6803  }
6804 
6805  for (i = 0; i < subsample_count && !pb->eof_reached; i++) {
6806  (*sample)->subsamples[i].bytes_of_clear_data = avio_rb16(pb);
6807  (*sample)->subsamples[i].bytes_of_protected_data = avio_rb32(pb);
6808  }
6809 
6810  if (pb->eof_reached) {
6811  av_log(c->fc, AV_LOG_ERROR, "hit EOF while reading sub-sample encryption info\n");
6813  *sample = NULL;
6814  return AVERROR_INVALIDDATA;
6815  }
6816  (*sample)->subsample_count = subsample_count;
6817  }
6818 
6819  return 0;
6820 }
6821 
6823 {
6824  AVEncryptionInfo **encrypted_samples;
6825  MOVEncryptionIndex *encryption_index;
6826  MOVStreamContext *sc;
6827  int use_subsamples, ret;
6828  unsigned int sample_count, i, alloc_size = 0;
6829 
6830  ret = get_current_encryption_info(c, &encryption_index, &sc);
6831  if (ret != 1)
6832  return ret;
6833 
6834  if (encryption_index->nb_encrypted_samples) {
6835  // This can happen if we have both saio/saiz and senc atoms.
6836  av_log(c->fc, AV_LOG_DEBUG, "Ignoring duplicate encryption info in senc\n");
6837  return 0;
6838  }
6839 
6840  avio_r8(pb); /* version */
6841  use_subsamples = avio_rb24(pb) & 0x02; /* flags */
6842 
6843  sample_count = avio_rb32(pb);
6844  if (sample_count >= INT_MAX / sizeof(*encrypted_samples))
6845  return AVERROR(ENOMEM);
6846 
6847  for (i = 0; i < sample_count; i++) {
6848  unsigned int min_samples = FFMIN(FFMAX(i + 1, 1024 * 1024), sample_count);
6849  encrypted_samples = av_fast_realloc(encryption_index->encrypted_samples, &alloc_size,
6850  min_samples * sizeof(*encrypted_samples));
6851  if (encrypted_samples) {
6852  encryption_index->encrypted_samples = encrypted_samples;
6853 
6855  c, pb, sc, &encryption_index->encrypted_samples[i], use_subsamples);
6856  } else {
6857  ret = AVERROR(ENOMEM);
6858  }
6859  if (pb->eof_reached) {
6860  av_log(c->fc, AV_LOG_ERROR, "Hit EOF while reading senc\n");
6861  if (ret >= 0)
6862  av_encryption_info_free(encryption_index->encrypted_samples[i]);
6864  }
6865 
6866  if (ret < 0) {
6867  for (; i > 0; i--)
6868  av_encryption_info_free(encryption_index->encrypted_samples[i - 1]);
6869  av_freep(&encryption_index->encrypted_samples);
6870  return ret;
6871  }
6872  }
6873  encryption_index->nb_encrypted_samples = sample_count;
6874 
6875  return 0;
6876 }
6877 
6879 {
6880  AVEncryptionInfo **sample, **encrypted_samples;
6881  int64_t prev_pos;
6882  size_t sample_count, sample_info_size, i;
6883  int ret = 0;
6884  unsigned int alloc_size = 0;
6885 
6886  if (encryption_index->nb_encrypted_samples)
6887  return 0;
6888  sample_count = encryption_index->auxiliary_info_sample_count;
6889  if (encryption_index->auxiliary_offsets_count != 1) {
6890  av_log(c->fc, AV_LOG_ERROR, "Multiple auxiliary info chunks are not supported\n");
6891  return AVERROR_PATCHWELCOME;
6892  }
6893  if (sample_count >= INT_MAX / sizeof(*encrypted_samples))
6894  return AVERROR(ENOMEM);
6895 
6896  prev_pos = avio_tell(pb);
6897  if (!(pb->seekable & AVIO_SEEKABLE_NORMAL) ||
6898  avio_seek(pb, encryption_index->auxiliary_offsets[0], SEEK_SET) != encryption_index->auxiliary_offsets[0]) {
6899  av_log(c->fc, AV_LOG_INFO, "Failed to seek for auxiliary info, will only parse senc atoms for encryption info\n");
6900  goto finish;
6901  }
6902 
6903  for (i = 0; i < sample_count && !pb->eof_reached; i++) {
6904  unsigned int min_samples = FFMIN(FFMAX(i + 1, 1024 * 1024), sample_count);
6905  encrypted_samples = av_fast_realloc(encryption_index->encrypted_samples, &alloc_size,
6906  min_samples * sizeof(*encrypted_samples));
6907  if (!encrypted_samples) {
6908  ret = AVERROR(ENOMEM);
6909  goto finish;
6910  }
6911  encryption_index->encrypted_samples = encrypted_samples;
6912 
6913  sample = &encryption_index->encrypted_samples[i];
6914  sample_info_size = encryption_index->auxiliary_info_default_size
6915  ? encryption_index->auxiliary_info_default_size
6916  : encryption_index->auxiliary_info_sizes[i];
6917 
6918  ret = mov_read_sample_encryption_info(c, pb, sc, sample, sample_info_size > sc->cenc.per_sample_iv_size);
6919  if (ret < 0)
6920  goto finish;
6921  }
6922  if (pb->eof_reached) {
6923  av_log(c->fc, AV_LOG_ERROR, "Hit EOF while reading auxiliary info\n");
6925  } else {
6926  encryption_index->nb_encrypted_samples = sample_count;
6927  }
6928 
6929 finish:
6930  avio_seek(pb, prev_pos, SEEK_SET);
6931  if (ret < 0) {
6932  for (; i > 0; i--) {
6933  av_encryption_info_free(encryption_index->encrypted_samples[i - 1]);
6934  }
6935  av_freep(&encryption_index->encrypted_samples);
6936  }
6937  return ret;
6938 }
6939 
6941 {
6942  MOVEncryptionIndex *encryption_index;
6943  MOVStreamContext *sc;
6944  int ret;
6945  unsigned int sample_count, aux_info_type, aux_info_param;
6946 
6947  ret = get_current_encryption_info(c, &encryption_index, &sc);
6948  if (ret != 1)
6949  return ret;
6950 
6951  if (encryption_index->nb_encrypted_samples) {
6952  // This can happen if we have both saio/saiz and senc atoms.
6953  av_log(c->fc, AV_LOG_DEBUG, "Ignoring duplicate encryption info in saiz\n");
6954  return 0;
6955  }
6956 
6957  if (encryption_index->auxiliary_info_sample_count) {
6958  av_log(c->fc, AV_LOG_ERROR, "Duplicate saiz atom\n");
6959  return AVERROR_INVALIDDATA;
6960  }
6961 
6962  avio_r8(pb); /* version */
6963  if (avio_rb24(pb) & 0x01) { /* flags */
6964  aux_info_type = avio_rb32(pb);
6965  aux_info_param = avio_rb32(pb);
6966  if (sc->cenc.default_encrypted_sample) {
6967  if (aux_info_type != sc->cenc.default_encrypted_sample->scheme) {
6968  av_log(c->fc, AV_LOG_DEBUG, "Ignoring saiz box with non-zero aux_info_type\n");
6969  return 0;
6970  }
6971  if (aux_info_param != 0) {
6972  av_log(c->fc, AV_LOG_DEBUG, "Ignoring saiz box with non-zero aux_info_type_parameter\n");
6973  return 0;
6974  }
6975  } else {
6976  // Didn't see 'schm' or 'tenc', so this isn't encrypted.
6977  if ((aux_info_type == MKBETAG('c','e','n','c') ||
6978  aux_info_type == MKBETAG('c','e','n','s') ||
6979  aux_info_type == MKBETAG('c','b','c','1') ||
6980  aux_info_type == MKBETAG('c','b','c','s')) &&
6981  aux_info_param == 0) {
6982  av_log(c->fc, AV_LOG_ERROR, "Saw encrypted saiz without schm/tenc\n");
6983  return AVERROR_INVALIDDATA;
6984  } else {
6985  return 0;
6986  }
6987  }
6988  } else if (!sc->cenc.default_encrypted_sample) {
6989  // Didn't see 'schm' or 'tenc', so this isn't encrypted.
6990  return 0;
6991  }
6992 
6993  encryption_index->auxiliary_info_default_size = avio_r8(pb);
6994  sample_count = avio_rb32(pb);
6995 
6996  if (encryption_index->auxiliary_info_default_size == 0) {
6997  if (sample_count == 0)
6998  return AVERROR_INVALIDDATA;
6999 
7000  encryption_index->auxiliary_info_sizes = av_malloc(sample_count);
7001  if (!encryption_index->auxiliary_info_sizes)
7002  return AVERROR(ENOMEM);
7003 
7004  ret = avio_read(pb, encryption_index->auxiliary_info_sizes, sample_count);
7005  if (ret != sample_count) {
7006  av_freep(&encryption_index->auxiliary_info_sizes);
7007 
7008  if (ret >= 0)
7010  av_log(c->fc, AV_LOG_ERROR, "Failed to read the auxiliary info, %s\n",
7011  av_err2str(ret));
7012  return ret;
7013  }
7014  }
7015  encryption_index->auxiliary_info_sample_count = sample_count;
7016 
7017  if (encryption_index->auxiliary_offsets_count) {
7018  return mov_parse_auxiliary_info(c, sc, pb, encryption_index);
7019  }
7020 
7021  return 0;
7022 }
7023 
7025 {
7026  uint64_t *auxiliary_offsets;
7027  MOVEncryptionIndex *encryption_index;
7028  MOVStreamContext *sc;
7029  int i, ret;
7030  unsigned int version, entry_count, aux_info_type, aux_info_param;
7031  unsigned int alloc_size = 0;
7032 
7033  ret = get_current_encryption_info(c, &encryption_index, &sc);
7034  if (ret != 1)
7035  return ret;
7036 
7037  if (encryption_index->nb_encrypted_samples) {
7038  // This can happen if we have both saio/saiz and senc atoms.
7039  av_log(c->fc, AV_LOG_DEBUG, "Ignoring duplicate encryption info in saio\n");
7040  return 0;
7041  }
7042 
7043  if (encryption_index->auxiliary_offsets_count) {
7044  av_log(c->fc, AV_LOG_ERROR, "Duplicate saio atom\n");
7045  return AVERROR_INVALIDDATA;
7046  }
7047 
7048  version = avio_r8(pb); /* version */
7049  if (avio_rb24(pb) & 0x01) { /* flags */
7050  aux_info_type = avio_rb32(pb);
7051  aux_info_param = avio_rb32(pb);
7052  if (sc->cenc.default_encrypted_sample) {
7053  if (aux_info_type != sc->cenc.default_encrypted_sample->scheme) {
7054  av_log(c->fc, AV_LOG_DEBUG, "Ignoring saio box with non-zero aux_info_type\n");
7055  return 0;
7056  }
7057  if (aux_info_param != 0) {
7058  av_log(c->fc, AV_LOG_DEBUG, "Ignoring saio box with non-zero aux_info_type_parameter\n");
7059  return 0;
7060  }
7061  } else {
7062  // Didn't see 'schm' or 'tenc', so this isn't encrypted.
7063  if ((aux_info_type == MKBETAG('c','e','n','c') ||
7064  aux_info_type == MKBETAG('c','e','n','s') ||
7065  aux_info_type == MKBETAG('c','b','c','1') ||
7066  aux_info_type == MKBETAG('c','b','c','s')) &&
7067  aux_info_param == 0) {
7068  av_log(c->fc, AV_LOG_ERROR, "Saw encrypted saio without schm/tenc\n");
7069  return AVERROR_INVALIDDATA;
7070  } else {
7071  return 0;
7072  }
7073  }
7074  } else if (!sc->cenc.default_encrypted_sample) {
7075  // Didn't see 'schm' or 'tenc', so this isn't encrypted.
7076  return 0;
7077  }
7078 
7079  entry_count = avio_rb32(pb);
7080  if (entry_count >= INT_MAX / sizeof(*auxiliary_offsets))
7081  return AVERROR(ENOMEM);
7082 
7083  for (i = 0; i < entry_count && !pb->eof_reached; i++) {
7084  unsigned int min_offsets = FFMIN(FFMAX(i + 1, 1024), entry_count);
7085  auxiliary_offsets = av_fast_realloc(
7086  encryption_index->auxiliary_offsets, &alloc_size,
7087  min_offsets * sizeof(*auxiliary_offsets));
7088  if (!auxiliary_offsets) {
7089  av_freep(&encryption_index->auxiliary_offsets);
7090  return AVERROR(ENOMEM);
7091  }
7092  encryption_index->auxiliary_offsets = auxiliary_offsets;
7093 
7094  if (version == 0) {
7095  encryption_index->auxiliary_offsets[i] = avio_rb32(pb);
7096  } else {
7097  encryption_index->auxiliary_offsets[i] = avio_rb64(pb);
7098  }
7099  if (c->frag_index.current >= 0) {
7100  encryption_index->auxiliary_offsets[i] += c->fragment.base_data_offset;
7101  }
7102  }
7103 
7104  if (pb->eof_reached) {
7105  av_log(c->fc, AV_LOG_ERROR, "Hit EOF while reading saio\n");
7106  av_freep(&encryption_index->auxiliary_offsets);
7107  return AVERROR_INVALIDDATA;
7108  }
7109 
7110  encryption_index->auxiliary_offsets_count = entry_count;
7111 
7112  if (encryption_index->auxiliary_info_sample_count) {
7113  return mov_parse_auxiliary_info(c, sc, pb, encryption_index);
7114  }
7115 
7116  return 0;
7117 }
7118 
7120 {
7121  AVEncryptionInitInfo *info, *old_init_info;
7122  uint8_t **key_ids;
7123  AVStream *st;
7124  const AVPacketSideData *old_side_data;
7125  uint8_t *side_data, *extra_data;
7126  size_t side_data_size;
7127  int ret = 0;
7128  unsigned int version, kid_count, extra_data_size, alloc_size = 0;
7129 
7130  if (c->fc->nb_streams < 1)
7131  return 0;
7132  st = c->fc->streams[c->fc->nb_streams-1];
7133 
7134  version = avio_r8(pb); /* version */
7135  avio_rb24(pb); /* flags */
7136 
7137  info = av_encryption_init_info_alloc(/* system_id_size */ 16, /* num_key_ids */ 0,
7138  /* key_id_size */ 16, /* data_size */ 0);
7139  if (!info)
7140  return AVERROR(ENOMEM);
7141 
7142  if ((ret = ffio_read_size(pb, info->system_id, 16)) < 0) {
7143  av_log(c->fc, AV_LOG_ERROR, "Failed to read the system id\n");
7144  goto finish;
7145  }
7146 
7147  if (version > 0) {
7148  kid_count = avio_rb32(pb);
7149  if (kid_count >= INT_MAX / sizeof(*key_ids)) {
7150  ret = AVERROR(ENOMEM);
7151  goto finish;
7152  }
7153 
7154  for (unsigned int i = 0; i < kid_count && !pb->eof_reached; i++) {
7155  unsigned int min_kid_count = FFMIN(FFMAX(i + 1, 1024), kid_count);
7156  key_ids = av_fast_realloc(info->key_ids, &alloc_size,
7157  min_kid_count * sizeof(*key_ids));
7158  if (!key_ids) {
7159  ret = AVERROR(ENOMEM);
7160  goto finish;
7161  }
7162  info->key_ids = key_ids;
7163 
7164  info->key_ids[i] = av_mallocz(16);
7165  if (!info->key_ids[i]) {
7166  ret = AVERROR(ENOMEM);
7167  goto finish;
7168  }
7169  info->num_key_ids = i + 1;
7170 
7171  if ((ret = ffio_read_size(pb, info->key_ids[i], 16)) < 0) {
7172  av_log(c->fc, AV_LOG_ERROR, "Failed to read the key id\n");
7173  goto finish;
7174  }
7175  }
7176 
7177  if (pb->eof_reached) {
7178  av_log(c->fc, AV_LOG_ERROR, "Hit EOF while reading pssh\n");
7180  goto finish;
7181  }
7182  }
7183 
7184  extra_data_size = avio_rb32(pb);
7185  extra_data = av_malloc(extra_data_size);
7186  if (!extra_data) {
7187  ret = AVERROR(ENOMEM);
7188  goto finish;
7189  }
7190  ret = avio_read(pb, extra_data, extra_data_size);
7191  if (ret != extra_data_size) {
7192  av_free(extra_data);
7193 
7194  if (ret >= 0)
7196  goto finish;
7197  }
7198 
7199  av_freep(&info->data); // malloc(0) may still allocate something.
7200  info->data = extra_data;
7201  info->data_size = extra_data_size;
7202 
7203  // If there is existing initialization data, append to the list.
7206  if (old_side_data) {
7207  old_init_info = av_encryption_init_info_get_side_data(old_side_data->data, old_side_data->size);
7208  if (old_init_info) {
7209  // Append to the end of the list.
7210  for (AVEncryptionInitInfo *cur = old_init_info;; cur = cur->next) {
7211  if (!cur->next) {
7212  cur->next = info;
7213  break;
7214  }
7215  }
7216  info = old_init_info;
7217  } else {
7218  // Assume existing side-data will be valid, so the only error we could get is OOM.
7219  ret = AVERROR(ENOMEM);
7220  goto finish;
7221  }
7222  }
7223 
7224  side_data = av_encryption_init_info_add_side_data(info, &side_data_size);
7225  if (!side_data) {
7226  ret = AVERROR(ENOMEM);
7227  goto finish;
7228  }
7232  side_data, side_data_size, 0))
7233  av_free(side_data);
7234 
7235 finish:
7237  return ret;
7238 }
7239 
7241 {
7242  AVStream *st;
7243  MOVStreamContext *sc;
7244 
7245  if (c->fc->nb_streams < 1)
7246  return 0;
7247  st = c->fc->streams[c->fc->nb_streams-1];
7248  sc = st->priv_data;
7249 
7250  if (sc->pseudo_stream_id != 0) {
7251  av_log(c->fc, AV_LOG_ERROR, "schm boxes are only supported in first sample descriptor\n");
7252  return AVERROR_PATCHWELCOME;
7253  }
7254 
7255  if (atom.size < 8)
7256  return AVERROR_INVALIDDATA;
7257 
7258  avio_rb32(pb); /* version and flags */
7259 
7260  if (!sc->cenc.default_encrypted_sample) {
7262  if (!sc->cenc.default_encrypted_sample) {
7263  return AVERROR(ENOMEM);
7264  }
7265  }
7266 
7268  return 0;
7269 }
7270 
7272 {
7273  AVStream *st;
7274  MOVStreamContext *sc;
7275  unsigned int version, pattern, is_protected, iv_size;
7276 
7277  if (c->fc->nb_streams < 1)
7278  return 0;
7279  st = c->fc->streams[c->fc->nb_streams-1];
7280  sc = st->priv_data;
7281 
7282  if (sc->pseudo_stream_id != 0) {
7283  av_log(c->fc, AV_LOG_ERROR, "tenc atom are only supported in first sample descriptor\n");
7284  return AVERROR_PATCHWELCOME;
7285  }
7286 
7287  if (!sc->cenc.default_encrypted_sample) {
7289  if (!sc->cenc.default_encrypted_sample) {
7290  return AVERROR(ENOMEM);
7291  }
7292  }
7293 
7294  if (atom.size < 20)
7295  return AVERROR_INVALIDDATA;
7296 
7297  version = avio_r8(pb); /* version */
7298  avio_rb24(pb); /* flags */
7299 
7300  avio_r8(pb); /* reserved */
7301  pattern = avio_r8(pb);
7302 
7303  if (version > 0) {
7304  sc->cenc.default_encrypted_sample->crypt_byte_block = pattern >> 4;
7305  sc->cenc.default_encrypted_sample->skip_byte_block = pattern & 0xf;
7306  }
7307 
7308  is_protected = avio_r8(pb);
7309  if (is_protected && !sc->cenc.encryption_index) {
7310  // The whole stream should be by-default encrypted.
7312  if (!sc->cenc.encryption_index)
7313  return AVERROR(ENOMEM);
7314  }
7315  sc->cenc.per_sample_iv_size = avio_r8(pb);
7316  if (sc->cenc.per_sample_iv_size != 0 && sc->cenc.per_sample_iv_size != 8 &&
7317  sc->cenc.per_sample_iv_size != 16) {
7318  av_log(c->fc, AV_LOG_ERROR, "invalid per-sample IV size value\n");
7319  return AVERROR_INVALIDDATA;
7320  }
7321  if (avio_read(pb, sc->cenc.default_encrypted_sample->key_id, 16) != 16) {
7322  av_log(c->fc, AV_LOG_ERROR, "failed to read the default key ID\n");
7323  return AVERROR_INVALIDDATA;
7324  }
7325 
7326  if (is_protected && !sc->cenc.per_sample_iv_size) {
7327  iv_size = avio_r8(pb);
7328  if (iv_size != 8 && iv_size != 16) {
7329  av_log(c->fc, AV_LOG_ERROR, "invalid default_constant_IV_size in tenc atom\n");
7330  return AVERROR_INVALIDDATA;
7331  }
7332 
7333  if (avio_read(pb, sc->cenc.default_encrypted_sample->iv, iv_size) != iv_size) {
7334  av_log(c->fc, AV_LOG_ERROR, "failed to read the default IV\n");
7335  return AVERROR_INVALIDDATA;
7336  }
7337  }
7338 
7339  return 0;
7340 }
7341 
7343 {
7344  AVStream *st;
7345  int last, type, size, ret;
7346  uint8_t buf[4];
7347 
7348  if (c->fc->nb_streams < 1)
7349  return 0;
7350  st = c->fc->streams[c->fc->nb_streams-1];
7351 
7352  if ((uint64_t)atom.size > (1<<30) || atom.size < 42)
7353  return AVERROR_INVALIDDATA;
7354 
7355  /* Check FlacSpecificBox version. */
7356  if (avio_r8(pb) != 0)
7357  return AVERROR_INVALIDDATA;
7358 
7359  avio_rb24(pb); /* Flags */
7360 
7361  if (avio_read(pb, buf, sizeof(buf)) != sizeof(buf)) {
7362  av_log(c->fc, AV_LOG_ERROR, "failed to read FLAC metadata block header\n");
7363  return pb->error < 0 ? pb->error : AVERROR_INVALIDDATA;
7364  }
7365  flac_parse_block_header(buf, &last, &type, &size);
7366 
7368  av_log(c->fc, AV_LOG_ERROR, "STREAMINFO must be first FLACMetadataBlock\n");
7369  return AVERROR_INVALIDDATA;
7370  }
7371 
7372  ret = ff_get_extradata(c->fc, st->codecpar, pb, size);
7373  if (ret < 0)
7374  return ret;
7375 
7376  if (!last)
7377  av_log(c->fc, AV_LOG_WARNING, "non-STREAMINFO FLACMetadataBlock(s) ignored\n");
7378 
7379  return 0;
7380 }
7381 
7383 {
7384  int i, ret;
7385  int bytes_of_protected_data;
7386 
7387  if (!sc->cenc.aes_ctr) {
7388  /* initialize the cipher */
7389  sc->cenc.aes_ctr = av_aes_ctr_alloc();
7390  if (!sc->cenc.aes_ctr) {
7391  return AVERROR(ENOMEM);
7392  }
7393 
7394  ret = av_aes_ctr_init(sc->cenc.aes_ctr, c->decryption_key);
7395  if (ret < 0) {
7396  return ret;
7397  }
7398  }
7399 
7401 
7402  if (!sample->subsample_count) {
7403  /* decrypt the whole packet */
7405  return 0;
7406  }
7407 
7408  for (i = 0; i < sample->subsample_count; i++) {
7409  if (sample->subsamples[i].bytes_of_clear_data + sample->subsamples[i].bytes_of_protected_data > size) {
7410  av_log(c->fc, AV_LOG_ERROR, "subsample size exceeds the packet size left\n");
7411  return AVERROR_INVALIDDATA;
7412  }
7413 
7414  /* skip the clear bytes */
7415  input += sample->subsamples[i].bytes_of_clear_data;
7416  size -= sample->subsamples[i].bytes_of_clear_data;
7417 
7418  /* decrypt the encrypted bytes */
7419 
7420  bytes_of_protected_data = sample->subsamples[i].bytes_of_protected_data;
7421  av_aes_ctr_crypt(sc->cenc.aes_ctr, input, input, bytes_of_protected_data);
7422 
7423  input += bytes_of_protected_data;
7424  size -= bytes_of_protected_data;
7425  }
7426 
7427  if (size > 0) {
7428  av_log(c->fc, AV_LOG_ERROR, "leftover packet bytes after subsample processing\n");
7429  return AVERROR_INVALIDDATA;
7430  }
7431 
7432  return 0;
7433 }
7434 
7436 {
7437  int i, ret;
7438  int num_of_encrypted_blocks;
7439  uint8_t iv[16];
7440 
7441  if (!sc->cenc.aes_ctx) {
7442  /* initialize the cipher */
7443  sc->cenc.aes_ctx = av_aes_alloc();
7444  if (!sc->cenc.aes_ctx) {
7445  return AVERROR(ENOMEM);
7446  }
7447 
7448  ret = av_aes_init(sc->cenc.aes_ctx, c->decryption_key, 16 * 8, 1);
7449  if (ret < 0) {
7450  return ret;
7451  }
7452  }
7453 
7454  memcpy(iv, sample->iv, 16);
7455 
7456  /* whole-block full sample encryption */
7457  if (!sample->subsample_count) {
7458  /* decrypt the whole packet */
7459  av_aes_crypt(sc->cenc.aes_ctx, input, input, size/16, iv, 1);
7460  return 0;
7461  }
7462 
7463  for (i = 0; i < sample->subsample_count; i++) {
7464  if (sample->subsamples[i].bytes_of_clear_data + sample->subsamples[i].bytes_of_protected_data > size) {
7465  av_log(c->fc, AV_LOG_ERROR, "subsample size exceeds the packet size left\n");
7466  return AVERROR_INVALIDDATA;
7467  }
7468 
7469  if (sample->subsamples[i].bytes_of_protected_data % 16) {
7470  av_log(c->fc, AV_LOG_ERROR, "subsample BytesOfProtectedData is not a multiple of 16\n");
7471  return AVERROR_INVALIDDATA;
7472  }
7473 
7474  /* skip the clear bytes */
7475  input += sample->subsamples[i].bytes_of_clear_data;
7476  size -= sample->subsamples[i].bytes_of_clear_data;
7477 
7478  /* decrypt the encrypted bytes */
7479  num_of_encrypted_blocks = sample->subsamples[i].bytes_of_protected_data/16;
7480  if (num_of_encrypted_blocks > 0) {
7481  av_aes_crypt(sc->cenc.aes_ctx, input, input, num_of_encrypted_blocks, iv, 1);
7482  }
7483  input += sample->subsamples[i].bytes_of_protected_data;
7484  size -= sample->subsamples[i].bytes_of_protected_data;
7485  }
7486 
7487  if (size > 0) {
7488  av_log(c->fc, AV_LOG_ERROR, "leftover packet bytes after subsample processing\n");
7489  return AVERROR_INVALIDDATA;
7490  }
7491 
7492  return 0;
7493 }
7494 
7496 {
7497  int i, ret, rem_bytes;
7498  uint8_t *data;
7499 
7500  if (!sc->cenc.aes_ctr) {
7501  /* initialize the cipher */
7502  sc->cenc.aes_ctr = av_aes_ctr_alloc();
7503  if (!sc->cenc.aes_ctr) {
7504  return AVERROR(ENOMEM);
7505  }
7506 
7507  ret = av_aes_ctr_init(sc->cenc.aes_ctr, c->decryption_key);
7508  if (ret < 0) {
7509  return ret;
7510  }
7511  }
7512 
7514 
7515  /* whole-block full sample encryption */
7516  if (!sample->subsample_count) {
7517  /* decrypt the whole packet */
7519  return 0;
7520  } else if (!sample->crypt_byte_block && !sample->skip_byte_block) {
7521  av_log(c->fc, AV_LOG_ERROR, "pattern encryption is not present in 'cens' scheme\n");
7522  return AVERROR_INVALIDDATA;
7523  }
7524 
7525  for (i = 0; i < sample->subsample_count; i++) {
7526  if (sample->subsamples[i].bytes_of_clear_data + sample->subsamples[i].bytes_of_protected_data > size) {
7527  av_log(c->fc, AV_LOG_ERROR, "subsample size exceeds the packet size left\n");
7528  return AVERROR_INVALIDDATA;
7529  }
7530 
7531  /* skip the clear bytes */
7532  input += sample->subsamples[i].bytes_of_clear_data;
7533  size -= sample->subsamples[i].bytes_of_clear_data;
7534 
7535  /* decrypt the encrypted bytes */
7536  data = input;
7537  rem_bytes = sample->subsamples[i].bytes_of_protected_data;
7538  while (rem_bytes > 0) {
7539  if (rem_bytes < 16*sample->crypt_byte_block) {
7540  break;
7541  }
7542  av_aes_ctr_crypt(sc->cenc.aes_ctr, data, data, 16*sample->crypt_byte_block);
7543  data += 16*sample->crypt_byte_block;
7544  rem_bytes -= 16*sample->crypt_byte_block;
7545  data += FFMIN(16*sample->skip_byte_block, rem_bytes);
7546  rem_bytes -= FFMIN(16*sample->skip_byte_block, rem_bytes);
7547  }
7548  input += sample->subsamples[i].bytes_of_protected_data;
7549  size -= sample->subsamples[i].bytes_of_protected_data;
7550  }
7551 
7552  if (size > 0) {
7553  av_log(c->fc, AV_LOG_ERROR, "leftover packet bytes after subsample processing\n");
7554  return AVERROR_INVALIDDATA;
7555  }
7556 
7557  return 0;
7558 }
7559 
7561 {
7562  int i, ret, rem_bytes;
7563  uint8_t iv[16];
7564  uint8_t *data;
7565 
7566  if (!sc->cenc.aes_ctx) {
7567  /* initialize the cipher */
7568  sc->cenc.aes_ctx = av_aes_alloc();
7569  if (!sc->cenc.aes_ctx) {
7570  return AVERROR(ENOMEM);
7571  }
7572 
7573  ret = av_aes_init(sc->cenc.aes_ctx, c->decryption_key, 16 * 8, 1);
7574  if (ret < 0) {
7575  return ret;
7576  }
7577  }
7578 
7579  /* whole-block full sample encryption */
7580  if (!sample->subsample_count) {
7581  /* decrypt the whole packet */
7582  memcpy(iv, sample->iv, 16);
7583  av_aes_crypt(sc->cenc.aes_ctx, input, input, size/16, iv, 1);
7584  return 0;
7585  } else if (!sample->crypt_byte_block && !sample->skip_byte_block) {
7586  av_log(c->fc, AV_LOG_ERROR, "pattern encryption is not present in 'cbcs' scheme\n");
7587  return AVERROR_INVALIDDATA;
7588  }
7589 
7590  for (i = 0; i < sample->subsample_count; i++) {
7591  if (sample->subsamples[i].bytes_of_clear_data + sample->subsamples[i].bytes_of_protected_data > size) {
7592  av_log(c->fc, AV_LOG_ERROR, "subsample size exceeds the packet size left\n");
7593  return AVERROR_INVALIDDATA;
7594  }
7595 
7596  /* skip the clear bytes */
7597  input += sample->subsamples[i].bytes_of_clear_data;
7598  size -= sample->subsamples[i].bytes_of_clear_data;
7599 
7600  /* decrypt the encrypted bytes */
7601  memcpy(iv, sample->iv, 16);
7602  data = input;
7603  rem_bytes = sample->subsamples[i].bytes_of_protected_data;
7604  while (rem_bytes > 0) {
7605  if (rem_bytes < 16*sample->crypt_byte_block) {
7606  break;
7607  }
7608  av_aes_crypt(sc->cenc.aes_ctx, data, data, sample->crypt_byte_block, iv, 1);
7609  data += 16*sample->crypt_byte_block;
7610  rem_bytes -= 16*sample->crypt_byte_block;
7611  data += FFMIN(16*sample->skip_byte_block, rem_bytes);
7612  rem_bytes -= FFMIN(16*sample->skip_byte_block, rem_bytes);
7613  }
7614  input += sample->subsamples[i].bytes_of_protected_data;
7615  size -= sample->subsamples[i].bytes_of_protected_data;
7616  }
7617 
7618  if (size > 0) {
7619  av_log(c->fc, AV_LOG_ERROR, "leftover packet bytes after subsample processing\n");
7620  return AVERROR_INVALIDDATA;
7621  }
7622 
7623  return 0;
7624 }
7625 
7627 {
7628  if (sample->scheme == MKBETAG('c','e','n','c') && !sample->crypt_byte_block && !sample->skip_byte_block) {
7629  return cenc_scheme_decrypt(c, sc, sample, input, size);
7630  } else if (sample->scheme == MKBETAG('c','b','c','1') && !sample->crypt_byte_block && !sample->skip_byte_block) {
7631  return cbc1_scheme_decrypt(c, sc, sample, input, size);
7632  } else if (sample->scheme == MKBETAG('c','e','n','s')) {
7633  return cens_scheme_decrypt(c, sc, sample, input, size);
7634  } else if (sample->scheme == MKBETAG('c','b','c','s')) {
7635  return cbcs_scheme_decrypt(c, sc, sample, input, size);
7636  } else {
7637  av_log(c->fc, AV_LOG_ERROR, "invalid encryption scheme\n");
7638  return AVERROR_INVALIDDATA;
7639  }
7640 }
7641 
7643 {
7644  int current = frag_index->current;
7645 
7646  if (!frag_index->nb_items)
7647  return NULL;
7648 
7649  // Check frag_index->current is the right one for pkt. It can out of sync.
7650  if (current >= 0 && current < frag_index->nb_items) {
7651  if (frag_index->item[current].moof_offset < pkt->pos &&
7652  (current + 1 == frag_index->nb_items ||
7653  frag_index->item[current + 1].moof_offset > pkt->pos))
7654  return get_frag_stream_info(frag_index, current, id);
7655  }
7656 
7657 
7658  for (int i = 0; i < frag_index->nb_items; i++) {
7659  if (frag_index->item[i].moof_offset > pkt->pos)
7660  break;
7661  current = i;
7662  }
7663  frag_index->current = current;
7664  return get_frag_stream_info(frag_index, current, id);
7665 }
7666 
7667 static int cenc_filter(MOVContext *mov, AVStream* st, MOVStreamContext *sc, AVPacket *pkt, int current_index)
7668 {
7669  MOVFragmentStreamInfo *frag_stream_info;
7670  MOVEncryptionIndex *encryption_index;
7671  AVEncryptionInfo *encrypted_sample;
7672  int encrypted_index, ret;
7673 
7674  frag_stream_info = get_frag_stream_info_from_pkt(&mov->frag_index, pkt, sc->id);
7675  encrypted_index = current_index;
7676  encryption_index = NULL;
7677  if (frag_stream_info) {
7678  // Note this only supports encryption info in the first sample descriptor.
7679  if (frag_stream_info->stsd_id == 1) {
7680  if (frag_stream_info->encryption_index) {
7681  encrypted_index = current_index - frag_stream_info->index_base;
7682  encryption_index = frag_stream_info->encryption_index;
7683  } else {
7684  encryption_index = sc->cenc.encryption_index;
7685  }
7686  }
7687  } else {
7688  encryption_index = sc->cenc.encryption_index;
7689  }
7690 
7691  if (encryption_index) {
7692  if (encryption_index->auxiliary_info_sample_count &&
7693  !encryption_index->nb_encrypted_samples) {
7694  av_log(mov->fc, AV_LOG_ERROR, "saiz atom found without saio\n");
7695  return AVERROR_INVALIDDATA;
7696  }
7697  if (encryption_index->auxiliary_offsets_count &&
7698  !encryption_index->nb_encrypted_samples) {
7699  av_log(mov->fc, AV_LOG_ERROR, "saio atom found without saiz\n");
7700  return AVERROR_INVALIDDATA;
7701  }
7702 
7703  if (!encryption_index->nb_encrypted_samples) {
7704  // Full-sample encryption with default settings.
7705  encrypted_sample = sc->cenc.default_encrypted_sample;
7706  } else if (encrypted_index >= 0 && encrypted_index < encryption_index->nb_encrypted_samples) {
7707  // Per-sample setting override.
7708  encrypted_sample = encryption_index->encrypted_samples[encrypted_index];
7709  if (!encrypted_sample)
7710  encrypted_sample = sc->cenc.default_encrypted_sample;
7711  } else {
7712  av_log(mov->fc, AV_LOG_ERROR, "Incorrect number of samples in encryption info\n");
7713  return AVERROR_INVALIDDATA;
7714  }
7715 
7716  if (mov->decryption_key) {
7717  return cenc_decrypt(mov, sc, encrypted_sample, pkt->data, pkt->size);
7718  } else {
7719  size_t size;
7720  uint8_t *side_data = av_encryption_info_add_side_data(encrypted_sample, &size);
7721  if (!side_data)
7722  return AVERROR(ENOMEM);
7724  if (ret < 0)
7725  av_free(side_data);
7726  return ret;
7727  }
7728  }
7729 
7730  return 0;
7731 }
7732 
7734 {
7735  const int OPUS_SEEK_PREROLL_MS = 80;
7736  int ret;
7737  AVStream *st;
7738  size_t size;
7739  uint16_t pre_skip;
7740 
7741  if (c->fc->nb_streams < 1)
7742  return 0;
7743  st = c->fc->streams[c->fc->nb_streams-1];
7744 
7745  if ((uint64_t)atom.size > (1<<30) || atom.size < 11)
7746  return AVERROR_INVALIDDATA;
7747 
7748  /* Check OpusSpecificBox version. */
7749  if (avio_r8(pb) != 0) {
7750  av_log(c->fc, AV_LOG_ERROR, "unsupported OpusSpecificBox version\n");
7751  return AVERROR_INVALIDDATA;
7752  }
7753 
7754  /* OpusSpecificBox size plus magic for Ogg OpusHead header. */
7755  size = atom.size + 8;
7756 
7757  if ((ret = ff_alloc_extradata(st->codecpar, size)) < 0)
7758  return ret;
7759 
7760  AV_WL32(st->codecpar->extradata, MKTAG('O','p','u','s'));
7761  AV_WL32(st->codecpar->extradata + 4, MKTAG('H','e','a','d'));
7762  AV_WB8(st->codecpar->extradata + 8, 1); /* OpusHead version */
7763  avio_read(pb, st->codecpar->extradata + 9, size - 9);
7764 
7765  /* OpusSpecificBox is stored in big-endian, but OpusHead is
7766  little-endian; aside from the preceeding magic and version they're
7767  otherwise currently identical. Data after output gain at offset 16
7768  doesn't need to be bytewapped. */
7769  pre_skip = AV_RB16(st->codecpar->extradata + 10);
7770  AV_WL16(st->codecpar->extradata + 10, pre_skip);
7771  AV_WL32(st->codecpar->extradata + 12, AV_RB32(st->codecpar->extradata + 12));
7772  AV_WL16(st->codecpar->extradata + 16, AV_RB16(st->codecpar->extradata + 16));
7773 
7774  st->codecpar->initial_padding = pre_skip;
7776  (AVRational){1, 1000},
7777  (AVRational){1, 48000});
7778 
7779  return 0;
7780 }
7781 
7783 {
7784  AVStream *st;
7785  unsigned format_info;
7786  int channel_assignment, channel_assignment1, channel_assignment2;
7787  int ratebits;
7788  uint64_t chmask;
7789 
7790  if (c->fc->nb_streams < 1)
7791  return 0;
7792  st = c->fc->streams[c->fc->nb_streams-1];
7793 
7794  if (atom.size < 10)
7795  return AVERROR_INVALIDDATA;
7796 
7797  format_info = avio_rb32(pb);
7798 
7799  ratebits = (format_info >> 28) & 0xF;
7800  channel_assignment1 = (format_info >> 15) & 0x1F;
7801  channel_assignment2 = format_info & 0x1FFF;
7802  if (channel_assignment2)
7803  channel_assignment = channel_assignment2;
7804  else
7805  channel_assignment = channel_assignment1;
7806 
7807  st->codecpar->frame_size = 40 << (ratebits & 0x7);
7808  st->codecpar->sample_rate = mlp_samplerate(ratebits);
7809 
7811  chmask = truehd_layout(channel_assignment);
7813 
7814  return 0;
7815 }
7816 
7818 {
7819  AVStream *st;
7820  uint8_t buf[ISOM_DVCC_DVVC_SIZE];
7821  int ret;
7822  int64_t read_size = atom.size;
7823 
7824  if (c->fc->nb_streams < 1)
7825  return 0;
7826  st = c->fc->streams[c->fc->nb_streams-1];
7827 
7828  // At most 24 bytes
7829  read_size = FFMIN(read_size, ISOM_DVCC_DVVC_SIZE);
7830 
7831  if ((ret = ffio_read_size(pb, buf, read_size)) < 0)
7832  return ret;
7833 
7834  return ff_isom_parse_dvcc_dvvc(c->fc, st, buf, read_size);
7835 }
7836 
7838 {
7839  AVFormatContext *ctx = c->fc;
7840  AVStream *st = NULL;
7841  AVBPrint scheme_buf, value_buf;
7842  int64_t scheme_str_len = 0, value_str_len = 0;
7843  int version, flags, ret = AVERROR_BUG;
7844  int64_t size = atom.size;
7845 
7846  if (atom.size < 6)
7847  // 4 bytes for version + flags, 2x 1 byte for null
7848  return AVERROR_INVALIDDATA;
7849 
7850  if (c->fc->nb_streams < 1)
7851  return 0;
7852  st = c->fc->streams[c->fc->nb_streams-1];
7853 
7854  version = avio_r8(pb);
7855  flags = avio_rb24(pb);
7856  size -= 4;
7857 
7858  if (version != 0 || flags != 0) {
7860  "Unsupported 'kind' box with version %d, flags: %x",
7861  version, flags);
7862  return AVERROR_INVALIDDATA;
7863  }
7864 
7865  av_bprint_init(&scheme_buf, 0, AV_BPRINT_SIZE_UNLIMITED);
7866  av_bprint_init(&value_buf, 0, AV_BPRINT_SIZE_UNLIMITED);
7867 
7868  if ((scheme_str_len = ff_read_string_to_bprint_overwrite(pb, &scheme_buf,
7869  size)) < 0) {
7870  ret = scheme_str_len;
7871  goto cleanup;
7872  }
7873 
7874  if (scheme_str_len + 1 >= size) {
7875  // we need to have another string, even if nullptr.
7876  // we check with + 1 since we expect that if size was not hit,
7877  // an additional null was read.
7879  goto cleanup;
7880  }
7881 
7882  size -= scheme_str_len + 1;
7883 
7884  if ((value_str_len = ff_read_string_to_bprint_overwrite(pb, &value_buf,
7885  size)) < 0) {
7886  ret = value_str_len;
7887  goto cleanup;
7888  }
7889 
7890  if (value_str_len == size) {
7891  // in case of no trailing null, box is not valid.
7893  goto cleanup;
7894  }
7895 
7897  "%s stream %d KindBox(scheme: %s, value: %s)\n",
7899  st->index,
7900  scheme_buf.str, value_buf.str);
7901 
7902  for (int i = 0; ff_mov_track_kind_table[i].scheme_uri; i++) {
7904  if (!av_strstart(scheme_buf.str, map.scheme_uri, NULL))
7905  continue;
7906 
7907  for (int j = 0; map.value_maps[j].disposition; j++) {
7908  const struct MP4TrackKindValueMapping value_map = map.value_maps[j];
7909  if (!av_strstart(value_buf.str, value_map.value, NULL))
7910  continue;
7911 
7912  st->disposition |= value_map.disposition;
7913  }
7914  }
7915 
7916  ret = 0;
7917 
7918 cleanup:
7919 
7920  av_bprint_finalize(&scheme_buf, NULL);
7921  av_bprint_finalize(&value_buf, NULL);
7922 
7923  return ret;
7924 }
7925 
7927 {
7928  AVStream *st;
7929  AVChannelLayout ch_layout = { 0 };
7930  int ret, i, version, type;
7931  int ambisonic_order, channel_order, normalization, channel_count;
7932  int ambi_channels, non_diegetic_channels;
7933 
7934  if (c->fc->nb_streams < 1)
7935  return 0;
7936 
7937  st = c->fc->streams[c->fc->nb_streams - 1];
7938 
7939  if (atom.size < 16) {
7940  av_log(c->fc, AV_LOG_ERROR, "SA3D audio box too small\n");
7941  return AVERROR_INVALIDDATA;
7942  }
7943 
7944  version = avio_r8(pb);
7945  if (version) {
7946  av_log(c->fc, AV_LOG_WARNING, "Unsupported SA3D box version %d\n", version);
7947  return 0;
7948  }
7949 
7950  type = avio_r8(pb);
7951  if (type & 0x7f) {
7952  av_log(c->fc, AV_LOG_WARNING,
7953  "Unsupported ambisonic type %d\n", type & 0x7f);
7954  return 0;
7955  }
7956  non_diegetic_channels = (type >> 7) * 2; // head_locked_stereo
7957 
7958  ambisonic_order = avio_rb32(pb);
7959 
7960  channel_order = avio_r8(pb);
7961  if (channel_order) {
7962  av_log(c->fc, AV_LOG_WARNING,
7963  "Unsupported channel_order %d\n", channel_order);
7964  return 0;
7965  }
7966 
7967  normalization = avio_r8(pb);
7968  if (normalization) {
7969  av_log(c->fc, AV_LOG_WARNING,
7970  "Unsupported normalization %d\n", normalization);
7971  return 0;
7972  }
7973 
7974  channel_count = avio_rb32(pb);
7975  if (ambisonic_order < 0 || ambisonic_order > 31 ||
7976  channel_count != ((ambisonic_order + 1LL) * (ambisonic_order + 1LL) +
7977  non_diegetic_channels)) {
7978  av_log(c->fc, AV_LOG_ERROR,
7979  "Invalid number of channels (%d / %d)\n",
7980  channel_count, ambisonic_order);
7981  return 0;
7982  }
7983  ambi_channels = channel_count - non_diegetic_channels;
7984 
7985  ret = av_channel_layout_custom_init(&ch_layout, channel_count);
7986  if (ret < 0)
7987  return 0;
7988 
7989  for (i = 0; i < channel_count; i++) {
7990  unsigned channel = avio_rb32(pb);
7991 
7992  if (channel >= channel_count) {
7993  av_log(c->fc, AV_LOG_ERROR, "Invalid channel index (%d / %d)\n",
7995  av_channel_layout_uninit(&ch_layout);
7996  return 0;
7997  }
7998  if (channel >= ambi_channels)
7999  ch_layout.u.map[i].id = channel - ambi_channels;
8000  else
8001  ch_layout.u.map[i].id = AV_CHAN_AMBISONIC_BASE + channel;
8002  }
8003 
8005  if (ret < 0) {
8006  av_channel_layout_uninit(&ch_layout);
8007  return 0;
8008  }
8009 
8011  st->codecpar->ch_layout = ch_layout;
8012 
8013  return 0;
8014 }
8015 
8017 {
8018  AVStream *st;
8019  int version;
8020 
8021  if (c->fc->nb_streams < 1)
8022  return 0;
8023 
8024  st = c->fc->streams[c->fc->nb_streams - 1];
8025 
8026  if (atom.size < 5) {
8027  av_log(c->fc, AV_LOG_ERROR, "Empty SAND audio box\n");
8028  return AVERROR_INVALIDDATA;
8029  }
8030 
8031  version = avio_r8(pb);
8032  if (version) {
8033  av_log(c->fc, AV_LOG_WARNING, "Unsupported SAND box version %d\n", version);
8034  return 0;
8035  }
8036 
8038 
8039  return 0;
8040 }
8041 
8042 static int rb_size(AVIOContext *pb, uint64_t* value, int size)
8043 {
8044  if (size == 0)
8045  *value = 0;
8046  else if (size == 1)
8047  *value = avio_r8(pb);
8048  else if (size == 2)
8049  *value = avio_rb16(pb);
8050  else if (size == 4)
8051  *value = avio_rb32(pb);
8052  else if (size == 8)
8053  *value = avio_rb64(pb);
8054  else
8055  return -1;
8056  return size;
8057 }
8058 
8060 {
8061  avio_rb32(pb); // version & flags.
8062  c->primary_item_id = avio_rb16(pb);
8063  av_log(c->fc, AV_LOG_TRACE, "pitm: primary_item_id %d\n", c->primary_item_id);
8064  return atom.size;
8065 }
8066 
8068 {
8069  c->idat_offset = avio_tell(pb);
8070  return 0;
8071 }
8072 
8074 {
8075  HEIFItem *heif_item;
8076  int version, offset_size, length_size, base_offset_size, index_size;
8077  int item_count, extent_count;
8078  int64_t base_offset, extent_offset, extent_length;
8079  uint8_t value;
8080 
8081  if (c->found_iloc) {
8082  av_log(c->fc, AV_LOG_INFO, "Duplicate iloc box found\n");
8083  return 0;
8084  }
8085 
8086  version = avio_r8(pb);
8087  avio_rb24(pb); // flags.
8088 
8089  value = avio_r8(pb);
8090  offset_size = (value >> 4) & 0xF;
8091  length_size = value & 0xF;
8092  value = avio_r8(pb);
8093  base_offset_size = (value >> 4) & 0xF;
8094  index_size = !version ? 0 : (value & 0xF);
8095  if (index_size) {
8096  avpriv_report_missing_feature(c->fc, "iloc: index_size != 0");
8097  return AVERROR_PATCHWELCOME;
8098  }
8099  item_count = (version < 2) ? avio_rb16(pb) : avio_rb32(pb);
8100 
8101  heif_item = av_realloc_array(c->heif_item, FFMAX(item_count, c->nb_heif_item), sizeof(*c->heif_item));
8102  if (!heif_item)
8103  return AVERROR(ENOMEM);
8104  c->heif_item = heif_item;
8105  if (item_count > c->nb_heif_item)
8106  memset(c->heif_item + c->nb_heif_item, 0,
8107  sizeof(*c->heif_item) * (item_count - c->nb_heif_item));
8108  c->nb_heif_item = FFMAX(c->nb_heif_item, item_count);
8109 
8110  av_log(c->fc, AV_LOG_TRACE, "iloc: item_count %d\n", item_count);
8111  for (int i = 0; i < item_count; i++) {
8112  int item_id = (version < 2) ? avio_rb16(pb) : avio_rb32(pb);
8113  int offset_type = (version > 0) ? avio_rb16(pb) & 0xf : 0;
8114 
8115  if (avio_feof(pb))
8116  return AVERROR_INVALIDDATA;
8117  if (offset_type > 1) {
8118  avpriv_report_missing_feature(c->fc, "iloc offset type %d", offset_type);
8119  return AVERROR_PATCHWELCOME;
8120  }
8121  c->heif_item[i].item_id = item_id;
8122 
8123  avio_rb16(pb); // data_reference_index.
8124  if (rb_size(pb, &base_offset, base_offset_size) < 0)
8125  return AVERROR_INVALIDDATA;
8126  extent_count = avio_rb16(pb);
8127  if (extent_count > 1) {
8128  // For still AVIF images, we only support one extent item.
8129  avpriv_report_missing_feature(c->fc, "iloc: extent_count > 1");
8130  return AVERROR_PATCHWELCOME;
8131  }
8132  for (int j = 0; j < extent_count; j++) {
8133  if (rb_size(pb, &extent_offset, offset_size) < 0 ||
8134  rb_size(pb, &extent_length, length_size) < 0)
8135  return AVERROR_INVALIDDATA;
8136  if (offset_type == 1)
8137  c->heif_item[i].is_idat_relative = 1;
8138  c->heif_item[i].extent_length = extent_length;
8139  c->heif_item[i].extent_offset = base_offset + extent_offset;
8140  av_log(c->fc, AV_LOG_TRACE, "iloc: item_idx %d, offset_type %d, "
8141  "extent_offset %"PRId64", extent_length %"PRId64"\n",
8142  i, offset_type, c->heif_item[i].extent_offset, c->heif_item[i].extent_length);
8143  }
8144  }
8145 
8146  c->found_iloc = 1;
8147  return atom.size;
8148 }
8149 
8150 static int mov_read_infe(MOVContext *c, AVIOContext *pb, MOVAtom atom, int idx)
8151 {
8152  AVBPrint item_name;
8153  int64_t size = atom.size;
8154  uint32_t item_type;
8155  int item_id;
8156  int version, ret;
8157 
8158  version = avio_r8(pb);
8159  avio_rb24(pb); // flags.
8160  size -= 4;
8161 
8162  if (version < 2) {
8163  avpriv_report_missing_feature(c->fc, "infe version < 2");
8164  avio_skip(pb, size);
8165  return 1;
8166  }
8167 
8168  item_id = version > 2 ? avio_rb32(pb) : avio_rb16(pb);
8169  avio_rb16(pb); // item_protection_index
8170  item_type = avio_rl32(pb);
8171  size -= 8;
8172 
8175  if (ret < 0) {
8177  return ret;
8178  }
8179 
8180  av_log(c->fc, AV_LOG_TRACE, "infe: item_id %d, item_type %s, item_name %s\n",
8181  item_id, av_fourcc2str(item_type), item_name.str);
8182 
8183  size -= ret + 1;
8184  if (size > 0)
8185  avio_skip(pb, size);
8186 
8187  if (ret)
8188  av_bprint_finalize(&item_name, &c->heif_item[idx].name);
8189  c->heif_item[idx].item_id = item_id;
8190  c->heif_item[idx].type = item_type;
8191 
8192  switch (item_type) {
8193  case MKTAG('a','v','0','1'):
8194  case MKTAG('h','v','c','1'):
8195  ret = heif_add_stream(c, &c->heif_item[idx]);
8196  if (ret < 0)
8197  return ret;
8198  break;
8199  }
8200 
8201  return 0;
8202 }
8203 
8205 {
8206  HEIFItem *heif_item;
8207  int entry_count;
8208  int version, got_stream = 0, ret, i;
8209 
8210  if (c->found_iinf) {
8211  av_log(c->fc, AV_LOG_WARNING, "Duplicate iinf box found\n");
8212  return 0;
8213  }
8214 
8215  version = avio_r8(pb);
8216  avio_rb24(pb); // flags.
8217  entry_count = version ? avio_rb32(pb) : avio_rb16(pb);
8218 
8219  heif_item = av_realloc_array(c->heif_item, FFMAX(entry_count, c->nb_heif_item), sizeof(*c->heif_item));
8220  if (!heif_item)
8221  return AVERROR(ENOMEM);
8222  c->heif_item = heif_item;
8223  if (entry_count > c->nb_heif_item)
8224  memset(c->heif_item + c->nb_heif_item, 0,
8225  sizeof(*c->heif_item) * (entry_count - c->nb_heif_item));
8226  c->nb_heif_item = FFMAX(c->nb_heif_item, entry_count);
8227 
8228  for (i = 0; i < entry_count; i++) {
8229  MOVAtom infe;
8230 
8231  infe.size = avio_rb32(pb) - 8;
8232  infe.type = avio_rl32(pb);
8233  ret = mov_read_infe(c, pb, infe, i);
8234  if (ret < 0)
8235  goto fail;
8236  if (!ret)
8237  got_stream = 1;
8238  }
8239 
8240  c->found_iinf = got_stream;
8241  return 0;
8242 fail:
8243  for (; i >= 0; i--) {
8244  HEIFItem *item = &c->heif_item[i];
8245 
8246  av_freep(&item->name);
8247  if (!item->st)
8248  continue;
8249 
8250  mov_free_stream_context(c->fc, item->st);
8251  ff_remove_stream(c->fc, item->st);
8252  item->st = NULL;
8253  }
8254  return ret;
8255 }
8256 
8258 {
8259  HEIFItem *item = NULL;
8260  HEIFGrid *grid;
8261  int entries, i;
8262  int from_item_id = version ? avio_rb32(pb) : avio_rb16(pb);
8263 
8264  for (int i = 0; i < c->nb_heif_grid; i++) {
8265  if (c->heif_grid[i].item->item_id == from_item_id) {
8266  av_log(c->fc, AV_LOG_ERROR, "More than one 'dimg' box "
8267  "referencing the same Derived Image item\n");
8268  return AVERROR_INVALIDDATA;
8269  }
8270  }
8271  for (int i = 0; i < c->nb_heif_item; i++) {
8272  if (c->heif_item[i].item_id != from_item_id)
8273  continue;
8274  item = &c->heif_item[i];
8275 
8276  switch (item->type) {
8277  case MKTAG('g','r','i','d'):
8278  case MKTAG('i','o','v','l'):
8279  break;
8280  default:
8281  avpriv_report_missing_feature(c->fc, "Derived Image item of type %s",
8282  av_fourcc2str(item->type));
8283  return 0;
8284  }
8285  break;
8286  }
8287  if (!item) {
8288  av_log(c->fc, AV_LOG_ERROR, "Missing grid information\n");
8289  return AVERROR_INVALIDDATA;
8290  }
8291 
8292  grid = av_realloc_array(c->heif_grid, c->nb_heif_grid + 1U,
8293  sizeof(*c->heif_grid));
8294  if (!grid)
8295  return AVERROR(ENOMEM);
8296  c->heif_grid = grid;
8297  grid = &grid[c->nb_heif_grid++];
8298 
8299  entries = avio_rb16(pb);
8300  grid->tile_id_list = av_malloc_array(entries, sizeof(*grid->tile_id_list));
8301  grid->tile_item_list = av_calloc(entries, sizeof(*grid->tile_item_list));
8302  if (!grid->tile_id_list || !grid->tile_item_list)
8303  return AVERROR(ENOMEM);
8304  /* 'to' item ids */
8305  for (i = 0; i < entries; i++)
8306  grid->tile_id_list[i] = version ? avio_rb32(pb) : avio_rb16(pb);
8307  grid->nb_tiles = entries;
8308  grid->item = item;
8309 
8310  av_log(c->fc, AV_LOG_TRACE, "dimg: from_item_id %d, entries %d\n",
8311  from_item_id, entries);
8312 
8313  return 0;
8314 }
8315 
8317 {
8318  int entries;
8319  int to_item_id, from_item_id = version ? avio_rb32(pb) : avio_rb16(pb);
8320 
8321  entries = avio_rb16(pb);
8322  if (entries > 1) {
8323  avpriv_request_sample(c->fc, "thmb in iref referencing several items");
8324  return AVERROR_PATCHWELCOME;
8325  }
8326  /* 'to' item ids */
8327  to_item_id = version ? avio_rb32(pb) : avio_rb16(pb);
8328 
8329  if (to_item_id != c->primary_item_id)
8330  return 0;
8331 
8332  c->thmb_item_id = from_item_id;
8333 
8334  av_log(c->fc, AV_LOG_TRACE, "thmb: from_item_id %d, entries %d\n",
8335  from_item_id, entries);
8336 
8337  return 0;
8338 }
8339 
8341 {
8342  int version = avio_r8(pb);
8343  avio_rb24(pb); // flags
8344  atom.size -= 4;
8345 
8346  if (version > 1) {
8347  av_log(c->fc, AV_LOG_WARNING, "Unknown iref box version %d\n", version);
8348  return 0;
8349  }
8350 
8351  while (atom.size) {
8352  uint32_t type, size = avio_rb32(pb);
8353  int64_t next = avio_tell(pb);
8354 
8355  if (size < 14 || next < 0 || next > INT64_MAX - size)
8356  return AVERROR_INVALIDDATA;
8357 
8358  next += size - 4;
8359  type = avio_rl32(pb);
8360  switch (type) {
8361  case MKTAG('d','i','m','g'):
8363  break;
8364  case MKTAG('t','h','m','b'):
8366  break;
8367  default:
8368  av_log(c->fc, AV_LOG_DEBUG, "Unknown iref type %s size %"PRIu32"\n",
8369  av_fourcc2str(type), size);
8370  }
8371 
8372  atom.size -= size;
8373  avio_seek(pb, next, SEEK_SET);
8374  }
8375  return 0;
8376 }
8377 
8379 {
8380  uint32_t width, height;
8381 
8382  avio_r8(pb); /* version */
8383  avio_rb24(pb); /* flags */
8384  width = avio_rb32(pb);
8385  height = avio_rb32(pb);
8386 
8387  av_log(c->fc, AV_LOG_TRACE, "ispe: item_id %d, width %u, height %u\n",
8388  c->cur_item_id, width, height);
8389 
8390  for (int i = 0; i < c->nb_heif_item; i++) {
8391  if (c->heif_item[i].item_id == c->cur_item_id) {
8392  c->heif_item[i].width = width;
8393  c->heif_item[i].height = height;
8394  break;
8395  }
8396  }
8397 
8398  return 0;
8399 }
8400 
8402 {
8403  typedef struct MOVAtoms {
8404  FFIOContext b;
8405  uint32_t type;
8406  int64_t size;
8407  uint8_t *data;
8408  } MOVAtoms;
8409  MOVAtoms *atoms = NULL;
8410  MOVAtom a;
8411  unsigned count;
8412  int nb_atoms = 0;
8413  int version, flags;
8414  int ret;
8415 
8416  a.size = avio_rb32(pb);
8417  a.type = avio_rl32(pb);
8418 
8419  if (a.size < 8 || a.type != MKTAG('i','p','c','o'))
8420  return AVERROR_INVALIDDATA;
8421 
8422  a.size -= 8;
8423  while (a.size >= 8) {
8424  MOVAtoms *ref = av_dynarray2_add((void**)&atoms, &nb_atoms, sizeof(MOVAtoms), NULL);
8425  if (!ref) {
8426  ret = AVERROR(ENOMEM);
8427  goto fail;
8428  }
8429  ref->data = NULL;
8430  ref->size = avio_rb32(pb);
8431  ref->type = avio_rl32(pb);
8432  if (ref->size > a.size || ref->size < 8)
8433  break;
8434  ref->data = av_malloc(ref->size);
8435  if (!ref->data) {
8437  goto fail;
8438  }
8439  av_log(c->fc, AV_LOG_TRACE, "ipco: index %d, box type %s\n", nb_atoms, av_fourcc2str(ref->type));
8440  avio_seek(pb, -8, SEEK_CUR);
8441  if (avio_read(pb, ref->data, ref->size) != ref->size) {
8443  goto fail;
8444  }
8445  ffio_init_read_context(&ref->b, ref->data, ref->size);
8446  a.size -= ref->size;
8447  }
8448 
8449  if (a.size) {
8451  goto fail;
8452  }
8453 
8454  a.size = avio_rb32(pb);
8455  a.type = avio_rl32(pb);
8456 
8457  if (a.size < 8 || a.type != MKTAG('i','p','m','a')) {
8459  goto fail;
8460  }
8461 
8462  version = avio_r8(pb);
8463  flags = avio_rb24(pb);
8464  count = avio_rb32(pb);
8465 
8466  for (int i = 0; i < count; i++) {
8467  int item_id = version ? avio_rb32(pb) : avio_rb16(pb);
8468  int assoc_count = avio_r8(pb);
8469 
8470  for (int j = 0; j < assoc_count; j++) {
8471  MOVAtoms *ref;
8472  int index = avio_r8(pb) & 0x7f;
8473  if (flags & 1) {
8474  index <<= 8;
8475  index |= avio_r8(pb);
8476  }
8477  if (index > nb_atoms || index <= 0) {
8479  goto fail;
8480  }
8481  ref = &atoms[--index];
8482 
8483  av_log(c->fc, AV_LOG_TRACE, "ipma: property_index %d, item_id %d, item_type %s\n",
8484  index + 1, item_id, av_fourcc2str(ref->type));
8485 
8486  c->cur_item_id = item_id;
8487 
8488  ret = mov_read_default(c, &ref->b.pub,
8489  (MOVAtom) { .size = ref->size,
8490  .type = MKTAG('i','p','c','o') });
8491  if (ret < 0)
8492  goto fail;
8493  ffio_init_read_context(&ref->b, ref->data, ref->size);
8494  }
8495  }
8496 
8497  ret = 0;
8498 fail:
8499  c->cur_item_id = -1;
8500  for (int i = 0; i < nb_atoms; i++)
8501  av_free(atoms[i].data);
8502  av_free(atoms);
8503 
8504  return ret;
8505 }
8506 
8508 { MKTAG('A','C','L','R'), mov_read_aclr },
8509 { MKTAG('A','P','R','G'), mov_read_avid },
8510 { MKTAG('A','A','L','P'), mov_read_avid },
8511 { MKTAG('A','R','E','S'), mov_read_ares },
8512 { MKTAG('a','v','s','s'), mov_read_avss },
8513 { MKTAG('a','v','1','C'), mov_read_glbl },
8514 { MKTAG('c','h','p','l'), mov_read_chpl },
8515 { MKTAG('c','o','6','4'), mov_read_stco },
8516 { MKTAG('c','o','l','r'), mov_read_colr },
8517 { MKTAG('c','t','t','s'), mov_read_ctts }, /* composition time to sample */
8518 { MKTAG('d','i','n','f'), mov_read_default },
8519 { MKTAG('D','p','x','E'), mov_read_dpxe },
8520 { MKTAG('d','r','e','f'), mov_read_dref },
8521 { MKTAG('e','d','t','s'), mov_read_default },
8522 { MKTAG('e','l','s','t'), mov_read_elst },
8523 { MKTAG('e','n','d','a'), mov_read_enda },
8524 { MKTAG('f','i','e','l'), mov_read_fiel },
8525 { MKTAG('a','d','r','m'), mov_read_adrm },
8526 { MKTAG('f','t','y','p'), mov_read_ftyp },
8527 { MKTAG('g','l','b','l'), mov_read_glbl },
8528 { MKTAG('h','d','l','r'), mov_read_hdlr },
8529 { MKTAG('i','l','s','t'), mov_read_ilst },
8530 { MKTAG('j','p','2','h'), mov_read_jp2h },
8531 { MKTAG('m','d','a','t'), mov_read_mdat },
8532 { MKTAG('m','d','h','d'), mov_read_mdhd },
8533 { MKTAG('m','d','i','a'), mov_read_default },
8534 { MKTAG('m','e','t','a'), mov_read_meta },
8535 { MKTAG('m','i','n','f'), mov_read_default },
8536 { MKTAG('m','o','o','f'), mov_read_moof },
8537 { MKTAG('m','o','o','v'), mov_read_moov },
8538 { MKTAG('m','v','e','x'), mov_read_default },
8539 { MKTAG('m','v','h','d'), mov_read_mvhd },
8540 { MKTAG('S','M','I',' '), mov_read_svq3 },
8541 { MKTAG('a','l','a','c'), mov_read_alac }, /* alac specific atom */
8542 { MKTAG('a','v','c','C'), mov_read_glbl },
8543 { MKTAG('p','a','s','p'), mov_read_pasp },
8544 { MKTAG('s','i','d','x'), mov_read_sidx },
8545 { MKTAG('s','t','b','l'), mov_read_default },
8546 { MKTAG('s','t','c','o'), mov_read_stco },
8547 { MKTAG('s','t','p','s'), mov_read_stps },
8548 { MKTAG('s','t','r','f'), mov_read_strf },
8549 { MKTAG('s','t','s','c'), mov_read_stsc },
8550 { MKTAG('s','t','s','d'), mov_read_stsd }, /* sample description */
8551 { MKTAG('s','t','s','s'), mov_read_stss }, /* sync sample */
8552 { MKTAG('s','t','s','z'), mov_read_stsz }, /* sample size */
8553 { MKTAG('s','t','t','s'), mov_read_stts },
8554 { MKTAG('s','t','z','2'), mov_read_stsz }, /* compact sample size */
8555 { MKTAG('s','d','t','p'), mov_read_sdtp }, /* independent and disposable samples */
8556 { MKTAG('t','k','h','d'), mov_read_tkhd }, /* track header */
8557 { MKTAG('t','f','d','t'), mov_read_tfdt },
8558 { MKTAG('t','f','h','d'), mov_read_tfhd }, /* track fragment header */
8559 { MKTAG('t','r','a','k'), mov_read_trak },
8560 { MKTAG('t','r','a','f'), mov_read_default },
8561 { MKTAG('t','r','e','f'), mov_read_default },
8562 { MKTAG('t','m','c','d'), mov_read_tmcd },
8563 { MKTAG('c','h','a','p'), mov_read_chap },
8564 { MKTAG('t','r','e','x'), mov_read_trex },
8565 { MKTAG('t','r','u','n'), mov_read_trun },
8566 { MKTAG('u','d','t','a'), mov_read_default },
8567 { MKTAG('w','a','v','e'), mov_read_wave },
8568 { MKTAG('e','s','d','s'), mov_read_esds },
8569 { MKTAG('d','a','c','3'), mov_read_dac3 }, /* AC-3 info */
8570 { MKTAG('d','e','c','3'), mov_read_dec3 }, /* EAC-3 info */
8571 { MKTAG('d','d','t','s'), mov_read_ddts }, /* DTS audio descriptor */
8572 { MKTAG('w','i','d','e'), mov_read_wide }, /* place holder */
8573 { MKTAG('w','f','e','x'), mov_read_wfex },
8574 { MKTAG('c','m','o','v'), mov_read_cmov },
8575 { MKTAG('c','h','a','n'), mov_read_chan }, /* channel layout from quicktime */
8576 { MKTAG('c','h','n','l'), mov_read_chnl }, /* channel layout from ISO-14496-12 */
8577 { MKTAG('d','v','c','1'), mov_read_dvc1 },
8578 { MKTAG('s','g','p','d'), mov_read_sgpd },
8579 { MKTAG('s','b','g','p'), mov_read_sbgp },
8580 { MKTAG('h','v','c','C'), mov_read_glbl },
8581 { MKTAG('v','v','c','C'), mov_read_glbl },
8582 { MKTAG('u','u','i','d'), mov_read_uuid },
8583 { MKTAG('C','i','n', 0x8e), mov_read_targa_y216 },
8584 { MKTAG('f','r','e','e'), mov_read_free },
8585 { MKTAG('-','-','-','-'), mov_read_custom },
8586 { MKTAG('s','i','n','f'), mov_read_default },
8587 { MKTAG('f','r','m','a'), mov_read_frma },
8588 { MKTAG('s','e','n','c'), mov_read_senc },
8589 { MKTAG('s','a','i','z'), mov_read_saiz },
8590 { MKTAG('s','a','i','o'), mov_read_saio },
8591 { MKTAG('p','s','s','h'), mov_read_pssh },
8592 { MKTAG('s','c','h','m'), mov_read_schm },
8593 { MKTAG('s','c','h','i'), mov_read_default },
8594 { MKTAG('t','e','n','c'), mov_read_tenc },
8595 { MKTAG('d','f','L','a'), mov_read_dfla },
8596 { MKTAG('s','t','3','d'), mov_read_st3d }, /* stereoscopic 3D video box */
8597 { MKTAG('s','v','3','d'), mov_read_sv3d }, /* spherical video box */
8598 { MKTAG('d','O','p','s'), mov_read_dops },
8599 { MKTAG('d','m','l','p'), mov_read_dmlp },
8600 { MKTAG('S','m','D','m'), mov_read_smdm },
8601 { MKTAG('C','o','L','L'), mov_read_coll },
8602 { MKTAG('v','p','c','C'), mov_read_vpcc },
8603 { MKTAG('m','d','c','v'), mov_read_mdcv },
8604 { MKTAG('c','l','l','i'), mov_read_clli },
8605 { MKTAG('d','v','c','C'), mov_read_dvcc_dvvc },
8606 { MKTAG('d','v','v','C'), mov_read_dvcc_dvvc },
8607 { MKTAG('d','v','w','C'), mov_read_dvcc_dvvc },
8608 { MKTAG('k','i','n','d'), mov_read_kind },
8609 { MKTAG('S','A','3','D'), mov_read_SA3D }, /* ambisonic audio box */
8610 { MKTAG('S','A','N','D'), mov_read_SAND }, /* non diegetic audio box */
8611 { MKTAG('i','l','o','c'), mov_read_iloc },
8612 { MKTAG('p','c','m','C'), mov_read_pcmc }, /* PCM configuration box */
8613 { MKTAG('p','i','t','m'), mov_read_pitm },
8614 { MKTAG('e','v','c','C'), mov_read_glbl },
8615 { MKTAG('i','d','a','t'), mov_read_idat },
8616 { MKTAG('i','r','e','f'), mov_read_iref },
8617 { MKTAG('i','s','p','e'), mov_read_ispe },
8618 { MKTAG('i','p','r','p'), mov_read_iprp },
8619 { MKTAG('i','i','n','f'), mov_read_iinf },
8620 { MKTAG('a','m','v','e'), mov_read_amve }, /* ambient viewing environment box */
8621 #if CONFIG_IAMFDEC
8622 { MKTAG('i','a','c','b'), mov_read_iacb },
8623 #endif
8624 { 0, NULL }
8625 };
8626 
8628 {
8629  int64_t total_size = 0;
8630  MOVAtom a;
8631  int i;
8632 
8633  if (c->atom_depth > 10) {
8634  av_log(c->fc, AV_LOG_ERROR, "Atoms too deeply nested\n");
8635  return AVERROR_INVALIDDATA;
8636  }
8637  c->atom_depth ++;
8638 
8639  if (atom.size < 0)
8640  atom.size = INT64_MAX;
8641  while (total_size <= atom.size - 8) {
8643  a.size = avio_rb32(pb);
8644  a.type = avio_rl32(pb);
8645  if (avio_feof(pb))
8646  break;
8647  if (((a.type == MKTAG('f','r','e','e') && c->moov_retry) ||
8648  a.type == MKTAG('h','o','o','v')) &&
8649  a.size >= 8 &&
8650  c->fc->strict_std_compliance < FF_COMPLIANCE_STRICT) {
8651  uint32_t type;
8652  avio_skip(pb, 4);
8653  type = avio_rl32(pb);
8654  if (avio_feof(pb))
8655  break;
8656  avio_seek(pb, -8, SEEK_CUR);
8657  if (type == MKTAG('m','v','h','d') ||
8658  type == MKTAG('c','m','o','v')) {
8659  av_log(c->fc, AV_LOG_ERROR, "Detected moov in a free or hoov atom.\n");
8660  a.type = MKTAG('m','o','o','v');
8661  }
8662  }
8663  if (atom.type != MKTAG('r','o','o','t') &&
8664  atom.type != MKTAG('m','o','o','v')) {
8665  if (a.type == MKTAG('t','r','a','k') ||
8666  a.type == MKTAG('m','d','a','t')) {
8667  av_log(c->fc, AV_LOG_ERROR, "Broken file, trak/mdat not at top-level\n");
8668  avio_skip(pb, -8);
8669  c->atom_depth --;
8670  return 0;
8671  }
8672  }
8673  total_size += 8;
8674  if (a.size == 1 && total_size + 8 <= atom.size) { /* 64 bit extended size */
8675  a.size = avio_rb64(pb) - 8;
8676  total_size += 8;
8677  }
8678  av_log(c->fc, AV_LOG_TRACE, "type:'%s' parent:'%s' sz: %"PRId64" %"PRId64" %"PRId64"\n",
8679  av_fourcc2str(a.type), av_fourcc2str(atom.type), a.size, total_size, atom.size);
8680  if (a.size == 0) {
8681  a.size = atom.size - total_size + 8;
8682  }
8683  if (a.size < 0)
8684  break;
8685  a.size -= 8;
8686  if (a.size < 0)
8687  break;
8688  a.size = FFMIN(a.size, atom.size - total_size);
8689 
8690  for (i = 0; mov_default_parse_table[i].type; i++)
8691  if (mov_default_parse_table[i].type == a.type) {
8693  break;
8694  }
8695 
8696  // container is user data
8697  if (!parse && (atom.type == MKTAG('u','d','t','a') ||
8698  atom.type == MKTAG('i','l','s','t')))
8700 
8701  // Supports parsing the QuickTime Metadata Keys.
8702  // https://developer.apple.com/library/mac/documentation/QuickTime/QTFF/Metadata/Metadata.html
8703  if (!parse && c->found_hdlr_mdta &&
8704  atom.type == MKTAG('m','e','t','a') &&
8705  a.type == MKTAG('k','e','y','s') &&
8706  c->meta_keys_count == 0) {
8707  parse = mov_read_keys;
8708  }
8709 
8710  if (!parse) { /* skip leaf atoms data */
8711  avio_skip(pb, a.size);
8712  } else {
8713  int64_t start_pos = avio_tell(pb);
8714  int64_t left;
8715  int err = parse(c, pb, a);
8716  if (err < 0) {
8717  c->atom_depth --;
8718  return err;
8719  }
8720  if (c->found_moov && c->found_mdat && a.size <= INT64_MAX - start_pos &&
8721  ((!(pb->seekable & AVIO_SEEKABLE_NORMAL) || c->fc->flags & AVFMT_FLAG_IGNIDX || c->frag_index.complete) ||
8722  start_pos + a.size == avio_size(pb))) {
8723  if (!(pb->seekable & AVIO_SEEKABLE_NORMAL) || c->fc->flags & AVFMT_FLAG_IGNIDX || c->frag_index.complete)
8724  c->next_root_atom = start_pos + a.size;
8725  c->atom_depth --;
8726  return 0;
8727  }
8728  left = a.size - avio_tell(pb) + start_pos;
8729  if (left > 0) /* skip garbage at atom end */
8730  avio_skip(pb, left);
8731  else if (left < 0) {
8732  av_log(c->fc, AV_LOG_WARNING,
8733  "overread end of atom '%s' by %"PRId64" bytes\n",
8734  av_fourcc2str(a.type), -left);
8735  avio_seek(pb, left, SEEK_CUR);
8736  }
8737  }
8738 
8739  total_size += a.size;
8740  }
8741 
8742  if (total_size < atom.size && atom.size < 0x7ffff)
8743  avio_skip(pb, atom.size - total_size);
8744 
8745  c->atom_depth --;
8746  return 0;
8747 }
8748 
8749 static int mov_probe(const AVProbeData *p)
8750 {
8751  int64_t offset;
8752  uint32_t tag;
8753  int score = 0;
8754  int moov_offset = -1;
8755 
8756  /* check file header */
8757  offset = 0;
8758  for (;;) {
8759  int64_t size;
8760  int minsize = 8;
8761  /* ignore invalid offset */
8762  if ((offset + 8ULL) > (unsigned int)p->buf_size)
8763  break;
8764  size = AV_RB32(p->buf + offset);
8765  if (size == 1 && offset + 16 <= (unsigned int)p->buf_size) {
8766  size = AV_RB64(p->buf+offset + 8);
8767  minsize = 16;
8768  } else if (size == 0) {
8769  size = p->buf_size - offset;
8770  }
8771  if (size < minsize) {
8772  offset += 4;
8773  continue;
8774  }
8775  tag = AV_RL32(p->buf + offset + 4);
8776  switch(tag) {
8777  /* check for obvious tags */
8778  case MKTAG('m','o','o','v'):
8779  moov_offset = offset + 4;
8780  case MKTAG('m','d','a','t'):
8781  case MKTAG('p','n','o','t'): /* detect movs with preview pics like ew.mov and april.mov */
8782  case MKTAG('u','d','t','a'): /* Packet Video PVAuthor adds this and a lot of more junk */
8783  case MKTAG('f','t','y','p'):
8784  if (tag == MKTAG('f','t','y','p') &&
8785  ( AV_RL32(p->buf + offset + 8) == MKTAG('j','p','2',' ')
8786  || AV_RL32(p->buf + offset + 8) == MKTAG('j','p','x',' ')
8787  || AV_RL32(p->buf + offset + 8) == MKTAG('j','x','l',' ')
8788  )) {
8789  score = FFMAX(score, 5);
8790  } else {
8791  score = AVPROBE_SCORE_MAX;
8792  }
8793  break;
8794  /* those are more common words, so rate then a bit less */
8795  case MKTAG('e','d','i','w'): /* xdcam files have reverted first tags */
8796  case MKTAG('w','i','d','e'):
8797  case MKTAG('f','r','e','e'):
8798  case MKTAG('j','u','n','k'):
8799  case MKTAG('p','i','c','t'):
8800  score = FFMAX(score, AVPROBE_SCORE_MAX - 5);
8801  break;
8802  case MKTAG(0x82,0x82,0x7f,0x7d):
8803  score = FFMAX(score, AVPROBE_SCORE_EXTENSION - 5);
8804  break;
8805  case MKTAG('s','k','i','p'):
8806  case MKTAG('u','u','i','d'):
8807  case MKTAG('p','r','f','l'):
8808  /* if we only find those cause probedata is too small at least rate them */
8809  score = FFMAX(score, AVPROBE_SCORE_EXTENSION);
8810  break;
8811  }
8812  if (size > INT64_MAX - offset)
8813  break;
8814  offset += size;
8815  }
8816  if (score > AVPROBE_SCORE_MAX - 50 && moov_offset != -1) {
8817  /* moov atom in the header - we should make sure that this is not a
8818  * MOV-packed MPEG-PS */
8819  offset = moov_offset;
8820 
8821  while (offset < (p->buf_size - 16)) { /* Sufficient space */
8822  /* We found an actual hdlr atom */
8823  if (AV_RL32(p->buf + offset ) == MKTAG('h','d','l','r') &&
8824  AV_RL32(p->buf + offset + 8) == MKTAG('m','h','l','r') &&
8825  AV_RL32(p->buf + offset + 12) == MKTAG('M','P','E','G')) {
8826  av_log(NULL, AV_LOG_WARNING, "Found media data tag MPEG indicating this is a MOV-packed MPEG-PS.\n");
8827  /* We found a media handler reference atom describing an
8828  * MPEG-PS-in-MOV, return a
8829  * low score to force expanding the probe window until
8830  * mpegps_probe finds what it needs */
8831  return 5;
8832  } else {
8833  /* Keep looking */
8834  offset += 2;
8835  }
8836  }
8837  }
8838 
8839  return score;
8840 }
8841 
8842 // must be done after parsing all trak because there's no order requirement
8844 {
8845  MOVContext *mov = s->priv_data;
8846  MOVStreamContext *sc;
8847  int64_t cur_pos;
8848  int i, j;
8849  int chapter_track;
8850 
8851  for (j = 0; j < mov->nb_chapter_tracks; j++) {
8852  AVStream *st = NULL;
8853  FFStream *sti = NULL;
8854  chapter_track = mov->chapter_tracks[j];
8855  for (i = 0; i < s->nb_streams; i++) {
8856  sc = mov->fc->streams[i]->priv_data;
8857  if (sc->id == chapter_track) {
8858  st = s->streams[i];
8859  break;
8860  }
8861  }
8862  if (!st) {
8863  av_log(s, AV_LOG_ERROR, "Referenced QT chapter track not found\n");
8864  continue;
8865  }
8866  sti = ffstream(st);
8867 
8868  sc = st->priv_data;
8869  cur_pos = avio_tell(sc->pb);
8870 
8871  if (st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO) {
8873  if (!st->attached_pic.data && sti->nb_index_entries) {
8874  // Retrieve the first frame, if possible
8875  AVIndexEntry *sample = &sti->index_entries[0];
8876  if (avio_seek(sc->pb, sample->pos, SEEK_SET) != sample->pos) {
8877  av_log(s, AV_LOG_ERROR, "Failed to retrieve first frame\n");
8878  goto finish;
8879  }
8880 
8881  if (ff_add_attached_pic(s, st, sc->pb, NULL, sample->size) < 0)
8882  goto finish;
8883  }
8884  } else {
8887  st->discard = AVDISCARD_ALL;
8888  for (int i = 0; i < sti->nb_index_entries; i++) {
8889  AVIndexEntry *sample = &sti->index_entries[i];
8890  int64_t end = i+1 < sti->nb_index_entries ? sti->index_entries[i+1].timestamp : st->duration;
8891  uint8_t *title;
8892  uint16_t ch;
8893  int len, title_len;
8894 
8895  if (end < sample->timestamp) {
8896  av_log(s, AV_LOG_WARNING, "ignoring stream duration which is shorter than chapters\n");
8897  end = AV_NOPTS_VALUE;
8898  }
8899 
8900  if (avio_seek(sc->pb, sample->pos, SEEK_SET) != sample->pos) {
8901  av_log(s, AV_LOG_ERROR, "Chapter %d not found in file\n", i);
8902  goto finish;
8903  }
8904 
8905  // the first two bytes are the length of the title
8906  len = avio_rb16(sc->pb);
8907  if (len > sample->size-2)
8908  continue;
8909  title_len = 2*len + 1;
8910  if (!(title = av_mallocz(title_len)))
8911  goto finish;
8912 
8913  // The samples could theoretically be in any encoding if there's an encd
8914  // atom following, but in practice are only utf-8 or utf-16, distinguished
8915  // instead by the presence of a BOM
8916  if (!len) {
8917  title[0] = 0;
8918  } else {
8919  ch = avio_rb16(sc->pb);
8920  if (ch == 0xfeff)
8921  avio_get_str16be(sc->pb, len, title, title_len);
8922  else if (ch == 0xfffe)
8923  avio_get_str16le(sc->pb, len, title, title_len);
8924  else {
8925  AV_WB16(title, ch);
8926  if (len == 1 || len == 2)
8927  title[len] = 0;
8928  else
8929  avio_get_str(sc->pb, INT_MAX, title + 2, len - 1);
8930  }
8931  }
8932 
8933  avpriv_new_chapter(s, i, st->time_base, sample->timestamp, end, title);
8934  av_freep(&title);
8935  }
8936  }
8937 finish:
8938  avio_seek(sc->pb, cur_pos, SEEK_SET);
8939  }
8940 }
8941 
8943  int64_t value, int flags)
8944 {
8945  AVTimecode tc;
8946  char buf[AV_TIMECODE_STR_SIZE];
8947  AVRational rate = st->avg_frame_rate;
8948  int ret = av_timecode_init(&tc, rate, flags, 0, s);
8949  if (ret < 0)
8950  return ret;
8951  av_dict_set(&st->metadata, "timecode",
8952  av_timecode_make_string(&tc, buf, value), 0);
8953  return 0;
8954 }
8955 
8957 {
8958  MOVStreamContext *sc = st->priv_data;
8959  FFStream *const sti = ffstream(st);
8960  char buf[AV_TIMECODE_STR_SIZE];
8961  int64_t cur_pos = avio_tell(sc->pb);
8962  int hh, mm, ss, ff, drop;
8963 
8964  if (!sti->nb_index_entries)
8965  return -1;
8966 
8967  avio_seek(sc->pb, sti->index_entries->pos, SEEK_SET);
8968  avio_skip(s->pb, 13);
8969  hh = avio_r8(s->pb);
8970  mm = avio_r8(s->pb);
8971  ss = avio_r8(s->pb);
8972  drop = avio_r8(s->pb);
8973  ff = avio_r8(s->pb);
8974  snprintf(buf, AV_TIMECODE_STR_SIZE, "%02d:%02d:%02d%c%02d",
8975  hh, mm, ss, drop ? ';' : ':', ff);
8976  av_dict_set(&st->metadata, "timecode", buf, 0);
8977 
8978  avio_seek(sc->pb, cur_pos, SEEK_SET);
8979  return 0;
8980 }
8981 
8983 {
8984  MOVStreamContext *sc = st->priv_data;
8985  FFStream *const sti = ffstream(st);
8986  int flags = 0;
8987  int64_t cur_pos = avio_tell(sc->pb);
8988  int64_t value;
8989  AVRational tc_rate = st->avg_frame_rate;
8990  int tmcd_nb_frames = sc->tmcd_nb_frames;
8991  int rounded_tc_rate;
8992 
8993  if (!sti->nb_index_entries)
8994  return -1;
8995 
8996  if (!tc_rate.num || !tc_rate.den || !tmcd_nb_frames)
8997  return -1;
8998 
8999  avio_seek(sc->pb, sti->index_entries->pos, SEEK_SET);
9000  value = avio_rb32(s->pb);
9001 
9002  if (sc->tmcd_flags & 0x0001) flags |= AV_TIMECODE_FLAG_DROPFRAME;
9003  if (sc->tmcd_flags & 0x0002) flags |= AV_TIMECODE_FLAG_24HOURSMAX;
9004  if (sc->tmcd_flags & 0x0004) flags |= AV_TIMECODE_FLAG_ALLOWNEGATIVE;
9005 
9006  /* Assume Counter flag is set to 1 in tmcd track (even though it is likely
9007  * not the case) and thus assume "frame number format" instead of QT one.
9008  * No sample with tmcd track can be found with a QT timecode at the moment,
9009  * despite what the tmcd track "suggests" (Counter flag set to 0 means QT
9010  * format). */
9011 
9012  /* 60 fps content have tmcd_nb_frames set to 30 but tc_rate set to 60, so
9013  * we multiply the frame number with the quotient.
9014  * See tickets #9492, #9710. */
9015  rounded_tc_rate = (tc_rate.num + tc_rate.den / 2LL) / tc_rate.den;
9016  /* Work around files where tmcd_nb_frames is rounded down from frame rate
9017  * instead of up. See ticket #5978. */
9018  if (tmcd_nb_frames == tc_rate.num / tc_rate.den &&
9019  s->strict_std_compliance < FF_COMPLIANCE_STRICT)
9020  tmcd_nb_frames = rounded_tc_rate;
9021  value = av_rescale(value, rounded_tc_rate, tmcd_nb_frames);
9022 
9024 
9025  avio_seek(sc->pb, cur_pos, SEEK_SET);
9026  return 0;
9027 }
9028 
9030  int i;
9031  if (!index || !*index) return;
9032  for (i = 0; i < (*index)->nb_encrypted_samples; i++) {
9033  av_encryption_info_free((*index)->encrypted_samples[i]);
9034  }
9035  av_freep(&(*index)->encrypted_samples);
9036  av_freep(&(*index)->auxiliary_info_sizes);
9037  av_freep(&(*index)->auxiliary_offsets);
9038  av_freep(index);
9039 }
9040 
9042 {
9043  MOVStreamContext *sc = st->priv_data;
9044 
9045  if (!sc || --sc->refcount) {
9046  st->priv_data = NULL;
9047  return;
9048  }
9049 
9050  av_freep(&sc->ctts_data);
9051  for (int i = 0; i < sc->drefs_count; i++) {
9052  av_freep(&sc->drefs[i].path);
9053  av_freep(&sc->drefs[i].dir);
9054  }
9055  av_freep(&sc->drefs);
9056 
9057  sc->drefs_count = 0;
9058 
9059  if (!sc->pb_is_copied)
9060  ff_format_io_close(s, &sc->pb);
9061 
9062  sc->pb = NULL;
9063  av_freep(&sc->chunk_offsets);
9064  av_freep(&sc->stsc_data);
9065  av_freep(&sc->sample_sizes);
9066  av_freep(&sc->keyframes);
9067  av_freep(&sc->stts_data);
9068  av_freep(&sc->sdtp_data);
9069  av_freep(&sc->stps_data);
9070  av_freep(&sc->elst_data);
9071  av_freep(&sc->rap_group);
9072  av_freep(&sc->sync_group);
9073  av_freep(&sc->sgpd_sync);
9074  av_freep(&sc->sample_offsets);
9075  av_freep(&sc->open_key_samples);
9076  av_freep(&sc->display_matrix);
9077  av_freep(&sc->index_ranges);
9078 
9079  if (sc->extradata)
9080  for (int i = 0; i < sc->stsd_count; i++)
9081  av_free(sc->extradata[i]);
9082  av_freep(&sc->extradata);
9083  av_freep(&sc->extradata_size);
9084 
9088 
9089  av_freep(&sc->stereo3d);
9090  av_freep(&sc->spherical);
9091  av_freep(&sc->mastering);
9092  av_freep(&sc->coll);
9093  av_freep(&sc->ambient);
9094 
9095 #if CONFIG_IAMFDEC
9096  if (sc->iamf)
9098 #endif
9099  av_freep(&sc->iamf);
9100 }
9101 
9103 {
9104  MOVContext *mov = s->priv_data;
9105  int i, j;
9106 
9107  for (i = 0; i < s->nb_streams; i++) {
9108  AVStream *st = s->streams[i];
9109 
9111  }
9112 
9113  av_freep(&mov->dv_demux);
9115  mov->dv_fctx = NULL;
9116 
9117  if (mov->meta_keys) {
9118  for (i = 1; i < mov->meta_keys_count; i++) {
9119  av_freep(&mov->meta_keys[i]);
9120  }
9121  av_freep(&mov->meta_keys);
9122  }
9123 
9124  av_freep(&mov->trex_data);
9125  av_freep(&mov->bitrates);
9126 
9127  for (i = 0; i < mov->frag_index.nb_items; i++) {
9129  for (j = 0; j < mov->frag_index.item[i].nb_stream_info; j++) {
9130  mov_free_encryption_index(&frag[j].encryption_index);
9131  }
9133  }
9134  av_freep(&mov->frag_index.item);
9135 
9136  av_freep(&mov->aes_decrypt);
9137  av_freep(&mov->chapter_tracks);
9138  for (i = 0; i < mov->nb_heif_item; i++)
9139  av_freep(&mov->heif_item[i].name);
9140  av_freep(&mov->heif_item);
9141  for (i = 0; i < mov->nb_heif_grid; i++) {
9142  av_freep(&mov->heif_grid[i].tile_id_list);
9144  }
9145  av_freep(&mov->heif_grid);
9146 
9147  return 0;
9148 }
9149 
9150 static int tmcd_is_referenced(AVFormatContext *s, int tmcd_id)
9151 {
9152  int i;
9153 
9154  for (i = 0; i < s->nb_streams; i++) {
9155  AVStream *st = s->streams[i];
9156  MOVStreamContext *sc = st->priv_data;
9157 
9158  if (st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO &&
9159  sc->timecode_track == tmcd_id)
9160  return 1;
9161  }
9162  return 0;
9163 }
9164 
9165 /* look for a tmcd track not referenced by any video track, and export it globally */
9167 {
9168  int i;
9169 
9170  for (i = 0; i < s->nb_streams; i++) {
9171  AVStream *st = s->streams[i];
9172 
9173  if (st->codecpar->codec_tag == MKTAG('t','m','c','d') &&
9174  !tmcd_is_referenced(s, i + 1)) {
9175  AVDictionaryEntry *tcr = av_dict_get(st->metadata, "timecode", NULL, 0);
9176  if (tcr) {
9177  av_dict_set(&s->metadata, "timecode", tcr->value, 0);
9178  break;
9179  }
9180  }
9181  }
9182 }
9183 
9184 static int read_tfra(MOVContext *mov, AVIOContext *f)
9185 {
9186  int version, fieldlength, i, j;
9187  int64_t pos = avio_tell(f);
9188  uint32_t size = avio_rb32(f);
9189  unsigned track_id, item_count;
9190 
9191  if (avio_rb32(f) != MKBETAG('t', 'f', 'r', 'a')) {
9192  return 1;
9193  }
9194  av_log(mov->fc, AV_LOG_VERBOSE, "found tfra\n");
9195 
9196  version = avio_r8(f);
9197  avio_rb24(f);
9198  track_id = avio_rb32(f);
9199  fieldlength = avio_rb32(f);
9200  item_count = avio_rb32(f);
9201  for (i = 0; i < item_count; i++) {
9202  int64_t time, offset;
9203  int index;
9204  MOVFragmentStreamInfo * frag_stream_info;
9205 
9206  if (avio_feof(f)) {
9207  return AVERROR_INVALIDDATA;
9208  }
9209 
9210  if (version == 1) {
9211  time = avio_rb64(f);
9212  offset = avio_rb64(f);
9213  } else {
9214  time = avio_rb32(f);
9215  offset = avio_rb32(f);
9216  }
9217 
9218  // The first sample of each stream in a fragment is always a random
9219  // access sample. So it's entry in the tfra can be used as the
9220  // initial PTS of the fragment.
9221  index = update_frag_index(mov, offset);
9222  frag_stream_info = get_frag_stream_info(&mov->frag_index, index, track_id);
9223  if (frag_stream_info &&
9224  frag_stream_info->first_tfra_pts == AV_NOPTS_VALUE)
9225  frag_stream_info->first_tfra_pts = time;
9226 
9227  for (j = 0; j < ((fieldlength >> 4) & 3) + 1; j++)
9228  avio_r8(f);
9229  for (j = 0; j < ((fieldlength >> 2) & 3) + 1; j++)
9230  avio_r8(f);
9231  for (j = 0; j < ((fieldlength >> 0) & 3) + 1; j++)
9232  avio_r8(f);
9233  }
9234 
9235  avio_seek(f, pos + size, SEEK_SET);
9236  return 0;
9237 }
9238 
9240 {
9241  int64_t stream_size = avio_size(f);
9242  int64_t original_pos = avio_tell(f);
9243  int64_t seek_ret;
9244  int ret = -1;
9245  if ((seek_ret = avio_seek(f, stream_size - 4, SEEK_SET)) < 0) {
9246  ret = seek_ret;
9247  goto fail;
9248  }
9249  c->mfra_size = avio_rb32(f);
9250  c->have_read_mfra_size = 1;
9251  if (!c->mfra_size || c->mfra_size > stream_size) {
9252  av_log(c->fc, AV_LOG_DEBUG, "doesn't look like mfra (unreasonable size)\n");
9253  goto fail;
9254  }
9255  if ((seek_ret = avio_seek(f, -((int64_t) c->mfra_size), SEEK_CUR)) < 0) {
9256  ret = seek_ret;
9257  goto fail;
9258  }
9259  if (avio_rb32(f) != c->mfra_size) {
9260  av_log(c->fc, AV_LOG_DEBUG, "doesn't look like mfra (size mismatch)\n");
9261  goto fail;
9262  }
9263  if (avio_rb32(f) != MKBETAG('m', 'f', 'r', 'a')) {
9264  av_log(c->fc, AV_LOG_DEBUG, "doesn't look like mfra (tag mismatch)\n");
9265  goto fail;
9266  }
9267  av_log(c->fc, AV_LOG_VERBOSE, "stream has mfra\n");
9268  do {
9269  ret = read_tfra(c, f);
9270  if (ret < 0)
9271  goto fail;
9272  } while (!ret);
9273  ret = 0;
9274  c->frag_index.complete = 1;
9275 fail:
9276  seek_ret = avio_seek(f, original_pos, SEEK_SET);
9277  if (seek_ret < 0) {
9278  av_log(c->fc, AV_LOG_ERROR,
9279  "failed to seek back after looking for mfra\n");
9280  ret = seek_ret;
9281  }
9282  return ret;
9283 }
9284 
9285 static int read_image_grid(AVFormatContext *s, const HEIFGrid *grid,
9286  AVStreamGroupTileGrid *tile_grid)
9287 {
9288  MOVContext *c = s->priv_data;
9289  const HEIFItem *item = grid->item;
9290  int64_t offset = 0, pos = avio_tell(s->pb);
9291  int x = 0, y = 0, i = 0;
9292  int tile_rows, tile_cols;
9293  int flags, size;
9294 
9295  if (!(s->pb->seekable & AVIO_SEEKABLE_NORMAL)) {
9296  av_log(c->fc, AV_LOG_INFO, "grid box with non seekable input\n");
9297  return AVERROR_PATCHWELCOME;
9298  }
9299  if (item->is_idat_relative) {
9300  if (!c->idat_offset) {
9301  av_log(c->fc, AV_LOG_ERROR, "missing idat box required by the image grid\n");
9302  return AVERROR_INVALIDDATA;
9303  }
9304  offset = c->idat_offset;
9305  }
9306 
9307  avio_seek(s->pb, item->extent_offset + offset, SEEK_SET);
9308 
9309  avio_r8(s->pb); /* version */
9310  flags = avio_r8(s->pb);
9311 
9312  tile_rows = avio_r8(s->pb) + 1;
9313  tile_cols = avio_r8(s->pb) + 1;
9314  /* actual width and height of output image */
9315  tile_grid->width = (flags & 1) ? avio_rb32(s->pb) : avio_rb16(s->pb);
9316  tile_grid->height = (flags & 1) ? avio_rb32(s->pb) : avio_rb16(s->pb);
9317 
9318  av_log(c->fc, AV_LOG_TRACE, "grid: grid_rows %d grid_cols %d output_width %d output_height %d\n",
9319  tile_rows, tile_cols, tile_grid->width, tile_grid->height);
9320 
9321  avio_seek(s->pb, pos, SEEK_SET);
9322 
9323  size = tile_rows * tile_cols;
9324  tile_grid->nb_tiles = grid->nb_tiles;
9325 
9326  if (tile_grid->nb_tiles != size)
9327  return AVERROR_INVALIDDATA;
9328 
9329  for (int i = 0; i < tile_cols; i++)
9330  tile_grid->coded_width += grid->tile_item_list[i]->width;
9331  for (int i = 0; i < size; i += tile_cols)
9332  tile_grid->coded_height += grid->tile_item_list[i]->height;
9333 
9334  tile_grid->offsets = av_calloc(tile_grid->nb_tiles, sizeof(*tile_grid->offsets));
9335  if (!tile_grid->offsets)
9336  return AVERROR(ENOMEM);
9337 
9338  while (y < tile_grid->coded_height) {
9339  int left_col = i;
9340 
9341  while (x < tile_grid->coded_width) {
9342  if (i == tile_grid->nb_tiles)
9343  return AVERROR_INVALIDDATA;
9344 
9345  tile_grid->offsets[i].idx = i;
9346  tile_grid->offsets[i].horizontal = x;
9347  tile_grid->offsets[i].vertical = y;
9348 
9349  x += grid->tile_item_list[i++]->width;
9350  }
9351 
9352  if (x > tile_grid->coded_width) {
9353  av_log(c->fc, AV_LOG_ERROR, "Non uniform HEIF tiles\n");
9354  return AVERROR_INVALIDDATA;
9355  }
9356 
9357  x = 0;
9358  y += grid->tile_item_list[left_col]->height;
9359  }
9360 
9361  if (y > tile_grid->coded_height || i != tile_grid->nb_tiles) {
9362  av_log(c->fc, AV_LOG_ERROR, "Non uniform HEIF tiles\n");
9363  return AVERROR_INVALIDDATA;
9364  }
9365 
9366  return 0;
9367 }
9368 
9369 static int read_image_iovl(AVFormatContext *s, const HEIFGrid *grid,
9370  AVStreamGroupTileGrid *tile_grid)
9371 {
9372  MOVContext *c = s->priv_data;
9373  const HEIFItem *item = grid->item;
9374  uint16_t canvas_fill_value[4];
9375  int64_t offset = 0, pos = avio_tell(s->pb);
9376  int ret = 0, flags;
9377 
9378  if (!(s->pb->seekable & AVIO_SEEKABLE_NORMAL)) {
9379  av_log(c->fc, AV_LOG_INFO, "iovl box with non seekable input\n");
9380  return AVERROR_PATCHWELCOME;
9381  }
9382  if (item->is_idat_relative) {
9383  if (!c->idat_offset) {
9384  av_log(c->fc, AV_LOG_ERROR, "missing idat box required by the image overlay\n");
9385  return AVERROR_INVALIDDATA;
9386  }
9387  offset = c->idat_offset;
9388  }
9389 
9390  avio_seek(s->pb, item->extent_offset + offset, SEEK_SET);
9391 
9392  avio_r8(s->pb); /* version */
9393  flags = avio_r8(s->pb);
9394 
9395  for (int i = 0; i < 4; i++)
9396  canvas_fill_value[i] = avio_rb16(s->pb);
9397  av_log(c->fc, AV_LOG_TRACE, "iovl: canvas_fill_value { %u, %u, %u, %u }\n",
9398  canvas_fill_value[0], canvas_fill_value[1],
9399  canvas_fill_value[2], canvas_fill_value[3]);
9400  for (int i = 0; i < 4; i++)
9401  tile_grid->background[i] = canvas_fill_value[i];
9402 
9403  /* actual width and height of output image */
9404  tile_grid->width =
9405  tile_grid->coded_width = (flags & 1) ? avio_rb32(s->pb) : avio_rb16(s->pb);
9406  tile_grid->height =
9407  tile_grid->coded_height = (flags & 1) ? avio_rb32(s->pb) : avio_rb16(s->pb);
9408  av_log(c->fc, AV_LOG_TRACE, "iovl: output_width %d, output_height %d\n",
9409  tile_grid->width, tile_grid->height);
9410 
9411  tile_grid->nb_tiles = grid->nb_tiles;
9412  tile_grid->offsets = av_malloc_array(tile_grid->nb_tiles, sizeof(*tile_grid->offsets));
9413  if (!tile_grid->offsets) {
9414  ret = AVERROR(ENOMEM);
9415  goto fail;
9416  }
9417 
9418  for (int i = 0; i < tile_grid->nb_tiles; i++) {
9419  tile_grid->offsets[i].idx = grid->tile_item_list[i]->st->index;
9420  tile_grid->offsets[i].horizontal = (flags & 1) ? avio_rb32(s->pb) : avio_rb16(s->pb);
9421  tile_grid->offsets[i].vertical = (flags & 1) ? avio_rb32(s->pb) : avio_rb16(s->pb);
9422  av_log(c->fc, AV_LOG_TRACE, "iovl: stream_idx[%d] %u, "
9423  "horizontal_offset[%d] %d, vertical_offset[%d] %d\n",
9424  i, tile_grid->offsets[i].idx,
9425  i, tile_grid->offsets[i].horizontal, i, tile_grid->offsets[i].vertical);
9426  }
9427 
9428 fail:
9429  avio_seek(s->pb, pos, SEEK_SET);
9430 
9431  return ret;
9432 }
9433 
9435 {
9436  MOVContext *mov = s->priv_data;
9437 
9438  for (int i = 0; i < mov->nb_heif_grid; i++) {
9440  AVStreamGroupTileGrid *tile_grid;
9441  const HEIFGrid *grid = &mov->heif_grid[i];
9442  int err, loop = 1;
9443 
9444  if (!stg)
9445  return AVERROR(ENOMEM);
9446 
9447  stg->id = grid->item->item_id;
9448  tile_grid = stg->params.tile_grid;
9449 
9450  for (int j = 0; j < grid->nb_tiles; j++) {
9451  int tile_id = grid->tile_id_list[j];
9452  int k;
9453 
9454  for (k = 0; k < mov->nb_heif_item; k++) {
9455  HEIFItem *item = &mov->heif_item[k];
9456  AVStream *st = item->st;
9457 
9458  if (item->item_id != tile_id)
9459  continue;
9460  if (!st) {
9461  av_log(s, AV_LOG_WARNING, "HEIF item id %d from grid id %d doesn't "
9462  "reference a stream\n",
9463  tile_id, grid->item->item_id);
9464  ff_remove_stream_group(s, stg);
9465  loop = 0;
9466  break;
9467  }
9468 
9469  grid->tile_item_list[j] = item;
9470 
9471  err = avformat_stream_group_add_stream(stg, st);
9472  if (err < 0 && err != AVERROR(EEXIST))
9473  return err;
9474 
9475  if (item->item_id != mov->primary_item_id)
9477  break;
9478  }
9479 
9480  if (k == mov->nb_heif_item) {
9481  av_assert0(loop);
9482  av_log(s, AV_LOG_WARNING, "HEIF item id %d referenced by grid id %d doesn't "
9483  "exist\n",
9484  tile_id, grid->item->item_id);
9485  ff_remove_stream_group(s, stg);
9486  loop = 0;
9487  }
9488  if (!loop)
9489  break;
9490  }
9491 
9492  if (!loop)
9493  continue;
9494 
9495  switch (grid->item->type) {
9496  case MKTAG('g','r','i','d'):
9497  err = read_image_grid(s, grid, tile_grid);
9498  break;
9499  case MKTAG('i','o','v','l'):
9500  err = read_image_iovl(s, grid, tile_grid);
9501  break;
9502  default:
9503  av_assert0(0);
9504  }
9505  if (err < 0)
9506  return err;
9507 
9508 
9509  if (grid->item->name)
9510  av_dict_set(&stg->metadata, "title", grid->item->name, 0);
9511  if (grid->item->item_id == mov->primary_item_id)
9513  }
9514 
9515  return 0;
9516 }
9517 
9519 {
9520  MOVContext *mov = s->priv_data;
9521  AVIOContext *pb = s->pb;
9522  int j, err;
9523  MOVAtom atom = { AV_RL32("root") };
9524  int i;
9525 
9526  if (mov->decryption_key_len != 0 && mov->decryption_key_len != AES_CTR_KEY_SIZE) {
9527  av_log(s, AV_LOG_ERROR, "Invalid decryption key len %d expected %d\n",
9529  return AVERROR(EINVAL);
9530  }
9531 
9532  mov->fc = s;
9533  mov->trak_index = -1;
9534  mov->thmb_item_id = -1;
9535  mov->primary_item_id = -1;
9536  mov->cur_item_id = -1;
9537  /* .mov and .mp4 aren't streamable anyway (only progressive download if moov is before mdat) */
9538  if (pb->seekable & AVIO_SEEKABLE_NORMAL)
9539  atom.size = avio_size(pb);
9540  else
9541  atom.size = INT64_MAX;
9542 
9543  /* check MOV header */
9544  do {
9545  if (mov->moov_retry)
9546  avio_seek(pb, 0, SEEK_SET);
9547  if ((err = mov_read_default(mov, pb, atom)) < 0) {
9548  av_log(s, AV_LOG_ERROR, "error reading header\n");
9549  return err;
9550  }
9551  } while ((pb->seekable & AVIO_SEEKABLE_NORMAL) &&
9552  !mov->found_moov && (!mov->found_iloc || !mov->found_iinf) && !mov->moov_retry++);
9553  if (!mov->found_moov && !mov->found_iloc && !mov->found_iinf) {
9554  av_log(s, AV_LOG_ERROR, "moov atom not found\n");
9555  return AVERROR_INVALIDDATA;
9556  }
9557  av_log(mov->fc, AV_LOG_TRACE, "on_parse_exit_offset=%"PRId64"\n", avio_tell(pb));
9558 
9559  if (mov->found_iloc && mov->found_iinf) {
9560  for (i = 0; i < mov->nb_heif_item; i++) {
9561  HEIFItem *item = &mov->heif_item[i];
9562  MOVStreamContext *sc;
9563  AVStream *st;
9564  int64_t offset = 0;
9565 
9566  if (!item->st) {
9567  if (item->item_id == mov->thmb_item_id) {
9568  av_log(s, AV_LOG_ERROR, "HEIF thumbnail doesn't reference a stream\n");
9569  return AVERROR_INVALIDDATA;
9570  }
9571  continue;
9572  }
9573  if (item->is_idat_relative) {
9574  if (!mov->idat_offset) {
9575  av_log(s, AV_LOG_ERROR, "Missing idat box for item %d\n", item->item_id);
9576  return AVERROR_INVALIDDATA;
9577  }
9578  offset = mov->idat_offset;
9579  }
9580 
9581  st = item->st;
9582  sc = st->priv_data;
9583  st->codecpar->width = item->width;
9584  st->codecpar->height = item->height;
9585 
9586  sc->sample_sizes[0] = item->extent_length;
9587  sc->chunk_offsets[0] = item->extent_offset + offset;
9588 
9589  if (item->item_id == mov->primary_item_id)
9591 
9592  mov_build_index(mov, st);
9593  }
9594 
9595  if (mov->nb_heif_grid) {
9596  err = mov_parse_tiles(s);
9597  if (err < 0)
9598  return err;
9599  }
9600  }
9601  // prevent iloc and iinf boxes from being parsed while reading packets.
9602  // this is needed because an iinf box may have been parsed but ignored
9603  // for having old infe boxes which create no streams.
9604  mov->found_iloc = mov->found_iinf = 1;
9605 
9606  if (pb->seekable & AVIO_SEEKABLE_NORMAL) {
9607  if (mov->nb_chapter_tracks > 0 && !mov->ignore_chapters)
9609  for (i = 0; i < s->nb_streams; i++)
9610  if (s->streams[i]->codecpar->codec_tag == AV_RL32("tmcd")) {
9611  mov_read_timecode_track(s, s->streams[i]);
9612  } else if (s->streams[i]->codecpar->codec_tag == AV_RL32("rtmd")) {
9613  mov_read_rtmd_track(s, s->streams[i]);
9614  }
9615  }
9616 
9617  /* copy timecode metadata from tmcd tracks to the related video streams */
9618  for (i = 0; i < s->nb_streams; i++) {
9619  AVStream *st = s->streams[i];
9620  MOVStreamContext *sc = st->priv_data;
9621  if (sc->timecode_track > 0) {
9622  AVDictionaryEntry *tcr;
9623  int tmcd_st_id = -1;
9624 
9625  for (j = 0; j < s->nb_streams; j++) {
9626  MOVStreamContext *sc2 = s->streams[j]->priv_data;
9627  if (sc2->id == sc->timecode_track)
9628  tmcd_st_id = j;
9629  }
9630 
9631  if (tmcd_st_id < 0 || tmcd_st_id == i)
9632  continue;
9633  tcr = av_dict_get(s->streams[tmcd_st_id]->metadata, "timecode", NULL, 0);
9634  if (tcr)
9635  av_dict_set(&st->metadata, "timecode", tcr->value, 0);
9636  }
9637  }
9639 
9640  for (i = 0; i < s->nb_streams; i++) {
9641  AVStream *st = s->streams[i];
9642  FFStream *const sti = ffstream(st);
9643  MOVStreamContext *sc = st->priv_data;
9644  fix_timescale(mov, sc);
9645  if (st->codecpar->codec_type == AVMEDIA_TYPE_AUDIO &&
9646  st->codecpar->codec_id == AV_CODEC_ID_AAC) {
9647  sti->skip_samples = sc->start_pad;
9648  }
9649  if (st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO && sc->nb_frames_for_fps > 0 && sc->duration_for_fps > 0)
9651  sc->time_scale*(int64_t)sc->nb_frames_for_fps, sc->duration_for_fps, INT_MAX);
9653  if (st->codecpar->width <= 0 || st->codecpar->height <= 0) {
9654  st->codecpar->width = sc->width;
9655  st->codecpar->height = sc->height;
9656  }
9658  if ((err = mov_rewrite_dvd_sub_extradata(st)) < 0)
9659  return err;
9660  }
9661  }
9662  if (mov->handbrake_version &&
9663  mov->handbrake_version <= 1000000*0 + 1000*10 + 2 && // 0.10.2
9664  st->codecpar->codec_id == AV_CODEC_ID_MP3) {
9665  av_log(s, AV_LOG_VERBOSE, "Forcing full parsing for mp3 stream\n");
9667  }
9668  }
9669 
9670  if (mov->trex_data || mov->use_mfra_for > 0) {
9671  for (i = 0; i < s->nb_streams; i++) {
9672  AVStream *st = s->streams[i];
9673  MOVStreamContext *sc = st->priv_data;
9674  if (sc->duration_for_fps > 0) {
9675  /* Akin to sc->data_size * 8 * sc->time_scale / sc->duration_for_fps but accounting for overflows. */
9676  st->codecpar->bit_rate = av_rescale(sc->data_size, ((int64_t) sc->time_scale) * 8, sc->duration_for_fps);
9677  if (st->codecpar->bit_rate == INT64_MIN) {
9678  av_log(s, AV_LOG_WARNING, "Overflow during bit rate calculation %"PRId64" * 8 * %d\n",
9679  sc->data_size, sc->time_scale);
9680  st->codecpar->bit_rate = 0;
9681  if (s->error_recognition & AV_EF_EXPLODE)
9682  return AVERROR_INVALIDDATA;
9683  }
9684  }
9685  }
9686  }
9687 
9688  for (i = 0; i < mov->bitrates_count && i < s->nb_streams; i++) {
9689  if (mov->bitrates[i]) {
9690  s->streams[i]->codecpar->bit_rate = mov->bitrates[i];
9691  }
9692  }
9693 
9695 
9696  for (i = 0; i < s->nb_streams; i++) {
9697  AVStream *st = s->streams[i];
9698  MOVStreamContext *sc = st->priv_data;
9699 
9700  switch (st->codecpar->codec_type) {
9701  case AVMEDIA_TYPE_AUDIO:
9702  err = ff_replaygain_export(st, s->metadata);
9703  if (err < 0)
9704  return err;
9705  break;
9706  case AVMEDIA_TYPE_VIDEO:
9707  if (sc->display_matrix) {
9710  (uint8_t*)sc->display_matrix, sizeof(int32_t) * 9, 0))
9711  return AVERROR(ENOMEM);
9712 
9713  sc->display_matrix = NULL;
9714  }
9715  if (sc->stereo3d) {
9718  (uint8_t *)sc->stereo3d, sizeof(*sc->stereo3d), 0))
9719  return AVERROR(ENOMEM);
9720 
9721  sc->stereo3d = NULL;
9722  }
9723  if (sc->spherical) {
9726  (uint8_t *)sc->spherical, sc->spherical_size, 0))
9727  return AVERROR(ENOMEM);
9728 
9729  sc->spherical = NULL;
9730  }
9731  if (sc->mastering) {
9734  (uint8_t *)sc->mastering, sizeof(*sc->mastering), 0))
9735  return AVERROR(ENOMEM);
9736 
9737  sc->mastering = NULL;
9738  }
9739  if (sc->coll) {
9742  (uint8_t *)sc->coll, sc->coll_size, 0))
9743  return AVERROR(ENOMEM);
9744 
9745  sc->coll = NULL;
9746  }
9747  if (sc->ambient) {
9750  (uint8_t *) sc->ambient, sc->ambient_size, 0))
9751  return AVERROR(ENOMEM);
9752 
9753  sc->ambient = NULL;
9754  }
9755  break;
9756  }
9757  }
9759 
9760  for (i = 0; i < mov->frag_index.nb_items; i++)
9761  if (mov->frag_index.item[i].moof_offset <= mov->fragment.moof_offset)
9762  mov->frag_index.item[i].headers_read = 1;
9763 
9764  return 0;
9765 }
9766 
9768 {
9770  int64_t best_dts = INT64_MAX;
9771  int i;
9772  MOVContext *mov = s->priv_data;
9773  int no_interleave = !mov->interleaved_read || !(s->pb->seekable & AVIO_SEEKABLE_NORMAL);
9774  for (i = 0; i < s->nb_streams; i++) {
9775  AVStream *avst = s->streams[i];
9776  FFStream *const avsti = ffstream(avst);
9777  MOVStreamContext *msc = avst->priv_data;
9778  if (msc->pb && msc->current_sample < avsti->nb_index_entries) {
9779  AVIndexEntry *current_sample = &avsti->index_entries[msc->current_sample];
9780  int64_t dts = av_rescale(current_sample->timestamp, AV_TIME_BASE, msc->time_scale);
9781  uint64_t dtsdiff = best_dts > dts ? best_dts - (uint64_t)dts : ((uint64_t)dts - best_dts);
9782  av_log(s, AV_LOG_TRACE, "stream %d, sample %d, dts %"PRId64"\n", i, msc->current_sample, dts);
9783  if (!sample || (no_interleave && current_sample->pos < sample->pos) ||
9784  ((s->pb->seekable & AVIO_SEEKABLE_NORMAL) &&
9785  ((msc->pb != s->pb && dts < best_dts) || (msc->pb == s->pb && dts != AV_NOPTS_VALUE &&
9786  ((dtsdiff <= AV_TIME_BASE && current_sample->pos < sample->pos) ||
9787  (dtsdiff > AV_TIME_BASE && dts < best_dts)))))) {
9788  sample = current_sample;
9789  best_dts = dts;
9790  *st = avst;
9791  }
9792  }
9793  }
9794  return sample;
9795 }
9796 
9797 static int should_retry(AVIOContext *pb, int error_code) {
9798  if (error_code == AVERROR_EOF || avio_feof(pb))
9799  return 0;
9800 
9801  return 1;
9802 }
9803 
9804 static int mov_switch_root(AVFormatContext *s, int64_t target, int index)
9805 {
9806  int ret;
9807  MOVContext *mov = s->priv_data;
9808 
9809  if (index >= 0 && index < mov->frag_index.nb_items)
9810  target = mov->frag_index.item[index].moof_offset;
9811  if (avio_seek(s->pb, target, SEEK_SET) != target) {
9812  av_log(mov->fc, AV_LOG_ERROR, "root atom offset 0x%"PRIx64": partial file\n", target);
9813  return AVERROR_INVALIDDATA;
9814  }
9815 
9816  mov->next_root_atom = 0;
9817  if (index < 0 || index >= mov->frag_index.nb_items)
9818  index = search_frag_moof_offset(&mov->frag_index, target);
9819  if (index < mov->frag_index.nb_items &&
9820  mov->frag_index.item[index].moof_offset == target) {
9821  if (index + 1 < mov->frag_index.nb_items)
9822  mov->next_root_atom = mov->frag_index.item[index + 1].moof_offset;
9823  if (mov->frag_index.item[index].headers_read)
9824  return 0;
9825  mov->frag_index.item[index].headers_read = 1;
9826  }
9827 
9828  mov->found_mdat = 0;
9829 
9830  ret = mov_read_default(mov, s->pb, (MOVAtom){ AV_RL32("root"), INT64_MAX });
9831  if (ret < 0)
9832  return ret;
9833  if (avio_feof(s->pb))
9834  return AVERROR_EOF;
9835  av_log(s, AV_LOG_TRACE, "read fragments, offset 0x%"PRIx64"\n", avio_tell(s->pb));
9836 
9837  return 1;
9838 }
9839 
9841 {
9842  MOVStreamContext *sc = st->priv_data;
9843  uint8_t *side, *extradata;
9844  int extradata_size;
9845 
9846  /* Save the current index. */
9847  sc->last_stsd_index = sc->stsc_data[sc->stsc_index].id - 1;
9848 
9849  /* Notify the decoder that extradata changed. */
9850  extradata_size = sc->extradata_size[sc->last_stsd_index];
9851  extradata = sc->extradata[sc->last_stsd_index];
9852  if (st->discard != AVDISCARD_ALL && extradata_size > 0 && extradata) {
9855  extradata_size);
9856  if (!side)
9857  return AVERROR(ENOMEM);
9858  memcpy(side, extradata, extradata_size);
9859  }
9860 
9861  return 0;
9862 }
9863 
9865 {
9866  int new_size, ret;
9867 
9868  if (size <= 8)
9869  return AVERROR_INVALIDDATA;
9870  new_size = ((size - 8) / 2) * 3;
9871  ret = av_new_packet(pkt, new_size);
9872  if (ret < 0)
9873  return ret;
9874 
9875  avio_skip(pb, 8);
9876  for (int j = 0; j < new_size; j += 3) {
9877  pkt->data[j] = 0xFC;
9878  pkt->data[j+1] = avio_r8(pb);
9879  pkt->data[j+2] = avio_r8(pb);
9880  }
9881 
9882  return 0;
9883 }
9884 
9886  int64_t current_index, AVPacket *pkt)
9887 {
9888  MOVStreamContext *sc = st->priv_data;
9889 
9890  pkt->stream_index = sc->ffindex;
9891  pkt->dts = sample->timestamp;
9892  if (sample->flags & AVINDEX_DISCARD_FRAME) {
9894  }
9895  if (sc->ctts_data && sc->ctts_index < sc->ctts_count) {
9897  /* update ctts context */
9898  sc->ctts_sample++;
9899  if (sc->ctts_index < sc->ctts_count &&
9900  sc->ctts_data[sc->ctts_index].count == sc->ctts_sample) {
9901  sc->ctts_index++;
9902  sc->ctts_sample = 0;
9903  }
9904  } else {
9905  int64_t next_dts = (sc->current_sample < ffstream(st)->nb_index_entries) ?
9907 
9908  if (next_dts >= pkt->dts)
9909  pkt->duration = next_dts - pkt->dts;
9910  pkt->pts = pkt->dts;
9911  }
9912 
9913  if (sc->sdtp_data && sc->current_sample <= sc->sdtp_count) {
9914  uint8_t sample_flags = sc->sdtp_data[sc->current_sample - 1];
9915  uint8_t sample_is_depended_on = (sample_flags >> 2) & 0x3;
9916  pkt->flags |= sample_is_depended_on == MOV_SAMPLE_DEPENDENCY_NO ? AV_PKT_FLAG_DISPOSABLE : 0;
9917  }
9918  pkt->flags |= sample->flags & AVINDEX_KEYFRAME ? AV_PKT_FLAG_KEY : 0;
9919  pkt->pos = sample->pos;
9920 
9921  /* Multiple stsd handling. */
9922  if (sc->stsc_data) {
9923  if (sc->stsc_data[sc->stsc_index].id > 0 &&
9924  sc->stsc_data[sc->stsc_index].id - 1 < sc->stsd_count &&
9925  sc->stsc_data[sc->stsc_index].id - 1 != sc->last_stsd_index) {
9926  int ret = mov_change_extradata(st, pkt);
9927  if (ret < 0)
9928  return ret;
9929  }
9930 
9931  /* Update the stsc index for the next sample */
9932  sc->stsc_sample++;
9933  if (mov_stsc_index_valid(sc->stsc_index, sc->stsc_count) &&
9934  mov_get_stsc_samples(sc, sc->stsc_index) == sc->stsc_sample) {
9935  sc->stsc_index++;
9936  sc->stsc_sample = 0;
9937  }
9938  }
9939 
9940  return 0;
9941 }
9942 
9944 {
9945  MOVContext *mov = s->priv_data;
9946  MOVStreamContext *sc;
9948  AVStream *st = NULL;
9949  int64_t current_index;
9950  int ret;
9951  mov->fc = s;
9952  retry:
9953  sample = mov_find_next_sample(s, &st);
9954  if (!sample || (mov->next_root_atom && sample->pos > mov->next_root_atom)) {
9955  if (!mov->next_root_atom)
9956  return AVERROR_EOF;
9957  if ((ret = mov_switch_root(s, mov->next_root_atom, -1)) < 0)
9958  return ret;
9959  goto retry;
9960  }
9961  sc = st->priv_data;
9962  /* must be done just before reading, to avoid infinite loop on sample */
9963  current_index = sc->current_index;
9965 
9966  if (mov->next_root_atom) {
9967  sample->pos = FFMIN(sample->pos, mov->next_root_atom);
9968  sample->size = FFMIN(sample->size, (mov->next_root_atom - sample->pos));
9969  }
9970 
9971  if (st->discard != AVDISCARD_ALL) {
9972  int64_t ret64 = avio_seek(sc->pb, sample->pos, SEEK_SET);
9973  if (ret64 != sample->pos) {
9974  av_log(mov->fc, AV_LOG_ERROR, "stream %d, offset 0x%"PRIx64": partial file\n",
9975  sc->ffindex, sample->pos);
9976  if (should_retry(sc->pb, ret64)) {
9978  } else if (ret64 < 0) {
9979  return (int)ret64;
9980  }
9981  return AVERROR_INVALIDDATA;
9982  }
9983 
9984  if (st->discard == AVDISCARD_NONKEY && !(sample->flags & AVINDEX_KEYFRAME)) {
9985  av_log(mov->fc, AV_LOG_DEBUG, "Nonkey frame from stream %d discarded due to AVDISCARD_NONKEY\n", sc->ffindex);
9986  goto retry;
9987  }
9988 
9989  if (st->codecpar->codec_id == AV_CODEC_ID_EIA_608 && sample->size > 8)
9990  ret = get_eia608_packet(sc->pb, pkt, sample->size);
9991 #if CONFIG_IAMFDEC
9992  else if (sc->iamf) {
9993  int64_t pts, dts, pos, duration;
9994  int flags, size = sample->size;
9995  ret = mov_finalize_packet(s, st, sample, current_index, pkt);
9996  pts = pkt->pts; dts = pkt->dts;
9997  pos = pkt->pos; flags = pkt->flags;
9998  duration = pkt->duration;
9999  while (!ret && size > 0) {
10000  ret = ff_iamf_read_packet(s, sc->iamf, sc->pb, size, pkt);
10001  if (ret < 0) {
10002  if (should_retry(sc->pb, ret))
10004  return ret;
10005  }
10006  size -= ret;
10007  pkt->pts = pts; pkt->dts = dts;
10008  pkt->pos = pos; pkt->flags |= flags;
10009  pkt->duration = duration;
10010  ret = ff_buffer_packet(s, pkt);
10011  }
10012  if (!ret)
10013  return FFERROR_REDO;
10014  }
10015 #endif
10016  else
10017  ret = av_get_packet(sc->pb, pkt, sample->size);
10018  if (ret < 0) {
10019  if (should_retry(sc->pb, ret)) {
10021  }
10022  return ret;
10023  }
10024 #if CONFIG_DV_DEMUXER
10025  if (mov->dv_demux && sc->dv_audio_container) {
10028  if (ret < 0)
10029  return ret;
10031  if (ret < 0)
10032  return ret;
10033  }
10034 #endif
10035  if (sc->has_palette) {
10036  uint8_t *pal;
10037 
10039  if (!pal) {
10040  av_log(mov->fc, AV_LOG_ERROR, "Cannot append palette to packet\n");
10041  } else {
10042  memcpy(pal, sc->palette, AVPALETTE_SIZE);
10043  sc->has_palette = 0;
10044  }
10045  }
10046  if (st->codecpar->codec_id == AV_CODEC_ID_MP3 && !ffstream(st)->need_parsing && pkt->size > 4) {
10047  if (ff_mpa_check_header(AV_RB32(pkt->data)) < 0)
10049  }
10050  }
10051 
10052  ret = mov_finalize_packet(s, st, sample, current_index, pkt);
10053  if (ret < 0)
10054  return ret;
10055 
10056  if (st->discard == AVDISCARD_ALL)
10057  goto retry;
10058 
10059  if (mov->aax_mode)
10060  aax_filter(pkt->data, pkt->size, mov);
10061 
10062  ret = cenc_filter(mov, st, sc, pkt, current_index);
10063  if (ret < 0) {
10064  return ret;
10065  }
10066 
10067  return 0;
10068 }
10069 
10070 static int mov_seek_fragment(AVFormatContext *s, AVStream *st, int64_t timestamp)
10071 {
10072  MOVContext *mov = s->priv_data;
10073  int index;
10074 
10075  if (!mov->frag_index.complete)
10076  return 0;
10077 
10078  index = search_frag_timestamp(s, &mov->frag_index, st, timestamp);
10079  if (index < 0)
10080  index = 0;
10081  if (!mov->frag_index.item[index].headers_read)
10082  return mov_switch_root(s, -1, index);
10083  if (index + 1 < mov->frag_index.nb_items)
10084  mov->next_root_atom = mov->frag_index.item[index + 1].moof_offset;
10085 
10086  return 0;
10087 }
10088 
10089 static int is_open_key_sample(const MOVStreamContext *sc, int sample)
10090 {
10091  // TODO: a bisect search would scale much better
10092  for (int i = 0; i < sc->open_key_samples_count; i++) {
10093  const int oks = sc->open_key_samples[i];
10094  if (oks == sample)
10095  return 1;
10096  if (oks > sample) /* list is monotically increasing so we can stop early */
10097  break;
10098  }
10099  return 0;
10100 }
10101 
10102 /*
10103  * Some key sample may be key frames but not IDR frames, so a random access to
10104  * them may not be allowed.
10105  */
10106 static int can_seek_to_key_sample(AVStream *st, int sample, int64_t requested_pts)
10107 {
10108  MOVStreamContext *sc = st->priv_data;
10109  FFStream *const sti = ffstream(st);
10110  int64_t key_sample_dts, key_sample_pts;
10111 
10112  if (st->codecpar->codec_id != AV_CODEC_ID_HEVC)
10113  return 1;
10114 
10115  if (sample >= sc->sample_offsets_count)
10116  return 1;
10117 
10118  key_sample_dts = sti->index_entries[sample].timestamp;
10119  key_sample_pts = key_sample_dts + sc->sample_offsets[sample] + sc->dts_shift;
10120 
10121  /*
10122  * If the sample needs to be presented before an open key sample, they may
10123  * not be decodable properly, even though they come after in decoding
10124  * order.
10125  */
10126  if (is_open_key_sample(sc, sample) && key_sample_pts > requested_pts)
10127  return 0;
10128 
10129  return 1;
10130 }
10131 
10132 static int mov_seek_stream(AVFormatContext *s, AVStream *st, int64_t timestamp, int flags)
10133 {
10134  MOVStreamContext *sc = st->priv_data;
10135  FFStream *const sti = ffstream(st);
10136  int sample, time_sample, ret;
10137  unsigned int i;
10138 
10139  // Here we consider timestamp to be PTS, hence try to offset it so that we
10140  // can search over the DTS timeline.
10141  timestamp -= (sc->min_corrected_pts + sc->dts_shift);
10142 
10143  ret = mov_seek_fragment(s, st, timestamp);
10144  if (ret < 0)
10145  return ret;
10146 
10147  for (;;) {
10148  sample = av_index_search_timestamp(st, timestamp, flags);
10149  av_log(s, AV_LOG_TRACE, "stream %d, timestamp %"PRId64", sample %d\n", st->index, timestamp, sample);
10150  if (sample < 0 && sti->nb_index_entries && timestamp < sti->index_entries[0].timestamp)
10151  sample = 0;
10152  if (sample < 0) /* not sure what to do */
10153  return AVERROR_INVALIDDATA;
10154 
10155  if (!sample || can_seek_to_key_sample(st, sample, timestamp))
10156  break;
10157  timestamp -= FFMAX(sc->min_sample_duration, 1);
10158  }
10159 
10161  av_log(s, AV_LOG_TRACE, "stream %d, found sample %d\n", st->index, sc->current_sample);
10162  /* adjust ctts index */
10163  if (sc->ctts_data) {
10164  time_sample = 0;
10165  for (i = 0; i < sc->ctts_count; i++) {
10166  int next = time_sample + sc->ctts_data[i].count;
10167  if (next > sc->current_sample) {
10168  sc->ctts_index = i;
10169  sc->ctts_sample = sc->current_sample - time_sample;
10170  break;
10171  }
10172  time_sample = next;
10173  }
10174  }
10175 
10176  /* adjust stsd index */
10177  if (sc->chunk_count) {
10178  time_sample = 0;
10179  for (i = 0; i < sc->stsc_count; i++) {
10180  int64_t next = time_sample + mov_get_stsc_samples(sc, i);
10181  if (next > sc->current_sample) {
10182  sc->stsc_index = i;
10183  sc->stsc_sample = sc->current_sample - time_sample;
10184  break;
10185  }
10186  av_assert0(next == (int)next);
10187  time_sample = next;
10188  }
10189  }
10190 
10191  return sample;
10192 }
10193 
10194 static int64_t mov_get_skip_samples(AVStream *st, int sample)
10195 {
10196  MOVStreamContext *sc = st->priv_data;
10197  FFStream *const sti = ffstream(st);
10198  int64_t first_ts = sti->index_entries[0].timestamp;
10199  int64_t ts = sti->index_entries[sample].timestamp;
10200  int64_t off;
10201 
10203  return 0;
10204 
10205  /* compute skip samples according to stream start_pad, seek ts and first ts */
10206  off = av_rescale_q(ts - first_ts, st->time_base,
10207  (AVRational){1, st->codecpar->sample_rate});
10208  return FFMAX(sc->start_pad - off, 0);
10209 }
10210 
10211 static int mov_read_seek(AVFormatContext *s, int stream_index, int64_t sample_time, int flags)
10212 {
10213  MOVContext *mc = s->priv_data;
10214  AVStream *st;
10215  FFStream *sti;
10216  int sample;
10217  int i;
10218 
10219  if (stream_index >= s->nb_streams)
10220  return AVERROR_INVALIDDATA;
10221 
10222  st = s->streams[stream_index];
10223  sti = ffstream(st);
10224  sample = mov_seek_stream(s, st, sample_time, flags);
10225  if (sample < 0)
10226  return sample;
10227 
10228  if (mc->seek_individually) {
10229  /* adjust seek timestamp to found sample timestamp */
10230  int64_t seek_timestamp = sti->index_entries[sample].timestamp;
10232 
10233  for (i = 0; i < s->nb_streams; i++) {
10234  AVStream *const st = s->streams[i];
10235  FFStream *const sti = ffstream(st);
10236  int64_t timestamp;
10237 
10238  if (stream_index == i)
10239  continue;
10240 
10241  timestamp = av_rescale_q(seek_timestamp, s->streams[stream_index]->time_base, st->time_base);
10242  sample = mov_seek_stream(s, st, timestamp, flags);
10243  if (sample >= 0)
10245  }
10246  } else {
10247  for (i = 0; i < s->nb_streams; i++) {
10248  MOVStreamContext *sc;
10249  st = s->streams[i];
10250  sc = st->priv_data;
10251  mov_current_sample_set(sc, 0);
10252  }
10253  while (1) {
10254  MOVStreamContext *sc;
10256  if (!entry)
10257  return AVERROR_INVALIDDATA;
10258  sc = st->priv_data;
10259  if (sc->ffindex == stream_index && sc->current_sample == sample)
10260  break;
10262  }
10263  }
10264  return 0;
10265 }
10266 
10267 #define OFFSET(x) offsetof(MOVContext, x)
10268 #define FLAGS AV_OPT_FLAG_VIDEO_PARAM | AV_OPT_FLAG_DECODING_PARAM
10269 static const AVOption mov_options[] = {
10270  {"use_absolute_path",
10271  "allow using absolute path when opening alias, this is a possible security issue",
10272  OFFSET(use_absolute_path), AV_OPT_TYPE_BOOL, {.i64 = 0},
10273  0, 1, FLAGS},
10274  {"seek_streams_individually",
10275  "Seek each stream individually to the closest point",
10276  OFFSET(seek_individually), AV_OPT_TYPE_BOOL, { .i64 = 1 },
10277  0, 1, FLAGS},
10278  {"ignore_editlist", "Ignore the edit list atom.", OFFSET(ignore_editlist), AV_OPT_TYPE_BOOL, {.i64 = 0},
10279  0, 1, FLAGS},
10280  {"advanced_editlist",
10281  "Modify the AVIndex according to the editlists. Use this option to decode in the order specified by the edits.",
10282  OFFSET(advanced_editlist), AV_OPT_TYPE_BOOL, {.i64 = 1},
10283  0, 1, FLAGS},
10284  {"ignore_chapters", "", OFFSET(ignore_chapters), AV_OPT_TYPE_BOOL, {.i64 = 0},
10285  0, 1, FLAGS},
10286  {"use_mfra_for",
10287  "use mfra for fragment timestamps",
10288  OFFSET(use_mfra_for), AV_OPT_TYPE_INT, {.i64 = FF_MOV_FLAG_MFRA_AUTO},
10290  .unit = "use_mfra_for"},
10291  {"auto", "auto", 0, AV_OPT_TYPE_CONST, {.i64 = FF_MOV_FLAG_MFRA_AUTO}, 0, 0,
10292  FLAGS, .unit = "use_mfra_for" },
10293  {"dts", "dts", 0, AV_OPT_TYPE_CONST, {.i64 = FF_MOV_FLAG_MFRA_DTS}, 0, 0,
10294  FLAGS, .unit = "use_mfra_for" },
10295  {"pts", "pts", 0, AV_OPT_TYPE_CONST, {.i64 = FF_MOV_FLAG_MFRA_PTS}, 0, 0,
10296  FLAGS, .unit = "use_mfra_for" },
10297  {"use_tfdt", "use tfdt for fragment timestamps", OFFSET(use_tfdt), AV_OPT_TYPE_BOOL, {.i64 = 1},
10298  0, 1, FLAGS},
10299  { "export_all", "Export unrecognized metadata entries", OFFSET(export_all),
10300  AV_OPT_TYPE_BOOL, { .i64 = 0 }, 0, 1, .flags = FLAGS },
10301  { "export_xmp", "Export full XMP metadata", OFFSET(export_xmp),
10302  AV_OPT_TYPE_BOOL, { .i64 = 0 }, 0, 1, .flags = FLAGS },
10303  { "activation_bytes", "Secret bytes for Audible AAX files", OFFSET(activation_bytes),
10305  { "audible_key", "AES-128 Key for Audible AAXC files", OFFSET(audible_key),
10307  { "audible_iv", "AES-128 IV for Audible AAXC files", OFFSET(audible_iv),
10309  { "audible_fixed_key", // extracted from libAAX_SDK.so and AAXSDKWin.dll files!
10310  "Fixed key used for handling Audible AAX files", OFFSET(audible_fixed_key),
10311  AV_OPT_TYPE_BINARY, {.str="77214d4b196a87cd520045fd20a51d67"},
10312  .flags = AV_OPT_FLAG_DECODING_PARAM },
10313  { "decryption_key", "The media decryption key (hex)", OFFSET(decryption_key), AV_OPT_TYPE_BINARY, .flags = AV_OPT_FLAG_DECODING_PARAM },
10314  { "enable_drefs", "Enable external track support.", OFFSET(enable_drefs), AV_OPT_TYPE_BOOL,
10315  {.i64 = 0}, 0, 1, FLAGS },
10316  { "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 },
10317  { "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 },
10318 
10319  { NULL },
10320 };
10321 
10322 static const AVClass mov_class = {
10323  .class_name = "mov,mp4,m4a,3gp,3g2,mj2",
10324  .item_name = av_default_item_name,
10325  .option = mov_options,
10326  .version = LIBAVUTIL_VERSION_INT,
10327 };
10328 
10330  .p.name = "mov,mp4,m4a,3gp,3g2,mj2",
10331  .p.long_name = NULL_IF_CONFIG_SMALL("QuickTime / MOV"),
10332  .p.priv_class = &mov_class,
10333  .p.extensions = "mov,mp4,m4a,3gp,3g2,mj2,psp,m4b,ism,ismv,isma,f4v,avif,heic,heif",
10335  .priv_data_size = sizeof(MOVContext),
10336  .flags_internal = FF_INFMT_FLAG_INIT_CLEANUP,
10337  .read_probe = mov_probe,
10342 };
avpriv_new_chapter
AVChapter * avpriv_new_chapter(AVFormatContext *s, int64_t id, AVRational time_base, int64_t start, int64_t end, const char *title)
Add a new chapter.
Definition: demux_utils.c:42
MOVStreamContext::ctts_allocated_size
unsigned int ctts_allocated_size
Definition: isom.h:181
item_name
item_name
Definition: libkvazaar.c:319
AV_CODEC_ID_PCM_S16LE
@ AV_CODEC_ID_PCM_S16LE
Definition: codec_id.h:328
mov_read_chpl
static int mov_read_chpl(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:575
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:6670
mov_read_meta
static int mov_read_meta(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:5208
AV_CODEC_ID_EIA_608
@ AV_CODEC_ID_EIA_608
Definition: codec_id.h:560
AV_PKT_DATA_DISPLAYMATRIX
@ AV_PKT_DATA_DISPLAYMATRIX
This side data contains a 3x3 transformation matrix describing an affine transformation that needs to...
Definition: packet.h:109
av_packet_unref
void av_packet_unref(AVPacket *pkt)
Wipe the packet.
Definition: packet.c:427
MOVContext::found_iloc
int found_iloc
'iloc' atom has been found
Definition: isom.h:297
AV_CODEC_ID_MACE6
@ AV_CODEC_ID_MACE6
Definition: codec_id.h:450
MOVFragmentStreamInfo::first_tfra_pts
int64_t first_tfra_pts
Definition: isom.h:136
ff_rfps_add_frame
int ff_rfps_add_frame(AVFormatContext *ic, AVStream *st, int64_t ts)
add frame for rfps calculation.
Definition: demux.c:2286
read_image_iovl
static int read_image_iovl(AVFormatContext *s, const HEIFGrid *grid, AVStreamGroupTileGrid *tile_grid)
Definition: mov.c:9369
AVMEDIA_TYPE_SUBTITLE
@ AVMEDIA_TYPE_SUBTITLE
Definition: avutil.h:204
AVIAMFSubmix::elements
AVIAMFSubmixElement ** elements
Array of submix elements.
Definition: iamf.h:552
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:186
AV_BPRINT_SIZE_UNLIMITED
#define AV_BPRINT_SIZE_UNLIMITED
MOV_TFHD_DEFAULT_FLAGS
#define MOV_TFHD_DEFAULT_FLAGS
Definition: isom.h:377
PUT_UTF8
#define PUT_UTF8(val, tmp, PUT_BYTE)
Definition: common.h:526
AV_TIMECODE_STR_SIZE
#define AV_TIMECODE_STR_SIZE
Definition: timecode.h:33
av_aes_init
int av_aes_init(AVAES *a, const uint8_t *key, int key_bits, int decrypt)
Initialize an AVAES context.
Definition: aes.c:201
AV_CODEC_ID_PCM_F32BE
@ AV_CODEC_ID_PCM_F32BE
Definition: codec_id.h:348
FFStream::skip_samples
int skip_samples
Number of samples to skip at the start of the frame decoded from the next packet.
Definition: internal.h:273
MOVStreamContext::audio_cid
int16_t audio_cid
stsd audio compression id
Definition: isom.h:211
AVMasteringDisplayMetadata::max_luminance
AVRational max_luminance
Max luminance of mastering display (cd/m^2).
Definition: mastering_display_metadata.h:57
AVSphericalProjection
AVSphericalProjection
Projection of the video surface(s) on a sphere.
Definition: spherical.h:47
AV_CODEC_ID_ADPCM_MS
@ AV_CODEC_ID_ADPCM_MS
Definition: codec_id.h:373
AVCodecParameters::extradata
uint8_t * extradata
Extra binary data needed for initializing the decoder, codec-dependent.
Definition: codec_par.h:69
mov_read_dops
static int mov_read_dops(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:7733
can_seek_to_key_sample
static int can_seek_to_key_sample(AVStream *st, int sample, int64_t requested_pts)
Definition: mov.c:10106
AV_CODEC_ID_ADPCM_IMA_QT
@ AV_CODEC_ID_ADPCM_IMA_QT
Definition: codec_id.h:367
entry
#define entry
Definition: aom_film_grain_template.c:66
AVFMT_NO_BYTE_SEEK
#define AVFMT_NO_BYTE_SEEK
Format does not allow seeking by bytes.
Definition: avformat.h:487
AV_EF_EXPLODE
#define AV_EF_EXPLODE
abort decoding on minor error detection
Definition: defs.h:51
AVStreamGroup::id
int64_t id
Group type-specific group ID.
Definition: avformat.h:1109
AV_CODEC_ID_AC3
@ AV_CODEC_ID_AC3
Definition: codec_id.h:443
HEIFItem::name
char * name
Definition: isom.h:274
MOVStreamContext::sync_group
MOVSbgp * sync_group
Definition: isom.h:229
MOVStreamContext::height
int height
tkhd height
Definition: isom.h:217
MOVContext::moov_retry
int moov_retry
Definition: isom.h:325
MOV_TRUN_SAMPLE_FLAGS
#define MOV_TRUN_SAMPLE_FLAGS
Definition: isom.h:385
AV_PKT_DATA_AMBIENT_VIEWING_ENVIRONMENT
@ AV_PKT_DATA_AMBIENT_VIEWING_ENVIRONMENT
Ambient viewing environment metadata, as defined by H.274.
Definition: packet.h:331
MOVContext::nb_chapter_tracks
unsigned int nb_chapter_tracks
Definition: isom.h:313
mix
static int mix(int c0, int c1)
Definition: 4xm.c:716
MOVStreamContext::last_stsd_index
int last_stsd_index
Definition: isom.h:244
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:398
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:1125
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:82
AV_WL32
#define AV_WL32(p, v)
Definition: intreadwrite.h:424
MOVStreamContext::extradata
uint8_t ** extradata
extradata array (and size) for multiple stsd
Definition: isom.h:242
mov_class
static const AVClass mov_class
Definition: mov.c:10322
AVSphericalMapping::bound_bottom
uint32_t bound_bottom
Distance from the bottom edge.
Definition: spherical.h:166
MOVStreamContext::open_key_samples
int * open_key_samples
Definition: isom.h:234
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:198
mov_read_targa_y216
static int mov_read_targa_y216(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:2118
mov_read_chnl
static int mov_read_chnl(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:1164
mov_read_moof
static int mov_read_moof(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:1672
av_bprint_init
void av_bprint_init(AVBPrint *buf, unsigned size_init, unsigned size_max)
Definition: bprint.c:69
cb
static double cb(void *priv, double x, double y)
Definition: vf_geq.c:242
ctype
#define ctype
Definition: afir_template.c:47
AVCodecParameters
This struct describes the properties of an encoded stream.
Definition: codec_par.h:47
AVFMT_FLAG_IGNIDX
#define AVFMT_FLAG_IGNIDX
Ignore index.
Definition: avformat.h:1408
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:9150
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:768
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:814
AV_FIELD_PROGRESSIVE
@ AV_FIELD_PROGRESSIVE
Definition: defs.h:200
mov_options
static const AVOption mov_options[]
Definition: mov.c:10269
mov_codec_id
static int mov_codec_id(AVStream *st, uint32_t format)
Definition: mov.c:2443
AV_PKT_DATA_MASTERING_DISPLAY_METADATA
@ AV_PKT_DATA_MASTERING_DISPLAY_METADATA
Mastering display metadata (based on SMPTE-2086:2014).
Definition: packet.h:223
MOVStreamContext::sample_offsets
int32_t * sample_offsets
Definition: isom.h:232
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:8073
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:586
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
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:2090
test_same_origin
static int test_same_origin(const char *src, const char *ref)
Definition: mov.c:4705
cbcs_scheme_decrypt
static int cbcs_scheme_decrypt(MOVContext *c, MOVStreamContext *sc, AVEncryptionInfo *sample, uint8_t *input, int size)
Definition: mov.c:7560
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:354
ambisonic_order
static int ambisonic_order(const AVChannelLayout *channel_layout)
If the layout is n-th order standard-order ambisonic, with optional extra non-diegetic channels at th...
Definition: channel_layout.c:481
MOVStreamContext::stsc_data
MOVStsc * stsc_data
Definition: isom.h:184
ff_buffer_packet
int ff_buffer_packet(AVFormatContext *s, AVPacket *pkt)
Definition: demux.c:609
IS_MATRIX_IDENT
#define IS_MATRIX_IDENT(matrix)
Definition: mov.c:5226
AVStreamGroup::disposition
int disposition
Stream group disposition - a combination of AV_DISPOSITION_* flags.
Definition: avformat.h:1166
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:3475
MOVStreamContext::spherical
AVSphericalMapping * spherical
Definition: isom.h:250
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:2095
MOVContext::primary_item_id
int primary_item_id
Definition: isom.h:350
MOVContext::found_moov
int found_moov
'moov' atom has been found
Definition: isom.h:296
mov_read_custom
static int mov_read_custom(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:5070
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:1323
HEIFGrid::nb_tiles
int nb_tiles
Definition: isom.h:288
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:375
mov_read_extradata
static int mov_read_extradata(MOVContext *c, AVIOContext *pb, MOVAtom atom, enum AVCodecID codec_id)
Definition: mov.c:2064
AVCOL_RANGE_JPEG
@ AVCOL_RANGE_JPEG
Full range content.
Definition: pixfmt.h:686
mpegaudiodecheader.h
MOVStreamContext::rap_group_count
unsigned int rap_group_count
Definition: isom.h:226
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:280
mov_read_mvhd
static int mov_read_mvhd(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:1774
mov_read_idat
static int mov_read_idat(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:8067
AVPacket::data
uint8_t * data
Definition: packet.h:524
MOVContext::found_mdat
int found_mdat
'mdat' atom has been found
Definition: isom.h:299
MOVStreamContext::drefs_count
unsigned drefs_count
Definition: isom.h:212
AVEncryptionInfo::crypt_byte_block
uint32_t crypt_byte_block
Only used for pattern encryption.
Definition: encryption_info.h:51
AV_PKT_DATA_ENCRYPTION_INIT_INFO
@ AV_PKT_DATA_ENCRYPTION_INIT_INFO
This side data is encryption initialization data.
Definition: packet.h:250
mov_read_avid
static int mov_read_avid(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:2110
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:357
MOVContext::trex_data
MOVTrackExt * trex_data
Definition: isom.h:308
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:3152
MOVContext::bitrates
int * bitrates
bitrates read before streams creation
Definition: isom.h:323
b
#define b
Definition: input.c:41
AVCOL_TRC_UNSPECIFIED
@ AVCOL_TRC_UNSPECIFIED
Definition: pixfmt.h:583
MOVContext::interleaved_read
int interleaved_read
Definition: isom.h:358
mov_read_tkhd
static int mov_read_tkhd(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:5234
MOVElst::rate
float rate
Definition: isom.h:76
AVStream::avg_frame_rate
AVRational avg_frame_rate
Average framerate.
Definition: avformat.h:832
table
static const uint16_t table[]
Definition: prosumer.c:205
spherical.h
mov_read_colr
static int mov_read_colr(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:1928
data
const char data[16]
Definition: mxf.c:148
set_last_stream_little_endian
static void set_last_stream_little_endian(AVFormatContext *fc)
Definition: mov.c:1813
mov_read_strf
static int mov_read_strf(MOVContext *c, AVIOContext *pb, MOVAtom atom)
An strf atom is a BITMAPINFOHEADER struct.
Definition: mov.c:2356
AV_CODEC_ID_ALAC
@ AV_CODEC_ID_ALAC
Definition: codec_id.h:456
HEIFItem::st
AVStream * st
Definition: isom.h:273
yuv_to_rgba
static uint32_t yuv_to_rgba(uint32_t ycbcr)
Definition: mov.c:2674
FF_COMPLIANCE_STRICT
#define FF_COMPLIANCE_STRICT
Strictly conform to all the things in the spec no matter what consequences.
Definition: defs.h:59
AVIOContext::error
int error
contains the error code or 0 if no error happened
Definition: avio.h:239
AV_CODEC_ID_AMR_NB
@ AV_CODEC_ID_AMR_NB
Definition: codec_id.h:421
av_iamf_mix_presentation_free
void av_iamf_mix_presentation_free(AVIAMFMixPresentation **pmix_presentation)
Free an AVIAMFMixPresentation and all its contents.
Definition: iamf.c:534
mov_parse_auxiliary_info
static int mov_parse_auxiliary_info(MOVContext *c, MOVStreamContext *sc, AVIOContext *pb, MOVEncryptionIndex *encryption_index)
Definition: mov.c:6878
mov_seek_stream
static int mov_seek_stream(AVFormatContext *s, AVStream *st, int64_t timestamp, int flags)
Definition: mov.c:10132
mov_read_saio
static int mov_read_saio(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:7024
mov_get_stsc_samples
static int64_t mov_get_stsc_samples(MOVStreamContext *sc, unsigned int index)
Definition: mov.c:3137
ff_get_wav_header
int ff_get_wav_header(void *logctx, AVIOContext *pb, AVCodecParameters *par, int size, int big_endian)
Definition: riffdec.c:95
AV_LOG_VERBOSE
#define AV_LOG_VERBOSE
Detailed information.
Definition: log.h:196
ff_codec_wav_tags
const AVCodecTag ff_codec_wav_tags[]
Definition: riff.c:519
get_edit_list_entry
static int get_edit_list_entry(MOVContext *mov, const MOVStreamContext *msc, unsigned int edit_list_index, int64_t *edit_list_media_time, int64_t *edit_list_duration, int64_t global_timescale)
Get ith edit list entry (media time, duration).
Definition: mov.c:3669
MOVFragmentIndexItem::moof_offset
int64_t moof_offset
Definition: isom.h:147
MOVStreamContext::spherical_size
size_t spherical_size
Definition: isom.h:251
mov_change_extradata
static int mov_change_extradata(AVStream *st, AVPacket *pkt)
Definition: mov.c:9840
fc
#define fc(width, name, range_min, range_max)
Definition: cbs_av1.c:464
MP4TrackKindMapping::scheme_uri
const char * scheme_uri
Definition: isom.h:459
AVINDEX_DISCARD_FRAME
#define AVINDEX_DISCARD_FRAME
Definition: avformat.h:611
AVPacket::duration
int64_t duration
Duration of this packet in AVStream->time_base units, 0 if unknown.
Definition: packet.h:542
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
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:3973
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:598
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:308
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:1031
iamf_parse.h
mov_read_moov
static int mov_read_moov(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:1426
FFNABS
#define FFNABS(a)
Negative Absolute value.
Definition: common.h:82
cffstream
static const av_always_inline FFStream * cffstream(const AVStream *st)
Definition: internal.h:422
mov_read_esds
static int mov_read_esds(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:824
MOVStreamContext::sample_count
unsigned int sample_count
Definition: isom.h:195
MOVTrackExt::flags
unsigned flags
Definition: isom.h:112
AVChannelLayout::nb_channels
int nb_channels
Number of channels in this layout.
Definition: channel_layout.h:313
HEIFItem::height
int height
Definition: isom.h:279
AV_SPHERICAL_EQUIRECTANGULAR
@ AV_SPHERICAL_EQUIRECTANGULAR
Video represents a sphere mapped on a flat surface using equirectangular projection.
Definition: spherical.h:52
intfloat.h
id3v1.h
MOVStreamContext::ctts_data
MOVCtts * ctts_data
Definition: isom.h:182
AV_CODEC_ID_R10K
@ AV_CODEC_ID_R10K
Definition: codec_id.h:197
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
MOVContext::advanced_editlist_autodisabled
int advanced_editlist_autodisabled
Definition: isom.h:317
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:2378
FFIOContext
Definition: avio_internal.h:28
AV_PKT_FLAG_KEY
#define AV_PKT_FLAG_KEY
The packet contains a keyframe.
Definition: packet.h:579
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:262
cenc_filter
static int cenc_filter(MOVContext *mov, AVStream *st, MOVStreamContext *sc, AVPacket *pkt, int current_index)
Definition: mov.c:7667
mov_read_sdtp
static int mov_read_sdtp(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:3441
mov_read_jp2h
static int mov_read_jp2h(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:2100
AVIndexEntry
Definition: avformat.h:602
AV_WB64
#define AV_WB64(p, v)
Definition: intreadwrite.h:431
MOVStreamContext::dv_audio_container
int dv_audio_container
Definition: isom.h:209
AV_CODEC_ID_AMR_WB
@ AV_CODEC_ID_AMR_WB
Definition: codec_id.h:422
mov_read_tfhd
static int mov_read_tfhd(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:5339
AV_CODEC_ID_BIN_DATA
@ AV_CODEC_ID_BIN_DATA
Definition: codec_id.h:590
av_malloc
#define av_malloc(s)
Definition: tableprint_vlc.h:30
OPUS_SEEK_PREROLL_MS
#define OPUS_SEEK_PREROLL_MS
Definition: oggparseopus.c:36
AV_CODEC_ID_H261
@ AV_CODEC_ID_H261
Definition: codec_id.h:55
IAMFMixPresentation::cmix
const AVIAMFMixPresentation * cmix
Definition: iamf.h:108
mov_read_wide
static int mov_read_wide(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:5917
AVINDEX_KEYFRAME
#define AVINDEX_KEYFRAME
Definition: avformat.h:610
AV_FIELD_BT
@ AV_FIELD_BT
Bottom coded first, top displayed first.
Definition: defs.h:204
MOVStreamContext::stsd_count
int stsd_count
Definition: isom.h:245
ff_mov_lang_to_iso639
int ff_mov_lang_to_iso639(unsigned code, char to[4])
Definition: isom.c:260
ff_generate_avci_extradata
int ff_generate_avci_extradata(AVStream *st)
Generate standard extradata for AVC-Intra based on width/height and field order.
Definition: demux_utils.c:200
ff_get_extradata
int ff_get_extradata(void *logctx, AVCodecParameters *par, AVIOContext *pb, int size)
Allocate extradata with additional AV_INPUT_BUFFER_PADDING_SIZE at end which is always set to 0 and f...
Definition: demux_utils.c:335
skip_bits
static void skip_bits(GetBitContext *s, int n)
Definition: get_bits.h:381
AVCodecParameters::color_primaries
enum AVColorPrimaries color_primaries
Definition: codec_par.h:167
AVEncryptionInfo::scheme
uint32_t scheme
The fourcc encryption scheme, in big-endian byte order.
Definition: encryption_info.h:45
MOVStreamContext::stsc_count
unsigned int stsc_count
Definition: isom.h:183
MOVStreamContext::has_palette
int has_palette
Definition: isom.h:220
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:377
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:114
OFFSET
#define OFFSET(x)
Definition: mov.c:10267
HEIFGrid::tile_item_list
HEIFItem ** tile_item_list
Definition: isom.h:286
AV_FIELD_TT
@ AV_FIELD_TT
Top coded_first, top displayed first.
Definition: defs.h:201
ff_iamf_read_packet
int ff_iamf_read_packet(AVFormatContext *s, IAMFDemuxContext *c, AVIOContext *pb, int max_size, AVPacket *pkt)
Definition: iamf_reader.c:267
MOVStreamContext::nb_frames_for_fps
int nb_frames_for_fps
Definition: isom.h:238
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:853
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:373
aax_filter
static int aax_filter(uint8_t *input, int size, MOVContext *c)
Definition: mov.c:1364
AV_OPT_TYPE_BINARY
@ AV_OPT_TYPE_BINARY
offset must point to a pointer immediately followed by an int for the length
Definition: opt.h:251
av_color_space_name
const char * av_color_space_name(enum AVColorSpace space)
Definition: pixdesc.c:3341
av_packet_add_side_data
int av_packet_add_side_data(AVPacket *pkt, enum AVPacketSideDataType type, uint8_t *data, size_t size)
Wrap an existing array as a packet side data.
Definition: packet.c:197
MOVStreamContext::mastering
AVMasteringDisplayMetadata * mastering
Definition: isom.h:252
AV_CODEC_ID_SPEEX
@ AV_CODEC_ID_SPEEX
Definition: codec_id.h:475
AV_FOURCC_MAX_STRING_SIZE
#define AV_FOURCC_MAX_STRING_SIZE
Definition: avutil.h:343
AV_PKT_DATA_PALETTE
@ AV_PKT_DATA_PALETTE
An AV_PKT_DATA_PALETTE side data packet contains exactly AVPALETTE_SIZE bytes worth of palette.
Definition: packet.h:47
ffstream
static av_always_inline FFStream * ffstream(AVStream *st)
Definition: internal.h:417
MOVFragmentIndexItem::current
int current
Definition: isom.h:149
AVFMT_SEEK_TO_PTS
#define AVFMT_SEEK_TO_PTS
Seeking is based on PTS.
Definition: avformat.h:503
AV_CODEC_ID_PCM_S16BE
@ AV_CODEC_ID_PCM_S16BE
Definition: codec_id.h:329
mov_read_mdhd
static int mov_read_mdhd(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:1728
mov_read_ctts
static int mov_read_ctts(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:3486
MOVTrackExt
Definition: isom.h:107
MOV_FRAG_SAMPLE_FLAG_IS_NON_SYNC
#define MOV_FRAG_SAMPLE_FLAG_IS_NON_SYNC
Definition: isom.h:389
fail
#define fail()
Definition: checkasm.h:181
mov_read_aclr
static int mov_read_aclr(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:2175
AVSEEK_FLAG_ANY
#define AVSEEK_FLAG_ANY
seek to any frame, even non-keyframes
Definition: avformat.h:2447
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:982
MOVContext::decryption_key
uint8_t * decryption_key
Definition: isom.h:343
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:275
timecode.h
get_current_frag_stream_info
static MOVFragmentStreamInfo * get_current_frag_stream_info(MOVFragmentIndex *frag_index)
Definition: mov.c:1483
MOVStreamContext::ctts_index
int ctts_index
Definition: isom.h:191
GetBitContext
Definition: get_bits.h:108
av_timecode_make_string
char * av_timecode_make_string(const AVTimecode *tc, char *buf, int framenum)
Load timecode string in buf.
Definition: timecode.c:103
rb_size
static int rb_size(AVIOContext *pb, uint64_t *value, int size)
Definition: mov.c:8042
AVStreamGroupTileGrid::coded_width
int coded_width
Width of the canvas.
Definition: avformat.h:997
av_iamf_audio_element_free
void av_iamf_audio_element_free(AVIAMFAudioElement **paudio_element)
Free an AVIAMFAudioElement and all its contents.
Definition: iamf.c:336
FFStream::index_entries_allocated_size
unsigned int index_entries_allocated_size
Definition: internal.h:252
read_close
static av_cold int read_close(AVFormatContext *ctx)
Definition: libcdio.c:143
mov_read_amve
static int mov_read_amve(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:6271
mov_read_enda
static int mov_read_enda(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:1842
mov_read_chap
static int mov_read_chap(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:5386
MOVParseTableEntry
Definition: mov.c:80
avio_tell
static av_always_inline int64_t avio_tell(AVIOContext *s)
ftell() equivalent for AVIOContext.
Definition: avio.h:494
MOV_TRUN_SAMPLE_DURATION
#define MOV_TRUN_SAMPLE_DURATION
Definition: isom.h:383
val
static double val(void *priv, double ch)
Definition: aeval.c:78
MOVCtts::duration
int duration
Definition: isom.h:64
type
it s the only field you need to keep assuming you have a context There is some magic you don t need to care about around this just let it vf type
Definition: writing_filters.txt:86
MOVContext
Definition: isom.h:291
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:1003
pts
static int64_t pts
Definition: transcode_aac.c:644
AVEncryptionInfo::iv
uint8_t * iv
The initialization vector.
Definition: encryption_info.h:71
AV_CODEC_ID_MP3
@ AV_CODEC_ID_MP3
preferred ID for decoding MPEG audio layer 1, 2 or 3
Definition: codec_id.h:441
AVStream::duration
int64_t duration
Decoding: duration of the stream, in stream time base.
Definition: avformat.h:802
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:216
MOVContext::meta_keys
char ** meta_keys
Definition: isom.h:302
MOVStreamContext::extradata_size
int * extradata_size
Definition: isom.h:243
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
AVIAMFAudioElement::audio_element_type
enum AVIAMFAudioElementType audio_element_type
Audio element type as defined in section 3.6 of IAMF.
Definition: iamf.h:379
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:456
update_frag_index
static int update_frag_index(MOVContext *c, int64_t offset)
Definition: mov.c:1596
AVRational::num
int num
Numerator.
Definition: rational.h:59
MOVStreamContext::keyframes
int * keyframes
Definition: isom.h:199
MOVEncryptionIndex::auxiliary_info_sample_count
size_t auxiliary_info_sample_count
Definition: isom.h:127
AV_FIELD_TB
@ AV_FIELD_TB
Top coded first, bottom displayed first.
Definition: defs.h:203
AVStream::attached_pic
AVPacket attached_pic
For streams with AV_DISPOSITION_ATTACHED_PIC disposition, this packet will contain the attached pictu...
Definition: avformat.h:841
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:6940
MOV_FRAG_SAMPLE_FLAG_DEPENDS_YES
#define MOV_FRAG_SAMPLE_FLAG_DEPENDS_YES
Definition: isom.h:396
MOVContext::idat_offset
int64_t idat_offset
Definition: isom.h:357
MOV_TRUN_DATA_OFFSET
#define MOV_TRUN_DATA_OFFSET
Definition: isom.h:381
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:24
AV_DICT_DONT_STRDUP_VAL
#define AV_DICT_DONT_STRDUP_VAL
Take ownership of a value that's been allocated with av_malloc() or another memory allocation functio...
Definition: dict.h:79
IAMFAudioElement::element
AVIAMFAudioElement * element
element backs celement iff the AVIAMFAudioElement is owned by this structure.
Definition: iamf.h:95
MOVStreamContext::elst_data
MOVElst * elst_data
Definition: isom.h:189
mov_read_ares
static int mov_read_ares(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:2132
mov_read_adrm
static int mov_read_adrm(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:1240
av_get_bits_per_sample
int av_get_bits_per_sample(enum AVCodecID codec_id)
Return codec bits per sample.
Definition: utils.c:547
AVCodecParameters::color_trc
enum AVColorTransferCharacteristic color_trc
Definition: codec_par.h:168
IAMFContext::audio_elements
IAMFAudioElement ** audio_elements
Definition: iamf.h:131
MOVFragmentIndex::complete
int complete
Definition: isom.h:156
AV_CODEC_ID_PCM_S8
@ AV_CODEC_ID_PCM_S8
Definition: codec_id.h:332
avassert.h
avio_rb32
unsigned int avio_rb32(AVIOContext *s)
Definition: aviobuf.c:761
AV_LOG_TRACE
#define AV_LOG_TRACE
Extremely verbose debugging, useful for libav* development.
Definition: log.h:206
MOVStreamContext::stsc_sample
int stsc_sample
Definition: isom.h:186
pkt
AVPacket * pkt
Definition: movenc.c:60
AV_LOG_ERROR
#define AV_LOG_ERROR
Something went wrong and cannot losslessly be recovered.
Definition: log.h:180
AV_CODEC_ID_MACE3
@ AV_CODEC_ID_MACE3
Definition: codec_id.h:449
MOVTrackExt::track_id
unsigned track_id
Definition: isom.h:108
mov_free_encryption_index
static void mov_free_encryption_index(MOVEncryptionIndex **index)
Definition: mov.c:9029
AV_CH_LOW_FREQUENCY
#define AV_CH_LOW_FREQUENCY
Definition: channel_layout.h:171
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:199
MOVStreamContext::dts_shift
int dts_shift
dts shift when ctts is negative
Definition: isom.h:218
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:221
mask
static const uint16_t mask[17]
Definition: lzw.c:38
AVCodecParameters::frame_size
int frame_size
Audio only.
Definition: codec_par.h:195
avio_get_str16le
int avio_get_str16le(AVIOContext *pb, int maxlen, char *buf, int buflen)
Read a UTF-16 string from pb and convert it to UTF-8.
mov_metadata_track_or_disc_number
static int mov_metadata_track_or_disc_number(MOVContext *c, AVIOContext *pb, unsigned len, const char *key)
Definition: mov.c:91
av_dict_get
AVDictionaryEntry * av_dict_get(const AVDictionary *m, const char *key, const AVDictionaryEntry *prev, int flags)
Get a dictionary entry with matching key.
Definition: dict.c:62
AES_CTR_KEY_SIZE
#define AES_CTR_KEY_SIZE
Definition: aes_ctr.h:35
MOVStreamContext::stsd_version
int stsd_version
Definition: isom.h:246
AV_STREAM_GROUP_PARAMS_IAMF_MIX_PRESENTATION
@ AV_STREAM_GROUP_PARAMS_IAMF_MIX_PRESENTATION
Definition: avformat.h:1083
ff_add_attached_pic
int ff_add_attached_pic(AVFormatContext *s, AVStream *st, AVIOContext *pb, AVBufferRef **buf, int size)
Add an attached pic to an AVStream.
Definition: demux_utils.c:116
av_fast_realloc
void * av_fast_realloc(void *ptr, unsigned int *size, size_t min_size)
Reallocate the given buffer if it is not large enough, otherwise do nothing.
Definition: mem.c:497
FF_MOV_FLAG_MFRA_PTS
#define FF_MOV_FLAG_MFRA_PTS
Definition: isom.h:432
width
#define width
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:6205
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:4862
IAMFSubStream::audio_substream_id
unsigned int audio_substream_id
Definition: iamf.h:83
MOVContext::fc
AVFormatContext * fc
Definition: isom.h:293
MOV_TFHD_DEFAULT_BASE_IS_MOOF
#define MOV_TFHD_DEFAULT_BASE_IS_MOOF
Definition: isom.h:379
av_new_packet
int av_new_packet(AVPacket *pkt, int size)
Allocate the payload of a packet and initialize its fields with default values.
Definition: packet.c:98
AV_CODEC_ID_BMP
@ AV_CODEC_ID_BMP
Definition: codec_id.h:130
AV_CODEC_ID_EVC
@ AV_CODEC_ID_EVC
Definition: codec_id.h:321
IAMFLayer::substream_count
unsigned int substream_count
Definition: iamf.h:78
MOV_TFHD_DEFAULT_DURATION
#define MOV_TFHD_DEFAULT_DURATION
Definition: isom.h:375
ALAC_EXTRADATA_SIZE
#define ALAC_EXTRADATA_SIZE
DRM_BLOB_SIZE
#define DRM_BLOB_SIZE
Definition: mov.c:1238
MOVStreamContext::sample_offsets_count
int sample_offsets_count
Definition: isom.h:233
MOVCtts::count
unsigned int count
Definition: isom.h:63
MOVStreamContext::drefs
MOVDref * drefs
Definition: isom.h:213
av_realloc_array
void * av_realloc_array(void *ptr, size_t nmemb, size_t size)
Definition: mem.c:217
format
Filter the word “frame” indicates either a video frame or a group of audio as stored in an AVFrame structure Format for each input and each output the list of supported formats For video that means pixel format For audio that means channel sample format(the sample packing is implied by the sample format) and sample rate. The lists are not just lists
AVInputFormat::name
const char * name
A comma separated list of short names for the format.
Definition: avformat.h:553
MOVContext::aes_decrypt
struct AVAES * aes_decrypt
Definition: isom.h:342
g
const char * g
Definition: vf_curves.c:128
AVProbeData::buf
unsigned char * buf
Buffer must have AVPROBE_PADDING_SIZE of extra allocated bytes filled with zero.
Definition: avformat.h:453
AVSphericalMapping::bound_top
uint32_t bound_top
Distance from the top edge.
Definition: spherical.h:164
AVMEDIA_TYPE_AUDIO
@ AVMEDIA_TYPE_AUDIO
Definition: avutil.h:202
AV_CODEC_ID_VP9
@ AV_CODEC_ID_VP9
Definition: codec_id.h:220
MOVFragmentIndex::nb_items
int nb_items
Definition: isom.h:158
AVCodecParameters::width
int width
Video only.
Definition: codec_par.h:134
AV_CHANNEL_ORDER_UNSPEC
@ AV_CHANNEL_ORDER_UNSPEC
Only the channel count is specified, without any further information about the channel order.
Definition: channel_layout.h:112
AV_CODEC_ID_MP2
@ AV_CODEC_ID_MP2
Definition: codec_id.h:440
MOV_TRUN_FIRST_SAMPLE_FLAGS
#define MOV_TRUN_FIRST_SAMPLE_FLAGS
Definition: isom.h:382
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:243
MOVStreamContext::keyframe_absent
int keyframe_absent
Definition: isom.h:197
info
MIPS optimizations info
Definition: mips.txt:2
MOVStts::duration
unsigned int duration
Definition: isom.h:59
MOVStreamContext::coll_size
size_t coll_size
Definition: isom.h:254
tile_rows
int tile_rows
Definition: h265_levels.c:217
av_mastering_display_metadata_alloc
AVMasteringDisplayMetadata * av_mastering_display_metadata_alloc(void)
Copyright (c) 2016 Neil Birkbeck neil.birkbeck@gmail.com
Definition: mastering_display_metadata.c:28
mov_estimate_video_delay
static void mov_estimate_video_delay(MOVContext *c, AVStream *st)
Definition: mov.c:3893
AVIndexEntry::timestamp
int64_t timestamp
Timestamp in AVStream.time_base units, preferably the time from which on correctly decoded frames are...
Definition: avformat.h:604
av_assert0
#define av_assert0(cond)
assert() equivalent, that is always enabled.
Definition: avassert.h:40
MOVStreamContext::min_corrected_pts
int64_t min_corrected_pts
minimum Composition time shown by the edits excluding empty edits.
Definition: isom.h:202
ffio_read_leb
unsigned int ffio_read_leb(AVIOContext *s)
Read a unsigned integer coded as a variable number of up to eight little-endian bytes,...
Definition: aviobuf.c:927
tile_cols
int tile_cols
Definition: av1_levels.c:73
MOVStreamContext::sdtp_count
unsigned int sdtp_count
Definition: isom.h:178
AV_LOG_DEBUG
#define AV_LOG_DEBUG
Stuff which is only useful for libav* developers.
Definition: log.h:201
AVPacketSideData::data
uint8_t * data
Definition: packet.h:376
ctx
AVFormatContext * ctx
Definition: movenc.c:49
get_bits.h
limits.h
mov_read_sidx
static int mov_read_sidx(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:5779
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:115
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:1041
FFStream::display_aspect_ratio
AVRational display_aspect_ratio
display aspect ratio (0 if unknown)
Definition: internal.h:368
IAMFContext::nb_mix_presentations
int nb_mix_presentations
Definition: iamf.h:134
mov_find_next_sample
static AVIndexEntry * mov_find_next_sample(AVFormatContext *s, AVStream **st)
Definition: mov.c:9767
AV_CODEC_ID_TARGA_Y216
@ AV_CODEC_ID_TARGA_Y216
Definition: codec_id.h:256
AVIndexEntry::min_distance
int min_distance
Minimum distance between this and the previous keyframe, used to avoid unneeded searching.
Definition: avformat.h:614
mov_read_dvcc_dvvc
static int mov_read_dvcc_dvvc(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:7817
MOVParseTableEntry::parse
int(* parse)(MOVContext *ctx, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:82
codec_id
enum AVCodecID codec_id
Definition: vaapi_decode.c:387
AV_CODEC_ID_SVQ3
@ AV_CODEC_ID_SVQ3
Definition: codec_id.h:75
key
const char * key
Definition: hwcontext_opencl.c:189
AVCodecParameters::nb_coded_side_data
int nb_coded_side_data
Amount of entries in coded_side_data.
Definition: codec_par.h:86
MOVStreamContext::sdtp_data
uint8_t * sdtp_data
Definition: isom.h:179
color_range
color_range
Definition: vf_selectivecolor.c:43
AVMEDIA_TYPE_DATA
@ AVMEDIA_TYPE_DATA
Opaque data information usually continuous.
Definition: avutil.h:203
mov_read_udta_string
static int mov_read_udta_string(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:329
mov_read_stss
static int mov_read_stss(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:3188
mov_read_ddts
static int mov_read_ddts(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:1092
mov_read_uuid
static int mov_read_uuid(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:6543
AVCOL_PRI_UNSPECIFIED
@ AVCOL_PRI_UNSPECIFIED
Definition: pixfmt.h:558
MOVTrackExt::duration
unsigned duration
Definition: isom.h:110
AV_CODEC_ID_H264
@ AV_CODEC_ID_H264
Definition: codec_id.h:79
av_content_light_metadata_alloc
AVContentLightMetadata * av_content_light_metadata_alloc(size_t *size)
Allocate an AVContentLightMetadata structure and set its fields to default values.
Definition: mastering_display_metadata.c:58
av_sha_final
void av_sha_final(AVSHA *ctx, uint8_t *digest)
Finish hashing and output digest value.
Definition: sha.c:347
MOVStreamContext::current_sample
int current_sample
Definition: isom.h:203
MOVFragmentStreamInfo::sidx_pts
int64_t sidx_pts
Definition: isom.h:135
MAX_REORDER_DELAY
#define MAX_REORDER_DELAY
Definition: mov.c:3892
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:9102
MOVAtom::size
int64_t size
Definition: isom.h:90
MOVStreamContext::refcount
int refcount
Definition: isom.h:169
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:438
AV_CODEC_ID_PNG
@ AV_CODEC_ID_PNG
Definition: codec_id.h:113
AV_CODEC_ID_AVUI
@ AV_CODEC_ID_AVUI
Definition: codec_id.h:255
if
if(ret)
Definition: filter_design.txt:179
mov_read_cmov
static int mov_read_cmov(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:5937
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:6768
FFStream::need_parsing
enum AVStreamParseType need_parsing
Definition: internal.h:386
MOVStreamContext::keyframe_count
unsigned int keyframe_count
Definition: isom.h:198
mov_read_SAND
static int mov_read_SAND(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:8016
IAMFAudioElement::audio_element_id
unsigned int audio_element_id
Definition: iamf.h:96
AVDISCARD_ALL
@ AVDISCARD_ALL
discard all
Definition: defs.h:219
AVFormatContext
Format I/O context.
Definition: avformat.h:1255
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:3326
MOVStreamContext::index_ranges
MOVIndexRange * index_ranges
Definition: isom.h:205
DDTS_SIZE
#define DDTS_SIZE
internal.h
MOVTrackExt::stsd_id
unsigned stsd_id
Definition: isom.h:109
set_frag_stream
static void set_frag_stream(MOVFragmentIndex *frag_index, int id)
Definition: mov.c:1463
mov_read_free
static int mov_read_free(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:6648
mov_realloc_extradata
static int mov_realloc_extradata(AVCodecParameters *par, MOVAtom atom)
Definition: mov.c:2027
AVStream::codecpar
AVCodecParameters * codecpar
Codec parameters associated with this stream.
Definition: avformat.h:766
AVChannelLayout::u
union AVChannelLayout::@379 u
Details about which channels are present in this layout.
LIBAVUTIL_VERSION_INT
#define LIBAVUTIL_VERSION_INT
Definition: version.h:85
AVSEEK_FLAG_BACKWARD
#define AVSEEK_FLAG_BACKWARD
Definition: avformat.h:2445
read_header
static int read_header(FFV1Context *f)
Definition: ffv1dec.c:550
aes.h
AVClass
Describe the class of an AVClass context structure.
Definition: log.h:66
avpriv_dv_get_packet
int avpriv_dv_get_packet(DVDemuxContext *c, AVPacket *pkt)
Definition: dv.c:731
MOVContext::ignore_editlist
int ignore_editlist
Definition: isom.h:315
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:782
NULL
#define NULL
Definition: coverity.c:32
sha.h
truehd_layout
static uint64_t truehd_layout(int chanmap)
Definition: mlp_parse.h:105
MOVDref
Definition: isom.h:79
AVERROR_PATCHWELCOME
#define AVERROR_PATCHWELCOME
Not yet implemented in FFmpeg, patches welcome.
Definition: error.h:64
AV_CODEC_ID_AV1
@ AV_CODEC_ID_AV1
Definition: codec_id.h:280
MOVStreamContext::ctts_count
unsigned int ctts_count
Definition: isom.h:180
AVEncryptionInitInfo
This describes info used to initialize an encryption key system.
Definition: encryption_info.h:88
isom.h
MP4TrackKindValueMapping::disposition
int disposition
Definition: isom.h:454
mov_read_ftyp
static int mov_read_ftyp(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:1378
AV_WB16
#define AV_WB16(p, v)
Definition: intreadwrite.h:403
MOVContext::nb_heif_grid
int nb_heif_grid
Definition: isom.h:355
read_image_grid
static int read_image_grid(AVFormatContext *s, const HEIFGrid *grid, AVStreamGroupTileGrid *tile_grid)
Definition: mov.c:9285
MOVElst
Definition: isom.h:73
av_aes_ctr_alloc
struct AVAESCTR * av_aes_ctr_alloc(void)
Allocate an AVAESCTR context.
Definition: aes_ctr.c:40
flac_parse_block_header
static av_always_inline void flac_parse_block_header(const uint8_t *block_header, int *last, int *type, int *size)
Parse the metadata block parameters from the header.
Definition: flac.h:63
AVRational
Rational number (pair of numerator and denominator).
Definition: rational.h:58
mov_read_sgpd
static int mov_read_sgpd(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:3552
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:692
mov_probe
static int mov_probe(const AVProbeData *p)
Definition: mov.c:8749
AVPALETTE_SIZE
#define AVPALETTE_SIZE
Definition: pixfmt.h:32
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:550
AVIndexEntry::flags
int flags
Definition: avformat.h:612
MOVStreamContext::time_offset
int64_t time_offset
time offset of the edit list entries
Definition: isom.h:201
mov_read_smdm
static int mov_read_smdm(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:6114
av_default_item_name
const char * av_default_item_name(void *ptr)
Return the context name.
Definition: log.c:237
avio_rb64
uint64_t avio_rb64(AVIOContext *s)
Definition: aviobuf.c:908
av_aes_crypt
void av_aes_crypt(AVAES *a, uint8_t *dst, const uint8_t *src, int count, uint8_t *iv, int decrypt)
Encrypt or decrypt a buffer using a previously initialized context.
Definition: aes.c:169
MOVStreamContext::current_index_range
MOVIndexRange * current_index_range
Definition: isom.h:206
mov_open_dref
static int mov_open_dref(MOVContext *c, AVIOContext **pb, const char *src, MOVDref *ref)
Definition: mov.c:4734
FFStream::nb_index_entries
int nb_index_entries
Definition: internal.h:251
AVProbeData
This structure contains the data a format has to probe a file.
Definition: avformat.h:451
av_aes_alloc
struct AVAES * av_aes_alloc(void)
Allocate an AVAES context.
Definition: aes.c:35
TAG_IS_AVCI
#define TAG_IS_AVCI(tag)
Definition: isom.h:408
IAMFSubStream
Definition: iamf.h:82
MOVStreamContext::timecode_track
int timecode_track
Definition: isom.h:215
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:7240
AVStream::metadata
AVDictionary * metadata
Definition: avformat.h:823
FLAC_STREAMINFO_SIZE
#define FLAC_STREAMINFO_SIZE
Definition: flac.h:32
av_color_primaries_name
const char * av_color_primaries_name(enum AVColorPrimaries primaries)
Definition: pixdesc.c:3299
HEVC_NAL_CRA_NUT
@ HEVC_NAL_CRA_NUT
Definition: hevc.h:50
FF_MOV_FLAG_MFRA_DTS
#define FF_MOV_FLAG_MFRA_DTS
Definition: isom.h:431
MOV_SAMPLE_DEPENDENCY_NO
#define MOV_SAMPLE_DEPENDENCY_NO
Definition: isom.h:405
mov_read_iref_thmb
static int mov_read_iref_thmb(MOVContext *c, AVIOContext *pb, int version)
Definition: mov.c:8316
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
MOVFragmentStreamInfo::index_base
int index_base
Definition: isom.h:140
MOVStreamContext::rap_group
MOVSbgp * rap_group
Definition: isom.h:227
AV_CODEC_ID_QDM2
@ AV_CODEC_ID_QDM2
Definition: codec_id.h:459
mov_read_ilst
static int mov_read_ilst(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:5015
AV_CH_FRONT_CENTER
#define AV_CH_FRONT_CENTER
Definition: channel_layout.h:170
AVCodecParameters::ch_layout
AVChannelLayout ch_layout
Audio only.
Definition: codec_par.h:180
AVStreamGroupTileGrid::offsets
struct AVStreamGroupTileGrid::@323 * offsets
An nb_tiles sized array of offsets in pixels from the topleft edge of the canvas, indicating where ea...
get_frag_stream_info_from_pkt
static MOVFragmentStreamInfo * get_frag_stream_info_from_pkt(MOVFragmentIndex *frag_index, AVPacket *pkt, int id)
Definition: mov.c:7642
get_sgpd_sync_index
static uint32_t get_sgpd_sync_index(const MOVStreamContext *sc, int nal_unit_type)
Definition: mov.c:4306
mov_read_fiel
static int mov_read_fiel(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:1993
MOV_MP4_TTML_TAG
#define MOV_MP4_TTML_TAG
Definition: isom.h:449
AV_PKT_DATA_CONTENT_LIGHT_LEVEL
@ AV_PKT_DATA_CONTENT_LIGHT_LEVEL
Content light level (based on CTA-861.3).
Definition: packet.h:236
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:373
MOVFragmentStreamInfo::stsd_id
int stsd_id
Definition: isom.h:143
MOVStreamContext::open_key_samples_count
int open_key_samples_count
Definition: isom.h:235
HEIFItem
Definition: isom.h:272
ff_codec_movaudio_tags
const AVCodecTag ff_codec_movaudio_tags[]
Definition: isom_tags.c:296
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:1196
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:2658
cid
uint16_t cid
Definition: mxfenc.c:2263
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:2868
MOVStts
Definition: isom.h:57
AVAudioServiceType
AVAudioServiceType
Definition: defs.h:222
AV_CODEC_ID_MPEG1VIDEO
@ AV_CODEC_ID_MPEG1VIDEO
Definition: codec_id.h:53
AV_CODEC_ID_GSM
@ AV_CODEC_ID_GSM
as in Berlin toast format
Definition: codec_id.h:458
AVStream::nb_frames
int64_t nb_frames
number of frames in this stream if known or 0
Definition: avformat.h:804
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:654
AVIAMFSubmixElement::audio_element_id
unsigned int audio_element_id
The id of the Audio Element this submix element references.
Definition: iamf.h:443
AV_CODEC_ID_EAC3
@ AV_CODEC_ID_EAC3
Definition: codec_id.h:480
should_retry
static int should_retry(AVIOContext *pb, int error_code)
Definition: mov.c:9797
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:495
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:229
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:543
AV_WB32
#define AV_WB32(p, v)
Definition: intreadwrite.h:417
mov_read_pasp
static int mov_read_pasp(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:1212
MOVContext::dv_demux
DVDemuxContext * dv_demux
Definition: isom.h:304
AV_CODEC_ID_AAC
@ AV_CODEC_ID_AAC
Definition: codec_id.h:442
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:7926
mov_read_elst
static int mov_read_elst(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:5990
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:1084
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:144
mov_read_header
static int mov_read_header(AVFormatContext *s)
Definition: mov.c:9518
AV_CODEC_ID_QCELP
@ AV_CODEC_ID_QCELP
Definition: codec_id.h:464
cbc1_scheme_decrypt
static int cbc1_scheme_decrypt(MOVContext *c, MOVStreamContext *sc, AVEncryptionInfo *sample, uint8_t *input, int size)
Definition: mov.c:7435
avio_rl32
unsigned int avio_rl32(AVIOContext *s)
Definition: aviobuf.c:730
AVDISCARD_NONKEY
@ AVDISCARD_NONKEY
discard all frames except keyframes
Definition: defs.h:218
MOVFragment::flags
unsigned flags
Definition: isom.h:104
f
f
Definition: af_crystalizer.c:121
AVIOContext
Bytestream IO Context.
Definition: avio.h:160
AV_CODEC_ID_PCM_S24LE
@ AV_CODEC_ID_PCM_S24LE
Definition: codec_id.h:340
mov_read_wave
static int mov_read_wave(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:2223
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:263
cens_scheme_decrypt
static int cens_scheme_decrypt(MOVContext *c, MOVStreamContext *sc, AVEncryptionInfo *sample, uint8_t *input, int size)
Definition: mov.c:7495
MOVContext::handbrake_version
int handbrake_version
Definition: isom.h:311
mov_free_stream_context
static void mov_free_stream_context(AVFormatContext *s, AVStream *st)
Definition: mov.c:9041
AVPacket::size
int size
Definition: packet.h:525
MOVStreamContext::ctts_sample
int ctts_sample
Definition: isom.h:192
NULL_IF_CONFIG_SMALL
#define NULL_IF_CONFIG_SMALL(x)
Return NULL if CONFIG_SMALL is true, otherwise the argument without modification.
Definition: internal.h:94
ff_codec_get_id
enum AVCodecID ff_codec_get_id(const AVCodecTag *tags, unsigned int tag)
Definition: utils.c:146
avformat_alloc_context
AVFormatContext * avformat_alloc_context(void)
Allocate an AVFormatContext.
Definition: options.c:161
MOVFragmentIndexItem
Definition: isom.h:146
get_current_encryption_info
static int get_current_encryption_info(MOVContext *c, MOVEncryptionIndex **encryption_index, MOVStreamContext **sc)
Gets the current encryption info and associated current stream context.
Definition: mov.c:6717
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
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:303
FFStream
Definition: internal.h:193
mov_read_dref
static int mov_read_dref(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:614
mov_current_sample_dec
static void mov_current_sample_dec(MOVStreamContext *sc)
Definition: mov.c:3961
AVSphericalMapping::bound_right
uint32_t bound_right
Distance from the right edge.
Definition: spherical.h:165
MOVStsc::first
int first
Definition: isom.h:68
find_prev_closest_index
static int find_prev_closest_index(AVStream *st, AVIndexEntry *e_old, int nb_old, MOVCtts *ctts_data, int64_t ctts_count, int64_t timestamp_pts, int flag, int64_t *index, int64_t *ctts_index, int64_t *ctts_sample)
Find the closest previous frame to the timestamp_pts, in e_old index entries.
Definition: mov.c:3711
av_bswap32
#define av_bswap32
Definition: bswap.h:28
MOVStreamContext::stsz_sample_size
unsigned int stsz_sample_size
always contains sample size from stsz atom
Definition: isom.h:194
FF_MOV_FLAG_MFRA_AUTO
#define FF_MOV_FLAG_MFRA_AUTO
Definition: isom.h:430
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:230
start_time
static int64_t start_time
Definition: ffplay.c:326
uuid.h
mov_read_trun
static int mov_read_trun(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:5472
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:8401
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:374
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:1145
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:3056
av_reallocp
int av_reallocp(void *ptr, size_t size)
Allocate, reallocate, or free a block of memory through a pointer to a pointer.
Definition: mem.c:188
ff_get_qtpalette
int ff_get_qtpalette(int codec_id, AVIOContext *pb, uint32_t *palette)
Retrieve the palette (or "color table" in QuickTime terms), either from the video sample description,...
Definition: qtpalette.c:323
AV_NOPTS_VALUE
#define AV_NOPTS_VALUE
Undefined timestamp value.
Definition: avutil.h:248
MKBETAG
#define MKBETAG(a, b, c, d)
Definition: macros.h:56
AV_CODEC_ID_QDMC
@ AV_CODEC_ID_QDMC
Definition: codec_id.h:490
av_fourcc_make_string
char * av_fourcc_make_string(char *buf, uint32_t fourcc)
Fill the provided buffer with a string containing a FourCC (four-character code) representation.
Definition: utils.c:73
AV_RB32
uint64_t_TMPL AV_WL64 unsigned int_TMPL AV_WL32 unsigned int_TMPL AV_WL24 unsigned int_TMPL AV_WL16 uint64_t_TMPL AV_WB64 unsigned int_TMPL AV_RB32
Definition: bytestream.h:96
avpriv_report_missing_feature
void avpriv_report_missing_feature(void *avc, const char *msg,...) av_printf_format(2
Log a generic warning message about a missing feature.
av_aes_ctr_set_full_iv
void av_aes_ctr_set_full_iv(struct AVAESCTR *a, const uint8_t *iv)
Forcefully change the "full" 16-byte iv, including the counter.
Definition: aes_ctr.c:52
AVStreamGroup::iamf_audio_element
struct AVIAMFAudioElement * iamf_audio_element
Definition: avformat.h:1123
MOVStreamContext::coll
AVContentLightMetadata * coll
Definition: isom.h:253
aes_ctr.h
ff_format_io_close
int ff_format_io_close(AVFormatContext *s, AVIOContext **pb)
Definition: avformat.c:944
HEIFItem::is_idat_relative
int is_idat_relative
Definition: isom.h:281
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:3808
MOVDref::path
char * path
Definition: isom.h:81
mov_current_sample_inc
static void mov_current_sample_inc(MOVStreamContext *sc)
Definition: mov.c:3949
AVStream::sample_aspect_ratio
AVRational sample_aspect_ratio
sample aspect ratio (0 if unknown)
Definition: avformat.h:821
FFInputFormat::p
AVInputFormat p
The public AVInputFormat.
Definition: demux.h:41
dovi_isom.h
AVPacket::dts
int64_t dts
Decompression timestamp in AVStream->time_base units; the time at which the packet is decompressed.
Definition: packet.h:523
AV_WL16
#define AV_WL16(p, v)
Definition: intreadwrite.h:410
fix_timescale
static void fix_timescale(MOVContext *c, MOVStreamContext *sc)
Definition: mov.c:4806
avio_r8
int avio_r8(AVIOContext *s)
Definition: aviobuf.c:603
IAMFAudioElement::substreams
IAMFSubStream * substreams
Definition: iamf.h:98
height
#define height
AVSphericalMapping::padding
uint32_t padding
Number of pixels to pad from the edge of each cube face.
Definition: spherical.h:178
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:877
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:347
mov_read_default
static int mov_read_default(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:8627
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:450
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:990
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:697
mov_read_packet
static int mov_read_packet(AVFormatContext *s, AVPacket *pkt)
Definition: mov.c:9943
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
attributes.h
MOVEncryptionIndex::auxiliary_offsets_count
size_t auxiliary_offsets_count
Definition: isom.h:130
AVPacket::flags
int flags
A combination of AV_PKT_FLAG values.
Definition: packet.h:530
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
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:1082
AVEncryptionInitInfo::next
struct AVEncryptionInitInfo * next
An optional pointer to the next initialization info in the list.
Definition: encryption_info.h:122
AVStreamGroup::streams
AVStream ** streams
A list of streams in the group.
Definition: avformat.h:1156
ff_rfps_calculate
void ff_rfps_calculate(AVFormatContext *ic)
Definition: demux.c:2347
input
and forward the test the status of outputs and forward it to the corresponding return FFERROR_NOT_READY If the filters stores internally one or a few frame for some input
Definition: filter_design.txt:172
MOV_MP4_IPCM_TAG
#define MOV_MP4_IPCM_TAG
Definition: isom.h:451
mov_read_clli
static int mov_read_clli(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:6242
MOVStreamContext::chunk_offsets
int64_t * chunk_offsets
Definition: isom.h:175
AVStreamGroup::iamf_mix_presentation
struct AVIAMFMixPresentation * iamf_mix_presentation
Definition: avformat.h:1124
MOVFragmentIndex::item
MOVFragmentIndexItem * item
Definition: isom.h:159
AV_LOG_INFO
#define AV_LOG_INFO
Standard information.
Definition: log.h:191
MOVStreamContext::iamf
struct IAMFDemuxContext * iamf
Definition: isom.h:269
FFERROR_REDO
#define FFERROR_REDO
Returned by demuxers to indicate that data was consumed but discarded (ignored streams or junk data).
Definition: demux.h:171
av_encryption_init_info_alloc
AVEncryptionInitInfo * av_encryption_init_info_alloc(uint32_t system_id_size, uint32_t num_key_ids, uint32_t key_id_size, uint32_t data_size)
Allocates an AVEncryptionInitInfo structure and sub-pointers to hold the given sizes.
Definition: encryption_info.c:178
MOVContext::heif_item
HEIFItem * heif_item
Definition: isom.h:352
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:223
MOVContext::decryption_key_len
int decryption_key_len
Definition: isom.h:344
av_aes_ctr_free
void av_aes_ctr_free(struct AVAESCTR *a)
Release an AVAESCTR context.
Definition: aes_ctr.c:83
mov_read_dfla
static int mov_read_dfla(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:7342
AVSHA::count
uint64_t count
number of bytes in buffer
Definition: sha.c:37
mov_default_parse_table
static const MOVParseTableEntry mov_default_parse_table[]
Definition: mov.c:8507
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:466
mov_metadata_creation_time
static void mov_metadata_creation_time(MOVContext *c, AVIOContext *pb, AVDictionary **metadata, int version)
Definition: mov.c:1698
mov_metadata_hmmt
static int mov_metadata_hmmt(MOVContext *c, AVIOContext *pb, unsigned len)
Definition: mov.c:308
AV_CODEC_ID_MJPEG
@ AV_CODEC_ID_MJPEG
Definition: codec_id.h:59
MOVFragmentStreamInfo::next_trun_dts
int64_t next_trun_dts
Definition: isom.h:138
MOVStreamContext::stsc_index
unsigned int stsc_index
Definition: isom.h:185
av_sha_alloc
struct AVSHA * av_sha_alloc(void)
Allocate an AVSHA context.
Definition: sha.c:46
mov_read_tenc
static int mov_read_tenc(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:7271
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:3131
mov_finalize_packet
static int mov_finalize_packet(AVFormatContext *s, AVStream *st, AVIndexEntry *sample, int64_t current_index, AVPacket *pkt)
Definition: mov.c:9885
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:10211
bprint.h
MOVContext::advanced_editlist
int advanced_editlist
Definition: isom.h:316
MOVStreamContext::time_scale
int time_scale
Definition: isom.h:200
mlp_parse.h
mac_to_unicode
static const uint32_t mac_to_unicode[128]
Definition: mov.c:150
AVStreamGroupTileGrid::width
int width
Width of the final image for presentation.
Definition: avformat.h:1067
MOVStreamContext::bytes_per_frame
unsigned int bytes_per_frame
Definition: isom.h:207
AVSphericalMapping::roll
int32_t roll
Rotation around the forward vector [-180, 180].
Definition: spherical.h:124
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:517
avio_internal.h
mov_read_trex
static int mov_read_trex(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:5407
search_frag_timestamp
static int search_frag_timestamp(AVFormatContext *s, MOVFragmentIndex *frag_index, AVStream *st, int64_t timestamp)
Definition: mov.c:1571
HEIFItem::width
int width
Definition: isom.h:278
FLAGS
#define FLAGS
Definition: mov.c:10268
MOVStreamContext::stereo3d
AVStereo3D * stereo3d
Definition: isom.h:249
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:4001
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:7119
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:2991
internal.h
AVCodecParameters::height
int height
Definition: codec_par.h:135
mov_rewrite_dvd_sub_extradata
static int mov_rewrite_dvd_sub_extradata(AVStream *st)
Definition: mov.c:2690
AV_TIME_BASE
#define AV_TIME_BASE
Internal time base represented as integer.
Definition: avutil.h:254
MOVStreamContext::stps_count
unsigned int stps_count
Definition: isom.h:187
AVCodecParameters::block_align
int block_align
Audio only.
Definition: codec_par.h:191
AV_CODEC_ID_TTML
@ AV_CODEC_ID_TTML
Definition: codec_id.h:574
av_malloc_array
#define av_malloc_array(a, b)
Definition: tableprint_vlc.h:31
AV_CODEC_ID_CAVS
@ AV_CODEC_ID_CAVS
Definition: codec_id.h:139
ff_mov_read_stsd_entries
int ff_mov_read_stsd_entries(MOVContext *c, AVIOContext *pb, int entries)
Definition: mov.c:2894
AV_FIELD_BB
@ AV_FIELD_BB
Bottom coded first, bottom displayed first.
Definition: defs.h:202
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:275
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:600
ff_id3v1_genre_str
const char *const ff_id3v1_genre_str[ID3v1_GENRE_MAX+1]
ID3v1 genres.
Definition: id3v1.c:26
MOVContext::frag_index
MOVFragmentIndex frag_index
Definition: isom.h:329
mov_read_vpcc
static int mov_read_vpcc(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:6070
AV_CODEC_ID_PCM_F64BE
@ AV_CODEC_ID_PCM_F64BE
Definition: codec_id.h:350
AV_CODEC_ID_HEVC
@ AV_CODEC_ID_HEVC
Definition: codec_id.h:226
value
it s the only field you need to keep assuming you have a context There is some magic you don t need to care about around this just let it vf default value
Definition: writing_filters.txt:86
av_url_split
void av_url_split(char *proto, int proto_size, char *authorization, int authorization_size, char *hostname, int hostname_size, int *port_ptr, char *path, int path_size, const char *url)
Split a URL string into components.
Definition: utils.c:359
MOVStreamContext::dref_id
int dref_id
Definition: isom.h:214
FFMIN
#define FFMIN(a, b)
Definition: macros.h:49
av_d2q
AVRational av_d2q(double d, int max)
Convert a double precision floating point number to a rational.
Definition: rational.c:106
fix_frag_index_entries
static void fix_frag_index_entries(MOVFragmentIndex *frag_index, int index, int id, int entries)
Definition: mov.c:1657
mov_finalize_stsd_codec
static int mov_finalize_stsd_codec(MOVContext *c, AVIOContext *pb, AVStream *st, MOVStreamContext *sc)
Definition: mov.c:2768
AV_CH_FRONT_LEFT
#define AV_CH_FRONT_LEFT
Definition: channel_layout.h:168
AV_CODEC_ID_PCM_S32BE
@ AV_CODEC_ID_PCM_S32BE
Definition: codec_id.h:337
mov_read_mdcv
static int mov_read_mdcv(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:6161
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:1230
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:5024
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:178
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:376
AVCOL_SPC_UNSPECIFIED
@ AVCOL_SPC_UNSPECIFIED
Definition: pixfmt.h:612
av_rescale
int64_t av_rescale(int64_t a, int64_t b, int64_t c)
Rescale a 64-bit integer with rounding to nearest.
Definition: mathematics.c:129
mov_build_index
static void mov_build_index(MOVContext *mov, AVStream *st)
Definition: mov.c:4377
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:2218
AVSHA
hash context
Definition: sha.c:35
AVCOL_RANGE_MPEG
@ AVCOL_RANGE_MPEG
Narrow or limited range content.
Definition: pixfmt.h:669
av_calloc
void * av_calloc(size_t nmemb, size_t size)
Definition: mem.c:264
MOVFragmentStreamInfo::tfdt_dts
int64_t tfdt_dts
Definition: isom.h:137
hevc.h
AV_IAMF_AUDIO_ELEMENT_TYPE_SCENE
@ AV_IAMF_AUDIO_ELEMENT_TYPE_SCENE
Definition: iamf.h:337
AVCodecParameters::field_order
enum AVFieldOrder field_order
Video only.
Definition: codec_par.h:161
MOVStreamContext::sample_sizes
int * sample_sizes
Definition: isom.h:196
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:104
mov_read_iinf
static int mov_read_iinf(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:8204
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:1026
get_stream_info_time
static int64_t get_stream_info_time(MOVFragmentStreamInfo *frag_stream_info)
Definition: mov.c:1523
MP4TrackKindValueMapping
Definition: isom.h:453
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:3849
AV_WB8
#define AV_WB8(p, d)
Definition: intreadwrite.h:394
MOVStreamContext::chunk_count
unsigned int chunk_count
Definition: isom.h:174
MOVStreamContext::data_size
int64_t data_size
Definition: isom.h:221
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:255
mov_read_tmcd
static int mov_read_tmcd(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:6059
mov_chan.h
AVStream::disposition
int disposition
Stream disposition - a combination of AV_DISPOSITION_* flags.
Definition: avformat.h:812
MOVStreamContext::ambient_size
size_t ambient_size
Definition: isom.h:256
tag
uint32_t tag
Definition: movenc.c:1788
AVStream::id
int id
Format-specific stream ID.
Definition: avformat.h:755
ret
ret
Definition: filter_design.txt:187
AVStream
Stream structure.
Definition: avformat.h:743
AV_LOG_FATAL
#define AV_LOG_FATAL
Something went wrong and recovery is not possible.
Definition: log.h:174
HEIFItem::extent_length
int64_t extent_length
Definition: isom.h:276
MOVEncryptionIndex::nb_encrypted_samples
unsigned int nb_encrypted_samples
Definition: isom.h:123
av_stereo3d_alloc
AVStereo3D * av_stereo3d_alloc(void)
Allocate an AVStereo3D structure and set its fields to default values.
Definition: stereo3d.c:29
mov_read_senc
static int mov_read_senc(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:6822
avio_seek
int64_t avio_seek(AVIOContext *s, int64_t offset, int whence)
fseek() equivalent for AVIOContext.
Definition: aviobuf.c:231
FFSWAP
#define FFSWAP(type, a, b)
Definition: macros.h:52
AVClass::class_name
const char * class_name
The name of the class; usually it is the same name as the context structure type to which the AVClass...
Definition: log.h:71
AVEncryptionInfo::key_id
uint8_t * key_id
The ID of the key used to encrypt the packet.
Definition: encryption_info.h:63
av_strlcat
size_t av_strlcat(char *dst, const char *src, size_t size)
Append the string src to the string dst, but to a total length of no more than size - 1 bytes,...
Definition: avstring.c:95
MOVStreamContext::stts_data
MOVStts * stts_data
Definition: isom.h:177
AVSphericalMapping::pitch
int32_t pitch
Rotation around the right vector [-90, 90].
Definition: spherical.h:123
AVStreamGroup::metadata
AVDictionary * metadata
Metadata that applies to the whole group.
Definition: avformat.h:1136
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:177
MOVSbgp::index
unsigned int index
Definition: isom.h:117
MOVContext::chapter_tracks
int * chapter_tracks
Definition: isom.h:312
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:704
AV_AUDIO_SERVICE_TYPE_KARAOKE
@ AV_AUDIO_SERVICE_TYPE_KARAOKE
Definition: defs.h:231
mov_read_dmlp
static int mov_read_dmlp(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:7782
AV_INPUT_BUFFER_PADDING_SIZE
#define AV_INPUT_BUFFER_PADDING_SIZE
Definition: defs.h:40
MOVStreamContext::pseudo_stream_id
int pseudo_stream_id
-1 means demux all ids
Definition: isom.h:210
MOVContext::time_scale
int time_scale
Definition: isom.h:294
id
enum AVCodecID id
Definition: dts2pts.c:365
mov_read_tfdt
static int mov_read_tfdt(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:5433
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:141
heif_add_stream
static int heif_add_stream(MOVContext *c, HEIFItem *item)
Definition: mov.c:5151
search_frag_moof_offset
static int search_frag_moof_offset(MOVFragmentIndex *frag_index, int64_t offset)
Definition: mov.c:1499
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:9804
MOVContext::use_mfra_for
int use_mfra_for
Definition: isom.h:326
AVEncryptionInfo
This describes encryption info for a packet.
Definition: encryption_info.h:43
add_ctts_entry
static int64_t add_ctts_entry(MOVCtts **ctts_data, unsigned int *ctts_count, unsigned int *allocated_size, int count, int duration)
Append a new ctts entry to ctts_data.
Definition: mov.c:3865
MOVStreamContext::encryption_index
MOVEncryptionIndex * encryption_index
Definition: isom.h:266
MIN_DATA_ENTRY_BOX_SIZE
#define MIN_DATA_ENTRY_BOX_SIZE
Definition: mov.c:613
AVStreamGroup
Definition: avformat.h:1090
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:749
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:10070
ff_configure_buffers_for_index
void ff_configure_buffers_for_index(AVFormatContext *s, int64_t time_tolerance)
Definition: seek.c:174
mov_parse_stsd_video
static void mov_parse_stsd_video(MOVContext *c, AVIOContext *pb, AVStream *st, MOVStreamContext *sc)
Definition: mov.c:2483
ff_codec_bmp_tags
const AVCodecTag ff_codec_bmp_tags[]
Definition: riff.c:36
mov_read_dec3
static int mov_read_dec3(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:1049
get_frag_time
static int64_t get_frag_time(AVFormatContext *s, AVStream *dst_st, MOVFragmentIndex *frag_index, int index)
Definition: mov.c:1533
MOVStreamContext::sample_size
unsigned int sample_size
may contain value calculated from stsd or value from stsz atom
Definition: isom.h:193
AVStreamGroup::nb_streams
unsigned int nb_streams
Number of elements in AVStreamGroup.streams.
Definition: avformat.h:1143
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:239
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:3608
MOVFragment::moof_offset
uint64_t moof_offset
Definition: isom.h:99
AVIO_SEEKABLE_NORMAL
#define AVIO_SEEKABLE_NORMAL
Seeking works like for a local file.
Definition: avio.h:41
av_packet_new_side_data
uint8_t * av_packet_new_side_data(AVPacket *pkt, enum AVPacketSideDataType type, size_t size)
Allocate new information of a packet.
Definition: packet.c:231
buffer
the frame and frame reference mechanism is intended to as much as expensive copies of that data while still allowing the filters to produce correct results The data is stored in buffers represented by AVFrame structures Several references can point to the same frame buffer
Definition: filter_design.txt:49
mov_read_glbl
static int mov_read_glbl(MOVContext *c, AVIOContext *pb, MOVAtom atom)
This function reads atom content and puts data in extradata without tag nor size unlike mov_read_extr...
Definition: mov.c:2280
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:6480
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:122
AV_OPT_TYPE_INT
@ AV_OPT_TYPE_INT
Definition: opt.h:245
MOVContext::dv_fctx
AVFormatContext * dv_fctx
Definition: isom.h:305
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:433
AV_CODEC_ID_DVAUDIO
@ AV_CODEC_ID_DVAUDIO
Definition: codec_id.h:446
AVStreamGroup::params
union AVStreamGroup::@324 params
Group type-specific parameters.
avformat_free_context
void avformat_free_context(AVFormatContext *s)
Free an AVFormatContext and all its streams.
Definition: avformat.c:141
MOVContext::aax_mode
unsigned int aax_mode
'aax' file has been detected
Definition: isom.h:331
mov_read_sv3d
static int mov_read_sv3d(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:6343
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:1339
mov_get_skip_samples
static int64_t mov_get_skip_samples(AVStream *st, int sample)
Definition: mov.c:10194
MOVFragmentIndex
Definition: isom.h:154
mov_read_infe
static int mov_read_infe(MOVContext *c, AVIOContext *pb, MOVAtom atom, int idx)
Definition: mov.c:8150
AV_RB8
uint64_t_TMPL AV_WL64 unsigned int_TMPL AV_WL32 unsigned int_TMPL AV_WL24 unsigned int_TMPL AV_WL16 uint64_t_TMPL AV_WB64 unsigned int_TMPL AV_WB32 unsigned int_TMPL AV_WB24 unsigned int_TMPL AV_WB16 unsigned int_TMPL AV_RB8
Definition: bytestream.h:99
ref
static int ref[MAX_W *MAX_W]
Definition: jpeg2000dwt.c:112
AVStream::r_frame_rate
AVRational r_frame_rate
Real base framerate of the stream.
Definition: avformat.h:909
MOVStreamContext::track_end
int64_t track_end
used for dts generation in fragmented movie files
Definition: isom.h:224
MOVStreamContext::sgpd_sync_count
uint32_t sgpd_sync_count
Definition: isom.h:231
MOVContext::fragment
MOVFragment fragment
current fragment in moof atom
Definition: isom.h:307
AVIndexEntry::pos
int64_t pos
Definition: avformat.h:603
AVIOContext::eof_reached
int eof_reached
true if was unable to read due to error or eof
Definition: avio.h:238
mov_metadata_int8_bypass_padding
static int mov_metadata_int8_bypass_padding(MOVContext *c, AVIOContext *pb, unsigned len, const char *key)
Definition: mov.c:111
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:863
mov_read_covr
static int mov_read_covr(MOVContext *c, AVIOContext *pb, int type, int len)
Definition: mov.c:215
MOVParseTableEntry::type
uint32_t type
Definition: mov.c:81
AVMasteringDisplayMetadata::min_luminance
AVRational min_luminance
Min luminance of mastering display (cd/m^2).
Definition: mastering_display_metadata.h:52
MOVStreamContext::per_sample_iv_size
unsigned int per_sample_iv_size
Definition: isom.h:264
ff_codec_movsubtitle_tags
const AVCodecTag ff_codec_movsubtitle_tags[]
Definition: isom.c:75
AVPacket::stream_index
int stream_index
Definition: packet.h:526
av_clip_uint8
#define av_clip_uint8
Definition: common.h:105
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:9166
MOVStreamContext::has_sidx
int has_sidx
Definition: isom.h:260
AV_CH_FRONT_RIGHT
#define AV_CH_FRONT_RIGHT
Definition: channel_layout.h:169
av_aes_ctr_crypt
void av_aes_ctr_crypt(struct AVAESCTR *a, uint8_t *dst, const uint8_t *src, int count)
Process a buffer using a previously initialized context.
Definition: aes_ctr.c:107
mov_metadata_gnre
static int mov_metadata_gnre(MOVContext *c, AVIOContext *pb, unsigned len, const char *key)
Definition: mov.c:134
AV_PKT_DATA_ENCRYPTION_INFO
@ AV_PKT_DATA_ENCRYPTION_INFO
This side data contains encryption info for how to decrypt the packet.
Definition: packet.h:256
FFStream::index_entries
AVIndexEntry * index_entries
Only used if the format does not support seeking natively.
Definition: internal.h:249
av_dict_set_int
int av_dict_set_int(AVDictionary **pm, const char *key, int64_t value, int flags)
Convenience wrapper for av_dict_set() that converts the value to a string and stores it.
Definition: dict.c:167
mov_read_dpxe
static int mov_read_dpxe(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:2105
AVIAMFSubmix::nb_elements
unsigned int nb_elements
Number of elements in the submix.
Definition: iamf.h:559
MOVFragmentStreamInfo::id
int id
Definition: isom.h:134
AVIO_FLAG_READ
#define AVIO_FLAG_READ
read-only
Definition: avio.h:617
tc
#define tc
Definition: regdef.h:69
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:121
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:284
MOVContext::thmb_item_id
int thmb_item_id
Definition: isom.h:356
mov_read_rtmd_track
static int mov_read_rtmd_track(AVFormatContext *s, AVStream *st)
Definition: mov.c:8956
AVMEDIA_TYPE_VIDEO
@ AVMEDIA_TYPE_VIDEO
Definition: avutil.h:201
read_probe
static int read_probe(const AVProbeData *p)
Definition: cdg.c:30
MOVStreamContext::pb_is_copied
int pb_is_copied
Definition: isom.h:170
AV_CODEC_ID_PCM_S32LE
@ AV_CODEC_ID_PCM_S32LE
Definition: codec_id.h:336
AVCodecParameters::bits_per_coded_sample
int bits_per_coded_sample
The number of bits per sample in the codedwords.
Definition: codec_par.h:110
mov_parse_tiles
static int mov_parse_tiles(AVFormatContext *s)
Definition: mov.c:9434
mem.h
MOVElst::time
int64_t time
Definition: isom.h:75
HEIFGrid
Definition: isom.h:284
mov_read_iref_dimg
static int mov_read_iref_dimg(MOVContext *c, AVIOContext *pb, int version)
Definition: mov.c:8257
mov_read_pcmc
static int mov_read_pcmc(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:1851
build_open_gop_key_points
static int build_open_gop_key_points(AVStream *st)
Definition: mov.c:4314
mov_parse_stsd_audio
static void mov_parse_stsd_audio(MOVContext *c, AVIOContext *pb, AVStream *st, MOVStreamContext *sc)
Definition: mov.c:2541
IAMFContext::mix_presentations
IAMFMixPresentation ** mix_presentations
Definition: iamf.h:133
AV_CODEC_ID_PCM_U8
@ AV_CODEC_ID_PCM_U8
Definition: codec_id.h:333
MOVContext::trak_index
int trak_index
Index of the current 'trak'.
Definition: isom.h:301
mov_read_timecode_track
static int mov_read_timecode_track(AVFormatContext *s, AVStream *st)
Definition: mov.c:8982
HEIFGrid::item
HEIFItem * item
Definition: isom.h:285
AVSphericalMapping::bound_left
uint32_t bound_left
Distance from the left edge.
Definition: spherical.h:163
mov_read_mac_string
static int mov_read_mac_string(MOVContext *c, AVIOContext *pb, int len, char *dst, int dstlen)
Definition: mov.c:169
MOVEncryptionIndex::auxiliary_info_sizes
uint8_t * auxiliary_info_sizes
Definition: isom.h:126
MOVFragment::stsd_id
unsigned stsd_id
Definition: isom.h:101
AVCodecParameters::video_delay
int video_delay
Video only.
Definition: codec_par.h:175
HEIFGrid::tile_id_list
int16_t * tile_id_list
Definition: isom.h:287
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:422
AV_CHANNEL_LAYOUT_MONO
#define AV_CHANNEL_LAYOUT_MONO
Definition: channel_layout.h:378
AV_CODEC_ID_PCM_F64LE
@ AV_CODEC_ID_PCM_F64LE
Definition: codec_id.h:351
AVStreamGroupTileGrid::height
int height
Height of the final image for presentation.
Definition: avformat.h:1077
read_tfra
static int read_tfra(MOVContext *mov, AVIOContext *f)
Definition: mov.c:9184
av_free
#define av_free(p)
Definition: tableprint_vlc.h:33
AVDictionaryEntry
Definition: dict.h:89
AVCodecParameters::codec_id
enum AVCodecID codec_id
Specific type of the encoded data (the codec used).
Definition: codec_par.h:55
FLAC_METADATA_TYPE_STREAMINFO
@ FLAC_METADATA_TYPE_STREAMINFO
Definition: flac.h:46
AVPacket
This structure stores compressed data.
Definition: packet.h:501
AVContentLightMetadata::MaxFALL
unsigned MaxFALL
Max average light level per frame (cd/m^2).
Definition: mastering_display_metadata.h:116
AV_OPT_TYPE_BOOL
@ AV_OPT_TYPE_BOOL
Definition: opt.h:261
cr
static double cr(void *priv, double x, double y)
Definition: vf_geq.c:243
MOVStreamContext::stps_data
unsigned * stps_data
partial sync sample for mpeg-2 open gop
Definition: isom.h:188
AV_CODEC_ID_ADPCM_IMA_WAV
@ AV_CODEC_ID_ADPCM_IMA_WAV
Definition: codec_id.h:368
MOVContext::nb_heif_item
int nb_heif_item
Definition: isom.h:353
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
src
INIT_CLIP pixel * src
Definition: h264pred_template.c:418
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:544
FFInputFormat
Definition: demux.h:37
mov_metadata_loci
static int mov_metadata_loci(MOVContext *c, AVIOContext *pb, unsigned len)
Definition: mov.c:258
AV_CODEC_ID_ILBC
@ AV_CODEC_ID_ILBC
Definition: codec_id.h:499
AV_CHAN_AMBISONIC_BASE
@ AV_CHAN_AMBISONIC_BASE
Range of channels between AV_CHAN_AMBISONIC_BASE and AV_CHAN_AMBISONIC_END represent Ambisonic compon...
Definition: channel_layout.h:101
MOV_TRUN_SAMPLE_SIZE
#define MOV_TRUN_SAMPLE_SIZE
Definition: isom.h:384
MOVStreamContext::tmcd_flags
uint32_t tmcd_flags
tmcd track flags
Definition: isom.h:222
int32_t
int32_t
Definition: audioconvert.c:56
MOVAtom::type
uint32_t type
Definition: isom.h:89
distance
static float distance(float x, float y, int band)
Definition: nellymoserenc.c:231
AVSTREAM_PARSE_FULL
@ AVSTREAM_PARSE_FULL
full parsing and repack
Definition: avformat.h:593
parse_timecode_in_framenum_format
static int parse_timecode_in_framenum_format(AVFormatContext *s, AVStream *st, int64_t value, int flags)
Definition: mov.c:8942
MOVStreamContext::tmcd_nb_frames
uint8_t tmcd_nb_frames
tmcd number of frames per tick / second
Definition: isom.h:223
AVIAMFSubmixElement
Submix element as defined in section 3.7 of IAMF.
Definition: iamf.h:437
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:474
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:225
MP4TrackKindValueMapping::value
const char * value
Definition: isom.h:455
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:797
MOVStsc::count
int count
Definition: isom.h:69
AV_CODEC_ID_PCM_F32LE
@ AV_CODEC_ID_PCM_F32LE
Definition: codec_id.h:349
ff_mov_demuxer
const FFInputFormat ff_mov_demuxer
Definition: mov.c:10329
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:248
MOVContext::heif_grid
HEIFGrid * heif_grid
Definition: isom.h:354
MOVStreamContext::min_sample_duration
uint32_t min_sample_duration
Definition: isom.h:236
MOVStreamContext::current_index
int64_t current_index
Definition: isom.h:204
AVERROR_INVALIDDATA
#define AVERROR_INVALIDDATA
Invalid data found when processing input.
Definition: error.h:61
ff_mov_track_kind_table
const struct MP4TrackKindMapping ff_mov_track_kind_table[]
Definition: isom.c:451
get_curr_st
static AVStream * get_curr_st(MOVContext *c)
Definition: mov.c:191
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:7626
MOVStreamContext::format
uint32_t format
Definition: isom.h:258
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:228
MOVContext::bitrates_count
int bitrates_count
Definition: isom.h:324
AV_CODEC_ID_VORBIS
@ AV_CODEC_ID_VORBIS
Definition: codec_id.h:445
AVDictionaryEntry::value
char * value
Definition: dict.h:91
AVStream::start_time
int64_t start_time
Decoding: pts of the first frame of the stream in presentation order, in stream time base.
Definition: avformat.h:792
MOVStreamContext::id
int id
AVStream id.
Definition: isom.h:171
MOVStreamContext::samples_per_frame
unsigned int samples_per_frame
Definition: isom.h:208
MOVElst::duration
int64_t duration
Definition: isom.h:74
ac3tab.h
avstring.h
mov_read_ispe
static int mov_read_ispe(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:8378
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:8340
IAMFMixPresentation::mix
AVIAMFMixPresentation * mix
mix backs cmix iff the AVIAMFMixPresentation is owned by this structure.
Definition: iamf.h:113
mov_read_mfra
static int mov_read_mfra(MOVContext *c, AVIOContext *f)
Definition: mov.c:9239
AV_CODEC_ID_FLV1
@ AV_CODEC_ID_FLV1
Definition: codec_id.h:73
mov_metadata_int8_no_padding
static int mov_metadata_int8_no_padding(MOVContext *c, AVIOContext *pb, unsigned len, const char *key)
Definition: mov.c:125
flac.h
AVStreamGroupTileGrid::idx
unsigned int idx
Index of the stream in the group this tile references.
Definition: avformat.h:1021
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:1444
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:7837
int
int
Definition: ffmpeg_filter.c:424
MOVStreamContext::stts_count
unsigned int stts_count
Definition: isom.h:176
MOVStreamContext::cenc
struct MOVStreamContext::@345 cenc
MOV_TRUN_SAMPLE_CTS
#define MOV_TRUN_SAMPLE_CTS
Definition: isom.h:386
AV_OPT_TYPE_CONST
@ AV_OPT_TYPE_CONST
Definition: opt.h:254
MOV_ISMV_TTML_TAG
#define MOV_ISMV_TTML_TAG
Definition: isom.h:448
snprintf
#define snprintf
Definition: snprintf.h:34
IAMFMixPresentation::mix_presentation_id
unsigned int mix_presentation_id
Definition: iamf.h:114
AVCodecParameters::initial_padding
int initial_padding
Audio only.
Definition: codec_par.h:203
AV_CODEC_ID_PCM_S24BE
@ AV_CODEC_ID_PCM_S24BE
Definition: codec_id.h:341
get_eia608_packet
static int get_eia608_packet(AVIOContext *pb, AVPacket *pkt, int size)
Definition: mov.c:9864
mov_read_st3d
static int mov_read_st3d(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:6296
is_open_key_sample
static int is_open_key_sample(const MOVStreamContext *sc, int sample)
Definition: mov.c:10089
mov_read_dvc1
static int mov_read_dvc1(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:2326
MOVStreamContext::elst_count
unsigned int elst_count
Definition: isom.h:190
av_color_transfer_name
const char * av_color_transfer_name(enum AVColorTransferCharacteristic transfer)
Definition: pixdesc.c:3320
avpriv_dict_set_timestamp
int avpriv_dict_set_timestamp(AVDictionary **dict, const char *key, int64_t timestamp)
Set a dictionary value to an ISO-8601 compliant timestamp string.
Definition: dict.c:278
AVChannelCustom::id
enum AVChannel id
Definition: channel_layout.h:268
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:2042
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:122
mov_read_chapters
static void mov_read_chapters(AVFormatContext *s)
Definition: mov.c:8843
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:265
MOVContext::cur_item_id
int cur_item_id
Definition: isom.h:351
AVFMT_EVENT_FLAG_METADATA_UPDATED
#define AVFMT_EVENT_FLAG_METADATA_UPDATED
Definition: avformat.h:1632
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:320
MOVContext::found_iinf
int found_iinf
'iinf' atom has been found
Definition: isom.h:298
MOVContext::meta_keys_count
unsigned meta_keys_count
Definition: isom.h:303
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:1041
MOVStreamContext::palette
uint32_t palette[256]
Definition: isom.h:219
cenc_scheme_decrypt
static int cenc_scheme_decrypt(MOVContext *c, MOVStreamContext *sc, AVEncryptionInfo *sample, uint8_t *input, int size)
Definition: mov.c:7382
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:758
mov_parse_stsd_data
static int mov_parse_stsd_data(MOVContext *c, AVIOContext *pb, AVStream *st, MOVStreamContext *sc, int64_t size)
Definition: mov.c:2722
AV_CH_SIDE_LEFT
#define AV_CH_SIDE_LEFT
Definition: channel_layout.h:177
ff_iamf_read_deinit
void ff_iamf_read_deinit(IAMFDemuxContext *c)
Definition: iamf_reader.c:328
AV_RB16
uint64_t_TMPL AV_WL64 unsigned int_TMPL AV_WL32 unsigned int_TMPL AV_WL24 unsigned int_TMPL AV_WL16 uint64_t_TMPL AV_WB64 unsigned int_TMPL AV_WB32 unsigned int_TMPL AV_WB24 unsigned int_TMPL AV_RB16
Definition: bytestream.h:98
av_realloc
void * av_realloc(void *ptr, size_t size)
Allocate, reallocate, or free a block of memory.
Definition: mem.c:155
av_encryption_init_info_add_side_data
uint8_t * av_encryption_init_info_add_side_data(const AVEncryptionInitInfo *info, size_t *side_data_size)
Allocates and initializes side data that holds a copy of the given encryption init info.
Definition: encryption_info.c:292
av_fourcc2str
#define av_fourcc2str(fourcc)
Definition: avutil.h:345
ff_mov_read_chan
int ff_mov_read_chan(AVFormatContext *s, AVIOContext *pb, AVStream *st, int64_t size)
Read 'chan' tag from the input stream.
Definition: mov_chan.c:526
av_index_search_timestamp
int av_index_search_timestamp(AVStream *st, int64_t timestamp, int flags)
Get the index for a specific timestamp.
Definition: seek.c:244
mov_read_pitm
static int mov_read_pitm(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:8059
MOVContext::ignore_chapters
int ignore_chapters
Definition: isom.h:318
mov_read_dac3
static int mov_read_dac3(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:829
MP4TrackKindMapping
Definition: isom.h:458
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:240
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:277
mov_read_stsz
static int mov_read_stsz(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:3238