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);
87 static int64_t add_ctts_entry(MOVCtts** ctts_data, unsigned int* ctts_count, unsigned int* allocated_size,
88  int count, int duration);
89 
91  unsigned len, const char *key)
92 {
93  char buf[16];
94 
95  short current, total = 0;
96  avio_rb16(pb); // unknown
97  current = avio_rb16(pb);
98  if (len >= 6)
99  total = avio_rb16(pb);
100  if (!total)
101  snprintf(buf, sizeof(buf), "%d", current);
102  else
103  snprintf(buf, sizeof(buf), "%d/%d", current, total);
104  c->fc->event_flags |= AVFMT_EVENT_FLAG_METADATA_UPDATED;
105  av_dict_set(&c->fc->metadata, key, buf, 0);
106 
107  return 0;
108 }
109 
111  unsigned len, const char *key)
112 {
113  /* bypass padding bytes */
114  avio_r8(pb);
115  avio_r8(pb);
116  avio_r8(pb);
117 
118  c->fc->event_flags |= AVFMT_EVENT_FLAG_METADATA_UPDATED;
119  av_dict_set_int(&c->fc->metadata, key, avio_r8(pb), 0);
120 
121  return 0;
122 }
123 
125  unsigned len, const char *key)
126 {
127  c->fc->event_flags |= AVFMT_EVENT_FLAG_METADATA_UPDATED;
128  av_dict_set_int(&c->fc->metadata, key, avio_r8(pb), 0);
129 
130  return 0;
131 }
132 
134  unsigned len, const char *key)
135 {
136  short genre;
137 
138  avio_r8(pb); // unknown
139 
140  genre = avio_r8(pb);
141  if (genre < 1 || genre > ID3v1_GENRE_MAX)
142  return 0;
143  c->fc->event_flags |= AVFMT_EVENT_FLAG_METADATA_UPDATED;
144  av_dict_set(&c->fc->metadata, key, ff_id3v1_genre_str[genre-1], 0);
145 
146  return 0;
147 }
148 
149 static const uint32_t mac_to_unicode[128] = {
150  0x00C4,0x00C5,0x00C7,0x00C9,0x00D1,0x00D6,0x00DC,0x00E1,
151  0x00E0,0x00E2,0x00E4,0x00E3,0x00E5,0x00E7,0x00E9,0x00E8,
152  0x00EA,0x00EB,0x00ED,0x00EC,0x00EE,0x00EF,0x00F1,0x00F3,
153  0x00F2,0x00F4,0x00F6,0x00F5,0x00FA,0x00F9,0x00FB,0x00FC,
154  0x2020,0x00B0,0x00A2,0x00A3,0x00A7,0x2022,0x00B6,0x00DF,
155  0x00AE,0x00A9,0x2122,0x00B4,0x00A8,0x2260,0x00C6,0x00D8,
156  0x221E,0x00B1,0x2264,0x2265,0x00A5,0x00B5,0x2202,0x2211,
157  0x220F,0x03C0,0x222B,0x00AA,0x00BA,0x03A9,0x00E6,0x00F8,
158  0x00BF,0x00A1,0x00AC,0x221A,0x0192,0x2248,0x2206,0x00AB,
159  0x00BB,0x2026,0x00A0,0x00C0,0x00C3,0x00D5,0x0152,0x0153,
160  0x2013,0x2014,0x201C,0x201D,0x2018,0x2019,0x00F7,0x25CA,
161  0x00FF,0x0178,0x2044,0x20AC,0x2039,0x203A,0xFB01,0xFB02,
162  0x2021,0x00B7,0x201A,0x201E,0x2030,0x00C2,0x00CA,0x00C1,
163  0x00CB,0x00C8,0x00CD,0x00CE,0x00CF,0x00CC,0x00D3,0x00D4,
164  0xF8FF,0x00D2,0x00DA,0x00DB,0x00D9,0x0131,0x02C6,0x02DC,
165  0x00AF,0x02D8,0x02D9,0x02DA,0x00B8,0x02DD,0x02DB,0x02C7,
166 };
167 
169  char *dst, int dstlen)
170 {
171  char *p = dst;
172  char *end = dst+dstlen-1;
173  int i;
174 
175  for (i = 0; i < len; i++) {
176  uint8_t t, c = avio_r8(pb);
177 
178  if (p >= end)
179  continue;
180 
181  if (c < 0x80)
182  *p++ = c;
183  else if (p < end)
184  PUT_UTF8(mac_to_unicode[c-0x80], t, if (p < end) *p++ = t;);
185  }
186  *p = 0;
187  return p - dst;
188 }
189 
191 {
192  AVStream *st = NULL;
193 
194  if (c->fc->nb_streams < 1)
195  return NULL;
196 
197  for (int i = 0; i < c->nb_heif_item; i++) {
198  HEIFItem *item = &c->heif_item[i];
199 
200  if (!item->st)
201  continue;
202  if (item->st->id != c->cur_item_id)
203  continue;
204 
205  st = item->st;
206  break;
207  }
208  if (!st)
209  st = c->fc->streams[c->fc->nb_streams-1];
210 
211  return st;
212 }
213 
214 static int mov_read_covr(MOVContext *c, AVIOContext *pb, int type, int len)
215 {
216  AVStream *st;
217  MOVStreamContext *sc;
218  enum AVCodecID id;
219  int ret;
220 
221  switch (type) {
222  case 0xd: id = AV_CODEC_ID_MJPEG; break;
223  case 0xe: id = AV_CODEC_ID_PNG; break;
224  case 0x1b: id = AV_CODEC_ID_BMP; break;
225  default:
226  av_log(c->fc, AV_LOG_WARNING, "Unknown cover type: 0x%x.\n", type);
227  avio_skip(pb, len);
228  return 0;
229  }
230 
231  sc = av_mallocz(sizeof(*sc));
232  if (!sc)
233  return AVERROR(ENOMEM);
234  ret = ff_add_attached_pic(c->fc, NULL, pb, NULL, len);
235  if (ret < 0) {
236  av_free(sc);
237  return ret;
238  }
239  st = c->fc->streams[c->fc->nb_streams - 1];
240  st->priv_data = sc;
241  sc->id = st->id;
242  sc->refcount = 1;
243 
244  if (st->attached_pic.size >= 8 && id != AV_CODEC_ID_BMP) {
245  if (AV_RB64(st->attached_pic.data) == 0x89504e470d0a1a0a) {
246  id = AV_CODEC_ID_PNG;
247  } else {
248  id = AV_CODEC_ID_MJPEG;
249  }
250  }
251  st->codecpar->codec_id = id;
252 
253  return 0;
254 }
255 
256 // 3GPP TS 26.244
257 static int mov_metadata_loci(MOVContext *c, AVIOContext *pb, unsigned len)
258 {
259  char language[4] = { 0 };
260  char buf[200], place[100];
261  uint16_t langcode = 0;
262  double longitude, latitude, altitude;
263  const char *key = "location";
264 
265  if (len < 4 + 2 + 1 + 1 + 4 + 4 + 4) {
266  av_log(c->fc, AV_LOG_ERROR, "loci too short\n");
267  return AVERROR_INVALIDDATA;
268  }
269 
270  avio_skip(pb, 4); // version+flags
271  langcode = avio_rb16(pb);
272  ff_mov_lang_to_iso639(langcode, language);
273  len -= 6;
274 
275  len -= avio_get_str(pb, len, place, sizeof(place));
276  if (len < 1) {
277  av_log(c->fc, AV_LOG_ERROR, "place name too long\n");
278  return AVERROR_INVALIDDATA;
279  }
280  avio_skip(pb, 1); // role
281  len -= 1;
282 
283  if (len < 12) {
284  av_log(c->fc, AV_LOG_ERROR,
285  "loci too short (%u bytes left, need at least %d)\n", len, 12);
286  return AVERROR_INVALIDDATA;
287  }
288  longitude = ((int32_t) avio_rb32(pb)) / (float) (1 << 16);
289  latitude = ((int32_t) avio_rb32(pb)) / (float) (1 << 16);
290  altitude = ((int32_t) avio_rb32(pb)) / (float) (1 << 16);
291 
292  // Try to output in the same format as the ?xyz field
293  snprintf(buf, sizeof(buf), "%+08.4f%+09.4f", latitude, longitude);
294  if (altitude)
295  av_strlcatf(buf, sizeof(buf), "%+f", altitude);
296  av_strlcatf(buf, sizeof(buf), "/%s", place);
297 
298  if (*language && strcmp(language, "und")) {
299  char key2[16];
300  snprintf(key2, sizeof(key2), "%s-%s", key, language);
301  av_dict_set(&c->fc->metadata, key2, buf, 0);
302  }
303  c->fc->event_flags |= AVFMT_EVENT_FLAG_METADATA_UPDATED;
304  return av_dict_set(&c->fc->metadata, key, buf, 0);
305 }
306 
307 static int mov_metadata_hmmt(MOVContext *c, AVIOContext *pb, unsigned len)
308 {
309  int i, n_hmmt;
310 
311  if (len < 2)
312  return 0;
313  if (c->ignore_chapters)
314  return 0;
315 
316  n_hmmt = avio_rb32(pb);
317  if (n_hmmt > len / 4)
318  return AVERROR_INVALIDDATA;
319  for (i = 0; i < n_hmmt && !pb->eof_reached; i++) {
320  int moment_time = avio_rb32(pb);
321  avpriv_new_chapter(c->fc, i, av_make_q(1, 1000), moment_time, AV_NOPTS_VALUE, NULL);
322  }
323  if (avio_feof(pb))
324  return AVERROR_INVALIDDATA;
325  return 0;
326 }
327 
329 {
330  char tmp_key[AV_FOURCC_MAX_STRING_SIZE] = {0};
331  char key2[32], language[4] = {0};
332  char *str = NULL;
333  const char *key = NULL;
334  uint16_t langcode = 0;
335  uint32_t data_type = 0, str_size, str_size_alloc;
336  int (*parse)(MOVContext*, AVIOContext*, unsigned, const char*) = NULL;
337  int raw = 0;
338  int num = 0;
339 
340  switch (atom.type) {
341  case MKTAG( '@','P','R','M'): key = "premiere_version"; raw = 1; break;
342  case MKTAG( '@','P','R','Q'): key = "quicktime_version"; raw = 1; break;
343  case MKTAG( 'X','M','P','_'):
344  if (c->export_xmp) { key = "xmp"; raw = 1; } break;
345  case MKTAG( 'a','A','R','T'): key = "album_artist"; break;
346  case MKTAG( 'a','k','I','D'): key = "account_type";
348  case MKTAG( 'a','p','I','D'): key = "account_id"; break;
349  case MKTAG( 'c','a','t','g'): key = "category"; break;
350  case MKTAG( 'c','p','i','l'): key = "compilation";
352  case MKTAG( 'c','p','r','t'): key = "copyright"; break;
353  case MKTAG( 'd','e','s','c'): key = "description"; break;
354  case MKTAG( 'd','i','s','k'): key = "disc";
356  case MKTAG( 'e','g','i','d'): key = "episode_uid";
358  case MKTAG( 'F','I','R','M'): key = "firmware"; raw = 1; break;
359  case MKTAG( 'g','n','r','e'): key = "genre";
360  parse = mov_metadata_gnre; break;
361  case MKTAG( 'h','d','v','d'): key = "hd_video";
363  case MKTAG( 'H','M','M','T'):
364  return mov_metadata_hmmt(c, pb, atom.size);
365  case MKTAG( 'k','e','y','w'): key = "keywords"; break;
366  case MKTAG( 'l','d','e','s'): key = "synopsis"; break;
367  case MKTAG( 'l','o','c','i'):
368  return mov_metadata_loci(c, pb, atom.size);
369  case MKTAG( 'm','a','n','u'): key = "make"; break;
370  case MKTAG( 'm','o','d','l'): key = "model"; break;
371  case MKTAG( 'p','c','s','t'): key = "podcast";
373  case MKTAG( 'p','g','a','p'): key = "gapless_playback";
375  case MKTAG( 'p','u','r','d'): key = "purchase_date"; break;
376  case MKTAG( 'r','t','n','g'): key = "rating";
378  case MKTAG( 's','o','a','a'): key = "sort_album_artist"; break;
379  case MKTAG( 's','o','a','l'): key = "sort_album"; break;
380  case MKTAG( 's','o','a','r'): key = "sort_artist"; break;
381  case MKTAG( 's','o','c','o'): key = "sort_composer"; break;
382  case MKTAG( 's','o','n','m'): key = "sort_name"; break;
383  case MKTAG( 's','o','s','n'): key = "sort_show"; break;
384  case MKTAG( 's','t','i','k'): key = "media_type";
386  case MKTAG( 't','r','k','n'): key = "track";
388  case MKTAG( 't','v','e','n'): key = "episode_id"; break;
389  case MKTAG( 't','v','e','s'): key = "episode_sort";
391  case MKTAG( 't','v','n','n'): key = "network"; break;
392  case MKTAG( 't','v','s','h'): key = "show"; break;
393  case MKTAG( 't','v','s','n'): key = "season_number";
395  case MKTAG(0xa9,'A','R','T'): key = "artist"; break;
396  case MKTAG(0xa9,'P','R','D'): key = "producer"; break;
397  case MKTAG(0xa9,'a','l','b'): key = "album"; break;
398  case MKTAG(0xa9,'a','u','t'): key = "artist"; break;
399  case MKTAG(0xa9,'c','h','p'): key = "chapter"; break;
400  case MKTAG(0xa9,'c','m','t'): key = "comment"; break;
401  case MKTAG(0xa9,'c','o','m'): key = "composer"; break;
402  case MKTAG(0xa9,'c','p','y'): key = "copyright"; break;
403  case MKTAG(0xa9,'d','a','y'): key = "date"; break;
404  case MKTAG(0xa9,'d','i','r'): key = "director"; break;
405  case MKTAG(0xa9,'d','i','s'): key = "disclaimer"; break;
406  case MKTAG(0xa9,'e','d','1'): key = "edit_date"; break;
407  case MKTAG(0xa9,'e','n','c'): key = "encoder"; break;
408  case MKTAG(0xa9,'f','m','t'): key = "original_format"; break;
409  case MKTAG(0xa9,'g','e','n'): key = "genre"; break;
410  case MKTAG(0xa9,'g','r','p'): key = "grouping"; break;
411  case MKTAG(0xa9,'h','s','t'): key = "host_computer"; break;
412  case MKTAG(0xa9,'i','n','f'): key = "comment"; break;
413  case MKTAG(0xa9,'l','y','r'): key = "lyrics"; break;
414  case MKTAG(0xa9,'m','a','k'): key = "make"; break;
415  case MKTAG(0xa9,'m','o','d'): key = "model"; break;
416  case MKTAG(0xa9,'n','a','m'): key = "title"; break;
417  case MKTAG(0xa9,'o','p','e'): key = "original_artist"; break;
418  case MKTAG(0xa9,'p','r','d'): key = "producer"; break;
419  case MKTAG(0xa9,'p','r','f'): key = "performers"; break;
420  case MKTAG(0xa9,'r','e','q'): key = "playback_requirements"; break;
421  case MKTAG(0xa9,'s','r','c'): key = "original_source"; break;
422  case MKTAG(0xa9,'s','t','3'): key = "subtitle"; break;
423  case MKTAG(0xa9,'s','w','r'): key = "encoder"; break;
424  case MKTAG(0xa9,'t','o','o'): key = "encoder"; break;
425  case MKTAG(0xa9,'t','r','k'): key = "track"; break;
426  case MKTAG(0xa9,'u','r','l'): key = "URL"; break;
427  case MKTAG(0xa9,'w','r','n'): key = "warning"; break;
428  case MKTAG(0xa9,'w','r','t'): key = "composer"; break;
429  case MKTAG(0xa9,'x','y','z'): key = "location"; break;
430  }
431 retry:
432  if (c->itunes_metadata && atom.size > 8) {
433  int data_size = avio_rb32(pb);
434  int tag = avio_rl32(pb);
435  if (tag == MKTAG('d','a','t','a') && data_size <= atom.size && data_size >= 16) {
436  data_type = avio_rb32(pb); // type
437  avio_rb32(pb); // unknown
438  str_size = data_size - 16;
439  atom.size -= 16;
440 
441  if (!key && c->found_hdlr_mdta && c->meta_keys) {
442  uint32_t index = av_bswap32(atom.type); // BE number has been read as LE
443  if (index < c->meta_keys_count && index > 0) {
444  key = c->meta_keys[index];
445  } else if (atom.type != MKTAG('c', 'o', 'v', 'r')) {
446  av_log(c->fc, AV_LOG_WARNING,
447  "The index of 'data' is out of range: %"PRId32" < 1 or >= %d.\n",
448  index, c->meta_keys_count);
449  }
450  }
451  if (atom.type == MKTAG('c', 'o', 'v', 'r') ||
452  (key && !strcmp(key, "com.apple.quicktime.artwork"))) {
453  int ret = mov_read_covr(c, pb, data_type, str_size);
454  if (ret < 0) {
455  av_log(c->fc, AV_LOG_ERROR, "Error parsing cover art.\n");
456  return ret;
457  }
458  atom.size -= str_size;
459  if (atom.size > 8)
460  goto retry;
461  return ret;
462  }
463  } else return 0;
464  } else if (atom.size > 4 && key && !c->itunes_metadata && !raw) {
465  str_size = avio_rb16(pb); // string length
466  if (str_size > atom.size) {
467  raw = 1;
468  avio_seek(pb, -2, SEEK_CUR);
469  av_log(c->fc, AV_LOG_WARNING, "UDTA parsing failed retrying raw\n");
470  goto retry;
471  }
472  langcode = avio_rb16(pb);
473  ff_mov_lang_to_iso639(langcode, language);
474  atom.size -= 4;
475  } else
476  str_size = atom.size;
477 
478  if (c->export_all && !key) {
479  key = av_fourcc_make_string(tmp_key, atom.type);
480  }
481 
482  if (!key)
483  return 0;
484  if (atom.size < 0 || str_size >= INT_MAX/2)
485  return AVERROR_INVALIDDATA;
486 
487  // Allocates enough space if data_type is a int32 or float32 number, otherwise
488  // worst-case requirement for output string in case of utf8 coded input
489  num = (data_type >= 21 && data_type <= 23);
490  str_size_alloc = (num ? 512 : (raw ? str_size : str_size * 2)) + 1;
491  str = av_mallocz(str_size_alloc);
492  if (!str)
493  return AVERROR(ENOMEM);
494 
495  if (parse)
496  parse(c, pb, str_size, key);
497  else {
498  if (!raw && (data_type == 3 || (data_type == 0 && (langcode < 0x400 || langcode == 0x7fff)))) { // MAC Encoded
499  mov_read_mac_string(c, pb, str_size, str, str_size_alloc);
500  } else if (data_type == 21) { // BE signed integer, variable size
501  int val = 0;
502  if (str_size == 1)
503  val = (int8_t)avio_r8(pb);
504  else if (str_size == 2)
505  val = (int16_t)avio_rb16(pb);
506  else if (str_size == 3)
507  val = ((int32_t)(avio_rb24(pb)<<8))>>8;
508  else if (str_size == 4)
509  val = (int32_t)avio_rb32(pb);
510  if (snprintf(str, str_size_alloc, "%d", val) >= str_size_alloc) {
511  av_log(c->fc, AV_LOG_ERROR,
512  "Failed to store the number (%d) in string.\n", val);
513  av_free(str);
514  return AVERROR_INVALIDDATA;
515  }
516  } else if (data_type == 22) { // BE unsigned integer, variable size
517  unsigned int val = 0;
518  if (str_size == 1)
519  val = avio_r8(pb);
520  else if (str_size == 2)
521  val = avio_rb16(pb);
522  else if (str_size == 3)
523  val = avio_rb24(pb);
524  else if (str_size == 4)
525  val = avio_rb32(pb);
526  if (snprintf(str, str_size_alloc, "%u", val) >= str_size_alloc) {
527  av_log(c->fc, AV_LOG_ERROR,
528  "Failed to store the number (%u) in string.\n", val);
529  av_free(str);
530  return AVERROR_INVALIDDATA;
531  }
532  } else if (data_type == 23 && str_size >= 4) { // BE float32
533  float val = av_int2float(avio_rb32(pb));
534  if (snprintf(str, str_size_alloc, "%f", val) >= str_size_alloc) {
535  av_log(c->fc, AV_LOG_ERROR,
536  "Failed to store the float32 number (%f) in string.\n", val);
537  av_free(str);
538  return AVERROR_INVALIDDATA;
539  }
540  } else if (data_type > 1 && data_type != 4) {
541  // data_type can be 0 if not set at all above. data_type 1 means
542  // UTF8 and 4 means "UTF8 sort". For any other type (UTF16 or e.g.
543  // a picture), don't return it blindly in a string that is supposed
544  // to be UTF8 text.
545  av_log(c->fc, AV_LOG_WARNING, "Skipping unhandled metadata %s of type %d\n", key, data_type);
546  av_free(str);
547  return 0;
548  } else {
549  int ret = ffio_read_size(pb, str, str_size);
550  if (ret < 0) {
551  av_free(str);
552  return ret;
553  }
554  str[str_size] = 0;
555  }
556  c->fc->event_flags |= AVFMT_EVENT_FLAG_METADATA_UPDATED;
557  av_dict_set(&c->fc->metadata, key, str, 0);
558  if (*language && strcmp(language, "und")) {
559  snprintf(key2, sizeof(key2), "%s-%s", key, language);
560  av_dict_set(&c->fc->metadata, key2, str, 0);
561  }
562  if (!strcmp(key, "encoder")) {
563  int major, minor, micro;
564  if (sscanf(str, "HandBrake %d.%d.%d", &major, &minor, &micro) == 3) {
565  c->handbrake_version = 1000000*major + 1000*minor + micro;
566  }
567  }
568  }
569 
570  av_freep(&str);
571  return 0;
572 }
573 
575 {
576  int64_t start;
577  int i, nb_chapters, str_len, version;
578  char str[256+1];
579  int ret;
580 
581  if (c->ignore_chapters)
582  return 0;
583 
584  if ((atom.size -= 5) < 0)
585  return 0;
586 
587  version = avio_r8(pb);
588  avio_rb24(pb);
589  if (version)
590  avio_rb32(pb); // ???
591  nb_chapters = avio_r8(pb);
592 
593  for (i = 0; i < nb_chapters; i++) {
594  if (atom.size < 9)
595  return 0;
596 
597  start = avio_rb64(pb);
598  str_len = avio_r8(pb);
599 
600  if ((atom.size -= 9+str_len) < 0)
601  return 0;
602 
603  ret = ffio_read_size(pb, str, str_len);
604  if (ret < 0)
605  return ret;
606  str[str_len] = 0;
607  avpriv_new_chapter(c->fc, i, (AVRational){1,10000000}, start, AV_NOPTS_VALUE, str);
608  }
609  return 0;
610 }
611 
612 #define MIN_DATA_ENTRY_BOX_SIZE 12
614 {
615  AVStream *st;
616  MOVStreamContext *sc;
617  int entries, i, j;
618 
619  if (c->fc->nb_streams < 1)
620  return 0;
621  st = c->fc->streams[c->fc->nb_streams-1];
622  sc = st->priv_data;
623 
624  avio_rb32(pb); // version + flags
625  entries = avio_rb32(pb);
626  if (!entries ||
627  entries > (atom.size - 1) / MIN_DATA_ENTRY_BOX_SIZE + 1 ||
628  entries >= UINT_MAX / sizeof(*sc->drefs))
629  return AVERROR_INVALIDDATA;
630 
631  for (i = 0; i < sc->drefs_count; i++) {
632  MOVDref *dref = &sc->drefs[i];
633  av_freep(&dref->path);
634  av_freep(&dref->dir);
635  }
636  av_free(sc->drefs);
637  sc->drefs_count = 0;
638  sc->drefs = av_mallocz(entries * sizeof(*sc->drefs));
639  if (!sc->drefs)
640  return AVERROR(ENOMEM);
641  sc->drefs_count = entries;
642 
643  for (i = 0; i < entries; i++) {
644  MOVDref *dref = &sc->drefs[i];
645  uint32_t size = avio_rb32(pb);
646  int64_t next = avio_tell(pb);
647 
648  if (size < 12 || next < 0 || next > INT64_MAX - size)
649  return AVERROR_INVALIDDATA;
650 
651  next += size - 4;
652 
653  dref->type = avio_rl32(pb);
654  avio_rb32(pb); // version + flags
655 
656  if (dref->type == MKTAG('a','l','i','s') && size > 150) {
657  /* macintosh alias record */
658  uint16_t volume_len, len;
659  int16_t type;
660  int ret;
661 
662  avio_skip(pb, 10);
663 
664  volume_len = avio_r8(pb);
665  volume_len = FFMIN(volume_len, 27);
666  ret = ffio_read_size(pb, dref->volume, 27);
667  if (ret < 0)
668  return ret;
669  dref->volume[volume_len] = 0;
670  av_log(c->fc, AV_LOG_DEBUG, "volume %s, len %d\n", dref->volume, volume_len);
671 
672  avio_skip(pb, 12);
673 
674  len = avio_r8(pb);
675  len = FFMIN(len, 63);
676  ret = ffio_read_size(pb, dref->filename, 63);
677  if (ret < 0)
678  return ret;
679  dref->filename[len] = 0;
680  av_log(c->fc, AV_LOG_DEBUG, "filename %s, len %d\n", dref->filename, len);
681 
682  avio_skip(pb, 16);
683 
684  /* read next level up_from_alias/down_to_target */
685  dref->nlvl_from = avio_rb16(pb);
686  dref->nlvl_to = avio_rb16(pb);
687  av_log(c->fc, AV_LOG_DEBUG, "nlvl from %d, nlvl to %d\n",
688  dref->nlvl_from, dref->nlvl_to);
689 
690  avio_skip(pb, 16);
691 
692  for (type = 0; type != -1 && avio_tell(pb) < next; ) {
693  if (avio_feof(pb))
694  return AVERROR_EOF;
695  type = avio_rb16(pb);
696  len = avio_rb16(pb);
697  av_log(c->fc, AV_LOG_DEBUG, "type %d, len %d\n", type, len);
698  if (len&1)
699  len += 1;
700  if (type == 2) { // absolute path
701  av_free(dref->path);
702  dref->path = av_mallocz(len+1);
703  if (!dref->path)
704  return AVERROR(ENOMEM);
705 
706  ret = ffio_read_size(pb, dref->path, len);
707  if (ret < 0) {
708  av_freep(&dref->path);
709  return ret;
710  }
711  if (len > volume_len && !strncmp(dref->path, dref->volume, volume_len)) {
712  len -= volume_len;
713  memmove(dref->path, dref->path+volume_len, len);
714  dref->path[len] = 0;
715  }
716  // trim string of any ending zeros
717  for (j = len - 1; j >= 0; j--) {
718  if (dref->path[j] == 0)
719  len--;
720  else
721  break;
722  }
723  for (j = 0; j < len; j++)
724  if (dref->path[j] == ':' || dref->path[j] == 0)
725  dref->path[j] = '/';
726  av_log(c->fc, AV_LOG_DEBUG, "path %s\n", dref->path);
727  } else if (type == 0) { // directory name
728  av_free(dref->dir);
729  dref->dir = av_malloc(len+1);
730  if (!dref->dir)
731  return AVERROR(ENOMEM);
732 
733  ret = ffio_read_size(pb, dref->dir, len);
734  if (ret < 0) {
735  av_freep(&dref->dir);
736  return ret;
737  }
738  dref->dir[len] = 0;
739  for (j = 0; j < len; j++)
740  if (dref->dir[j] == ':')
741  dref->dir[j] = '/';
742  av_log(c->fc, AV_LOG_DEBUG, "dir %s\n", dref->dir);
743  } else
744  avio_skip(pb, len);
745  }
746  } else {
747  av_log(c->fc, AV_LOG_DEBUG, "Unknown dref type 0x%08"PRIx32" size %"PRIu32"\n",
748  dref->type, size);
749  entries--;
750  i--;
751  }
752  avio_seek(pb, next, SEEK_SET);
753  }
754  return 0;
755 }
756 
758 {
759  AVStream *st;
760  uint32_t type;
761  uint32_t ctype;
762  int64_t title_size;
763  char *title_str;
764  int ret;
765 
766  avio_r8(pb); /* version */
767  avio_rb24(pb); /* flags */
768 
769  /* component type */
770  ctype = avio_rl32(pb);
771  type = avio_rl32(pb); /* component subtype */
772 
773  av_log(c->fc, AV_LOG_TRACE, "ctype=%s\n", av_fourcc2str(ctype));
774  av_log(c->fc, AV_LOG_TRACE, "stype=%s\n", av_fourcc2str(type));
775 
776  if (c->trak_index < 0) { // meta not inside a trak
777  if (type == MKTAG('m','d','t','a')) {
778  c->found_hdlr_mdta = 1;
779  }
780  return 0;
781  }
782 
783  st = c->fc->streams[c->fc->nb_streams-1];
784 
785  if (type == MKTAG('v','i','d','e'))
787  else if (type == MKTAG('s','o','u','n'))
789  else if (type == MKTAG('m','1','a',' '))
791  else if ((type == MKTAG('s','u','b','p')) || (type == MKTAG('c','l','c','p')))
793 
794  avio_rb32(pb); /* component manufacture */
795  avio_rb32(pb); /* component flags */
796  avio_rb32(pb); /* component flags mask */
797 
798  title_size = atom.size - 24;
799  if (title_size > 0) {
800  if (title_size > FFMIN(INT_MAX, SIZE_MAX-1))
801  return AVERROR_INVALIDDATA;
802  title_str = av_malloc(title_size + 1); /* Add null terminator */
803  if (!title_str)
804  return AVERROR(ENOMEM);
805 
806  ret = ffio_read_size(pb, title_str, title_size);
807  if (ret < 0) {
808  av_freep(&title_str);
809  return ret;
810  }
811  title_str[title_size] = 0;
812  if (title_str[0]) {
813  int off = (!c->isom && title_str[0] == title_size - 1);
814  // flag added so as to not set stream handler name if already set from mdia->hdlr
815  av_dict_set(&st->metadata, "handler_name", title_str + off, AV_DICT_DONT_OVERWRITE);
816  }
817  av_freep(&title_str);
818  }
819 
820  return 0;
821 }
822 
824 {
825  return ff_mov_read_esds(c->fc, pb);
826 }
827 
829 {
830  AVStream *st;
831  AVPacketSideData *sd;
832  enum AVAudioServiceType *ast;
833  int ac3info, acmod, lfeon, bsmod;
834  uint64_t mask;
835 
836  if (c->fc->nb_streams < 1)
837  return 0;
838  st = c->fc->streams[c->fc->nb_streams-1];
839 
843  sizeof(*ast), 0);
844  if (!sd)
845  return AVERROR(ENOMEM);
846 
847  ast = (enum AVAudioServiceType*)sd->data;
848  ac3info = avio_rb24(pb);
849  bsmod = (ac3info >> 14) & 0x7;
850  acmod = (ac3info >> 11) & 0x7;
851  lfeon = (ac3info >> 10) & 0x1;
852 
854  if (lfeon)
858 
859  *ast = bsmod;
860  if (st->codecpar->ch_layout.nb_channels > 1 && bsmod == 0x7)
862 
863  return 0;
864 }
865 
866 #if CONFIG_IAMFDEC
867 static int mov_read_iacb(MOVContext *c, AVIOContext *pb, MOVAtom atom)
868 {
869  AVStream *st;
870  MOVStreamContext *sc;
871  FFIOContext b;
872  AVIOContext *descriptor_pb;
873  AVDictionary *metadata;
874  IAMFContext *iamf;
875  int64_t start_time, duration;
876  unsigned descriptors_size;
877  int nb_frames, disposition;
878  int version, ret;
879 
880  if (atom.size < 5)
881  return AVERROR_INVALIDDATA;
882 
883  if (c->fc->nb_streams < 1)
884  return 0;
885 
886  version = avio_r8(pb);
887  if (version != 1) {
888  av_log(c->fc, AV_LOG_ERROR, "%s configurationVersion %d",
889  version < 1 ? "invalid" : "unsupported", version);
890  return AVERROR_INVALIDDATA;
891  }
892 
893  descriptors_size = ffio_read_leb(pb);
894  if (!descriptors_size || descriptors_size > INT_MAX)
895  return AVERROR_INVALIDDATA;
896 
897  st = c->fc->streams[c->fc->nb_streams - 1];
898  sc = st->priv_data;
899 
900  sc->iamf = av_mallocz(sizeof(*sc->iamf));
901  if (!sc->iamf)
902  return AVERROR(ENOMEM);
903  iamf = &sc->iamf->iamf;
904 
905  st->codecpar->extradata = av_malloc(descriptors_size);
906  if (!st->codecpar->extradata)
907  return AVERROR(ENOMEM);
908  st->codecpar->extradata_size = descriptors_size;
909 
910  ret = avio_read(pb, st->codecpar->extradata, descriptors_size);
911  if (ret != descriptors_size)
912  return ret < 0 ? ret : AVERROR_INVALIDDATA;
913 
914  ffio_init_read_context(&b, st->codecpar->extradata, descriptors_size);
915  descriptor_pb = &b.pub;
916 
917  ret = ff_iamfdec_read_descriptors(iamf, descriptor_pb, descriptors_size, c->fc);
918  if (ret < 0)
919  return ret;
920 
921  metadata = st->metadata;
922  st->metadata = NULL;
923  start_time = st->start_time;
924  nb_frames = st->nb_frames;
925  duration = st->duration;
926  disposition = st->disposition;
927 
928  for (int i = 0; i < iamf->nb_audio_elements; i++) {
929  IAMFAudioElement *audio_element = iamf->audio_elements[i];
930  const AVIAMFAudioElement *element;
931  AVStreamGroup *stg =
933 
934  if (!stg) {
935  ret = AVERROR(ENOMEM);
936  goto fail;
937  }
938 
940  stg->id = audio_element->audio_element_id;
941  /* Transfer ownership */
942  element = stg->params.iamf_audio_element = audio_element->element;
943  audio_element->element = NULL;
944 
945  for (int j = 0; j < audio_element->nb_substreams; j++) {
946  IAMFSubStream *substream = &audio_element->substreams[j];
947  AVStream *stream;
948 
949  if (!i && !j) {
950  if (audio_element->layers[0].substream_count != 1)
951  disposition &= ~AV_DISPOSITION_DEFAULT;
952  stream = st;
953  } else
954  stream = avformat_new_stream(c->fc, NULL);
955  if (!stream) {
956  ret = AVERROR(ENOMEM);
957  goto fail;
958  }
959 
960  stream->start_time = start_time;
961  stream->nb_frames = nb_frames;
962  stream->duration = duration;
963  stream->disposition = disposition;
964  if (stream != st) {
965  stream->priv_data = sc;
966  sc->refcount++;
967  }
968 
971  if (i || j) {
973  if (audio_element->layers[0].substream_count == 1)
975  }
976 
977  ret = avcodec_parameters_copy(stream->codecpar, substream->codecpar);
978  if (ret < 0)
979  goto fail;
980 
981  stream->id = substream->audio_substream_id;
982 
983  avpriv_set_pts_info(st, 64, 1, sc->time_scale);
984 
985  ret = avformat_stream_group_add_stream(stg, stream);
986  if (ret < 0)
987  goto fail;
988  }
989 
990  ret = av_dict_copy(&stg->metadata, metadata, 0);
991  if (ret < 0)
992  goto fail;
993  }
994 
995  for (int i = 0; i < iamf->nb_mix_presentations; i++) {
996  IAMFMixPresentation *mix_presentation = iamf->mix_presentations[i];
997  const AVIAMFMixPresentation *mix = mix_presentation->cmix;
998  AVStreamGroup *stg =
1000 
1001  if (!stg) {
1002  ret = AVERROR(ENOMEM);
1003  goto fail;
1004  }
1005 
1007  stg->id = mix_presentation->mix_presentation_id;
1008  /* Transfer ownership */
1009  stg->params.iamf_mix_presentation = mix_presentation->mix;
1010  mix_presentation->mix = NULL;
1011 
1012  for (int j = 0; j < mix->nb_submixes; j++) {
1013  const AVIAMFSubmix *submix = mix->submixes[j];
1014 
1015  for (int k = 0; k < submix->nb_elements; k++) {
1016  const AVIAMFSubmixElement *submix_element = submix->elements[k];
1017  const AVStreamGroup *audio_element = NULL;
1018 
1019  for (int l = 0; l < c->fc->nb_stream_groups; l++)
1020  if (c->fc->stream_groups[l]->type == AV_STREAM_GROUP_PARAMS_IAMF_AUDIO_ELEMENT &&
1021  c->fc->stream_groups[l]->id == submix_element->audio_element_id) {
1022  audio_element = c->fc->stream_groups[l];
1023  break;
1024  }
1025  av_assert0(audio_element);
1026 
1027  for (int l = 0; l < audio_element->nb_streams; l++) {
1028  ret = avformat_stream_group_add_stream(stg, audio_element->streams[l]);
1029  if (ret < 0 && ret != AVERROR(EEXIST))
1030  goto fail;
1031  }
1032  }
1033  }
1034 
1035  ret = av_dict_copy(&stg->metadata, metadata, 0);
1036  if (ret < 0)
1037  goto fail;
1038  }
1039 
1040  ret = 0;
1041 fail:
1042  av_dict_free(&metadata);
1043 
1044  return ret;
1045 }
1046 #endif
1047 
1049 {
1050  AVStream *st;
1051  AVPacketSideData *sd;
1052  enum AVAudioServiceType *ast;
1053  int eac3info, acmod, lfeon, bsmod;
1054  uint64_t mask;
1055 
1056  if (c->fc->nb_streams < 1)
1057  return 0;
1058  st = c->fc->streams[c->fc->nb_streams-1];
1059 
1063  sizeof(*ast), 0);
1064  if (!sd)
1065  return AVERROR(ENOMEM);
1066 
1067  ast = (enum AVAudioServiceType*)sd->data;
1068 
1069  /* No need to parse fields for additional independent substreams and its
1070  * associated dependent substreams since libavcodec's E-AC-3 decoder
1071  * does not support them yet. */
1072  avio_rb16(pb); /* data_rate and num_ind_sub */
1073  eac3info = avio_rb24(pb);
1074  bsmod = (eac3info >> 12) & 0x1f;
1075  acmod = (eac3info >> 9) & 0x7;
1076  lfeon = (eac3info >> 8) & 0x1;
1077 
1079  if (lfeon)
1083 
1084  *ast = bsmod;
1085  if (st->codecpar->ch_layout.nb_channels > 1 && bsmod == 0x7)
1087 
1088  return 0;
1089 }
1090 
1092 {
1093 #define DDTS_SIZE 20
1094  uint8_t buf[DDTS_SIZE + AV_INPUT_BUFFER_PADDING_SIZE];
1095  AVStream *st = NULL;
1096  uint32_t frame_duration_code = 0;
1097  uint32_t channel_layout_code = 0;
1098  GetBitContext gb;
1099  int ret;
1100 
1101  if ((ret = ffio_read_size(pb, buf, DDTS_SIZE)) < 0)
1102  return ret;
1103 
1104  init_get_bits(&gb, buf, 8 * DDTS_SIZE);
1105 
1106  if (c->fc->nb_streams < 1) {
1107  return 0;
1108  }
1109  st = c->fc->streams[c->fc->nb_streams-1];
1110 
1111  st->codecpar->sample_rate = get_bits_long(&gb, 32);
1112  if (st->codecpar->sample_rate <= 0) {
1113  av_log(c->fc, AV_LOG_ERROR, "Invalid sample rate %d\n", st->codecpar->sample_rate);
1114  return AVERROR_INVALIDDATA;
1115  }
1116  skip_bits_long(&gb, 32); /* max bitrate */
1117  st->codecpar->bit_rate = get_bits_long(&gb, 32);
1118  st->codecpar->bits_per_coded_sample = get_bits(&gb, 8);
1119  frame_duration_code = get_bits(&gb, 2);
1120  skip_bits(&gb, 30); /* various fields */
1121  channel_layout_code = get_bits(&gb, 16);
1122 
1123  st->codecpar->frame_size =
1124  (frame_duration_code == 0) ? 512 :
1125  (frame_duration_code == 1) ? 1024 :
1126  (frame_duration_code == 2) ? 2048 :
1127  (frame_duration_code == 3) ? 4096 : 0;
1128 
1129  if (channel_layout_code > 0xff) {
1130  av_log(c->fc, AV_LOG_WARNING, "Unsupported DTS audio channel layout\n");
1131  }
1134  ((channel_layout_code & 0x1) ? AV_CH_FRONT_CENTER : 0) |
1135  ((channel_layout_code & 0x2) ? AV_CH_FRONT_LEFT : 0) |
1136  ((channel_layout_code & 0x2) ? AV_CH_FRONT_RIGHT : 0) |
1137  ((channel_layout_code & 0x4) ? AV_CH_SIDE_LEFT : 0) |
1138  ((channel_layout_code & 0x4) ? AV_CH_SIDE_RIGHT : 0) |
1139  ((channel_layout_code & 0x8) ? AV_CH_LOW_FREQUENCY : 0));
1140 
1141  return 0;
1142 }
1143 
1145 {
1146  AVStream *st;
1147 
1148  if (c->fc->nb_streams < 1)
1149  return 0;
1150  st = c->fc->streams[c->fc->nb_streams-1];
1151 
1152  if (atom.size < 16)
1153  return 0;
1154 
1155  /* skip version and flags */
1156  avio_skip(pb, 4);
1157 
1158  ff_mov_read_chan(c->fc, pb, st, atom.size - 4);
1159 
1160  return 0;
1161 }
1162 
1164 {
1165  int64_t end = av_sat_add64(avio_tell(pb), atom.size);
1166  int version, flags;
1167  int ret;
1168  AVStream *st;
1169 
1170  if (c->fc->nb_streams < 1)
1171  return 0;
1172  st = c->fc->streams[c->fc->nb_streams-1];
1173 
1174  version = avio_r8(pb);
1175  flags = avio_rb24(pb);
1176  if (version != 0 || flags != 0) {
1177  av_log(c->fc, AV_LOG_ERROR,
1178  "Unsupported 'chnl' box with version %d, flags: %#x",
1179  version, flags);
1180  return AVERROR_INVALIDDATA;
1181  }
1182 
1183  ret = ff_mov_read_chnl(c->fc, pb, st);
1184  if (ret < 0)
1185  return ret;
1186 
1187  if (avio_tell(pb) != end) {
1188  av_log(c->fc, AV_LOG_WARNING, "skip %" PRId64 " bytes of unknown data inside chnl\n",
1189  end - avio_tell(pb));
1190  avio_seek(pb, end, SEEK_SET);
1191  }
1192  return ret;
1193 }
1194 
1196 {
1197  AVStream *st;
1198  int ret;
1199 
1200  if (c->fc->nb_streams < 1)
1201  return 0;
1202  st = c->fc->streams[c->fc->nb_streams-1];
1203 
1204  if ((ret = ff_get_wav_header(c->fc, pb, st->codecpar, atom.size, 0)) < 0)
1205  av_log(c->fc, AV_LOG_WARNING, "get_wav_header failed\n");
1206 
1207  return ret;
1208 }
1209 
1210 /* This atom overrides any previously set aspect ratio */
1212 {
1213  const int num = avio_rb32(pb);
1214  const int den = avio_rb32(pb);
1215  AVStream *st;
1216 
1217  if (c->fc->nb_streams < 1)
1218  return 0;
1219  st = c->fc->streams[c->fc->nb_streams-1];
1220 
1221  if (den != 0) {
1223  num, den, 32767);
1224  }
1225  return 0;
1226 }
1227 
1228 /* this atom contains actual media data */
1230 {
1231  if (atom.size == 0) /* wrong one (MP4) */
1232  return 0;
1233  c->found_mdat=1;
1234  return 0; /* now go for moov */
1235 }
1236 
1237 #define DRM_BLOB_SIZE 56
1238 
1240 {
1241  uint8_t intermediate_key[20];
1242  uint8_t intermediate_iv[20];
1243  uint8_t input[64];
1244  uint8_t output[64];
1245  uint8_t file_checksum[20];
1246  uint8_t calculated_checksum[20];
1247  char checksum_string[2 * sizeof(file_checksum) + 1];
1248  struct AVSHA *sha;
1249  int i;
1250  int ret = 0;
1251  uint8_t *activation_bytes = c->activation_bytes;
1252  uint8_t *fixed_key = c->audible_fixed_key;
1253 
1254  c->aax_mode = 1;
1255 
1256  sha = av_sha_alloc();
1257  if (!sha)
1258  return AVERROR(ENOMEM);
1259  av_free(c->aes_decrypt);
1260  c->aes_decrypt = av_aes_alloc();
1261  if (!c->aes_decrypt) {
1262  ret = AVERROR(ENOMEM);
1263  goto fail;
1264  }
1265 
1266  /* drm blob processing */
1267  avio_read(pb, output, 8); // go to offset 8, absolute position 0x251
1269  avio_read(pb, output, 4); // go to offset 4, absolute position 0x28d
1270  avio_read(pb, file_checksum, 20);
1271 
1272  // required by external tools
1273  ff_data_to_hex(checksum_string, file_checksum, sizeof(file_checksum), 1);
1274  av_log(c->fc, AV_LOG_INFO, "[aax] file checksum == %s\n", checksum_string);
1275 
1276  /* verify activation data */
1277  if (!activation_bytes) {
1278  av_log(c->fc, AV_LOG_WARNING, "[aax] activation_bytes option is missing!\n");
1279  ret = 0; /* allow ffprobe to continue working on .aax files */
1280  goto fail;
1281  }
1282  if (c->activation_bytes_size != 4) {
1283  av_log(c->fc, AV_LOG_FATAL, "[aax] activation_bytes value needs to be 4 bytes!\n");
1284  ret = AVERROR(EINVAL);
1285  goto fail;
1286  }
1287 
1288  /* verify fixed key */
1289  if (c->audible_fixed_key_size != 16) {
1290  av_log(c->fc, AV_LOG_FATAL, "[aax] audible_fixed_key value needs to be 16 bytes!\n");
1291  ret = AVERROR(EINVAL);
1292  goto fail;
1293  }
1294 
1295  /* AAX (and AAX+) key derivation */
1296  av_sha_init(sha, 160);
1297  av_sha_update(sha, fixed_key, 16);
1298  av_sha_update(sha, activation_bytes, 4);
1299  av_sha_final(sha, intermediate_key);
1300  av_sha_init(sha, 160);
1301  av_sha_update(sha, fixed_key, 16);
1302  av_sha_update(sha, intermediate_key, 20);
1303  av_sha_update(sha, activation_bytes, 4);
1304  av_sha_final(sha, intermediate_iv);
1305  av_sha_init(sha, 160);
1306  av_sha_update(sha, intermediate_key, 16);
1307  av_sha_update(sha, intermediate_iv, 16);
1308  av_sha_final(sha, calculated_checksum);
1309  if (memcmp(calculated_checksum, file_checksum, 20)) { // critical error
1310  av_log(c->fc, AV_LOG_ERROR, "[aax] mismatch in checksums!\n");
1312  goto fail;
1313  }
1314  av_aes_init(c->aes_decrypt, intermediate_key, 128, 1);
1315  av_aes_crypt(c->aes_decrypt, output, input, DRM_BLOB_SIZE >> 4, intermediate_iv, 1);
1316  for (i = 0; i < 4; i++) {
1317  // file data (in output) is stored in big-endian mode
1318  if (activation_bytes[i] != output[3 - i]) { // critical error
1319  av_log(c->fc, AV_LOG_ERROR, "[aax] error in drm blob decryption!\n");
1321  goto fail;
1322  }
1323  }
1324  memcpy(c->file_key, output + 8, 16);
1325  memcpy(input, output + 26, 16);
1326  av_sha_init(sha, 160);
1327  av_sha_update(sha, input, 16);
1328  av_sha_update(sha, c->file_key, 16);
1329  av_sha_update(sha, fixed_key, 16);
1330  av_sha_final(sha, c->file_iv);
1331 
1332 fail:
1333  av_free(sha);
1334 
1335  return ret;
1336 }
1337 
1339 {
1340  if (c->audible_key_size != 16) {
1341  av_log(c->fc, AV_LOG_FATAL, "[aaxc] audible_key value needs to be 16 bytes!\n");
1342  return AVERROR(EINVAL);
1343  }
1344 
1345  if (c->audible_iv_size != 16) {
1346  av_log(c->fc, AV_LOG_FATAL, "[aaxc] audible_iv value needs to be 16 bytes!\n");
1347  return AVERROR(EINVAL);
1348  }
1349 
1350  c->aes_decrypt = av_aes_alloc();
1351  if (!c->aes_decrypt) {
1352  return AVERROR(ENOMEM);
1353  }
1354 
1355  memcpy(c->file_key, c->audible_key, 16);
1356  memcpy(c->file_iv, c->audible_iv, 16);
1357  c->aax_mode = 1;
1358 
1359  return 0;
1360 }
1361 
1362 // Audible AAX (and AAX+) bytestream decryption
1363 static int aax_filter(uint8_t *input, int size, MOVContext *c)
1364 {
1365  int blocks = 0;
1366  unsigned char iv[16];
1367 
1368  memcpy(iv, c->file_iv, 16); // iv is overwritten
1369  blocks = size >> 4; // trailing bytes are not encrypted!
1370  av_aes_init(c->aes_decrypt, c->file_key, 128, 1);
1371  av_aes_crypt(c->aes_decrypt, input, input, blocks, iv, 1);
1372 
1373  return 0;
1374 }
1375 
1376 /* read major brand, minor version and compatible brands and store them as metadata */
1378 {
1379  uint32_t minor_ver;
1380  int comp_brand_size;
1381  char* comp_brands_str;
1382  uint8_t type[5] = {0};
1383  int ret = ffio_read_size(pb, type, 4);
1384  if (ret < 0)
1385  return ret;
1386  if (c->fc->nb_streams) {
1387  if (c->fc->strict_std_compliance >= FF_COMPLIANCE_STRICT)
1388  return AVERROR_INVALIDDATA;
1389  av_log(c->fc, AV_LOG_DEBUG, "Ignoring duplicate FTYP\n");
1390  return 0;
1391  }
1392 
1393  if (strcmp(type, "qt "))
1394  c->isom = 1;
1395  av_log(c->fc, AV_LOG_DEBUG, "ISO: File Type Major Brand: %.4s\n",(char *)&type);
1396  av_dict_set(&c->fc->metadata, "major_brand", type, 0);
1397  minor_ver = avio_rb32(pb); /* minor version */
1398  av_dict_set_int(&c->fc->metadata, "minor_version", minor_ver, 0);
1399 
1400  comp_brand_size = atom.size - 8;
1401  if (comp_brand_size < 0 || comp_brand_size == INT_MAX)
1402  return AVERROR_INVALIDDATA;
1403  comp_brands_str = av_malloc(comp_brand_size + 1); /* Add null terminator */
1404  if (!comp_brands_str)
1405  return AVERROR(ENOMEM);
1406 
1407  ret = ffio_read_size(pb, comp_brands_str, comp_brand_size);
1408  if (ret < 0) {
1409  av_freep(&comp_brands_str);
1410  return ret;
1411  }
1412  comp_brands_str[comp_brand_size] = 0;
1413  av_dict_set(&c->fc->metadata, "compatible_brands",
1414  comp_brands_str, AV_DICT_DONT_STRDUP_VAL);
1415 
1416  // Logic for handling Audible's .aaxc files
1417  if (!strcmp(type, "aaxc")) {
1418  mov_aaxc_crypto(c);
1419  }
1420 
1421  return 0;
1422 }
1423 
1424 /* this atom should contain all header atoms */
1426 {
1427  int ret;
1428 
1429  if (c->found_moov) {
1430  av_log(c->fc, AV_LOG_WARNING, "Found duplicated MOOV Atom. Skipped it\n");
1431  avio_skip(pb, atom.size);
1432  return 0;
1433  }
1434 
1435  if ((ret = mov_read_default(c, pb, atom)) < 0)
1436  return ret;
1437  /* we parsed the 'moov' atom, we can terminate the parsing as soon as we find the 'mdat' */
1438  /* so we don't parse the whole file if over a network */
1439  c->found_moov=1;
1440  return 0; /* now go for mdat */
1441 }
1442 
1444  MOVFragmentIndex *frag_index,
1445  int index,
1446  int id)
1447 {
1448  int i;
1449  MOVFragmentIndexItem * item;
1450 
1451  if (index < 0 || index >= frag_index->nb_items)
1452  return NULL;
1453  item = &frag_index->item[index];
1454  for (i = 0; i < item->nb_stream_info; i++)
1455  if (item->stream_info[i].id == id)
1456  return &item->stream_info[i];
1457 
1458  // This shouldn't happen
1459  return NULL;
1460 }
1461 
1462 static void set_frag_stream(MOVFragmentIndex *frag_index, int id)
1463 {
1464  int i;
1465  MOVFragmentIndexItem * item;
1466 
1467  if (frag_index->current < 0 ||
1468  frag_index->current >= frag_index->nb_items)
1469  return;
1470 
1471  item = &frag_index->item[frag_index->current];
1472  for (i = 0; i < item->nb_stream_info; i++)
1473  if (item->stream_info[i].id == id) {
1474  item->current = i;
1475  return;
1476  }
1477 
1478  // id not found. This shouldn't happen.
1479  item->current = -1;
1480 }
1481 
1483  MOVFragmentIndex *frag_index)
1484 {
1485  MOVFragmentIndexItem *item;
1486  if (frag_index->current < 0 ||
1487  frag_index->current >= frag_index->nb_items)
1488  return NULL;
1489 
1490  item = &frag_index->item[frag_index->current];
1491  if (item->current >= 0 && item->current < item->nb_stream_info)
1492  return &item->stream_info[item->current];
1493 
1494  // This shouldn't happen
1495  return NULL;
1496 }
1497 
1498 static int search_frag_moof_offset(MOVFragmentIndex *frag_index, int64_t offset)
1499 {
1500  int a, b, m;
1501  int64_t moof_offset;
1502 
1503  // Optimize for appending new entries
1504  if (!frag_index->nb_items ||
1505  frag_index->item[frag_index->nb_items - 1].moof_offset < offset)
1506  return frag_index->nb_items;
1507 
1508  a = -1;
1509  b = frag_index->nb_items;
1510 
1511  while (b - a > 1) {
1512  m = (a + b) >> 1;
1513  moof_offset = frag_index->item[m].moof_offset;
1514  if (moof_offset >= offset)
1515  b = m;
1516  if (moof_offset <= offset)
1517  a = m;
1518  }
1519  return b;
1520 }
1521 
1522 static int64_t get_stream_info_time(MOVFragmentStreamInfo * frag_stream_info)
1523 {
1524  av_assert0(frag_stream_info);
1525  if (frag_stream_info->sidx_pts != AV_NOPTS_VALUE)
1526  return frag_stream_info->sidx_pts;
1527  if (frag_stream_info->first_tfra_pts != AV_NOPTS_VALUE)
1528  return frag_stream_info->first_tfra_pts;
1529  return frag_stream_info->tfdt_dts;
1530 }
1531 
1532 static int64_t get_frag_time(AVFormatContext *s, AVStream *dst_st,
1533  MOVFragmentIndex *frag_index, int index)
1534 {
1535  MOVFragmentStreamInfo * frag_stream_info;
1536  MOVStreamContext *sc = dst_st->priv_data;
1537  int64_t timestamp;
1538  int i, j;
1539 
1540  // If the stream is referenced by any sidx, limit the search
1541  // to fragments that referenced this stream in the sidx
1542  if (sc->has_sidx) {
1543  frag_stream_info = get_frag_stream_info(frag_index, index, sc->id);
1544  if (frag_stream_info->sidx_pts != AV_NOPTS_VALUE)
1545  return frag_stream_info->sidx_pts;
1546  if (frag_stream_info->first_tfra_pts != AV_NOPTS_VALUE)
1547  return frag_stream_info->first_tfra_pts;
1548  return frag_stream_info->sidx_pts;
1549  }
1550 
1551  for (i = 0; i < frag_index->item[index].nb_stream_info; i++) {
1552  AVStream *frag_stream = NULL;
1553  frag_stream_info = &frag_index->item[index].stream_info[i];
1554  for (j = 0; j < s->nb_streams; j++) {
1555  MOVStreamContext *sc2 = s->streams[j]->priv_data;
1556  if (sc2->id == frag_stream_info->id)
1557  frag_stream = s->streams[j];
1558  }
1559  if (!frag_stream) {
1560  av_log(s, AV_LOG_WARNING, "No stream matching sidx ID found.\n");
1561  continue;
1562  }
1563  timestamp = get_stream_info_time(frag_stream_info);
1564  if (timestamp != AV_NOPTS_VALUE)
1565  return av_rescale_q(timestamp, frag_stream->time_base, dst_st->time_base);
1566  }
1567  return AV_NOPTS_VALUE;
1568 }
1569 
1571  AVStream *st, int64_t timestamp)
1572 {
1573  int a, b, m, m0;
1574  int64_t frag_time;
1575 
1576  a = -1;
1577  b = frag_index->nb_items;
1578 
1579  while (b - a > 1) {
1580  m0 = m = (a + b) >> 1;
1581 
1582  while (m < b &&
1583  (frag_time = get_frag_time(s, st, frag_index, m)) == AV_NOPTS_VALUE)
1584  m++;
1585 
1586  if (m < b && frag_time <= timestamp)
1587  a = m;
1588  else
1589  b = m0;
1590  }
1591 
1592  return a;
1593 }
1594 
1595 static int update_frag_index(MOVContext *c, int64_t offset)
1596 {
1597  int index, i;
1598  MOVFragmentIndexItem * item;
1599  MOVFragmentStreamInfo * frag_stream_info;
1600 
1601  // If moof_offset already exists in frag_index, return index to it
1602  index = search_frag_moof_offset(&c->frag_index, offset);
1603  if (index < c->frag_index.nb_items &&
1604  c->frag_index.item[index].moof_offset == offset)
1605  return index;
1606 
1607  // offset is not yet in frag index.
1608  // Insert new item at index (sorted by moof offset)
1609  item = av_fast_realloc(c->frag_index.item,
1610  &c->frag_index.allocated_size,
1611  (c->frag_index.nb_items + 1) *
1612  sizeof(*c->frag_index.item));
1613  if (!item)
1614  return -1;
1615  c->frag_index.item = item;
1616 
1617  frag_stream_info = av_realloc_array(NULL, c->fc->nb_streams,
1618  sizeof(*item->stream_info));
1619  if (!frag_stream_info)
1620  return -1;
1621 
1622  for (i = 0; i < c->fc->nb_streams; i++) {
1623  // Avoid building frag index if streams lack track id.
1624  MOVStreamContext *sc = c->fc->streams[i]->priv_data;
1625  if (sc->id < 0) {
1626  av_free(frag_stream_info);
1627  return AVERROR_INVALIDDATA;
1628  }
1629 
1630  frag_stream_info[i].id = sc->id;
1631  frag_stream_info[i].sidx_pts = AV_NOPTS_VALUE;
1632  frag_stream_info[i].tfdt_dts = AV_NOPTS_VALUE;
1633  frag_stream_info[i].next_trun_dts = AV_NOPTS_VALUE;
1634  frag_stream_info[i].first_tfra_pts = AV_NOPTS_VALUE;
1635  frag_stream_info[i].index_base = -1;
1636  frag_stream_info[i].index_entry = -1;
1637  frag_stream_info[i].encryption_index = NULL;
1638  frag_stream_info[i].stsd_id = -1;
1639  }
1640 
1641  if (index < c->frag_index.nb_items)
1642  memmove(c->frag_index.item + index + 1, c->frag_index.item + index,
1643  (c->frag_index.nb_items - index) * sizeof(*c->frag_index.item));
1644 
1645  item = &c->frag_index.item[index];
1646  item->headers_read = 0;
1647  item->current = 0;
1648  item->nb_stream_info = c->fc->nb_streams;
1649  item->moof_offset = offset;
1650  item->stream_info = frag_stream_info;
1651  c->frag_index.nb_items++;
1652 
1653  return index;
1654 }
1655 
1656 static void fix_frag_index_entries(MOVFragmentIndex *frag_index, int index,
1657  int id, int entries)
1658 {
1659  int i;
1660  MOVFragmentStreamInfo * frag_stream_info;
1661 
1662  if (index < 0)
1663  return;
1664  for (i = index; i < frag_index->nb_items; i++) {
1665  frag_stream_info = get_frag_stream_info(frag_index, i, id);
1666  if (frag_stream_info && frag_stream_info->index_entry >= 0)
1667  frag_stream_info->index_entry += entries;
1668  }
1669 }
1670 
1672 {
1673  // Set by mov_read_tfhd(). mov_read_trun() will reject files missing tfhd.
1674  c->fragment.found_tfhd = 0;
1675 
1676  if (!c->has_looked_for_mfra && c->use_mfra_for > 0) {
1677  c->has_looked_for_mfra = 1;
1678  if (pb->seekable & AVIO_SEEKABLE_NORMAL) {
1679  int ret;
1680  av_log(c->fc, AV_LOG_VERBOSE, "stream has moof boxes, will look "
1681  "for a mfra\n");
1682  if ((ret = mov_read_mfra(c, pb)) < 0) {
1683  av_log(c->fc, AV_LOG_VERBOSE, "found a moof box but failed to "
1684  "read the mfra (may be a live ismv)\n");
1685  }
1686  } else {
1687  av_log(c->fc, AV_LOG_VERBOSE, "found a moof box but stream is not "
1688  "seekable, can not look for mfra\n");
1689  }
1690  }
1691  c->fragment.moof_offset = c->fragment.implicit_offset = avio_tell(pb) - 8;
1692  av_log(c->fc, AV_LOG_TRACE, "moof offset %"PRIx64"\n", c->fragment.moof_offset);
1693  c->frag_index.current = update_frag_index(c, c->fragment.moof_offset);
1694  return mov_read_default(c, pb, atom);
1695 }
1696 
1698 {
1699  int64_t time;
1700  if (version == 1) {
1701  time = avio_rb64(pb);
1702  avio_rb64(pb);
1703  if (time < 0) {
1704  av_log(c->fc, AV_LOG_DEBUG, "creation_time is negative\n");
1705  return;
1706  }
1707  } else {
1708  time = avio_rb32(pb);
1709  avio_rb32(pb); /* modification time */
1710  if (time > 0 && time < 2082844800) {
1711  av_log(c->fc, AV_LOG_WARNING, "Detected creation time before 1970, parsing as unix timestamp.\n");
1712  time += 2082844800;
1713  }
1714  }
1715  if (time) {
1716  time -= 2082844800; /* seconds between 1904-01-01 and Epoch */
1717 
1718  if ((int64_t)(time * 1000000ULL) / 1000000 != time) {
1719  av_log(c->fc, AV_LOG_DEBUG, "creation_time is not representable\n");
1720  return;
1721  }
1722 
1723  avpriv_dict_set_timestamp(metadata, "creation_time", time * 1000000);
1724  }
1725 }
1726 
1728 {
1729  AVStream *st;
1730  MOVStreamContext *sc;
1731  int version;
1732  char language[4] = {0};
1733  unsigned lang;
1734 
1735  if (c->fc->nb_streams < 1)
1736  return 0;
1737  st = c->fc->streams[c->fc->nb_streams-1];
1738  sc = st->priv_data;
1739 
1740  if (sc->time_scale) {
1741  av_log(c->fc, AV_LOG_ERROR, "Multiple mdhd?\n");
1742  return AVERROR_INVALIDDATA;
1743  }
1744 
1745  version = avio_r8(pb);
1746  if (version > 1) {
1747  avpriv_request_sample(c->fc, "Version %d", version);
1748  return AVERROR_PATCHWELCOME;
1749  }
1750  avio_rb24(pb); /* flags */
1752 
1753  sc->time_scale = avio_rb32(pb);
1754  if (sc->time_scale <= 0) {
1755  av_log(c->fc, AV_LOG_ERROR, "Invalid mdhd time scale %d, defaulting to 1\n", sc->time_scale);
1756  sc->time_scale = 1;
1757  }
1758  st->duration = (version == 1) ? avio_rb64(pb) : avio_rb32(pb); /* duration */
1759 
1760  if ((version == 1 && st->duration == UINT64_MAX) ||
1761  (version != 1 && st->duration == UINT32_MAX)) {
1762  st->duration = 0;
1763  }
1764 
1765  lang = avio_rb16(pb); /* language */
1766  if (ff_mov_lang_to_iso639(lang, language))
1767  av_dict_set(&st->metadata, "language", language, 0);
1768  avio_rb16(pb); /* quality */
1769 
1770  return 0;
1771 }
1772 
1774 {
1775  int i;
1776  int version = avio_r8(pb); /* version */
1777  avio_rb24(pb); /* flags */
1778 
1779  mov_metadata_creation_time(c, pb, &c->fc->metadata, version);
1780  c->time_scale = avio_rb32(pb); /* time scale */
1781  if (c->time_scale <= 0) {
1782  av_log(c->fc, AV_LOG_ERROR, "Invalid mvhd time scale %d, defaulting to 1\n", c->time_scale);
1783  c->time_scale = 1;
1784  }
1785  av_log(c->fc, AV_LOG_TRACE, "time scale = %i\n", c->time_scale);
1786 
1787  c->duration = (version == 1) ? avio_rb64(pb) : avio_rb32(pb); /* duration */
1788  avio_rb32(pb); /* preferred scale */
1789 
1790  avio_rb16(pb); /* preferred volume */
1791 
1792  avio_skip(pb, 10); /* reserved */
1793 
1794  /* movie display matrix, store it in main context and use it later on */
1795  for (i = 0; i < 3; i++) {
1796  c->movie_display_matrix[i][0] = avio_rb32(pb); // 16.16 fixed point
1797  c->movie_display_matrix[i][1] = avio_rb32(pb); // 16.16 fixed point
1798  c->movie_display_matrix[i][2] = avio_rb32(pb); // 2.30 fixed point
1799  }
1800 
1801  avio_rb32(pb); /* preview time */
1802  avio_rb32(pb); /* preview duration */
1803  avio_rb32(pb); /* poster time */
1804  avio_rb32(pb); /* selection time */
1805  avio_rb32(pb); /* selection duration */
1806  avio_rb32(pb); /* current time */
1807  avio_rb32(pb); /* next track ID */
1808 
1809  return 0;
1810 }
1811 
1813 {
1814  AVStream *st;
1815 
1816  if (fc->nb_streams < 1)
1817  return;
1818  st = fc->streams[fc->nb_streams-1];
1819 
1820  switch (st->codecpar->codec_id) {
1821  case AV_CODEC_ID_PCM_S16BE:
1823  break;
1824  case AV_CODEC_ID_PCM_S24BE:
1826  break;
1827  case AV_CODEC_ID_PCM_S32BE:
1829  break;
1830  case AV_CODEC_ID_PCM_F32BE:
1832  break;
1833  case AV_CODEC_ID_PCM_F64BE:
1835  break;
1836  default:
1837  break;
1838  }
1839 }
1840 
1842 {
1843  int little_endian = avio_rb16(pb) & 0xFF;
1844  av_log(c->fc, AV_LOG_TRACE, "enda %d\n", little_endian);
1845  if (little_endian == 1)
1847  return 0;
1848 }
1849 
1851 {
1852  int format_flags;
1853  int version, flags;
1854  int pcm_sample_size;
1855  AVFormatContext *fc = c->fc;
1856  AVStream *st;
1857  MOVStreamContext *sc;
1858 
1859  if (atom.size < 6) {
1860  av_log(c->fc, AV_LOG_ERROR, "Empty pcmC box\n");
1861  return AVERROR_INVALIDDATA;
1862  }
1863 
1864  version = avio_r8(pb);
1865  flags = avio_rb24(pb);
1866 
1867  if (version != 0 || flags != 0) {
1868  av_log(c->fc, AV_LOG_ERROR,
1869  "Unsupported 'pcmC' box with version %d, flags: %x",
1870  version, flags);
1871  return AVERROR_INVALIDDATA;
1872  }
1873 
1874  format_flags = avio_r8(pb);
1875  pcm_sample_size = avio_r8(pb);
1876 
1877  if (fc->nb_streams < 1)
1878  return AVERROR_INVALIDDATA;
1879 
1880  st = fc->streams[fc->nb_streams - 1];
1881  sc = st->priv_data;
1882 
1883  if (sc->format == MOV_MP4_FPCM_TAG) {
1884  switch (pcm_sample_size) {
1885  case 32:
1887  break;
1888  case 64:
1890  break;
1891  default:
1892  av_log(fc, AV_LOG_ERROR, "invalid pcm_sample_size %d for %s\n",
1893  pcm_sample_size,
1894  av_fourcc2str(sc->format));
1895  return AVERROR_INVALIDDATA;
1896  }
1897  } else if (sc->format == MOV_MP4_IPCM_TAG) {
1898  switch (pcm_sample_size) {
1899  case 16:
1901  break;
1902  case 24:
1904  break;
1905  case 32:
1907  break;
1908  default:
1909  av_log(fc, AV_LOG_ERROR, "invalid pcm_sample_size %d for %s\n",
1910  pcm_sample_size,
1911  av_fourcc2str(sc->format));
1912  return AVERROR_INVALIDDATA;
1913  }
1914  } else {
1915  av_log(fc, AV_LOG_ERROR, "'pcmC' with invalid sample entry '%s'\n",
1916  av_fourcc2str(sc->format));
1917  return AVERROR_INVALIDDATA;
1918  }
1919 
1920  if (format_flags & 1) // indicates little-endian format. If not present, big-endian format is used
1923 
1924  return 0;
1925 }
1926 
1928 {
1929  AVStream *st;
1930  char color_parameter_type[5] = { 0 };
1931  uint16_t color_primaries, color_trc, color_matrix;
1932  int ret;
1933 
1934  st = get_curr_st(c);
1935  if (!st)
1936  return 0;
1937 
1938  ret = ffio_read_size(pb, color_parameter_type, 4);
1939  if (ret < 0)
1940  return ret;
1941  if (strncmp(color_parameter_type, "nclx", 4) &&
1942  strncmp(color_parameter_type, "nclc", 4) &&
1943  strncmp(color_parameter_type, "prof", 4)) {
1944  av_log(c->fc, AV_LOG_WARNING, "unsupported color_parameter_type %s\n",
1945  color_parameter_type);
1946  return 0;
1947  }
1948 
1949  if (!strncmp(color_parameter_type, "prof", 4)) {
1953  atom.size - 4, 0);
1954  if (!sd)
1955  return AVERROR(ENOMEM);
1956  ret = ffio_read_size(pb, sd->data, atom.size - 4);
1957  if (ret < 0)
1958  return ret;
1959  } else {
1960  color_primaries = avio_rb16(pb);
1961  color_trc = avio_rb16(pb);
1962  color_matrix = avio_rb16(pb);
1963 
1964  av_log(c->fc, AV_LOG_TRACE,
1965  "%s: pri %d trc %d matrix %d",
1966  color_parameter_type, color_primaries, color_trc, color_matrix);
1967 
1968  if (!strncmp(color_parameter_type, "nclx", 4)) {
1969  uint8_t color_range = avio_r8(pb) >> 7;
1970  av_log(c->fc, AV_LOG_TRACE, " full %"PRIu8"", color_range);
1971  if (color_range)
1973  else
1975  }
1976 
1979  if (!av_color_transfer_name(color_trc))
1980  color_trc = AVCOL_TRC_UNSPECIFIED;
1981  if (!av_color_space_name(color_matrix))
1982  color_matrix = AVCOL_SPC_UNSPECIFIED;
1983 
1985  st->codecpar->color_trc = color_trc;
1986  st->codecpar->color_space = color_matrix;
1987  av_log(c->fc, AV_LOG_TRACE, "\n");
1988  }
1989  return 0;
1990 }
1991 
1993 {
1994  AVStream *st;
1995  unsigned mov_field_order;
1996  enum AVFieldOrder decoded_field_order = AV_FIELD_UNKNOWN;
1997 
1998  if (c->fc->nb_streams < 1) // will happen with jp2 files
1999  return 0;
2000  st = c->fc->streams[c->fc->nb_streams-1];
2001  if (atom.size < 2)
2002  return AVERROR_INVALIDDATA;
2003  mov_field_order = avio_rb16(pb);
2004  if ((mov_field_order & 0xFF00) == 0x0100)
2005  decoded_field_order = AV_FIELD_PROGRESSIVE;
2006  else if ((mov_field_order & 0xFF00) == 0x0200) {
2007  switch (mov_field_order & 0xFF) {
2008  case 0x01: decoded_field_order = AV_FIELD_TT;
2009  break;
2010  case 0x06: decoded_field_order = AV_FIELD_BB;
2011  break;
2012  case 0x09: decoded_field_order = AV_FIELD_TB;
2013  break;
2014  case 0x0E: decoded_field_order = AV_FIELD_BT;
2015  break;
2016  }
2017  }
2018  if (decoded_field_order == AV_FIELD_UNKNOWN && mov_field_order) {
2019  av_log(c->fc, AV_LOG_ERROR, "Unknown MOV field order 0x%04x\n", mov_field_order);
2020  }
2021  st->codecpar->field_order = decoded_field_order;
2022 
2023  return 0;
2024 }
2025 
2027 {
2028  int err = 0;
2029  uint64_t size = (uint64_t)par->extradata_size + atom.size + 8 + AV_INPUT_BUFFER_PADDING_SIZE;
2030  if (size > INT_MAX || (uint64_t)atom.size > INT_MAX)
2031  return AVERROR_INVALIDDATA;
2032  if ((err = av_reallocp(&par->extradata, size)) < 0) {
2033  par->extradata_size = 0;
2034  return err;
2035  }
2037  return 0;
2038 }
2039 
2040 /* Read a whole atom into the extradata return the size of the atom read, possibly truncated if != atom.size */
2042  AVCodecParameters *par, uint8_t *buf)
2043 {
2044  int64_t result = atom.size;
2045  int err;
2046 
2047  AV_WB32(buf , atom.size + 8);
2048  AV_WL32(buf + 4, atom.type);
2049  err = ffio_read_size(pb, buf + 8, atom.size);
2050  if (err < 0) {
2051  par->extradata_size -= atom.size;
2052  return err;
2053  } else if (err < atom.size) {
2054  av_log(c->fc, AV_LOG_WARNING, "truncated extradata\n");
2055  par->extradata_size -= atom.size - err;
2056  result = err;
2057  }
2058  memset(buf + 8 + err, 0, AV_INPUT_BUFFER_PADDING_SIZE);
2059  return result;
2060 }
2061 
2062 /* FIXME modify QDM2/SVQ3/H.264 decoders to take full atom as extradata */
2064  enum AVCodecID codec_id)
2065 {
2066  AVStream *st;
2067  uint64_t original_size;
2068  int err;
2069 
2070  if (c->fc->nb_streams < 1) // will happen with jp2 files
2071  return 0;
2072  st = c->fc->streams[c->fc->nb_streams-1];
2073 
2074  if (st->codecpar->codec_id != codec_id)
2075  return 0; /* unexpected codec_id - don't mess with extradata */
2076 
2077  original_size = st->codecpar->extradata_size;
2078  err = mov_realloc_extradata(st->codecpar, atom);
2079  if (err)
2080  return err;
2081 
2082  err = mov_read_atom_into_extradata(c, pb, atom, st->codecpar, st->codecpar->extradata + original_size);
2083  if (err < 0)
2084  return err;
2085  return 0; // Note: this is the original behavior to ignore truncation.
2086 }
2087 
2088 /* wrapper functions for reading ALAC/AVS/MJPEG/MJPEG2000 extradata atoms only for those codecs */
2090 {
2091  return mov_read_extradata(c, pb, atom, AV_CODEC_ID_ALAC);
2092 }
2093 
2095 {
2096  return mov_read_extradata(c, pb, atom, AV_CODEC_ID_CAVS);
2097 }
2098 
2100 {
2101  return mov_read_extradata(c, pb, atom, AV_CODEC_ID_JPEG2000);
2102 }
2103 
2105 {
2106  return mov_read_extradata(c, pb, atom, AV_CODEC_ID_R10K);
2107 }
2108 
2110 {
2111  int ret = mov_read_extradata(c, pb, atom, AV_CODEC_ID_AVUI);
2112  if (!ret)
2113  ret = mov_read_extradata(c, pb, atom, AV_CODEC_ID_DNXHD);
2114  return ret;
2115 }
2116 
2118 {
2119  int ret = mov_read_extradata(c, pb, atom, AV_CODEC_ID_TARGA_Y216);
2120 
2121  if (!ret && c->fc->nb_streams >= 1) {
2122  AVCodecParameters *par = c->fc->streams[c->fc->nb_streams-1]->codecpar;
2123  if (par->extradata_size >= 40) {
2124  par->height = AV_RB16(&par->extradata[36]);
2125  par->width = AV_RB16(&par->extradata[38]);
2126  }
2127  }
2128  return ret;
2129 }
2130 
2132 {
2133  if (c->fc->nb_streams >= 1) {
2134  AVStream *const st = c->fc->streams[c->fc->nb_streams - 1];
2135  FFStream *const sti = ffstream(st);
2136  AVCodecParameters *par = st->codecpar;
2137 
2138  if (par->codec_tag == MKTAG('A', 'V', 'i', 'n') &&
2139  par->codec_id == AV_CODEC_ID_H264 &&
2140  atom.size > 11) {
2141  int cid;
2142  avio_skip(pb, 10);
2143  cid = avio_rb16(pb);
2144  /* For AVID AVCI50, force width of 1440 to be able to select the correct SPS and PPS */
2145  if (cid == 0xd4d || cid == 0xd4e)
2146  par->width = 1440;
2147  return 0;
2148  } else if ((par->codec_tag == MKTAG('A', 'V', 'd', '1') ||
2149  par->codec_tag == MKTAG('A', 'V', 'j', '2') ||
2150  par->codec_tag == MKTAG('A', 'V', 'd', 'n')) &&
2151  atom.size >= 24) {
2152  int num, den;
2153  avio_skip(pb, 12);
2154  num = avio_rb32(pb);
2155  den = avio_rb32(pb);
2156  if (num <= 0 || den <= 0)
2157  return 0;
2158  switch (avio_rb32(pb)) {
2159  case 2:
2160  if (den >= INT_MAX / 2)
2161  return 0;
2162  den *= 2;
2163  case 1:
2164  sti->display_aspect_ratio = (AVRational){ num, den };
2165  default:
2166  return 0;
2167  }
2168  }
2169  }
2170 
2171  return mov_read_avid(c, pb, atom);
2172 }
2173 
2175 {
2176  int ret = 0;
2177  int length = 0;
2178  uint64_t original_size;
2179  if (c->fc->nb_streams >= 1) {
2180  AVCodecParameters *par = c->fc->streams[c->fc->nb_streams-1]->codecpar;
2181  if (par->codec_id == AV_CODEC_ID_H264)
2182  return 0;
2183  if (atom.size == 16) {
2184  original_size = par->extradata_size;
2185  ret = mov_realloc_extradata(par, atom);
2186  if (!ret) {
2187  length = mov_read_atom_into_extradata(c, pb, atom, par, par->extradata + original_size);
2188  if (length == atom.size) {
2189  const uint8_t range_value = par->extradata[original_size + 19];
2190  switch (range_value) {
2191  case 1:
2193  break;
2194  case 2:
2196  break;
2197  default:
2198  av_log(c->fc, AV_LOG_WARNING, "ignored unknown aclr value (%d)\n", range_value);
2199  break;
2200  }
2201  ff_dlog(c->fc, "color_range: %d\n", par->color_range);
2202  } else {
2203  /* For some reason the whole atom was not added to the extradata */
2204  av_log(c->fc, AV_LOG_ERROR, "aclr not decoded - incomplete atom\n");
2205  }
2206  } else {
2207  av_log(c->fc, AV_LOG_ERROR, "aclr not decoded - unable to add atom to extradata\n");
2208  }
2209  } else {
2210  av_log(c->fc, AV_LOG_WARNING, "aclr not decoded - unexpected size %"PRId64"\n", atom.size);
2211  }
2212  }
2213 
2214  return ret;
2215 }
2216 
2218 {
2219  return mov_read_extradata(c, pb, atom, AV_CODEC_ID_SVQ3);
2220 }
2221 
2223 {
2224  AVStream *st;
2225  int ret;
2226 
2227  if (c->fc->nb_streams < 1)
2228  return 0;
2229  st = c->fc->streams[c->fc->nb_streams-1];
2230 
2231  if ((uint64_t)atom.size > (1<<30))
2232  return AVERROR_INVALIDDATA;
2233 
2234  if (st->codecpar->codec_id == AV_CODEC_ID_QDM2 ||
2237  // pass all frma atom to codec, needed at least for QDMC and QDM2
2238  ret = ff_get_extradata(c->fc, st->codecpar, pb, atom.size);
2239  if (ret < 0)
2240  return ret;
2241  } else if (atom.size > 8) { /* to read frma, esds atoms */
2242  if (st->codecpar->codec_id == AV_CODEC_ID_ALAC && atom.size >= 24) {
2243  uint64_t buffer;
2244  ret = ffio_ensure_seekback(pb, 8);
2245  if (ret < 0)
2246  return ret;
2247  buffer = avio_rb64(pb);
2248  atom.size -= 8;
2249  if ( (buffer & 0xFFFFFFFF) == MKBETAG('f','r','m','a')
2250  && buffer >> 32 <= atom.size
2251  && buffer >> 32 >= 8) {
2252  avio_skip(pb, -8);
2253  atom.size += 8;
2254  } else if (!st->codecpar->extradata_size) {
2255 #define ALAC_EXTRADATA_SIZE 36
2257  if (!st->codecpar->extradata)
2258  return AVERROR(ENOMEM);
2261  AV_WB32(st->codecpar->extradata + 4, MKTAG('a','l','a','c'));
2262  AV_WB64(st->codecpar->extradata + 12, buffer);
2263  avio_read(pb, st->codecpar->extradata + 20, 16);
2264  avio_skip(pb, atom.size - 24);
2265  return 0;
2266  }
2267  }
2268  if ((ret = mov_read_default(c, pb, atom)) < 0)
2269  return ret;
2270  } else
2271  avio_skip(pb, atom.size);
2272  return 0;
2273 }
2274 
2275 /**
2276  * This function reads atom content and puts data in extradata without tag
2277  * nor size unlike mov_read_extradata.
2278  */
2280 {
2281  AVStream *st;
2282  int ret;
2283 
2284  st = get_curr_st(c);
2285  if (!st)
2286  return 0;
2287 
2288  if ((uint64_t)atom.size > (1<<30))
2289  return AVERROR_INVALIDDATA;
2290 
2291  if (atom.type == MKTAG('v','v','c','C')) {
2292  avio_skip(pb, 4);
2293  atom.size -= 4;
2294  }
2295 
2296  if (atom.size >= 10) {
2297  // Broken files created by legacy versions of libavformat will
2298  // wrap a whole fiel atom inside of a glbl atom.
2299  unsigned size = avio_rb32(pb);
2300  unsigned type = avio_rl32(pb);
2301  if (avio_feof(pb))
2302  return AVERROR_INVALIDDATA;
2303  avio_seek(pb, -8, SEEK_CUR);
2304  if (type == MKTAG('f','i','e','l') && size == atom.size)
2305  return mov_read_default(c, pb, atom);
2306  }
2307  if (st->codecpar->extradata_size > 1 && st->codecpar->extradata) {
2308  av_log(c->fc, AV_LOG_WARNING, "ignoring multiple glbl\n");
2309  return 0;
2310  }
2311  ret = ff_get_extradata(c->fc, st->codecpar, pb, atom.size);
2312  if (ret < 0)
2313  return ret;
2314  if (atom.type == MKTAG('h','v','c','C') && st->codecpar->codec_tag == MKTAG('d','v','h','1'))
2315  /* HEVC-based Dolby Vision derived from hvc1.
2316  Happens to match with an identifier
2317  previously utilized for DV. Thus, if we have
2318  the hvcC extradata box available as specified,
2319  set codec to HEVC */
2321 
2322  return 0;
2323 }
2324 
2326 {
2327  AVStream *st;
2328  uint8_t profile_level;
2329  int ret;
2330 
2331  if (c->fc->nb_streams < 1)
2332  return 0;
2333  st = c->fc->streams[c->fc->nb_streams-1];
2334 
2335  if (atom.size >= (1<<28) || atom.size < 7)
2336  return AVERROR_INVALIDDATA;
2337 
2338  profile_level = avio_r8(pb);
2339  if ((profile_level & 0xf0) != 0xc0)
2340  return 0;
2341 
2342  avio_seek(pb, 6, SEEK_CUR);
2343  ret = ff_get_extradata(c->fc, st->codecpar, pb, atom.size - 7);
2344  if (ret < 0)
2345  return ret;
2346 
2347  return 0;
2348 }
2349 
2350 /**
2351  * An strf atom is a BITMAPINFOHEADER struct. This struct is 40 bytes itself,
2352  * but can have extradata appended at the end after the 40 bytes belonging
2353  * to the struct.
2354  */
2356 {
2357  AVStream *st;
2358  int ret;
2359 
2360  if (c->fc->nb_streams < 1)
2361  return 0;
2362  if (atom.size <= 40)
2363  return 0;
2364  st = c->fc->streams[c->fc->nb_streams-1];
2365 
2366  if ((uint64_t)atom.size > (1<<30))
2367  return AVERROR_INVALIDDATA;
2368 
2369  avio_skip(pb, 40);
2370  ret = ff_get_extradata(c->fc, st->codecpar, pb, atom.size - 40);
2371  if (ret < 0)
2372  return ret;
2373 
2374  return 0;
2375 }
2376 
2378 {
2379  AVStream *st;
2380  MOVStreamContext *sc;
2381  unsigned int i, entries;
2382 
2383  if (c->trak_index < 0) {
2384  av_log(c->fc, AV_LOG_WARNING, "STCO outside TRAK\n");
2385  return 0;
2386  }
2387  if (c->fc->nb_streams < 1)
2388  return 0;
2389  st = c->fc->streams[c->fc->nb_streams-1];
2390  sc = st->priv_data;
2391 
2392  avio_r8(pb); /* version */
2393  avio_rb24(pb); /* flags */
2394 
2395  // Clamp allocation size for `chunk_offsets` -- don't throw an error for an
2396  // invalid count since the EOF path doesn't throw either.
2397  entries = avio_rb32(pb);
2398  entries =
2399  FFMIN(entries,
2400  FFMAX(0, (atom.size - 8) /
2401  (atom.type == MKTAG('s', 't', 'c', 'o') ? 4 : 8)));
2402 
2403  if (!entries)
2404  return 0;
2405 
2406  if (sc->chunk_offsets) {
2407  av_log(c->fc, AV_LOG_WARNING, "Ignoring duplicated STCO atom\n");
2408  return 0;
2409  }
2410 
2411  av_free(sc->chunk_offsets);
2412  sc->chunk_count = 0;
2413  sc->chunk_offsets = av_malloc_array(entries, sizeof(*sc->chunk_offsets));
2414  if (!sc->chunk_offsets)
2415  return AVERROR(ENOMEM);
2416  sc->chunk_count = entries;
2417 
2418  if (atom.type == MKTAG('s','t','c','o'))
2419  for (i = 0; i < entries && !pb->eof_reached; i++)
2420  sc->chunk_offsets[i] = avio_rb32(pb);
2421  else if (atom.type == MKTAG('c','o','6','4'))
2422  for (i = 0; i < entries && !pb->eof_reached; i++) {
2423  sc->chunk_offsets[i] = avio_rb64(pb);
2424  if (sc->chunk_offsets[i] < 0) {
2425  av_log(c->fc, AV_LOG_WARNING, "Impossible chunk_offset\n");
2426  sc->chunk_offsets[i] = 0;
2427  }
2428  }
2429  else
2430  return AVERROR_INVALIDDATA;
2431 
2432  sc->chunk_count = i;
2433 
2434  if (pb->eof_reached) {
2435  av_log(c->fc, AV_LOG_WARNING, "reached eof, corrupted STCO atom\n");
2436  return AVERROR_EOF;
2437  }
2438 
2439  return 0;
2440 }
2441 
2442 static int mov_codec_id(AVStream *st, uint32_t format)
2443 {
2445 
2446  if (id <= 0 &&
2447  ((format & 0xFFFF) == 'm' + ('s' << 8) ||
2448  (format & 0xFFFF) == 'T' + ('S' << 8)))
2450 
2451  if (st->codecpar->codec_type != AVMEDIA_TYPE_VIDEO && id > 0) {
2453  } else if (st->codecpar->codec_type != AVMEDIA_TYPE_AUDIO &&
2454  /* skip old ASF MPEG-4 tag */
2455  format && format != MKTAG('m','p','4','s')) {
2457  if (id <= 0)
2459  if (id > 0)
2461  else if (st->codecpar->codec_type == AVMEDIA_TYPE_DATA ||
2463  st->codecpar->codec_id == AV_CODEC_ID_NONE)) {
2465  if (id <= 0) {
2467  AV_CODEC_ID_TTML : id;
2468  }
2469 
2470  if (id > 0)
2472  else
2474  }
2475  }
2476 
2477  st->codecpar->codec_tag = format;
2478 
2479  return id;
2480 }
2481 
2483  AVStream *st, MOVStreamContext *sc)
2484 {
2485  uint8_t codec_name[32] = { 0 };
2486  int64_t stsd_start;
2487  unsigned int len;
2488  uint32_t id = 0;
2489 
2490  /* The first 16 bytes of the video sample description are already
2491  * read in ff_mov_read_stsd_entries() */
2492  stsd_start = avio_tell(pb) - 16;
2493 
2494  avio_rb16(pb); /* version */
2495  avio_rb16(pb); /* revision level */
2496  id = avio_rl32(pb); /* vendor */
2497  av_dict_set(&st->metadata, "vendor_id", av_fourcc2str(id), 0);
2498  avio_rb32(pb); /* temporal quality */
2499  avio_rb32(pb); /* spatial quality */
2500 
2501  st->codecpar->width = avio_rb16(pb); /* width */
2502  st->codecpar->height = avio_rb16(pb); /* height */
2503 
2504  avio_rb32(pb); /* horiz resolution */
2505  avio_rb32(pb); /* vert resolution */
2506  avio_rb32(pb); /* data size, always 0 */
2507  avio_rb16(pb); /* frames per samples */
2508 
2509  len = avio_r8(pb); /* codec name, pascal string */
2510  if (len > 31)
2511  len = 31;
2512  mov_read_mac_string(c, pb, len, codec_name, sizeof(codec_name));
2513  if (len < 31)
2514  avio_skip(pb, 31 - len);
2515 
2516  if (codec_name[0])
2517  av_dict_set(&st->metadata, "encoder", codec_name, 0);
2518 
2519  /* codec_tag YV12 triggers an UV swap in rawdec.c */
2520  if (!strncmp(codec_name, "Planar Y'CbCr 8-bit 4:2:0", 25)) {
2521  st->codecpar->codec_tag = MKTAG('I', '4', '2', '0');
2522  st->codecpar->width &= ~1;
2523  st->codecpar->height &= ~1;
2524  }
2525  /* Flash Media Server uses tag H.263 with Sorenson Spark */
2526  if (st->codecpar->codec_tag == MKTAG('H','2','6','3') &&
2527  !strncmp(codec_name, "Sorenson H263", 13))
2529 
2530  st->codecpar->bits_per_coded_sample = avio_rb16(pb); /* depth */
2531 
2532  avio_seek(pb, stsd_start, SEEK_SET);
2533 
2534  if (ff_get_qtpalette(st->codecpar->codec_id, pb, sc->palette)) {
2535  st->codecpar->bits_per_coded_sample &= 0x1F;
2536  sc->has_palette = 1;
2537  }
2538 }
2539 
2541  AVStream *st, MOVStreamContext *sc)
2542 {
2543  int bits_per_sample, flags;
2544  uint16_t version = avio_rb16(pb);
2545  uint32_t id = 0;
2546  AVDictionaryEntry *compatible_brands = av_dict_get(c->fc->metadata, "compatible_brands", NULL, AV_DICT_MATCH_CASE);
2547  int channel_count;
2548 
2549  avio_rb16(pb); /* revision level */
2550  id = avio_rl32(pb); /* vendor */
2551  av_dict_set(&st->metadata, "vendor_id", av_fourcc2str(id), 0);
2552 
2553  channel_count = avio_rb16(pb);
2554 
2556  st->codecpar->ch_layout.nb_channels = channel_count;
2557  st->codecpar->bits_per_coded_sample = avio_rb16(pb); /* sample size */
2558  av_log(c->fc, AV_LOG_TRACE, "audio channels %d\n", channel_count);
2559 
2560  sc->audio_cid = avio_rb16(pb);
2561  avio_rb16(pb); /* packet size = 0 */
2562 
2563  st->codecpar->sample_rate = ((avio_rb32(pb) >> 16));
2564 
2565  // Read QT version 1 fields. In version 0 these do not exist.
2566  av_log(c->fc, AV_LOG_TRACE, "version =%d, isom =%d\n", version, c->isom);
2567  if (!c->isom ||
2568  (compatible_brands && strstr(compatible_brands->value, "qt ")) ||
2569  (sc->stsd_version == 0 && version > 0)) {
2570  if (version == 1) {
2571  sc->samples_per_frame = avio_rb32(pb);
2572  avio_rb32(pb); /* bytes per packet */
2573  sc->bytes_per_frame = avio_rb32(pb);
2574  avio_rb32(pb); /* bytes per sample */
2575  } else if (version == 2) {
2576  avio_rb32(pb); /* sizeof struct only */
2578  channel_count = avio_rb32(pb);
2580  st->codecpar->ch_layout.nb_channels = channel_count;
2581  avio_rb32(pb); /* always 0x7F000000 */
2583 
2584  flags = avio_rb32(pb); /* lpcm format specific flag */
2585  sc->bytes_per_frame = avio_rb32(pb);
2586  sc->samples_per_frame = avio_rb32(pb);
2587  if (st->codecpar->codec_tag == MKTAG('l','p','c','m'))
2588  st->codecpar->codec_id =
2590  flags);
2591  }
2592  if (version == 0 || (version == 1 && sc->audio_cid != -2)) {
2593  /* can't correctly handle variable sized packet as audio unit */
2594  switch (st->codecpar->codec_id) {
2595  case AV_CODEC_ID_MP2:
2596  case AV_CODEC_ID_MP3:
2598  break;
2599  }
2600  }
2601  }
2602 
2603  if (sc->format == 0) {
2604  if (st->codecpar->bits_per_coded_sample == 8)
2605  st->codecpar->codec_id = mov_codec_id(st, MKTAG('r','a','w',' '));
2606  else if (st->codecpar->bits_per_coded_sample == 16)
2607  st->codecpar->codec_id = mov_codec_id(st, MKTAG('t','w','o','s'));
2608  }
2609 
2610  switch (st->codecpar->codec_id) {
2611  case AV_CODEC_ID_PCM_S8:
2612  case AV_CODEC_ID_PCM_U8:
2613  if (st->codecpar->bits_per_coded_sample == 16)
2615  break;
2616  case AV_CODEC_ID_PCM_S16LE:
2617  case AV_CODEC_ID_PCM_S16BE:
2618  if (st->codecpar->bits_per_coded_sample == 8)
2620  else if (st->codecpar->bits_per_coded_sample == 24)
2621  st->codecpar->codec_id =
2624  else if (st->codecpar->bits_per_coded_sample == 32)
2625  st->codecpar->codec_id =
2628  break;
2629  /* set values for old format before stsd version 1 appeared */
2630  case AV_CODEC_ID_MACE3:
2631  sc->samples_per_frame = 6;
2633  break;
2634  case AV_CODEC_ID_MACE6:
2635  sc->samples_per_frame = 6;
2637  break;
2639  sc->samples_per_frame = 64;
2641  break;
2642  case AV_CODEC_ID_GSM:
2643  sc->samples_per_frame = 160;
2644  sc->bytes_per_frame = 33;
2645  break;
2646  default:
2647  break;
2648  }
2649 
2650  bits_per_sample = av_get_bits_per_sample(st->codecpar->codec_id);
2651  if (bits_per_sample && (bits_per_sample >> 3) * (uint64_t)st->codecpar->ch_layout.nb_channels <= INT_MAX) {
2652  st->codecpar->bits_per_coded_sample = bits_per_sample;
2653  sc->sample_size = (bits_per_sample >> 3) * st->codecpar->ch_layout.nb_channels;
2654  }
2655 }
2656 
2658  AVStream *st, MOVStreamContext *sc,
2659  int64_t size)
2660 {
2661  // ttxt stsd contains display flags, justification, background
2662  // color, fonts, and default styles, so fake an atom to read it
2663  MOVAtom fake_atom = { .size = size };
2664  // mp4s contains a regular esds atom, dfxp ISMV TTML has no content
2665  // in extradata unlike stpp MP4 TTML.
2666  if (st->codecpar->codec_tag != AV_RL32("mp4s") &&
2668  mov_read_glbl(c, pb, fake_atom);
2669  st->codecpar->width = sc->width;
2670  st->codecpar->height = sc->height;
2671 }
2672 
2673 static uint32_t yuv_to_rgba(uint32_t ycbcr)
2674 {
2675  uint8_t r, g, b;
2676  int y, cb, cr;
2677 
2678  y = (ycbcr >> 16) & 0xFF;
2679  cr = (ycbcr >> 8) & 0xFF;
2680  cb = ycbcr & 0xFF;
2681 
2682  b = av_clip_uint8((1164 * (y - 16) + 2018 * (cb - 128)) / 1000);
2683  g = av_clip_uint8((1164 * (y - 16) - 813 * (cr - 128) - 391 * (cb - 128)) / 1000);
2684  r = av_clip_uint8((1164 * (y - 16) + 1596 * (cr - 128) ) / 1000);
2685 
2686  return (r << 16) | (g << 8) | b;
2687 }
2688 
2690 {
2691  char buf[256] = {0};
2692  uint8_t *src = st->codecpar->extradata;
2693  int i, ret;
2694 
2695  if (st->codecpar->extradata_size != 64)
2696  return 0;
2697 
2698  if (st->codecpar->width > 0 && st->codecpar->height > 0)
2699  snprintf(buf, sizeof(buf), "size: %dx%d\n",
2700  st->codecpar->width, st->codecpar->height);
2701  av_strlcat(buf, "palette: ", sizeof(buf));
2702 
2703  for (i = 0; i < 16; i++) {
2704  uint32_t yuv = AV_RB32(src + i * 4);
2705  uint32_t rgba = yuv_to_rgba(yuv);
2706 
2707  av_strlcatf(buf, sizeof(buf), "%06"PRIx32"%s", rgba, i != 15 ? ", " : "");
2708  }
2709 
2710  if (av_strlcat(buf, "\n", sizeof(buf)) >= sizeof(buf))
2711  return 0;
2712 
2713  ret = ff_alloc_extradata(st->codecpar, strlen(buf));
2714  if (ret < 0)
2715  return ret;
2716  memcpy(st->codecpar->extradata, buf, st->codecpar->extradata_size);
2717 
2718  return 0;
2719 }
2720 
2722  AVStream *st, MOVStreamContext *sc,
2723  int64_t size)
2724 {
2725  int ret;
2726 
2727  if (st->codecpar->codec_tag == MKTAG('t','m','c','d')) {
2728  if ((int)size != size)
2729  return AVERROR(ENOMEM);
2730 
2731  ret = ff_get_extradata(c->fc, st->codecpar, pb, size);
2732  if (ret < 0)
2733  return ret;
2734  if (size > 16) {
2735  MOVStreamContext *tmcd_ctx = st->priv_data;
2736  int val;
2737  val = AV_RB32(st->codecpar->extradata + 4);
2738  tmcd_ctx->tmcd_flags = val;
2739  st->avg_frame_rate.num = AV_RB32(st->codecpar->extradata + 8); /* timescale */
2740  st->avg_frame_rate.den = AV_RB32(st->codecpar->extradata + 12); /* frameDuration */
2741  tmcd_ctx->tmcd_nb_frames = st->codecpar->extradata[16]; /* number of frames */
2742  if (size > 30) {
2743  uint32_t len = AV_RB32(st->codecpar->extradata + 18); /* name atom length */
2744  uint32_t format = AV_RB32(st->codecpar->extradata + 22);
2745  if (format == AV_RB32("name") && (int64_t)size >= (int64_t)len + 18) {
2746  uint16_t str_size = AV_RB16(st->codecpar->extradata + 26); /* string length */
2747  if (str_size > 0 && size >= (int)str_size + 30 &&
2748  st->codecpar->extradata[30] /* Don't add empty string */) {
2749  char *reel_name = av_malloc(str_size + 1);
2750  if (!reel_name)
2751  return AVERROR(ENOMEM);
2752  memcpy(reel_name, st->codecpar->extradata + 30, str_size);
2753  reel_name[str_size] = 0; /* Add null terminator */
2754  av_dict_set(&st->metadata, "reel_name", reel_name,
2756  }
2757  }
2758  }
2759  }
2760  } else {
2761  /* other codec type, just skip (rtp, mp4s ...) */
2762  avio_skip(pb, size);
2763  }
2764  return 0;
2765 }
2766 
2768  AVStream *st, MOVStreamContext *sc)
2769 {
2770  FFStream *const sti = ffstream(st);
2771 
2772  if (st->codecpar->codec_type == AVMEDIA_TYPE_AUDIO &&
2773  !st->codecpar->sample_rate && sc->time_scale > 1)
2774  st->codecpar->sample_rate = sc->time_scale;
2775 
2776  /* special codec parameters handling */
2777  switch (st->codecpar->codec_id) {
2778 #if CONFIG_DV_DEMUXER
2779  case AV_CODEC_ID_DVAUDIO:
2780  if (c->dv_fctx) {
2781  avpriv_request_sample(c->fc, "multiple DV audio streams");
2782  return AVERROR(ENOSYS);
2783  }
2784 
2785  c->dv_fctx = avformat_alloc_context();
2786  if (!c->dv_fctx) {
2787  av_log(c->fc, AV_LOG_ERROR, "dv demux context alloc error\n");
2788  return AVERROR(ENOMEM);
2789  }
2790  c->dv_demux = avpriv_dv_init_demux(c->dv_fctx);
2791  if (!c->dv_demux) {
2792  av_log(c->fc, AV_LOG_ERROR, "dv demux context init error\n");
2793  return AVERROR(ENOMEM);
2794  }
2795  sc->dv_audio_container = 1;
2797  break;
2798 #endif
2799  /* no ifdef since parameters are always those */
2800  case AV_CODEC_ID_QCELP:
2803  // force sample rate for qcelp when not stored in mov
2804  if (st->codecpar->codec_tag != MKTAG('Q','c','l','p'))
2805  st->codecpar->sample_rate = 8000;
2806  // FIXME: Why is the following needed for some files?
2807  sc->samples_per_frame = 160;
2808  if (!sc->bytes_per_frame)
2809  sc->bytes_per_frame = 35;
2810  break;
2811  case AV_CODEC_ID_AMR_NB:
2814  /* force sample rate for amr, stsd in 3gp does not store sample rate */
2815  st->codecpar->sample_rate = 8000;
2816  break;
2817  case AV_CODEC_ID_AMR_WB:
2820  st->codecpar->sample_rate = 16000;
2821  break;
2822  case AV_CODEC_ID_MP2:
2823  case AV_CODEC_ID_MP3:
2824  /* force type after stsd for m1a hdlr */
2826  break;
2827  case AV_CODEC_ID_GSM:
2828  case AV_CODEC_ID_ADPCM_MS:
2830  case AV_CODEC_ID_ILBC:
2831  case AV_CODEC_ID_MACE3:
2832  case AV_CODEC_ID_MACE6:
2833  case AV_CODEC_ID_QDM2:
2835  break;
2836  case AV_CODEC_ID_ALAC:
2837  if (st->codecpar->extradata_size == 36) {
2838  int channel_count = AV_RB8(st->codecpar->extradata + 21);
2839  if (st->codecpar->ch_layout.nb_channels != channel_count) {
2842  st->codecpar->ch_layout.nb_channels = channel_count;
2843  }
2844  st->codecpar->sample_rate = AV_RB32(st->codecpar->extradata + 32);
2845  }
2846  break;
2847  case AV_CODEC_ID_AC3:
2848  case AV_CODEC_ID_EAC3:
2850  case AV_CODEC_ID_VC1:
2851  case AV_CODEC_ID_VP8:
2852  case AV_CODEC_ID_VP9:
2854  break;
2855  case AV_CODEC_ID_EVC:
2856  case AV_CODEC_ID_AV1:
2857  /* field_order detection of H264 requires parsing */
2858  case AV_CODEC_ID_H264:
2860  break;
2861  default:
2862  break;
2863  }
2864  return 0;
2865 }
2866 
2868  int codec_tag, int format,
2869  int64_t size)
2870 {
2871  if (codec_tag &&
2872  (codec_tag != format &&
2873  // AVID 1:1 samples with differing data format and codec tag exist
2874  (codec_tag != AV_RL32("AV1x") || format != AV_RL32("AVup")) &&
2875  // prores is allowed to have differing data format and codec tag
2876  codec_tag != AV_RL32("apcn") && codec_tag != AV_RL32("apch") &&
2877  // so is dv (sigh)
2878  codec_tag != AV_RL32("dvpp") && codec_tag != AV_RL32("dvcp") &&
2879  (c->fc->video_codec_id ? ff_codec_get_id(ff_codec_movvideo_tags, format) != c->fc->video_codec_id
2880  : codec_tag != MKTAG('j','p','e','g')))) {
2881  /* Multiple fourcc, we skip JPEG. This is not correct, we should
2882  * export it as a separate AVStream but this needs a few changes
2883  * in the MOV demuxer, patch welcome. */
2884 
2885  av_log(c->fc, AV_LOG_WARNING, "multiple fourcc not supported\n");
2886  avio_skip(pb, size);
2887  return 1;
2888  }
2889 
2890  return 0;
2891 }
2892 
2894 {
2895  AVStream *st;
2896  MOVStreamContext *sc;
2897  int pseudo_stream_id;
2898 
2899  av_assert0 (c->fc->nb_streams >= 1);
2900  st = c->fc->streams[c->fc->nb_streams-1];
2901  sc = st->priv_data;
2902 
2903  for (pseudo_stream_id = 0;
2904  pseudo_stream_id < entries && !pb->eof_reached;
2905  pseudo_stream_id++) {
2906  //Parsing Sample description table
2907  enum AVCodecID id;
2908  int ret, dref_id = 1;
2909  MOVAtom a = { AV_RL32("stsd") };
2910  int64_t start_pos = avio_tell(pb);
2911  int64_t size = avio_rb32(pb); /* size */
2912  uint32_t format = avio_rl32(pb); /* data format */
2913 
2914  if (size >= 16) {
2915  avio_rb32(pb); /* reserved */
2916  avio_rb16(pb); /* reserved */
2917  dref_id = avio_rb16(pb);
2918  } else if (size <= 7) {
2919  av_log(c->fc, AV_LOG_ERROR,
2920  "invalid size %"PRId64" in stsd\n", size);
2921  return AVERROR_INVALIDDATA;
2922  }
2923 
2925  size - (avio_tell(pb) - start_pos))) {
2926  sc->stsd_count++;
2927  continue;
2928  }
2929 
2930  sc->pseudo_stream_id = st->codecpar->codec_tag ? -1 : pseudo_stream_id;
2931  sc->dref_id= dref_id;
2932  sc->format = format;
2933 
2934  id = mov_codec_id(st, format);
2935 
2936  av_log(c->fc, AV_LOG_TRACE,
2937  "size=%"PRId64" 4CC=%s codec_type=%d\n", size,
2939 
2940  st->codecpar->codec_id = id;
2942  mov_parse_stsd_video(c, pb, st, sc);
2943  } else if (st->codecpar->codec_type==AVMEDIA_TYPE_AUDIO) {
2944  mov_parse_stsd_audio(c, pb, st, sc);
2945  if (st->codecpar->sample_rate < 0) {
2946  av_log(c->fc, AV_LOG_ERROR, "Invalid sample rate %d\n", st->codecpar->sample_rate);
2947  return AVERROR_INVALIDDATA;
2948  }
2949  if (st->codecpar->ch_layout.nb_channels < 0) {
2950  av_log(c->fc, AV_LOG_ERROR, "Invalid channels %d\n", st->codecpar->ch_layout.nb_channels);
2951  return AVERROR_INVALIDDATA;
2952  }
2953  } else if (st->codecpar->codec_type==AVMEDIA_TYPE_SUBTITLE){
2954  mov_parse_stsd_subtitle(c, pb, st, sc,
2955  size - (avio_tell(pb) - start_pos));
2956  } else {
2957  ret = mov_parse_stsd_data(c, pb, st, sc,
2958  size - (avio_tell(pb) - start_pos));
2959  if (ret < 0)
2960  return ret;
2961  }
2962  /* this will read extra atoms at the end (wave, alac, damr, avcC, hvcC, SMI ...) */
2963  a.size = size - (avio_tell(pb) - start_pos);
2964  if (a.size > 8) {
2965  if ((ret = mov_read_default(c, pb, a)) < 0)
2966  return ret;
2967  } else if (a.size > 0)
2968  avio_skip(pb, a.size);
2969 
2970  if (sc->extradata && st->codecpar->extradata) {
2971  int extra_size = st->codecpar->extradata_size;
2972 
2973  /* Move the current stream extradata to the stream context one. */
2974  sc->extradata_size[pseudo_stream_id] = extra_size;
2975  sc->extradata[pseudo_stream_id] = st->codecpar->extradata;
2976  st->codecpar->extradata = NULL;
2977  st->codecpar->extradata_size = 0;
2978  }
2979  sc->stsd_count++;
2980  }
2981 
2982  if (pb->eof_reached) {
2983  av_log(c->fc, AV_LOG_WARNING, "reached eof, corrupted STSD atom\n");
2984  return AVERROR_EOF;
2985  }
2986 
2987  return 0;
2988 }
2989 
2991 {
2992  AVStream *st;
2993  MOVStreamContext *sc;
2994  int ret, entries;
2995 
2996  if (c->fc->nb_streams < 1)
2997  return 0;
2998  st = c->fc->streams[c->fc->nb_streams - 1];
2999  sc = st->priv_data;
3000 
3001  sc->stsd_version = avio_r8(pb);
3002  avio_rb24(pb); /* flags */
3003  entries = avio_rb32(pb);
3004 
3005  /* Each entry contains a size (4 bytes) and format (4 bytes). */
3006  if (entries <= 0 || entries > atom.size / 8 || entries > 1024) {
3007  av_log(c->fc, AV_LOG_ERROR, "invalid STSD entries %d\n", entries);
3008  return AVERROR_INVALIDDATA;
3009  }
3010 
3011  if (sc->extradata) {
3012  av_log(c->fc, AV_LOG_ERROR,
3013  "Duplicate stsd found in this track.\n");
3014  return AVERROR_INVALIDDATA;
3015  }
3016 
3017  /* Prepare space for hosting multiple extradata. */
3018  sc->extradata = av_calloc(entries, sizeof(*sc->extradata));
3019  if (!sc->extradata)
3020  return AVERROR(ENOMEM);
3021 
3022  sc->extradata_size = av_calloc(entries, sizeof(*sc->extradata_size));
3023  if (!sc->extradata_size) {
3024  ret = AVERROR(ENOMEM);
3025  goto fail;
3026  }
3027 
3028  ret = ff_mov_read_stsd_entries(c, pb, entries);
3029  if (ret < 0)
3030  goto fail;
3031 
3032  /* Restore back the primary extradata. */
3033  av_freep(&st->codecpar->extradata);
3034  st->codecpar->extradata_size = sc->extradata_size[0];
3035  if (sc->extradata_size[0]) {
3037  if (!st->codecpar->extradata)
3038  return AVERROR(ENOMEM);
3039  memcpy(st->codecpar->extradata, sc->extradata[0], sc->extradata_size[0]);
3040  }
3041 
3042  return mov_finalize_stsd_codec(c, pb, st, sc);
3043 fail:
3044  if (sc->extradata) {
3045  int j;
3046  for (j = 0; j < sc->stsd_count; j++)
3047  av_freep(&sc->extradata[j]);
3048  }
3049 
3050  av_freep(&sc->extradata);
3051  av_freep(&sc->extradata_size);
3052  return ret;
3053 }
3054 
3056 {
3057  AVStream *st;
3058  MOVStreamContext *sc;
3059  unsigned int i, entries;
3060 
3061  if (c->fc->nb_streams < 1)
3062  return 0;
3063  st = c->fc->streams[c->fc->nb_streams-1];
3064  sc = st->priv_data;
3065 
3066  avio_r8(pb); /* version */
3067  avio_rb24(pb); /* flags */
3068 
3069  entries = avio_rb32(pb);
3070  if ((uint64_t)entries * 12 + 4 > atom.size)
3071  return AVERROR_INVALIDDATA;
3072 
3073  av_log(c->fc, AV_LOG_TRACE, "track[%u].stsc.entries = %u\n", c->fc->nb_streams - 1, entries);
3074 
3075  if (!entries)
3076  return 0;
3077  if (sc->stsc_data) {
3078  av_log(c->fc, AV_LOG_WARNING, "Ignoring duplicated STSC atom\n");
3079  return 0;
3080  }
3081  av_free(sc->stsc_data);
3082  sc->stsc_count = 0;
3083  sc->stsc_data = av_malloc_array(entries, sizeof(*sc->stsc_data));
3084  if (!sc->stsc_data)
3085  return AVERROR(ENOMEM);
3086 
3087  for (i = 0; i < entries && !pb->eof_reached; i++) {
3088  sc->stsc_data[i].first = avio_rb32(pb);
3089  sc->stsc_data[i].count = avio_rb32(pb);
3090  sc->stsc_data[i].id = avio_rb32(pb);
3091  }
3092 
3093  sc->stsc_count = i;
3094  for (i = sc->stsc_count - 1; i < UINT_MAX; i--) {
3095  int64_t first_min = i + 1;
3096  if ((i+1 < sc->stsc_count && sc->stsc_data[i].first >= sc->stsc_data[i+1].first) ||
3097  (i > 0 && sc->stsc_data[i].first <= sc->stsc_data[i-1].first) ||
3098  sc->stsc_data[i].first < first_min ||
3099  sc->stsc_data[i].count < 1 ||
3100  sc->stsc_data[i].id < 1) {
3101  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);
3102  if (i+1 >= sc->stsc_count) {
3103  if (sc->stsc_data[i].count == 0 && i > 0) {
3104  sc->stsc_count --;
3105  continue;
3106  }
3107  sc->stsc_data[i].first = FFMAX(sc->stsc_data[i].first, first_min);
3108  if (i > 0 && sc->stsc_data[i].first <= sc->stsc_data[i-1].first)
3109  sc->stsc_data[i].first = FFMIN(sc->stsc_data[i-1].first + 1LL, INT_MAX);
3110  sc->stsc_data[i].count = FFMAX(sc->stsc_data[i].count, 1);
3111  sc->stsc_data[i].id = FFMAX(sc->stsc_data[i].id, 1);
3112  continue;
3113  }
3114  av_assert0(sc->stsc_data[i+1].first >= 2);
3115  // We replace this entry by the next valid
3116  sc->stsc_data[i].first = sc->stsc_data[i+1].first - 1;
3117  sc->stsc_data[i].count = sc->stsc_data[i+1].count;
3118  sc->stsc_data[i].id = sc->stsc_data[i+1].id;
3119  }
3120  }
3121 
3122  if (pb->eof_reached) {
3123  av_log(c->fc, AV_LOG_WARNING, "reached eof, corrupted STSC atom\n");
3124  return AVERROR_EOF;
3125  }
3126 
3127  return 0;
3128 }
3129 
3130 static inline int mov_stsc_index_valid(unsigned int index, unsigned int count)
3131 {
3132  return index < count - 1;
3133 }
3134 
3135 /* Compute the samples value for the stsc entry at the given index. */
3136 static inline int64_t mov_get_stsc_samples(MOVStreamContext *sc, unsigned int index)
3137 {
3138  int chunk_count;
3139 
3141  chunk_count = sc->stsc_data[index + 1].first - sc->stsc_data[index].first;
3142  else {
3143  // Validation for stsc / stco happens earlier in mov_read_stsc + mov_read_trak.
3145  chunk_count = sc->chunk_count - (sc->stsc_data[index].first - 1);
3146  }
3147 
3148  return sc->stsc_data[index].count * (int64_t)chunk_count;
3149 }
3150 
3152 {
3153  AVStream *st;
3154  MOVStreamContext *sc;
3155  unsigned i, entries;
3156 
3157  if (c->fc->nb_streams < 1)
3158  return 0;
3159  st = c->fc->streams[c->fc->nb_streams-1];
3160  sc = st->priv_data;
3161 
3162  avio_rb32(pb); // version + flags
3163 
3164  entries = avio_rb32(pb);
3165  if (sc->stps_data)
3166  av_log(c->fc, AV_LOG_WARNING, "Duplicated STPS atom\n");
3167  av_free(sc->stps_data);
3168  sc->stps_count = 0;
3169  sc->stps_data = av_malloc_array(entries, sizeof(*sc->stps_data));
3170  if (!sc->stps_data)
3171  return AVERROR(ENOMEM);
3172 
3173  for (i = 0; i < entries && !pb->eof_reached; i++) {
3174  sc->stps_data[i] = avio_rb32(pb);
3175  }
3176 
3177  sc->stps_count = i;
3178 
3179  if (pb->eof_reached) {
3180  av_log(c->fc, AV_LOG_WARNING, "reached eof, corrupted STPS atom\n");
3181  return AVERROR_EOF;
3182  }
3183 
3184  return 0;
3185 }
3186 
3188 {
3189  AVStream *st;
3190  FFStream *sti;
3191  MOVStreamContext *sc;
3192  unsigned int i, entries;
3193 
3194  if (c->fc->nb_streams < 1)
3195  return 0;
3196  st = c->fc->streams[c->fc->nb_streams-1];
3197  sti = ffstream(st);
3198  sc = st->priv_data;
3199 
3200  avio_r8(pb); /* version */
3201  avio_rb24(pb); /* flags */
3202 
3203  entries = avio_rb32(pb);
3204 
3205  av_log(c->fc, AV_LOG_TRACE, "keyframe_count = %u\n", entries);
3206 
3207  if (!entries) {
3208  sc->keyframe_absent = 1;
3209  if (!sti->need_parsing && st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO)
3211  return 0;
3212  }
3213  if (sc->keyframes)
3214  av_log(c->fc, AV_LOG_WARNING, "Duplicated STSS atom\n");
3215  if (entries >= UINT_MAX / sizeof(int))
3216  return AVERROR_INVALIDDATA;
3217  av_freep(&sc->keyframes);
3218  sc->keyframe_count = 0;
3219  sc->keyframes = av_malloc_array(entries, sizeof(*sc->keyframes));
3220  if (!sc->keyframes)
3221  return AVERROR(ENOMEM);
3222 
3223  for (i = 0; i < entries && !pb->eof_reached; i++) {
3224  sc->keyframes[i] = avio_rb32(pb);
3225  }
3226 
3227  sc->keyframe_count = i;
3228 
3229  if (pb->eof_reached) {
3230  av_log(c->fc, AV_LOG_WARNING, "reached eof, corrupted STSS atom\n");
3231  return AVERROR_EOF;
3232  }
3233 
3234  return 0;
3235 }
3236 
3238 {
3239  AVStream *st;
3240  MOVStreamContext *sc;
3241  unsigned int i, entries, sample_size, field_size, num_bytes;
3242  GetBitContext gb;
3243  unsigned char* buf;
3244  int ret;
3245 
3246  if (c->fc->nb_streams < 1)
3247  return 0;
3248  st = c->fc->streams[c->fc->nb_streams-1];
3249  sc = st->priv_data;
3250 
3251  avio_r8(pb); /* version */
3252  avio_rb24(pb); /* flags */
3253 
3254  if (atom.type == MKTAG('s','t','s','z')) {
3255  sample_size = avio_rb32(pb);
3256  if (!sc->sample_size) /* do not overwrite value computed in stsd */
3257  sc->sample_size = sample_size;
3258  sc->stsz_sample_size = sample_size;
3259  field_size = 32;
3260  } else {
3261  sample_size = 0;
3262  avio_rb24(pb); /* reserved */
3263  field_size = avio_r8(pb);
3264  }
3265  entries = avio_rb32(pb);
3266 
3267  av_log(c->fc, AV_LOG_TRACE, "sample_size = %u sample_count = %u\n", sc->sample_size, entries);
3268 
3269  sc->sample_count = entries;
3270  if (sample_size)
3271  return 0;
3272 
3273  if (field_size != 4 && field_size != 8 && field_size != 16 && field_size != 32) {
3274  av_log(c->fc, AV_LOG_ERROR, "Invalid sample field size %u\n", field_size);
3275  return AVERROR_INVALIDDATA;
3276  }
3277 
3278  if (!entries)
3279  return 0;
3280  if (entries >= (INT_MAX - 4 - 8 * AV_INPUT_BUFFER_PADDING_SIZE) / field_size)
3281  return AVERROR_INVALIDDATA;
3282  if (sc->sample_sizes)
3283  av_log(c->fc, AV_LOG_WARNING, "Duplicated STSZ atom\n");
3284  av_free(sc->sample_sizes);
3285  sc->sample_count = 0;
3286  sc->sample_sizes = av_malloc_array(entries, sizeof(*sc->sample_sizes));
3287  if (!sc->sample_sizes)
3288  return AVERROR(ENOMEM);
3289 
3290  num_bytes = (entries*field_size+4)>>3;
3291 
3292  buf = av_malloc(num_bytes+AV_INPUT_BUFFER_PADDING_SIZE);
3293  if (!buf) {
3294  av_freep(&sc->sample_sizes);
3295  return AVERROR(ENOMEM);
3296  }
3297 
3298  ret = ffio_read_size(pb, buf, num_bytes);
3299  if (ret < 0) {
3300  av_freep(&sc->sample_sizes);
3301  av_free(buf);
3302  av_log(c->fc, AV_LOG_WARNING, "STSZ atom truncated\n");
3303  return 0;
3304  }
3305 
3306  init_get_bits(&gb, buf, 8*num_bytes);
3307 
3308  for (i = 0; i < entries; i++) {
3309  sc->sample_sizes[i] = get_bits_long(&gb, field_size);
3310  if (sc->sample_sizes[i] < 0) {
3311  av_free(buf);
3312  av_log(c->fc, AV_LOG_ERROR, "Invalid sample size %d\n", sc->sample_sizes[i]);
3313  return AVERROR_INVALIDDATA;
3314  }
3315  sc->data_size += sc->sample_sizes[i];
3316  }
3317 
3318  sc->sample_count = i;
3319 
3320  av_free(buf);
3321 
3322  return 0;
3323 }
3324 
3326 {
3327  AVStream *st;
3328  MOVStreamContext *sc;
3329  unsigned int i, entries, alloc_size = 0;
3330  int64_t duration = 0;
3331  int64_t total_sample_count = 0;
3332  int64_t current_dts = 0;
3333  int64_t corrected_dts = 0;
3334 
3335  if (c->fc->nb_streams < 1)
3336  return 0;
3337  st = c->fc->streams[c->fc->nb_streams-1];
3338  sc = st->priv_data;
3339 
3340  avio_r8(pb); /* version */
3341  avio_rb24(pb); /* flags */
3342  entries = avio_rb32(pb);
3343 
3344  av_log(c->fc, AV_LOG_TRACE, "track[%u].stts.entries = %u\n",
3345  c->fc->nb_streams-1, entries);
3346 
3347  if (sc->stts_data)
3348  av_log(c->fc, AV_LOG_WARNING, "Duplicated STTS atom\n");
3349  av_freep(&sc->stts_data);
3350  sc->stts_count = 0;
3351  if (entries >= INT_MAX / sizeof(*sc->stts_data))
3352  return AVERROR(ENOMEM);
3353 
3354  for (i = 0; i < entries && !pb->eof_reached; i++) {
3355  unsigned int sample_duration;
3356  unsigned int sample_count;
3357  unsigned int min_entries = FFMIN(FFMAX(i + 1, 1024 * 1024), entries);
3358  MOVStts *stts_data = av_fast_realloc(sc->stts_data, &alloc_size,
3359  min_entries * sizeof(*sc->stts_data));
3360  if (!stts_data) {
3361  av_freep(&sc->stts_data);
3362  sc->stts_count = 0;
3363  return AVERROR(ENOMEM);
3364  }
3365  sc->stts_count = min_entries;
3366  sc->stts_data = stts_data;
3367 
3368  sample_count = avio_rb32(pb);
3369  sample_duration = avio_rb32(pb);
3370 
3371  sc->stts_data[i].count= sample_count;
3372  sc->stts_data[i].duration= sample_duration;
3373 
3374  av_log(c->fc, AV_LOG_TRACE, "sample_count=%u, sample_duration=%u\n",
3375  sample_count, sample_duration);
3376 
3377  /* STTS sample offsets are uint32 but some files store it as int32
3378  * with negative values used to correct DTS delays.
3379  There may be abnormally large values as well. */
3380  if (sample_duration > c->max_stts_delta) {
3381  // assume high delta is a correction if negative when cast as int32
3382  int32_t delta_magnitude = (int32_t)sample_duration;
3383  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",
3384  sample_duration, i, sample_count, st->index);
3385  sc->stts_data[i].duration = 1;
3386  corrected_dts += (delta_magnitude < 0 ? (int64_t)delta_magnitude : 1) * sample_count;
3387  } else {
3388  corrected_dts += sample_duration * sample_count;
3389  }
3390 
3391  current_dts += sc->stts_data[i].duration * sample_count;
3392 
3393  if (current_dts > corrected_dts) {
3394  int64_t drift = (current_dts - corrected_dts)/FFMAX(sample_count, 1);
3395  uint32_t correction = (sc->stts_data[i].duration > drift) ? drift : sc->stts_data[i].duration - 1;
3396  current_dts -= correction * sample_count;
3397  sc->stts_data[i].duration -= correction;
3398  }
3399 
3400  duration+=(int64_t)sc->stts_data[i].duration*(uint64_t)sc->stts_data[i].count;
3401  total_sample_count+=sc->stts_data[i].count;
3402  }
3403 
3404  sc->stts_count = i;
3405 
3406  if (duration > 0 &&
3407  duration <= INT64_MAX - sc->duration_for_fps &&
3408  total_sample_count <= INT_MAX - sc->nb_frames_for_fps) {
3409  sc->duration_for_fps += duration;
3410  sc->nb_frames_for_fps += total_sample_count;
3411  }
3412 
3413  if (pb->eof_reached) {
3414  av_log(c->fc, AV_LOG_WARNING, "reached eof, corrupted STTS atom\n");
3415  return AVERROR_EOF;
3416  }
3417 
3418  st->nb_frames= total_sample_count;
3419  if (duration)
3420  st->duration= FFMIN(st->duration, duration);
3421 
3422  // All samples have zero duration. They have higher chance be chose by
3423  // mov_find_next_sample, which leads to seek again and again.
3424  //
3425  // It's AVERROR_INVALIDDATA actually, but such files exist in the wild.
3426  // So only mark data stream as discarded for safety.
3427  if (!duration && sc->stts_count &&
3429  av_log(c->fc, AV_LOG_WARNING,
3430  "All samples in data stream index:id [%d:%d] have zero "
3431  "duration, stream set to be discarded by default. Override "
3432  "using AVStream->discard or -discard for ffmpeg command.\n",
3433  st->index, sc->id);
3434  st->discard = AVDISCARD_ALL;
3435  }
3436  sc->track_end = duration;
3437  return 0;
3438 }
3439 
3441 {
3442  AVStream *st;
3443  MOVStreamContext *sc;
3444  int64_t i, entries;
3445 
3446  if (c->fc->nb_streams < 1)
3447  return 0;
3448  st = c->fc->streams[c->fc->nb_streams - 1];
3449  sc = st->priv_data;
3450 
3451  avio_r8(pb); /* version */
3452  avio_rb24(pb); /* flags */
3453  entries = atom.size - 4;
3454 
3455  av_log(c->fc, AV_LOG_TRACE, "track[%u].sdtp.entries = %" PRId64 "\n",
3456  c->fc->nb_streams - 1, entries);
3457 
3458  if (sc->sdtp_data)
3459  av_log(c->fc, AV_LOG_WARNING, "Duplicated SDTP atom\n");
3460  av_freep(&sc->sdtp_data);
3461  sc->sdtp_count = 0;
3462 
3463  sc->sdtp_data = av_malloc(entries);
3464  if (!sc->sdtp_data)
3465  return AVERROR(ENOMEM);
3466 
3467  for (i = 0; i < entries && !pb->eof_reached; i++)
3468  sc->sdtp_data[i] = avio_r8(pb);
3469  sc->sdtp_count = i;
3470 
3471  return 0;
3472 }
3473 
3474 static void mov_update_dts_shift(MOVStreamContext *sc, int duration, void *logctx)
3475 {
3476  if (duration < 0) {
3477  if (duration == INT_MIN) {
3478  av_log(logctx, AV_LOG_WARNING, "mov_update_dts_shift(): dts_shift set to %d\n", INT_MAX);
3479  duration++;
3480  }
3481  sc->dts_shift = FFMAX(sc->dts_shift, -duration);
3482  }
3483 }
3484 
3486 {
3487  AVStream *st;
3488  MOVStreamContext *sc;
3489  unsigned int i, entries, ctts_count = 0;
3490 
3491  if (c->fc->nb_streams < 1)
3492  return 0;
3493  st = c->fc->streams[c->fc->nb_streams-1];
3494  sc = st->priv_data;
3495 
3496  avio_r8(pb); /* version */
3497  avio_rb24(pb); /* flags */
3498  entries = avio_rb32(pb);
3499 
3500  av_log(c->fc, AV_LOG_TRACE, "track[%u].ctts.entries = %u\n", c->fc->nb_streams - 1, entries);
3501 
3502  if (!entries)
3503  return 0;
3504  if (entries >= UINT_MAX / sizeof(*sc->ctts_data))
3505  return AVERROR_INVALIDDATA;
3506  av_freep(&sc->ctts_data);
3507  sc->ctts_data = av_fast_realloc(NULL, &sc->ctts_allocated_size, entries * sizeof(*sc->ctts_data));
3508  if (!sc->ctts_data)
3509  return AVERROR(ENOMEM);
3510 
3511  for (i = 0; i < entries && !pb->eof_reached; i++) {
3512  int count = avio_rb32(pb);
3513  int duration = avio_rb32(pb);
3514 
3515  if (count <= 0) {
3516  av_log(c->fc, AV_LOG_TRACE,
3517  "ignoring CTTS entry with count=%d duration=%d\n",
3518  count, duration);
3519  continue;
3520  }
3521 
3522  add_ctts_entry(&sc->ctts_data, &ctts_count, &sc->ctts_allocated_size,
3523  count, duration);
3524 
3525  av_log(c->fc, AV_LOG_TRACE, "count=%d, duration=%d\n",
3526  count, duration);
3527 
3528  if (FFNABS(duration) < -(1<<28) && i+2<entries) {
3529  av_log(c->fc, AV_LOG_WARNING, "CTTS invalid\n");
3530  av_freep(&sc->ctts_data);
3531  sc->ctts_count = 0;
3532  return 0;
3533  }
3534 
3535  if (i+2<entries)
3536  mov_update_dts_shift(sc, duration, c->fc);
3537  }
3538 
3539  sc->ctts_count = ctts_count;
3540 
3541  if (pb->eof_reached) {
3542  av_log(c->fc, AV_LOG_WARNING, "reached eof, corrupted CTTS atom\n");
3543  return AVERROR_EOF;
3544  }
3545 
3546  av_log(c->fc, AV_LOG_TRACE, "dts shift %d\n", sc->dts_shift);
3547 
3548  return 0;
3549 }
3550 
3552 {
3553  AVStream *st;
3554  MOVStreamContext *sc;
3555  uint8_t version;
3556  uint32_t grouping_type;
3557  uint32_t default_length;
3558  av_unused uint32_t default_group_description_index;
3559  uint32_t entry_count;
3560 
3561  if (c->fc->nb_streams < 1)
3562  return 0;
3563  st = c->fc->streams[c->fc->nb_streams - 1];
3564  sc = st->priv_data;
3565 
3566  version = avio_r8(pb); /* version */
3567  avio_rb24(pb); /* flags */
3568  grouping_type = avio_rl32(pb);
3569 
3570  /*
3571  * This function only supports "sync" boxes, but the code is able to parse
3572  * other boxes (such as "tscl", "tsas" and "stsa")
3573  */
3574  if (grouping_type != MKTAG('s','y','n','c'))
3575  return 0;
3576 
3577  default_length = version >= 1 ? avio_rb32(pb) : 0;
3578  default_group_description_index = version >= 2 ? avio_rb32(pb) : 0;
3579  entry_count = avio_rb32(pb);
3580 
3581  av_freep(&sc->sgpd_sync);
3582  sc->sgpd_sync_count = entry_count;
3583  sc->sgpd_sync = av_calloc(entry_count, sizeof(*sc->sgpd_sync));
3584  if (!sc->sgpd_sync)
3585  return AVERROR(ENOMEM);
3586 
3587  for (uint32_t i = 0; i < entry_count && !pb->eof_reached; i++) {
3588  uint32_t description_length = default_length;
3589  if (version >= 1 && default_length == 0)
3590  description_length = avio_rb32(pb);
3591  if (grouping_type == MKTAG('s','y','n','c')) {
3592  const uint8_t nal_unit_type = avio_r8(pb) & 0x3f;
3593  sc->sgpd_sync[i] = nal_unit_type;
3594  description_length -= 1;
3595  }
3596  avio_skip(pb, description_length);
3597  }
3598 
3599  if (pb->eof_reached) {
3600  av_log(c->fc, AV_LOG_WARNING, "reached eof, corrupted SGPD atom\n");
3601  return AVERROR_EOF;
3602  }
3603 
3604  return 0;
3605 }
3606 
3608 {
3609  AVStream *st;
3610  MOVStreamContext *sc;
3611  unsigned int i, entries;
3612  uint8_t version;
3613  uint32_t grouping_type;
3614  MOVSbgp *table, **tablep;
3615  int *table_count;
3616 
3617  if (c->fc->nb_streams < 1)
3618  return 0;
3619  st = c->fc->streams[c->fc->nb_streams-1];
3620  sc = st->priv_data;
3621 
3622  version = avio_r8(pb); /* version */
3623  avio_rb24(pb); /* flags */
3624  grouping_type = avio_rl32(pb);
3625 
3626  if (grouping_type == MKTAG('r','a','p',' ')) {
3627  tablep = &sc->rap_group;
3628  table_count = &sc->rap_group_count;
3629  } else if (grouping_type == MKTAG('s','y','n','c')) {
3630  tablep = &sc->sync_group;
3631  table_count = &sc->sync_group_count;
3632  } else {
3633  return 0;
3634  }
3635 
3636  if (version == 1)
3637  avio_rb32(pb); /* grouping_type_parameter */
3638 
3639  entries = avio_rb32(pb);
3640  if (!entries)
3641  return 0;
3642  if (*tablep)
3643  av_log(c->fc, AV_LOG_WARNING, "Duplicated SBGP %s atom\n", av_fourcc2str(grouping_type));
3644  av_freep(tablep);
3645  table = av_malloc_array(entries, sizeof(*table));
3646  if (!table)
3647  return AVERROR(ENOMEM);
3648  *tablep = table;
3649 
3650  for (i = 0; i < entries && !pb->eof_reached; i++) {
3651  table[i].count = avio_rb32(pb); /* sample_count */
3652  table[i].index = avio_rb32(pb); /* group_description_index */
3653  }
3654 
3655  *table_count = i;
3656 
3657  if (pb->eof_reached) {
3658  av_log(c->fc, AV_LOG_WARNING, "reached eof, corrupted SBGP atom\n");
3659  return AVERROR_EOF;
3660  }
3661 
3662  return 0;
3663 }
3664 
3665 /**
3666  * Get ith edit list entry (media time, duration).
3667  */
3669  const MOVStreamContext *msc,
3670  unsigned int edit_list_index,
3671  int64_t *edit_list_media_time,
3672  int64_t *edit_list_duration,
3673  int64_t global_timescale)
3674 {
3675  if (edit_list_index == msc->elst_count) {
3676  return 0;
3677  }
3678  *edit_list_media_time = msc->elst_data[edit_list_index].time;
3679  *edit_list_duration = msc->elst_data[edit_list_index].duration;
3680 
3681  /* duration is in global timescale units;convert to msc timescale */
3682  if (global_timescale == 0) {
3683  avpriv_request_sample(mov->fc, "Support for mvhd.timescale = 0 with editlists");
3684  return 0;
3685  }
3686  *edit_list_duration = av_rescale(*edit_list_duration, msc->time_scale,
3687  global_timescale);
3688  return 1;
3689 }
3690 
3691 /**
3692  * Find the closest previous frame to the timestamp_pts, in e_old index
3693  * entries. Searching for just any frame / just key frames can be controlled by
3694  * last argument 'flag'.
3695  * Note that if ctts_data is not NULL, we will always search for a key frame
3696  * irrespective of the value of 'flag'. If we don't find any keyframe, we will
3697  * return the first frame of the video.
3698  *
3699  * Here the timestamp_pts is considered to be a presentation timestamp and
3700  * the timestamp of index entries are considered to be decoding timestamps.
3701  *
3702  * Returns 0 if successful in finding a frame, else returns -1.
3703  * Places the found index corresponding output arg.
3704  *
3705  * If ctts_old is not NULL, then refines the searched entry by searching
3706  * backwards from the found timestamp, to find the frame with correct PTS.
3707  *
3708  * Places the found ctts_index and ctts_sample in corresponding output args.
3709  */
3711  AVIndexEntry *e_old,
3712  int nb_old,
3713  MOVCtts* ctts_data,
3714  int64_t ctts_count,
3715  int64_t timestamp_pts,
3716  int flag,
3717  int64_t* index,
3718  int64_t* ctts_index,
3719  int64_t* ctts_sample)
3720 {
3721  MOVStreamContext *msc = st->priv_data;
3722  FFStream *const sti = ffstream(st);
3723  AVIndexEntry *e_keep = sti->index_entries;
3724  int nb_keep = sti->nb_index_entries;
3725  int64_t i = 0;
3726  int64_t index_ctts_count;
3727 
3728  av_assert0(index);
3729 
3730  // If dts_shift > 0, then all the index timestamps will have to be offset by
3731  // at least dts_shift amount to obtain PTS.
3732  // Hence we decrement the searched timestamp_pts by dts_shift to find the closest index element.
3733  if (msc->dts_shift > 0) {
3734  timestamp_pts -= msc->dts_shift;
3735  }
3736 
3737  sti->index_entries = e_old;
3738  sti->nb_index_entries = nb_old;
3739  *index = av_index_search_timestamp(st, timestamp_pts, flag | AVSEEK_FLAG_BACKWARD);
3740 
3741  // Keep going backwards in the index entries until the timestamp is the same.
3742  if (*index >= 0) {
3743  for (i = *index; i > 0 && e_old[i].timestamp == e_old[i - 1].timestamp;
3744  i--) {
3745  if ((flag & AVSEEK_FLAG_ANY) ||
3746  (e_old[i - 1].flags & AVINDEX_KEYFRAME)) {
3747  *index = i - 1;
3748  }
3749  }
3750  }
3751 
3752  // If we have CTTS then refine the search, by searching backwards over PTS
3753  // computed by adding corresponding CTTS durations to index timestamps.
3754  if (ctts_data && *index >= 0) {
3755  av_assert0(ctts_index);
3756  av_assert0(ctts_sample);
3757  // Find out the ctts_index for the found frame.
3758  *ctts_index = 0;
3759  *ctts_sample = 0;
3760  for (index_ctts_count = 0; index_ctts_count < *index; index_ctts_count++) {
3761  if (*ctts_index < ctts_count) {
3762  (*ctts_sample)++;
3763  if (ctts_data[*ctts_index].count == *ctts_sample) {
3764  (*ctts_index)++;
3765  *ctts_sample = 0;
3766  }
3767  }
3768  }
3769 
3770  while (*index >= 0 && (*ctts_index) >= 0 && (*ctts_index) < ctts_count) {
3771  // Find a "key frame" with PTS <= timestamp_pts (So that we can decode B-frames correctly).
3772  // No need to add dts_shift to the timestamp here becase timestamp_pts has already been
3773  // compensated by dts_shift above.
3774  if ((e_old[*index].timestamp + ctts_data[*ctts_index].duration) <= timestamp_pts &&
3775  (e_old[*index].flags & AVINDEX_KEYFRAME)) {
3776  break;
3777  }
3778 
3779  (*index)--;
3780  if (*ctts_sample == 0) {
3781  (*ctts_index)--;
3782  if (*ctts_index >= 0)
3783  *ctts_sample = ctts_data[*ctts_index].count - 1;
3784  } else {
3785  (*ctts_sample)--;
3786  }
3787  }
3788  }
3789 
3790  /* restore AVStream state*/
3791  sti->index_entries = e_keep;
3792  sti->nb_index_entries = nb_keep;
3793  return *index >= 0 ? 0 : -1;
3794 }
3795 
3796 /**
3797  * Add index entry with the given values, to the end of ffstream(st)->index_entries.
3798  * Returns the new size ffstream(st)->index_entries if successful, else returns -1.
3799  *
3800  * This function is similar to ff_add_index_entry in libavformat/utils.c
3801  * except that here we are always unconditionally adding an index entry to
3802  * the end, instead of searching the entries list and skipping the add if
3803  * there is an existing entry with the same timestamp.
3804  * This is needed because the mov_fix_index calls this func with the same
3805  * unincremented timestamp for successive discarded frames.
3806  */
3807 static int64_t add_index_entry(AVStream *st, int64_t pos, int64_t timestamp,
3808  int size, int distance, int flags)
3809 {
3810  FFStream *const sti = ffstream(st);
3811  AVIndexEntry *entries, *ie;
3812  int64_t index = -1;
3813  const size_t min_size_needed = (sti->nb_index_entries + 1) * sizeof(AVIndexEntry);
3814 
3815  // Double the allocation each time, to lower memory fragmentation.
3816  // Another difference from ff_add_index_entry function.
3817  const size_t requested_size =
3818  min_size_needed > sti->index_entries_allocated_size ?
3819  FFMAX(min_size_needed, 2 * sti->index_entries_allocated_size) :
3820  min_size_needed;
3821 
3822  if (sti->nb_index_entries + 1U >= UINT_MAX / sizeof(AVIndexEntry))
3823  return -1;
3824 
3825  entries = av_fast_realloc(sti->index_entries,
3827  requested_size);
3828  if (!entries)
3829  return -1;
3830 
3831  sti->index_entries = entries;
3832 
3833  index = sti->nb_index_entries++;
3834  ie= &entries[index];
3835 
3836  ie->pos = pos;
3837  ie->timestamp = timestamp;
3838  ie->min_distance= distance;
3839  ie->size= size;
3840  ie->flags = flags;
3841  return index;
3842 }
3843 
3844 /**
3845  * Rewrite timestamps of index entries in the range [end_index - frame_duration_buffer_size, end_index)
3846  * by subtracting end_ts successively by the amounts given in frame_duration_buffer.
3847  */
3848 static void fix_index_entry_timestamps(AVStream* st, int end_index, int64_t end_ts,
3849  int64_t* frame_duration_buffer,
3850  int frame_duration_buffer_size) {
3851  FFStream *const sti = ffstream(st);
3852  int i = 0;
3853  av_assert0(end_index >= 0 && end_index <= sti->nb_index_entries);
3854  for (i = 0; i < frame_duration_buffer_size; i++) {
3855  end_ts -= frame_duration_buffer[frame_duration_buffer_size - 1 - i];
3856  sti->index_entries[end_index - 1 - i].timestamp = end_ts;
3857  }
3858 }
3859 
3860 /**
3861  * Append a new ctts entry to ctts_data.
3862  * Returns the new ctts_count if successful, else returns -1.
3863  */
3864 static int64_t add_ctts_entry(MOVCtts** ctts_data, unsigned int* ctts_count, unsigned int* allocated_size,
3865  int count, int duration)
3866 {
3867  MOVCtts *ctts_buf_new;
3868  const size_t min_size_needed = (*ctts_count + 1) * sizeof(MOVCtts);
3869  const size_t requested_size =
3870  min_size_needed > *allocated_size ?
3871  FFMAX(min_size_needed, 2 * (*allocated_size)) :
3872  min_size_needed;
3873 
3874  if ((unsigned)(*ctts_count) >= UINT_MAX / sizeof(MOVCtts) - 1)
3875  return -1;
3876 
3877  ctts_buf_new = av_fast_realloc(*ctts_data, allocated_size, requested_size);
3878 
3879  if (!ctts_buf_new)
3880  return -1;
3881 
3882  *ctts_data = ctts_buf_new;
3883 
3884  ctts_buf_new[*ctts_count].count = count;
3885  ctts_buf_new[*ctts_count].duration = duration;
3886 
3887  *ctts_count = (*ctts_count) + 1;
3888  return *ctts_count;
3889 }
3890 
3891 #define MAX_REORDER_DELAY 16
3893 {
3894  MOVStreamContext *msc = st->priv_data;
3895  FFStream *const sti = ffstream(st);
3896  int ctts_ind = 0;
3897  int ctts_sample = 0;
3898  int64_t pts_buf[MAX_REORDER_DELAY + 1]; // Circular buffer to sort pts.
3899  int buf_start = 0;
3900  int j, r, num_swaps;
3901 
3902  for (j = 0; j < MAX_REORDER_DELAY + 1; j++)
3903  pts_buf[j] = INT64_MIN;
3904 
3905  if (st->codecpar->video_delay <= 0 && msc->ctts_data &&
3907  st->codecpar->video_delay = 0;
3908  for (int ind = 0; ind < sti->nb_index_entries && ctts_ind < msc->ctts_count; ++ind) {
3909  // Point j to the last elem of the buffer and insert the current pts there.
3910  j = buf_start;
3911  buf_start = (buf_start + 1);
3912  if (buf_start == MAX_REORDER_DELAY + 1)
3913  buf_start = 0;
3914 
3915  pts_buf[j] = sti->index_entries[ind].timestamp + msc->ctts_data[ctts_ind].duration;
3916 
3917  // The timestamps that are already in the sorted buffer, and are greater than the
3918  // current pts, are exactly the timestamps that need to be buffered to output PTS
3919  // in correct sorted order.
3920  // Hence the video delay (which is the buffer size used to sort DTS and output PTS),
3921  // can be computed as the maximum no. of swaps any particular timestamp needs to
3922  // go through, to keep this buffer in sorted order.
3923  num_swaps = 0;
3924  while (j != buf_start) {
3925  r = j - 1;
3926  if (r < 0) r = MAX_REORDER_DELAY;
3927  if (pts_buf[j] < pts_buf[r]) {
3928  FFSWAP(int64_t, pts_buf[j], pts_buf[r]);
3929  ++num_swaps;
3930  } else {
3931  break;
3932  }
3933  j = r;
3934  }
3935  st->codecpar->video_delay = FFMAX(st->codecpar->video_delay, num_swaps);
3936 
3937  ctts_sample++;
3938  if (ctts_sample == msc->ctts_data[ctts_ind].count) {
3939  ctts_ind++;
3940  ctts_sample = 0;
3941  }
3942  }
3943  av_log(c->fc, AV_LOG_DEBUG, "Setting codecpar->delay to %d for stream st: %d\n",
3944  st->codecpar->video_delay, st->index);
3945  }
3946 }
3947 
3949 {
3950  sc->current_sample++;
3951  sc->current_index++;
3952  if (sc->index_ranges &&
3953  sc->current_index >= sc->current_index_range->end &&
3954  sc->current_index_range->end) {
3955  sc->current_index_range++;
3957  }
3958 }
3959 
3961 {
3962  sc->current_sample--;
3963  sc->current_index--;
3964  if (sc->index_ranges &&
3966  sc->current_index_range > sc->index_ranges) {
3967  sc->current_index_range--;
3968  sc->current_index = sc->current_index_range->end - 1;
3969  }
3970 }
3971 
3972 static void mov_current_sample_set(MOVStreamContext *sc, int current_sample)
3973 {
3974  int64_t range_size;
3975 
3976  sc->current_sample = current_sample;
3977  sc->current_index = current_sample;
3978  if (!sc->index_ranges) {
3979  return;
3980  }
3981 
3982  for (sc->current_index_range = sc->index_ranges;
3983  sc->current_index_range->end;
3984  sc->current_index_range++) {
3985  range_size = sc->current_index_range->end - sc->current_index_range->start;
3986  if (range_size > current_sample) {
3987  sc->current_index = sc->current_index_range->start + current_sample;
3988  break;
3989  }
3990  current_sample -= range_size;
3991  }
3992 }
3993 
3994 /**
3995  * Fix ffstream(st)->index_entries, so that it contains only the entries (and the entries
3996  * which are needed to decode them) that fall in the edit list time ranges.
3997  * Also fixes the timestamps of the index entries to match the timeline
3998  * specified the edit lists.
3999  */
4000 static void mov_fix_index(MOVContext *mov, AVStream *st)
4001 {
4002  MOVStreamContext *msc = st->priv_data;
4003  FFStream *const sti = ffstream(st);
4004  AVIndexEntry *e_old = sti->index_entries;
4005  int nb_old = sti->nb_index_entries;
4006  const AVIndexEntry *e_old_end = e_old + nb_old;
4007  const AVIndexEntry *current = NULL;
4008  MOVCtts *ctts_data_old = msc->ctts_data;
4009  int64_t ctts_index_old = 0;
4010  int64_t ctts_sample_old = 0;
4011  int64_t ctts_count_old = msc->ctts_count;
4012  int64_t edit_list_media_time = 0;
4013  int64_t edit_list_duration = 0;
4014  int64_t frame_duration = 0;
4015  int64_t edit_list_dts_counter = 0;
4016  int64_t edit_list_dts_entry_end = 0;
4017  int64_t edit_list_start_ctts_sample = 0;
4018  int64_t curr_cts;
4019  int64_t curr_ctts = 0;
4020  int64_t empty_edits_sum_duration = 0;
4021  int64_t edit_list_index = 0;
4022  int64_t index;
4023  int flags;
4024  int64_t start_dts = 0;
4025  int64_t edit_list_start_encountered = 0;
4026  int64_t search_timestamp = 0;
4027  int64_t* frame_duration_buffer = NULL;
4028  int num_discarded_begin = 0;
4029  int first_non_zero_audio_edit = -1;
4030  int packet_skip_samples = 0;
4031  MOVIndexRange *current_index_range = NULL;
4032  int found_keyframe_after_edit = 0;
4033  int found_non_empty_edit = 0;
4034 
4035  if (!msc->elst_data || msc->elst_count <= 0 || nb_old <= 0) {
4036  return;
4037  }
4038 
4039  // allocate the index ranges array
4040  msc->index_ranges = av_malloc_array(msc->elst_count + 1,
4041  sizeof(msc->index_ranges[0]));
4042  if (!msc->index_ranges) {
4043  av_log(mov->fc, AV_LOG_ERROR, "Cannot allocate index ranges buffer\n");
4044  return;
4045  }
4046  msc->current_index_range = msc->index_ranges;
4047 
4048  // Clean AVStream from traces of old index
4049  sti->index_entries = NULL;
4051  sti->nb_index_entries = 0;
4052 
4053  // Clean ctts fields of MOVStreamContext
4054  msc->ctts_data = NULL;
4055  msc->ctts_count = 0;
4056  msc->ctts_index = 0;
4057  msc->ctts_sample = 0;
4058  msc->ctts_allocated_size = 0;
4059 
4060  // Reinitialize min_corrected_pts so that it can be computed again.
4061  msc->min_corrected_pts = -1;
4062 
4063  // If the dts_shift is positive (in case of negative ctts values in mov),
4064  // then negate the DTS by dts_shift
4065  if (msc->dts_shift > 0) {
4066  edit_list_dts_entry_end -= msc->dts_shift;
4067  av_log(mov->fc, AV_LOG_DEBUG, "Shifting DTS by %d because of negative CTTS.\n", msc->dts_shift);
4068  }
4069 
4070  start_dts = edit_list_dts_entry_end;
4071 
4072  while (get_edit_list_entry(mov, msc, edit_list_index, &edit_list_media_time,
4073  &edit_list_duration, mov->time_scale)) {
4074  av_log(mov->fc, AV_LOG_DEBUG, "Processing st: %d, edit list %"PRId64" - media time: %"PRId64", duration: %"PRId64"\n",
4075  st->index, edit_list_index, edit_list_media_time, edit_list_duration);
4076  edit_list_index++;
4077  edit_list_dts_counter = edit_list_dts_entry_end;
4078  edit_list_dts_entry_end += edit_list_duration;
4079  num_discarded_begin = 0;
4080  if (!found_non_empty_edit && edit_list_media_time == -1) {
4081  empty_edits_sum_duration += edit_list_duration;
4082  continue;
4083  }
4084  found_non_empty_edit = 1;
4085 
4086  // If we encounter a non-negative edit list reset the skip_samples/start_pad fields and set them
4087  // according to the edit list below.
4088  if (st->codecpar->codec_type == AVMEDIA_TYPE_AUDIO) {
4089  if (first_non_zero_audio_edit < 0) {
4090  first_non_zero_audio_edit = 1;
4091  } else {
4092  first_non_zero_audio_edit = 0;
4093  }
4094 
4095  if (first_non_zero_audio_edit > 0)
4096  sti->skip_samples = msc->start_pad = 0;
4097  }
4098 
4099  // While reordering frame index according to edit list we must handle properly
4100  // the scenario when edit list entry starts from none key frame.
4101  // We find closest previous key frame and preserve it and consequent frames in index.
4102  // All frames which are outside edit list entry time boundaries will be dropped after decoding.
4103  search_timestamp = edit_list_media_time;
4104  if (st->codecpar->codec_type == AVMEDIA_TYPE_AUDIO) {
4105  // Audio decoders like AAC need need a decoder delay samples previous to the current sample,
4106  // to correctly decode this frame. Hence for audio we seek to a frame 1 sec. before the
4107  // edit_list_media_time to cover the decoder delay.
4108  search_timestamp = FFMAX(search_timestamp - msc->time_scale, e_old[0].timestamp);
4109  }
4110 
4111  if (find_prev_closest_index(st, e_old, nb_old, ctts_data_old, ctts_count_old, search_timestamp, 0,
4112  &index, &ctts_index_old, &ctts_sample_old) < 0) {
4113  av_log(mov->fc, AV_LOG_WARNING,
4114  "st: %d edit list: %"PRId64" Missing key frame while searching for timestamp: %"PRId64"\n",
4115  st->index, edit_list_index, search_timestamp);
4116  if (find_prev_closest_index(st, e_old, nb_old, ctts_data_old, ctts_count_old, search_timestamp, AVSEEK_FLAG_ANY,
4117  &index, &ctts_index_old, &ctts_sample_old) < 0) {
4118  av_log(mov->fc, AV_LOG_WARNING,
4119  "st: %d edit list %"PRId64" Cannot find an index entry before timestamp: %"PRId64".\n",
4120  st->index, edit_list_index, search_timestamp);
4121  index = 0;
4122  ctts_index_old = 0;
4123  ctts_sample_old = 0;
4124  }
4125  }
4126  current = e_old + index;
4127  edit_list_start_ctts_sample = ctts_sample_old;
4128 
4129  // Iterate over index and arrange it according to edit list
4130  edit_list_start_encountered = 0;
4131  found_keyframe_after_edit = 0;
4132  for (; current < e_old_end; current++, index++) {
4133  // check if frame outside edit list mark it for discard
4134  frame_duration = (current + 1 < e_old_end) ?
4135  ((current + 1)->timestamp - current->timestamp) : edit_list_duration;
4136 
4137  flags = current->flags;
4138 
4139  // frames (pts) before or after edit list
4140  curr_cts = current->timestamp + msc->dts_shift;
4141  curr_ctts = 0;
4142 
4143  if (ctts_data_old && ctts_index_old < ctts_count_old) {
4144  curr_ctts = ctts_data_old[ctts_index_old].duration;
4145  av_log(mov->fc, AV_LOG_TRACE, "stts: %"PRId64" ctts: %"PRId64", ctts_index: %"PRId64", ctts_count: %"PRId64"\n",
4146  curr_cts, curr_ctts, ctts_index_old, ctts_count_old);
4147  curr_cts += curr_ctts;
4148  ctts_sample_old++;
4149  if (ctts_sample_old == ctts_data_old[ctts_index_old].count) {
4150  if (add_ctts_entry(&msc->ctts_data, &msc->ctts_count,
4151  &msc->ctts_allocated_size,
4152  ctts_data_old[ctts_index_old].count - edit_list_start_ctts_sample,
4153  ctts_data_old[ctts_index_old].duration) == -1) {
4154  av_log(mov->fc, AV_LOG_ERROR, "Cannot add CTTS entry %"PRId64" - {%"PRId64", %d}\n",
4155  ctts_index_old,
4156  ctts_data_old[ctts_index_old].count - edit_list_start_ctts_sample,
4157  ctts_data_old[ctts_index_old].duration);
4158  break;
4159  }
4160  ctts_index_old++;
4161  ctts_sample_old = 0;
4162  edit_list_start_ctts_sample = 0;
4163  }
4164  }
4165 
4166  if (curr_cts < edit_list_media_time || curr_cts >= (edit_list_duration + edit_list_media_time)) {
4168  curr_cts < edit_list_media_time && curr_cts + frame_duration > edit_list_media_time &&
4169  first_non_zero_audio_edit > 0) {
4170  packet_skip_samples = edit_list_media_time - curr_cts;
4171  sti->skip_samples += packet_skip_samples;
4172 
4173  // Shift the index entry timestamp by packet_skip_samples to be correct.
4174  edit_list_dts_counter -= packet_skip_samples;
4175  if (edit_list_start_encountered == 0) {
4176  edit_list_start_encountered = 1;
4177  // Make timestamps strictly monotonically increasing for audio, by rewriting timestamps for
4178  // discarded packets.
4179  if (frame_duration_buffer) {
4180  fix_index_entry_timestamps(st, sti->nb_index_entries, edit_list_dts_counter,
4181  frame_duration_buffer, num_discarded_begin);
4182  av_freep(&frame_duration_buffer);
4183  }
4184  }
4185 
4186  av_log(mov->fc, AV_LOG_DEBUG, "skip %d audio samples from curr_cts: %"PRId64"\n", packet_skip_samples, curr_cts);
4187  } else {
4189  av_log(mov->fc, AV_LOG_DEBUG, "drop a frame at curr_cts: %"PRId64" @ %"PRId64"\n", curr_cts, index);
4190 
4191  if (edit_list_start_encountered == 0) {
4192  num_discarded_begin++;
4193  frame_duration_buffer = av_realloc(frame_duration_buffer,
4194  num_discarded_begin * sizeof(int64_t));
4195  if (!frame_duration_buffer) {
4196  av_log(mov->fc, AV_LOG_ERROR, "Cannot reallocate frame duration buffer\n");
4197  break;
4198  }
4199  frame_duration_buffer[num_discarded_begin - 1] = frame_duration;
4200 
4201  // Increment skip_samples for the first non-zero audio edit list
4202  if (st->codecpar->codec_type == AVMEDIA_TYPE_AUDIO &&
4203  first_non_zero_audio_edit > 0 && st->codecpar->codec_id != AV_CODEC_ID_VORBIS) {
4204  sti->skip_samples += frame_duration;
4205  }
4206  }
4207  }
4208  } else {
4209  if (msc->min_corrected_pts < 0) {
4210  msc->min_corrected_pts = edit_list_dts_counter + curr_ctts + msc->dts_shift;
4211  } else {
4212  msc->min_corrected_pts = FFMIN(msc->min_corrected_pts, edit_list_dts_counter + curr_ctts + msc->dts_shift);
4213  }
4214  if (edit_list_start_encountered == 0) {
4215  edit_list_start_encountered = 1;
4216  // Make timestamps strictly monotonically increasing by rewriting timestamps for
4217  // discarded packets.
4218  if (frame_duration_buffer) {
4219  fix_index_entry_timestamps(st, sti->nb_index_entries, edit_list_dts_counter,
4220  frame_duration_buffer, num_discarded_begin);
4221  av_freep(&frame_duration_buffer);
4222  }
4223  }
4224  }
4225 
4226  if (add_index_entry(st, current->pos, edit_list_dts_counter, current->size,
4227  current->min_distance, flags) == -1) {
4228  av_log(mov->fc, AV_LOG_ERROR, "Cannot add index entry\n");
4229  break;
4230  }
4231 
4232  // Update the index ranges array
4233  if (!current_index_range || index != current_index_range->end) {
4234  current_index_range = current_index_range ? current_index_range + 1
4235  : msc->index_ranges;
4236  current_index_range->start = index;
4237  }
4238  current_index_range->end = index + 1;
4239 
4240  // Only start incrementing DTS in frame_duration amounts, when we encounter a frame in edit list.
4241  if (edit_list_start_encountered > 0) {
4242  edit_list_dts_counter = edit_list_dts_counter + frame_duration;
4243  }
4244 
4245  // Break when found first key frame after edit entry completion
4246  if ((curr_cts + frame_duration >= (edit_list_duration + edit_list_media_time)) &&
4248  if (ctts_data_old) {
4249  // If we have CTTS and this is the first keyframe after edit elist,
4250  // wait for one more, because there might be trailing B-frames after this I-frame
4251  // that do belong to the edit.
4252  if (st->codecpar->codec_type != AVMEDIA_TYPE_AUDIO && found_keyframe_after_edit == 0) {
4253  found_keyframe_after_edit = 1;
4254  continue;
4255  }
4256  if (ctts_sample_old != 0) {
4257  if (add_ctts_entry(&msc->ctts_data, &msc->ctts_count,
4258  &msc->ctts_allocated_size,
4259  ctts_sample_old - edit_list_start_ctts_sample,
4260  ctts_data_old[ctts_index_old].duration) == -1) {
4261  av_log(mov->fc, AV_LOG_ERROR, "Cannot add CTTS entry %"PRId64" - {%"PRId64", %d}\n",
4262  ctts_index_old, ctts_sample_old - edit_list_start_ctts_sample,
4263  ctts_data_old[ctts_index_old].duration);
4264  break;
4265  }
4266  }
4267  }
4268  break;
4269  }
4270  }
4271  }
4272  // If there are empty edits, then msc->min_corrected_pts might be positive
4273  // intentionally. So we subtract the sum duration of emtpy edits here.
4274  msc->min_corrected_pts -= empty_edits_sum_duration;
4275 
4276  // If the minimum pts turns out to be greater than zero after fixing the index, then we subtract the
4277  // dts by that amount to make the first pts zero.
4278  if (st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO) {
4279  if (msc->min_corrected_pts > 0) {
4280  av_log(mov->fc, AV_LOG_DEBUG, "Offset DTS by %"PRId64" to make first pts zero.\n", msc->min_corrected_pts);
4281  for (int i = 0; i < sti->nb_index_entries; ++i)
4283  }
4284  }
4285  // Start time should be equal to zero or the duration of any empty edits.
4286  st->start_time = empty_edits_sum_duration;
4287 
4288  // Update av stream length, if it ends up shorter than the track's media duration
4289  st->duration = FFMIN(st->duration, edit_list_dts_entry_end - start_dts);
4290  msc->start_pad = sti->skip_samples;
4291 
4292  // Free the old index and the old CTTS structures
4293  av_free(e_old);
4294  av_free(ctts_data_old);
4295  av_freep(&frame_duration_buffer);
4296 
4297  // Null terminate the index ranges array
4298  current_index_range = current_index_range ? current_index_range + 1
4299  : msc->index_ranges;
4300  current_index_range->start = 0;
4301  current_index_range->end = 0;
4302  msc->current_index = msc->index_ranges[0].start;
4303 }
4304 
4305 static uint32_t get_sgpd_sync_index(const MOVStreamContext *sc, int nal_unit_type)
4306 {
4307  for (uint32_t i = 0; i < sc->sgpd_sync_count; i++)
4308  if (sc->sgpd_sync[i] == HEVC_NAL_CRA_NUT)
4309  return i + 1;
4310  return 0;
4311 }
4312 
4314 {
4315  int k;
4316  int sample_id = 0;
4317  uint32_t cra_index;
4318  MOVStreamContext *sc = st->priv_data;
4319 
4320  if (st->codecpar->codec_id != AV_CODEC_ID_HEVC || !sc->sync_group_count)
4321  return 0;
4322 
4323  /* Build an unrolled index of the samples */
4324  sc->sample_offsets_count = 0;
4325  for (uint32_t i = 0; i < sc->ctts_count; i++) {
4326  if (sc->ctts_data[i].count > INT_MAX - sc->sample_offsets_count)
4327  return AVERROR(ENOMEM);
4328  sc->sample_offsets_count += sc->ctts_data[i].count;
4329  }
4330  av_freep(&sc->sample_offsets);
4332  if (!sc->sample_offsets)
4333  return AVERROR(ENOMEM);
4334  k = 0;
4335  for (uint32_t i = 0; i < sc->ctts_count; i++)
4336  for (int j = 0; j < sc->ctts_data[i].count; j++)
4337  sc->sample_offsets[k++] = sc->ctts_data[i].duration;
4338 
4339  /* The following HEVC NAL type reveal the use of open GOP sync points
4340  * (TODO: BLA types may also be concerned) */
4341  cra_index = get_sgpd_sync_index(sc, HEVC_NAL_CRA_NUT); /* Clean Random Access */
4342  if (!cra_index)
4343  return 0;
4344 
4345  /* Build a list of open-GOP key samples */
4346  sc->open_key_samples_count = 0;
4347  for (uint32_t i = 0; i < sc->sync_group_count; i++)
4348  if (sc->sync_group[i].index == cra_index) {
4349  if (sc->sync_group[i].count > INT_MAX - sc->open_key_samples_count)
4350  return AVERROR(ENOMEM);
4352  }
4353  av_freep(&sc->open_key_samples);
4355  if (!sc->open_key_samples)
4356  return AVERROR(ENOMEM);
4357  k = 0;
4358  for (uint32_t i = 0; i < sc->sync_group_count; i++) {
4359  const MOVSbgp *sg = &sc->sync_group[i];
4360  if (sg->index == cra_index)
4361  for (uint32_t j = 0; j < sg->count; j++)
4362  sc->open_key_samples[k++] = sample_id;
4363  if (sg->count > INT_MAX - sample_id)
4364  return AVERROR_PATCHWELCOME;
4365  sample_id += sg->count;
4366  }
4367 
4368  /* Identify the minimal time step between samples */
4369  sc->min_sample_duration = UINT_MAX;
4370  for (uint32_t i = 0; i < sc->stts_count; i++)
4372 
4373  return 0;
4374 }
4375 
4376 static void mov_build_index(MOVContext *mov, AVStream *st)
4377 {
4378  MOVStreamContext *sc = st->priv_data;
4379  FFStream *const sti = ffstream(st);
4380  int64_t current_offset;
4381  int64_t current_dts = 0;
4382  unsigned int stts_index = 0;
4383  unsigned int stsc_index = 0;
4384  unsigned int stss_index = 0;
4385  unsigned int stps_index = 0;
4386  unsigned int i, j;
4387  uint64_t stream_size = 0;
4388  MOVCtts *ctts_data_old = sc->ctts_data;
4389  unsigned int ctts_count_old = sc->ctts_count;
4390 
4391  int ret = build_open_gop_key_points(st);
4392  if (ret < 0)
4393  return;
4394 
4395  if (sc->elst_count) {
4396  int i, edit_start_index = 0, multiple_edits = 0;
4397  int64_t empty_duration = 0; // empty duration of the first edit list entry
4398  int64_t start_time = 0; // start time of the media
4399 
4400  for (i = 0; i < sc->elst_count; i++) {
4401  const MOVElst *e = &sc->elst_data[i];
4402  if (i == 0 && e->time == -1) {
4403  /* if empty, the first entry is the start time of the stream
4404  * relative to the presentation itself */
4405  empty_duration = e->duration;
4406  edit_start_index = 1;
4407  } else if (i == edit_start_index && e->time >= 0) {
4408  start_time = e->time;
4409  } else {
4410  multiple_edits = 1;
4411  }
4412  }
4413 
4414  if (multiple_edits && !mov->advanced_editlist) {
4416  av_log(mov->fc, AV_LOG_WARNING, "multiple edit list entries, "
4417  "not supported in fragmented MP4 files\n");
4418  else
4419  av_log(mov->fc, AV_LOG_WARNING, "multiple edit list entries, "
4420  "Use -advanced_editlist to correctly decode otherwise "
4421  "a/v desync might occur\n");
4422  }
4423 
4424  /* adjust first dts according to edit list */
4425  if ((empty_duration || start_time) && mov->time_scale > 0) {
4426  if (empty_duration)
4427  empty_duration = av_rescale(empty_duration, sc->time_scale, mov->time_scale);
4428 
4429  if (av_sat_sub64(start_time, empty_duration) != start_time - (uint64_t)empty_duration)
4430  av_log(mov->fc, AV_LOG_WARNING, "start_time - empty_duration is not representable\n");
4431 
4432  sc->time_offset = start_time - (uint64_t)empty_duration;
4434  if (!mov->advanced_editlist)
4435  current_dts = -sc->time_offset;
4436  }
4437 
4438  if (!multiple_edits && !mov->advanced_editlist &&
4440  sc->start_pad = start_time;
4441  }
4442 
4443  /* only use old uncompressed audio chunk demuxing when stts specifies it */
4444  if (!(st->codecpar->codec_type == AVMEDIA_TYPE_AUDIO &&
4445  sc->stts_count == 1 && sc->stts_data[0].duration == 1)) {
4446  unsigned int current_sample = 0;
4447  unsigned int stts_sample = 0;
4448  unsigned int sample_size;
4449  unsigned int distance = 0;
4450  unsigned int rap_group_index = 0;
4451  unsigned int rap_group_sample = 0;
4452  int rap_group_present = sc->rap_group_count && sc->rap_group;
4453  int key_off = (sc->keyframe_count && sc->keyframes[0] > 0) || (sc->stps_count && sc->stps_data[0] > 0);
4454 
4455  current_dts -= sc->dts_shift;
4456 
4457  if (!sc->sample_count || sti->nb_index_entries)
4458  return;
4459  if (sc->sample_count >= UINT_MAX / sizeof(*sti->index_entries) - sti->nb_index_entries)
4460  return;
4461  if (av_reallocp_array(&sti->index_entries,
4462  sti->nb_index_entries + sc->sample_count,
4463  sizeof(*sti->index_entries)) < 0) {
4464  sti->nb_index_entries = 0;
4465  return;
4466  }
4467  sti->index_entries_allocated_size = (sti->nb_index_entries + sc->sample_count) * sizeof(*sti->index_entries);
4468 
4469  if (ctts_data_old) {
4470  // Expand ctts entries such that we have a 1-1 mapping with samples
4471  if (sc->sample_count >= UINT_MAX / sizeof(*sc->ctts_data))
4472  return;
4473  sc->ctts_count = 0;
4474  sc->ctts_allocated_size = 0;
4476  sc->sample_count * sizeof(*sc->ctts_data));
4477  if (!sc->ctts_data) {
4478  av_free(ctts_data_old);
4479  return;
4480  }
4481 
4482  memset((uint8_t*)(sc->ctts_data), 0, sc->ctts_allocated_size);
4483 
4484  for (i = 0; i < ctts_count_old &&
4485  sc->ctts_count < sc->sample_count; i++)
4486  for (j = 0; j < ctts_data_old[i].count &&
4487  sc->ctts_count < sc->sample_count; j++)
4488  add_ctts_entry(&sc->ctts_data, &sc->ctts_count,
4489  &sc->ctts_allocated_size, 1,
4490  ctts_data_old[i].duration);
4491  av_free(ctts_data_old);
4492  }
4493 
4494  for (i = 0; i < sc->chunk_count; i++) {
4495  int64_t next_offset = i+1 < sc->chunk_count ? sc->chunk_offsets[i+1] : INT64_MAX;
4496  current_offset = sc->chunk_offsets[i];
4497  while (mov_stsc_index_valid(stsc_index, sc->stsc_count) &&
4498  i + 1 == sc->stsc_data[stsc_index + 1].first)
4499  stsc_index++;
4500 
4501  if (next_offset > current_offset && sc->sample_size>0 && sc->sample_size < sc->stsz_sample_size &&
4502  sc->stsc_data[stsc_index].count * (int64_t)sc->stsz_sample_size > next_offset - current_offset) {
4503  av_log(mov->fc, AV_LOG_WARNING, "STSZ sample size %d invalid (too large), ignoring\n", sc->stsz_sample_size);
4504  sc->stsz_sample_size = sc->sample_size;
4505  }
4506  if (sc->stsz_sample_size>0 && sc->stsz_sample_size < sc->sample_size) {
4507  av_log(mov->fc, AV_LOG_WARNING, "STSZ sample size %d invalid (too small), ignoring\n", sc->stsz_sample_size);
4508  sc->stsz_sample_size = sc->sample_size;
4509  }
4510 
4511  for (j = 0; j < sc->stsc_data[stsc_index].count; j++) {
4512  int keyframe = 0;
4513  if (current_sample >= sc->sample_count) {
4514  av_log(mov->fc, AV_LOG_ERROR, "wrong sample count\n");
4515  return;
4516  }
4517 
4518  if (!sc->keyframe_absent && (!sc->keyframe_count || current_sample+key_off == sc->keyframes[stss_index])) {
4519  keyframe = 1;
4520  if (stss_index + 1 < sc->keyframe_count)
4521  stss_index++;
4522  } else if (sc->stps_count && current_sample+key_off == sc->stps_data[stps_index]) {
4523  keyframe = 1;
4524  if (stps_index + 1 < sc->stps_count)
4525  stps_index++;
4526  }
4527  if (rap_group_present && rap_group_index < sc->rap_group_count) {
4528  if (sc->rap_group[rap_group_index].index > 0)
4529  keyframe = 1;
4530  if (++rap_group_sample == sc->rap_group[rap_group_index].count) {
4531  rap_group_sample = 0;
4532  rap_group_index++;
4533  }
4534  }
4535  if (sc->keyframe_absent
4536  && !sc->stps_count
4537  && !rap_group_present
4538  && (st->codecpar->codec_type == AVMEDIA_TYPE_AUDIO || (i==0 && j==0)))
4539  keyframe = 1;
4540  if (keyframe)
4541  distance = 0;
4542  sample_size = sc->stsz_sample_size > 0 ? sc->stsz_sample_size : sc->sample_sizes[current_sample];
4543  if (current_offset > INT64_MAX - sample_size) {
4544  av_log(mov->fc, AV_LOG_ERROR, "Current offset %"PRId64" or sample size %u is too large\n",
4545  current_offset,
4546  sample_size);
4547  return;
4548  }
4549 
4550  if (sc->pseudo_stream_id == -1 ||
4551  sc->stsc_data[stsc_index].id - 1 == sc->pseudo_stream_id) {
4552  AVIndexEntry *e;
4553  if (sample_size > 0x3FFFFFFF) {
4554  av_log(mov->fc, AV_LOG_ERROR, "Sample size %u is too large\n", sample_size);
4555  return;
4556  }
4557  e = &sti->index_entries[sti->nb_index_entries++];
4558  e->pos = current_offset;
4559  e->timestamp = current_dts;
4560  e->size = sample_size;
4561  e->min_distance = distance;
4562  e->flags = keyframe ? AVINDEX_KEYFRAME : 0;
4563  av_log(mov->fc, AV_LOG_TRACE, "AVIndex stream %d, sample %u, offset %"PRIx64", dts %"PRId64", "
4564  "size %u, distance %u, keyframe %d\n", st->index, current_sample,
4565  current_offset, current_dts, sample_size, distance, keyframe);
4566  if (st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO && sti->nb_index_entries < 100)
4567  ff_rfps_add_frame(mov->fc, st, current_dts);
4568  }
4569 
4570  current_offset += sample_size;
4571  stream_size += sample_size;
4572 
4573  current_dts += sc->stts_data[stts_index].duration;
4574 
4575  distance++;
4576  stts_sample++;
4577  current_sample++;
4578  if (stts_index + 1 < sc->stts_count && stts_sample == sc->stts_data[stts_index].count) {
4579  stts_sample = 0;
4580  stts_index++;
4581  }
4582  }
4583  }
4584  if (st->duration > 0)
4585  st->codecpar->bit_rate = stream_size*8*sc->time_scale/st->duration;
4586  } else {
4587  unsigned chunk_samples, total = 0;
4588 
4589  if (!sc->chunk_count)
4590  return;
4591 
4592  // compute total chunk count
4593  for (i = 0; i < sc->stsc_count; i++) {
4594  unsigned count, chunk_count;
4595 
4596  chunk_samples = sc->stsc_data[i].count;
4597  if (i != sc->stsc_count - 1 &&
4598  sc->samples_per_frame && chunk_samples % sc->samples_per_frame) {
4599  av_log(mov->fc, AV_LOG_ERROR, "error unaligned chunk\n");
4600  return;
4601  }
4602 
4603  if (sc->samples_per_frame >= 160) { // gsm
4604  count = chunk_samples / sc->samples_per_frame;
4605  } else if (sc->samples_per_frame > 1) {
4606  unsigned samples = (1024/sc->samples_per_frame)*sc->samples_per_frame;
4607  count = (chunk_samples+samples-1) / samples;
4608  } else {
4609  count = (chunk_samples+1023) / 1024;
4610  }
4611 
4612  if (mov_stsc_index_valid(i, sc->stsc_count))
4613  chunk_count = sc->stsc_data[i+1].first - sc->stsc_data[i].first;
4614  else
4615  chunk_count = sc->chunk_count - (sc->stsc_data[i].first - 1);
4616  total += chunk_count * count;
4617  }
4618 
4619  av_log(mov->fc, AV_LOG_TRACE, "chunk count %u\n", total);
4620  if (total >= UINT_MAX / sizeof(*sti->index_entries) - sti->nb_index_entries)
4621  return;
4622  if (av_reallocp_array(&sti->index_entries,
4623  sti->nb_index_entries + total,
4624  sizeof(*sti->index_entries)) < 0) {
4625  sti->nb_index_entries = 0;
4626  return;
4627  }
4628  sti->index_entries_allocated_size = (sti->nb_index_entries + total) * sizeof(*sti->index_entries);
4629 
4630  // populate index
4631  for (i = 0; i < sc->chunk_count; i++) {
4632  current_offset = sc->chunk_offsets[i];
4633  if (mov_stsc_index_valid(stsc_index, sc->stsc_count) &&
4634  i + 1 == sc->stsc_data[stsc_index + 1].first)
4635  stsc_index++;
4636  chunk_samples = sc->stsc_data[stsc_index].count;
4637 
4638  while (chunk_samples > 0) {
4639  AVIndexEntry *e;
4640  unsigned size, samples;
4641 
4642  if (sc->samples_per_frame > 1 && !sc->bytes_per_frame) {
4644  "Zero bytes per frame, but %d samples per frame",
4645  sc->samples_per_frame);
4646  return;
4647  }
4648 
4649  if (sc->samples_per_frame >= 160) { // gsm
4650  samples = sc->samples_per_frame;
4651  size = sc->bytes_per_frame;
4652  } else {
4653  if (sc->samples_per_frame > 1) {
4654  samples = FFMIN((1024 / sc->samples_per_frame)*
4655  sc->samples_per_frame, chunk_samples);
4657  } else {
4658  samples = FFMIN(1024, chunk_samples);
4659  size = samples * sc->sample_size;
4660  }
4661  }
4662 
4663  if (sti->nb_index_entries >= total) {
4664  av_log(mov->fc, AV_LOG_ERROR, "wrong chunk count %u\n", total);
4665  return;
4666  }
4667  if (size > 0x3FFFFFFF) {
4668  av_log(mov->fc, AV_LOG_ERROR, "Sample size %u is too large\n", size);
4669  return;
4670  }
4671  e = &sti->index_entries[sti->nb_index_entries++];
4672  e->pos = current_offset;
4673  e->timestamp = current_dts;
4674  e->size = size;
4675  e->min_distance = 0;
4676  e->flags = AVINDEX_KEYFRAME;
4677  av_log(mov->fc, AV_LOG_TRACE, "AVIndex stream %d, chunk %u, offset %"PRIx64", dts %"PRId64", "
4678  "size %u, duration %u\n", st->index, i, current_offset, current_dts,
4679  size, samples);
4680 
4681  current_offset += size;
4682  current_dts += samples;
4683  chunk_samples -= samples;
4684  }
4685  }
4686  }
4687 
4688  if (!mov->ignore_editlist && mov->advanced_editlist) {
4689  // Fix index according to edit lists.
4690  mov_fix_index(mov, st);
4691  }
4692 
4693  // Update start time of the stream.
4695  st->start_time = sti->index_entries[0].timestamp + sc->dts_shift;
4696  if (sc->ctts_data) {
4697  st->start_time += sc->ctts_data[0].duration;
4698  }
4699  }
4700 
4701  mov_estimate_video_delay(mov, st);
4702 }
4703 
4704 static int test_same_origin(const char *src, const char *ref) {
4705  char src_proto[64];
4706  char ref_proto[64];
4707  char src_auth[256];
4708  char ref_auth[256];
4709  char src_host[256];
4710  char ref_host[256];
4711  int src_port=-1;
4712  int ref_port=-1;
4713 
4714  av_url_split(src_proto, sizeof(src_proto), src_auth, sizeof(src_auth), src_host, sizeof(src_host), &src_port, NULL, 0, src);
4715  av_url_split(ref_proto, sizeof(ref_proto), ref_auth, sizeof(ref_auth), ref_host, sizeof(ref_host), &ref_port, NULL, 0, ref);
4716 
4717  if (strlen(src) == 0) {
4718  return -1;
4719  } else if (strlen(src_auth) + 1 >= sizeof(src_auth) ||
4720  strlen(ref_auth) + 1 >= sizeof(ref_auth) ||
4721  strlen(src_host) + 1 >= sizeof(src_host) ||
4722  strlen(ref_host) + 1 >= sizeof(ref_host)) {
4723  return 0;
4724  } else if (strcmp(src_proto, ref_proto) ||
4725  strcmp(src_auth, ref_auth) ||
4726  strcmp(src_host, ref_host) ||
4727  src_port != ref_port) {
4728  return 0;
4729  } else
4730  return 1;
4731 }
4732 
4733 static int mov_open_dref(MOVContext *c, AVIOContext **pb, const char *src, MOVDref *ref)
4734 {
4735  /* try relative path, we do not try the absolute because it can leak information about our
4736  system to an attacker */
4737  if (ref->nlvl_to > 0 && ref->nlvl_from > 0) {
4738  char filename[1025];
4739  const char *src_path;
4740  int i, l;
4741 
4742  /* find a source dir */
4743  src_path = strrchr(src, '/');
4744  if (src_path)
4745  src_path++;
4746  else
4747  src_path = src;
4748 
4749  /* find a next level down to target */
4750  for (i = 0, l = strlen(ref->path) - 1; l >= 0; l--)
4751  if (ref->path[l] == '/') {
4752  if (i == ref->nlvl_to - 1)
4753  break;
4754  else
4755  i++;
4756  }
4757 
4758  /* compose filename if next level down to target was found */
4759  if (i == ref->nlvl_to - 1 && src_path - src < sizeof(filename)) {
4760  memcpy(filename, src, src_path - src);
4761  filename[src_path - src] = 0;
4762 
4763  for (i = 1; i < ref->nlvl_from; i++)
4764  av_strlcat(filename, "../", sizeof(filename));
4765 
4766  av_strlcat(filename, ref->path + l + 1, sizeof(filename));
4767  if (!c->use_absolute_path) {
4768  int same_origin = test_same_origin(src, filename);
4769 
4770  if (!same_origin) {
4771  av_log(c->fc, AV_LOG_ERROR,
4772  "Reference with mismatching origin, %s not tried for security reasons, "
4773  "set demuxer option use_absolute_path to allow it anyway\n",
4774  ref->path);
4775  return AVERROR(ENOENT);
4776  }
4777 
4778  if (strstr(ref->path + l + 1, "..") ||
4779  strstr(ref->path + l + 1, ":") ||
4780  (ref->nlvl_from > 1 && same_origin < 0) ||
4781  (filename[0] == '/' && src_path == src))
4782  return AVERROR(ENOENT);
4783  }
4784 
4785  if (strlen(filename) + 1 == sizeof(filename))
4786  return AVERROR(ENOENT);
4787  if (!c->fc->io_open(c->fc, pb, filename, AVIO_FLAG_READ, NULL))
4788  return 0;
4789  }
4790  } else if (c->use_absolute_path) {
4791  av_log(c->fc, AV_LOG_WARNING, "Using absolute path on user request, "
4792  "this is a possible security issue\n");
4793  if (!c->fc->io_open(c->fc, pb, ref->path, AVIO_FLAG_READ, NULL))
4794  return 0;
4795  } else {
4796  av_log(c->fc, AV_LOG_ERROR,
4797  "Absolute path %s not tried for security reasons, "
4798  "set demuxer option use_absolute_path to allow absolute paths\n",
4799  ref->path);
4800  }
4801 
4802  return AVERROR(ENOENT);
4803 }
4804 
4806 {
4807  if (sc->time_scale <= 0) {
4808  av_log(c->fc, AV_LOG_WARNING, "stream %d, timescale not set\n", sc->ffindex);
4809  sc->time_scale = c->time_scale;
4810  if (sc->time_scale <= 0)
4811  sc->time_scale = 1;
4812  }
4813 }
4814 
4815 #if CONFIG_IAMFDEC
4816 static int mov_update_iamf_streams(MOVContext *c, const AVStream *st)
4817 {
4818  const MOVStreamContext *sc = st->priv_data;
4819  const IAMFContext *iamf = &sc->iamf->iamf;
4820 
4821  for (int i = 0; i < iamf->nb_audio_elements; i++) {
4822  const AVStreamGroup *stg = NULL;
4823 
4824  for (int j = 0; j < c->fc->nb_stream_groups; j++)
4825  if (c->fc->stream_groups[j]->id == iamf->audio_elements[i]->audio_element_id)
4826  stg = c->fc->stream_groups[j];
4827  av_assert0(stg);
4828 
4829  for (int j = 0; j < stg->nb_streams; j++) {
4830  const FFStream *sti = cffstream(st);
4831  AVStream *out = stg->streams[j];
4832  FFStream *out_sti = ffstream(stg->streams[j]);
4833 
4834  out->codecpar->bit_rate = 0;
4835 
4836  if (out == st)
4837  continue;
4838 
4839  out->time_base = st->time_base;
4840  out->start_time = st->start_time;
4841  out->duration = st->duration;
4842  out->nb_frames = st->nb_frames;
4843  out->discard = st->discard;
4844 
4845  av_assert0(!out_sti->index_entries);
4847  if (!out_sti->index_entries)
4848  return AVERROR(ENOMEM);
4849 
4851  out_sti->nb_index_entries = sti->nb_index_entries;
4852  out_sti->skip_samples = sti->skip_samples;
4853  memcpy(out_sti->index_entries, sti->index_entries, sti->index_entries_allocated_size);
4854  }
4855  }
4856 
4857  return 0;
4858 }
4859 #endif
4860 
4862 {
4863  AVStream *st;
4864  MOVStreamContext *sc;
4865  int ret;
4866 
4867  st = avformat_new_stream(c->fc, NULL);
4868  if (!st) return AVERROR(ENOMEM);
4869  st->id = -1;
4870  sc = av_mallocz(sizeof(MOVStreamContext));
4871  if (!sc) return AVERROR(ENOMEM);
4872 
4873  st->priv_data = sc;
4875  sc->ffindex = st->index;
4876  c->trak_index = st->index;
4877  sc->refcount = 1;
4878 
4879  if ((ret = mov_read_default(c, pb, atom)) < 0)
4880  return ret;
4881 
4882  c->trak_index = -1;
4883 
4884  // Here stsc refers to a chunk not described in stco. This is technically invalid,
4885  // but we can overlook it (clearing stsc) whenever stts_count == 0 (indicating no samples).
4886  if (!sc->chunk_count && !sc->stts_count && sc->stsc_count) {
4887  sc->stsc_count = 0;
4888  av_freep(&sc->stsc_data);
4889  }
4890 
4891  /* sanity checks */
4892  if ((sc->chunk_count && (!sc->stts_count || !sc->stsc_count ||
4893  (!sc->sample_size && !sc->sample_count))) ||
4894  (!sc->chunk_count && sc->sample_count)) {
4895  av_log(c->fc, AV_LOG_ERROR, "stream %d, missing mandatory atoms, broken header\n",
4896  st->index);
4897  return 0;
4898  }
4899  if (sc->stsc_count && sc->stsc_data[ sc->stsc_count - 1 ].first > sc->chunk_count) {
4900  av_log(c->fc, AV_LOG_ERROR, "stream %d, contradictionary STSC and STCO\n",
4901  st->index);
4902  return AVERROR_INVALIDDATA;
4903  }
4904 
4905  fix_timescale(c, sc);
4906 
4907  avpriv_set_pts_info(st, 64, 1, sc->time_scale);
4908 
4909  /*
4910  * Advanced edit list support does not work with fragemented MP4s, which
4911  * have stsc, stsz, stco, and stts with zero entries in the moov atom.
4912  * In these files, trun atoms may be streamed in.
4913  */
4914  if (!sc->stts_count && c->advanced_editlist) {
4915 
4916  av_log(c->fc, AV_LOG_VERBOSE, "advanced_editlist does not work with fragmented "
4917  "MP4. disabling.\n");
4918  c->advanced_editlist = 0;
4919  c->advanced_editlist_autodisabled = 1;
4920  }
4921 
4922  mov_build_index(c, st);
4923 
4924 #if CONFIG_IAMFDEC
4925  if (sc->iamf) {
4926  ret = mov_update_iamf_streams(c, st);
4927  if (ret < 0)
4928  return ret;
4929  }
4930 #endif
4931 
4932  if (sc->dref_id-1 < sc->drefs_count && sc->drefs[sc->dref_id-1].path) {
4933  MOVDref *dref = &sc->drefs[sc->dref_id - 1];
4934  if (c->enable_drefs) {
4935  if (mov_open_dref(c, &sc->pb, c->fc->url, dref) < 0)
4936  av_log(c->fc, AV_LOG_ERROR,
4937  "stream %d, error opening alias: path='%s', dir='%s', "
4938  "filename='%s', volume='%s', nlvl_from=%d, nlvl_to=%d\n",
4939  st->index, dref->path, dref->dir, dref->filename,
4940  dref->volume, dref->nlvl_from, dref->nlvl_to);
4941  } else {
4942  av_log(c->fc, AV_LOG_WARNING,
4943  "Skipped opening external track: "
4944  "stream %d, alias: path='%s', dir='%s', "
4945  "filename='%s', volume='%s', nlvl_from=%d, nlvl_to=%d."
4946  "Set enable_drefs to allow this.\n",
4947  st->index, dref->path, dref->dir, dref->filename,
4948  dref->volume, dref->nlvl_from, dref->nlvl_to);
4949  }
4950  } else {
4951  sc->pb = c->fc->pb;
4952  sc->pb_is_copied = 1;
4953  }
4954 
4955  if (st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO) {
4956  if (!st->sample_aspect_ratio.num && st->codecpar->width && st->codecpar->height &&
4957  sc->height && sc->width &&
4958  (st->codecpar->width != sc->width || st->codecpar->height != sc->height)) {
4959  st->sample_aspect_ratio = av_d2q(((double)st->codecpar->height * sc->width) /
4960  ((double)st->codecpar->width * sc->height), INT_MAX);
4961  }
4962 
4963 #if FF_API_R_FRAME_RATE
4964  if (sc->stts_count == 1 || (sc->stts_count == 2 && sc->stts_data[1].count == 1))
4966  sc->time_scale, sc->stts_data[0].duration, INT_MAX);
4967 #endif
4968  }
4969 
4970  // done for ai5q, ai52, ai55, ai1q, ai12 and ai15.
4971  if (!st->codecpar->extradata_size && st->codecpar->codec_id == AV_CODEC_ID_H264 &&
4972  TAG_IS_AVCI(st->codecpar->codec_tag)) {
4974  if (ret < 0)
4975  return ret;
4976  }
4977 
4978  switch (st->codecpar->codec_id) {
4979 #if CONFIG_H261_DECODER
4980  case AV_CODEC_ID_H261:
4981 #endif
4982 #if CONFIG_H263_DECODER
4983  case AV_CODEC_ID_H263:
4984 #endif
4985 #if CONFIG_MPEG4_DECODER
4986  case AV_CODEC_ID_MPEG4:
4987 #endif
4988  st->codecpar->width = 0; /* let decoder init width/height */
4989  st->codecpar->height= 0;
4990  break;
4991  }
4992 
4993  // If the duration of the mp3 packets is not constant, then they could need a parser
4994  if (st->codecpar->codec_id == AV_CODEC_ID_MP3
4995  && sc->stts_count > 3
4996  && sc->stts_count*10 > st->nb_frames
4997  && sc->time_scale == st->codecpar->sample_rate) {
4999  }
5000  /* Do not need those anymore. */
5001  av_freep(&sc->chunk_offsets);
5002  av_freep(&sc->sample_sizes);
5003  av_freep(&sc->keyframes);
5004  av_freep(&sc->stts_data);
5005  av_freep(&sc->stps_data);
5006  av_freep(&sc->elst_data);
5007  av_freep(&sc->rap_group);
5008  av_freep(&sc->sync_group);
5009  av_freep(&sc->sgpd_sync);
5010 
5011  return 0;
5012 }
5013 
5015 {
5016  int ret;
5017  c->itunes_metadata = 1;
5018  ret = mov_read_default(c, pb, atom);
5019  c->itunes_metadata = 0;
5020  return ret;
5021 }
5022 
5024 {
5025  uint32_t count;
5026  uint32_t i;
5027 
5028  if (atom.size < 8)
5029  return 0;
5030 
5031  avio_skip(pb, 4);
5032  count = avio_rb32(pb);
5033  atom.size -= 8;
5034  if (count >= UINT_MAX / sizeof(*c->meta_keys)) {
5035  av_log(c->fc, AV_LOG_ERROR,
5036  "The 'keys' atom with the invalid key count: %"PRIu32"\n", count);
5037  return AVERROR_INVALIDDATA;
5038  }
5039 
5040  c->meta_keys_count = count + 1;
5041  c->meta_keys = av_mallocz(c->meta_keys_count * sizeof(*c->meta_keys));
5042  if (!c->meta_keys)
5043  return AVERROR(ENOMEM);
5044 
5045  for (i = 1; i <= count; ++i) {
5046  uint32_t key_size = avio_rb32(pb);
5047  uint32_t type = avio_rl32(pb);
5048  if (key_size < 8 || key_size > atom.size) {
5049  av_log(c->fc, AV_LOG_ERROR,
5050  "The key# %"PRIu32" in meta has invalid size:"
5051  "%"PRIu32"\n", i, key_size);
5052  return AVERROR_INVALIDDATA;
5053  }
5054  atom.size -= key_size;
5055  key_size -= 8;
5056  if (type != MKTAG('m','d','t','a')) {
5057  avio_skip(pb, key_size);
5058  continue;
5059  }
5060  c->meta_keys[i] = av_mallocz(key_size + 1);
5061  if (!c->meta_keys[i])
5062  return AVERROR(ENOMEM);
5063  avio_read(pb, c->meta_keys[i], key_size);
5064  }
5065 
5066  return 0;
5067 }
5068 
5070 {
5071  int64_t end = av_sat_add64(avio_tell(pb), atom.size);
5072  uint8_t *key = NULL, *val = NULL, *mean = NULL;
5073  int i;
5074  int ret = 0;
5075  AVStream *st;
5076  MOVStreamContext *sc;
5077 
5078  if (c->fc->nb_streams < 1)
5079  return 0;
5080  st = c->fc->streams[c->fc->nb_streams-1];
5081  sc = st->priv_data;
5082 
5083  for (i = 0; i < 3; i++) {
5084  uint8_t **p;
5085  uint32_t len, tag;
5086 
5087  if (end - avio_tell(pb) <= 12)
5088  break;
5089 
5090  len = avio_rb32(pb);
5091  tag = avio_rl32(pb);
5092  avio_skip(pb, 4); // flags
5093 
5094  if (len < 12 || len - 12 > end - avio_tell(pb))
5095  break;
5096  len -= 12;
5097 
5098  if (tag == MKTAG('m', 'e', 'a', 'n'))
5099  p = &mean;
5100  else if (tag == MKTAG('n', 'a', 'm', 'e'))
5101  p = &key;
5102  else if (tag == MKTAG('d', 'a', 't', 'a') && len > 4) {
5103  avio_skip(pb, 4);
5104  len -= 4;
5105  p = &val;
5106  } else
5107  break;
5108 
5109  if (*p)
5110  break;
5111 
5112  *p = av_malloc(len + 1);
5113  if (!*p) {
5114  ret = AVERROR(ENOMEM);
5115  break;
5116  }
5117  ret = ffio_read_size(pb, *p, len);
5118  if (ret < 0) {
5119  av_freep(p);
5120  break;
5121  }
5122  (*p)[len] = 0;
5123  }
5124 
5125  if (mean && key && val) {
5126  if (strcmp(key, "iTunSMPB") == 0) {
5127  int priming, remainder, samples;
5128  if(sscanf(val, "%*X %X %X %X", &priming, &remainder, &samples) == 3){
5129  if(priming>0 && priming<16384)
5130  sc->start_pad = priming;
5131  }
5132  }
5133  if (strcmp(key, "cdec") != 0) {
5134  av_dict_set(&c->fc->metadata, key, val,
5136  key = val = NULL;
5137  }
5138  } else {
5139  av_log(c->fc, AV_LOG_VERBOSE,
5140  "Unhandled or malformed custom metadata of size %"PRId64"\n", atom.size);
5141  }
5142 
5143  avio_seek(pb, end, SEEK_SET);
5144  av_freep(&key);
5145  av_freep(&val);
5146  av_freep(&mean);
5147  return ret;
5148 }
5149 
5151 {
5152  MOVStreamContext *sc;
5153  AVStream *st;
5154 
5155  st = avformat_new_stream(c->fc, NULL);
5156  if (!st)
5157  return AVERROR(ENOMEM);
5158  sc = av_mallocz(sizeof(MOVStreamContext));
5159  if (!sc)
5160  return AVERROR(ENOMEM);
5161 
5162  item->st = st;
5163  st->id = item->item_id;
5164  st->priv_data = sc;
5166  st->codecpar->codec_id = mov_codec_id(st, item->type);
5167  sc->id = st->id;
5168  sc->ffindex = st->index;
5169  st->avg_frame_rate.num = st->avg_frame_rate.den = 1;
5170  st->time_base.num = st->time_base.den = 1;
5171  st->nb_frames = 1;
5172  sc->time_scale = 1;
5173  sc->pb = c->fc->pb;
5174  sc->pb_is_copied = 1;
5175  sc->refcount = 1;
5176 
5177  if (item->name)
5178  av_dict_set(&st->metadata, "title", item->name, 0);
5179 
5180  // Populate the necessary fields used by mov_build_index.
5181  sc->stsc_count = 1;
5182  sc->stsc_data = av_malloc_array(1, sizeof(*sc->stsc_data));
5183  if (!sc->stsc_data)
5184  return AVERROR(ENOMEM);
5185  sc->stsc_data[0].first = 1;
5186  sc->stsc_data[0].count = 1;
5187  sc->stsc_data[0].id = 1;
5188  sc->chunk_count = 1;
5189  sc->chunk_offsets = av_malloc_array(1, sizeof(*sc->chunk_offsets));
5190  if (!sc->chunk_offsets)
5191  return AVERROR(ENOMEM);
5192  sc->sample_count = 1;
5193  sc->sample_sizes = av_malloc_array(1, sizeof(*sc->sample_sizes));
5194  if (!sc->sample_sizes)
5195  return AVERROR(ENOMEM);
5196  sc->stts_count = 1;
5197  sc->stts_data = av_malloc_array(1, sizeof(*sc->stts_data));
5198  if (!sc->stts_data)
5199  return AVERROR(ENOMEM);
5200  sc->stts_data[0].count = 1;
5201  // Not used for still images. But needed by mov_build_index.
5202  sc->stts_data[0].duration = 0;
5203 
5204  return 0;
5205 }
5206 
5208 {
5209  while (atom.size > 8) {
5210  uint32_t tag;
5211  if (avio_feof(pb))
5212  return AVERROR_EOF;
5213  tag = avio_rl32(pb);
5214  atom.size -= 4;
5215  if (tag == MKTAG('h','d','l','r')) {
5216  avio_seek(pb, -8, SEEK_CUR);
5217  atom.size += 8;
5218  return mov_read_default(c, pb, atom);
5219  }
5220  }
5221  return 0;
5222 }
5223 
5224 // return 1 when matrix is identity, 0 otherwise
5225 #define IS_MATRIX_IDENT(matrix) \
5226  ( (matrix)[0][0] == (1 << 16) && \
5227  (matrix)[1][1] == (1 << 16) && \
5228  (matrix)[2][2] == (1 << 30) && \
5229  !(matrix)[0][1] && !(matrix)[0][2] && \
5230  !(matrix)[1][0] && !(matrix)[1][2] && \
5231  !(matrix)[2][0] && !(matrix)[2][1])
5232 
5234 {
5235  int i, j, e;
5236  int width;
5237  int height;
5238  int display_matrix[3][3];
5239  int res_display_matrix[3][3] = { { 0 } };
5240  AVStream *st;
5241  MOVStreamContext *sc;
5242  int version;
5243  int flags;
5244 
5245  if (c->fc->nb_streams < 1)
5246  return 0;
5247  st = c->fc->streams[c->fc->nb_streams-1];
5248  sc = st->priv_data;
5249 
5250  // Each stream (trak) should have exactly 1 tkhd. This catches bad files and
5251  // avoids corrupting AVStreams mapped to an earlier tkhd.
5252  if (st->id != -1)
5253  return AVERROR_INVALIDDATA;
5254 
5255  version = avio_r8(pb);
5256  flags = avio_rb24(pb);
5258 
5259  if (version == 1) {
5260  avio_rb64(pb);
5261  avio_rb64(pb);
5262  } else {
5263  avio_rb32(pb); /* creation time */
5264  avio_rb32(pb); /* modification time */
5265  }
5266  st->id = (int)avio_rb32(pb); /* track id (NOT 0 !)*/
5267  sc->id = st->id;
5268  avio_rb32(pb); /* reserved */
5269 
5270  /* highlevel (considering edits) duration in movie timebase */
5271  (version == 1) ? avio_rb64(pb) : avio_rb32(pb);
5272  avio_rb32(pb); /* reserved */
5273  avio_rb32(pb); /* reserved */
5274 
5275  avio_rb16(pb); /* layer */
5276  avio_rb16(pb); /* alternate group */
5277  avio_rb16(pb); /* volume */
5278  avio_rb16(pb); /* reserved */
5279 
5280  //read in the display matrix (outlined in ISO 14496-12, Section 6.2.2)
5281  // they're kept in fixed point format through all calculations
5282  // save u,v,z to store the whole matrix in the AV_PKT_DATA_DISPLAYMATRIX
5283  // side data, but the scale factor is not needed to calculate aspect ratio
5284  for (i = 0; i < 3; i++) {
5285  display_matrix[i][0] = avio_rb32(pb); // 16.16 fixed point
5286  display_matrix[i][1] = avio_rb32(pb); // 16.16 fixed point
5287  display_matrix[i][2] = avio_rb32(pb); // 2.30 fixed point
5288  }
5289 
5290  width = avio_rb32(pb); // 16.16 fixed point track width
5291  height = avio_rb32(pb); // 16.16 fixed point track height
5292  sc->width = width >> 16;
5293  sc->height = height >> 16;
5294 
5295  // apply the moov display matrix (after the tkhd one)
5296  for (i = 0; i < 3; i++) {
5297  const int sh[3] = { 16, 16, 30 };
5298  for (j = 0; j < 3; j++) {
5299  for (e = 0; e < 3; e++) {
5300  res_display_matrix[i][j] +=
5301  ((int64_t) display_matrix[i][e] *
5302  c->movie_display_matrix[e][j]) >> sh[e];
5303  }
5304  }
5305  }
5306 
5307  // save the matrix when it is not the default identity
5308  if (!IS_MATRIX_IDENT(res_display_matrix)) {
5309  av_freep(&sc->display_matrix);
5310  sc->display_matrix = av_malloc(sizeof(int32_t) * 9);
5311  if (!sc->display_matrix)
5312  return AVERROR(ENOMEM);
5313 
5314  for (i = 0; i < 3; i++)
5315  for (j = 0; j < 3; j++)
5316  sc->display_matrix[i * 3 + j] = res_display_matrix[i][j];
5317  }
5318 
5319  // transform the display width/height according to the matrix
5320  // to keep the same scale, use [width height 1<<16]
5321  if (width && height && sc->display_matrix) {
5322  double disp_transform[2];
5323 
5324  for (i = 0; i < 2; i++)
5325  disp_transform[i] = hypot(sc->display_matrix[0 + i],
5326  sc->display_matrix[3 + i]);
5327 
5328  if (disp_transform[0] > 1 && disp_transform[1] > 1 &&
5329  disp_transform[0] < (1<<24) && disp_transform[1] < (1<<24) &&
5330  fabs((disp_transform[0] / disp_transform[1]) - 1.0) > 0.01)
5332  disp_transform[0] / disp_transform[1],
5333  INT_MAX);
5334  }
5335  return 0;
5336 }
5337 
5339 {
5340  MOVFragment *frag = &c->fragment;
5341  MOVTrackExt *trex = NULL;
5342  int flags, track_id, i;
5343  MOVFragmentStreamInfo * frag_stream_info;
5344 
5345  avio_r8(pb); /* version */
5346  flags = avio_rb24(pb);
5347 
5348  track_id = avio_rb32(pb);
5349  if (!track_id)
5350  return AVERROR_INVALIDDATA;
5351  for (i = 0; i < c->trex_count; i++)
5352  if (c->trex_data[i].track_id == track_id) {
5353  trex = &c->trex_data[i];
5354  break;
5355  }
5356  if (!trex) {
5357  av_log(c->fc, AV_LOG_WARNING, "could not find corresponding trex (id %u)\n", track_id);
5358  return 0;
5359  }
5360  c->fragment.found_tfhd = 1;
5361  frag->track_id = track_id;
5362  set_frag_stream(&c->frag_index, track_id);
5363 
5366  frag->moof_offset : frag->implicit_offset;
5367  frag->stsd_id = flags & MOV_TFHD_STSD_ID ? avio_rb32(pb) : trex->stsd_id;
5368 
5370  avio_rb32(pb) : trex->duration;
5371  frag->size = flags & MOV_TFHD_DEFAULT_SIZE ?
5372  avio_rb32(pb) : trex->size;
5373  frag->flags = flags & MOV_TFHD_DEFAULT_FLAGS ?
5374  avio_rb32(pb) : trex->flags;
5375  av_log(c->fc, AV_LOG_TRACE, "frag flags 0x%x\n", frag->flags);
5376 
5377  frag_stream_info = get_current_frag_stream_info(&c->frag_index);
5378  if (frag_stream_info) {
5379  frag_stream_info->next_trun_dts = AV_NOPTS_VALUE;
5380  frag_stream_info->stsd_id = frag->stsd_id;
5381  }
5382  return 0;
5383 }
5384 
5386 {
5387  unsigned i, num;
5388  void *new_tracks;
5389 
5390  num = atom.size / 4;
5391  if (!(new_tracks = av_malloc_array(num, sizeof(int))))
5392  return AVERROR(ENOMEM);
5393 
5394  av_free(c->chapter_tracks);
5395  c->chapter_tracks = new_tracks;
5396  c->nb_chapter_tracks = num;
5397 
5398  for (i = 0; i < num && !pb->eof_reached; i++)
5399  c->chapter_tracks[i] = avio_rb32(pb);
5400 
5401  c->nb_chapter_tracks = i;
5402 
5403  return 0;
5404 }
5405 
5407 {
5408  MOVTrackExt *trex;
5409  int err;
5410 
5411  if ((uint64_t)c->trex_count+1 >= UINT_MAX / sizeof(*c->trex_data))
5412  return AVERROR_INVALIDDATA;
5413  if ((err = av_reallocp_array(&c->trex_data, c->trex_count + 1,
5414  sizeof(*c->trex_data))) < 0) {
5415  c->trex_count = 0;
5416  return err;
5417  }
5418 
5419  c->fc->duration = AV_NOPTS_VALUE; // the duration from mvhd is not representing the whole file when fragments are used.
5420 
5421  trex = &c->trex_data[c->trex_count++];
5422  avio_r8(pb); /* version */
5423  avio_rb24(pb); /* flags */
5424  trex->track_id = avio_rb32(pb);
5425  trex->stsd_id = avio_rb32(pb);
5426  trex->duration = avio_rb32(pb);
5427  trex->size = avio_rb32(pb);
5428  trex->flags = avio_rb32(pb);
5429  return 0;
5430 }
5431 
5433 {
5434  MOVFragment *frag = &c->fragment;
5435  AVStream *st = NULL;
5436  MOVStreamContext *sc;
5437  int version, i;
5438  MOVFragmentStreamInfo * frag_stream_info;
5439  int64_t base_media_decode_time;
5440 
5441  for (i = 0; i < c->fc->nb_streams; i++) {
5442  sc = c->fc->streams[i]->priv_data;
5443  if (sc->id == frag->track_id) {
5444  st = c->fc->streams[i];
5445  break;
5446  }
5447  }
5448  if (!st) {
5449  av_log(c->fc, AV_LOG_WARNING, "could not find corresponding track id %u\n", frag->track_id);
5450  return 0;
5451  }
5452  sc = st->priv_data;
5453  if (sc->pseudo_stream_id + 1 != frag->stsd_id && sc->pseudo_stream_id != -1)
5454  return 0;
5455  version = avio_r8(pb);
5456  avio_rb24(pb); /* flags */
5457  if (version) {
5458  base_media_decode_time = avio_rb64(pb);
5459  } else {
5460  base_media_decode_time = avio_rb32(pb);
5461  }
5462 
5463  frag_stream_info = get_current_frag_stream_info(&c->frag_index);
5464  if (frag_stream_info)
5465  frag_stream_info->tfdt_dts = base_media_decode_time;
5466  sc->track_end = base_media_decode_time;
5467 
5468  return 0;
5469 }
5470 
5472 {
5473  MOVFragment *frag = &c->fragment;
5474  AVStream *st = NULL;
5475  FFStream *sti = NULL;
5476  MOVStreamContext *sc;
5477  MOVCtts *ctts_data;
5478  uint64_t offset;
5479  int64_t dts, pts = AV_NOPTS_VALUE;
5480  int data_offset = 0;
5481  unsigned entries, first_sample_flags = frag->flags;
5482  int flags, distance, i;
5483  int64_t prev_dts = AV_NOPTS_VALUE;
5484  int next_frag_index = -1, index_entry_pos;
5485  size_t requested_size;
5486  size_t old_ctts_allocated_size;
5487  AVIndexEntry *new_entries;
5488  MOVFragmentStreamInfo * frag_stream_info;
5489 
5490  if (!frag->found_tfhd) {
5491  av_log(c->fc, AV_LOG_ERROR, "trun track id unknown, no tfhd was found\n");
5492  return AVERROR_INVALIDDATA;
5493  }
5494 
5495  for (i = 0; i < c->fc->nb_streams; i++) {
5496  sc = c->fc->streams[i]->priv_data;
5497  if (sc->id == frag->track_id) {
5498  st = c->fc->streams[i];
5499  sti = ffstream(st);
5500  break;
5501  }
5502  }
5503  if (!st) {
5504  av_log(c->fc, AV_LOG_WARNING, "could not find corresponding track id %u\n", frag->track_id);
5505  return 0;
5506  }
5507  sc = st->priv_data;
5508  if (sc->pseudo_stream_id+1 != frag->stsd_id && sc->pseudo_stream_id != -1)
5509  return 0;
5510 
5511  // Find the next frag_index index that has a valid index_entry for
5512  // the current track_id.
5513  //
5514  // A valid index_entry means the trun for the fragment was read
5515  // and it's samples are in index_entries at the given position.
5516  // New index entries will be inserted before the index_entry found.
5517  index_entry_pos = sti->nb_index_entries;
5518  for (i = c->frag_index.current + 1; i < c->frag_index.nb_items; i++) {
5519  frag_stream_info = get_frag_stream_info(&c->frag_index, i, frag->track_id);
5520  if (frag_stream_info && frag_stream_info->index_entry >= 0) {
5521  next_frag_index = i;
5522  index_entry_pos = frag_stream_info->index_entry;
5523  break;
5524  }
5525  }
5526  av_assert0(index_entry_pos <= sti->nb_index_entries);
5527 
5528  avio_r8(pb); /* version */
5529  flags = avio_rb24(pb);
5530  entries = avio_rb32(pb);
5531  av_log(c->fc, AV_LOG_TRACE, "flags 0x%x entries %u\n", flags, entries);
5532 
5533  if ((uint64_t)entries+sc->ctts_count >= UINT_MAX/sizeof(*sc->ctts_data))
5534  return AVERROR_INVALIDDATA;
5535  if (flags & MOV_TRUN_DATA_OFFSET) data_offset = avio_rb32(pb);
5536  if (flags & MOV_TRUN_FIRST_SAMPLE_FLAGS) first_sample_flags = avio_rb32(pb);
5537 
5538  frag_stream_info = get_current_frag_stream_info(&c->frag_index);
5539  if (frag_stream_info) {
5540  if (frag_stream_info->next_trun_dts != AV_NOPTS_VALUE) {
5541  dts = frag_stream_info->next_trun_dts - sc->time_offset;
5542  } else if (frag_stream_info->first_tfra_pts != AV_NOPTS_VALUE &&
5543  c->use_mfra_for == FF_MOV_FLAG_MFRA_PTS) {
5544  pts = frag_stream_info->first_tfra_pts;
5545  av_log(c->fc, AV_LOG_DEBUG, "found mfra time %"PRId64
5546  ", using it for pts\n", pts);
5547  } else if (frag_stream_info->first_tfra_pts != AV_NOPTS_VALUE &&
5548  c->use_mfra_for == FF_MOV_FLAG_MFRA_DTS) {
5549  dts = frag_stream_info->first_tfra_pts;
5550  av_log(c->fc, AV_LOG_DEBUG, "found mfra time %"PRId64
5551  ", using it for dts\n", pts);
5552  } else {
5553  int has_tfdt = frag_stream_info->tfdt_dts != AV_NOPTS_VALUE;
5554  int has_sidx = frag_stream_info->sidx_pts != AV_NOPTS_VALUE;
5555  int fallback_tfdt = !c->use_tfdt && !has_sidx && has_tfdt;
5556  int fallback_sidx = c->use_tfdt && !has_tfdt && has_sidx;
5557 
5558  if (fallback_sidx) {
5559  av_log(c->fc, AV_LOG_DEBUG, "use_tfdt set but no tfdt found, using sidx instead\n");
5560  }
5561  if (fallback_tfdt) {
5562  av_log(c->fc, AV_LOG_DEBUG, "use_tfdt not set but no sidx found, using tfdt instead\n");
5563  }
5564 
5565  if (has_tfdt && c->use_tfdt || fallback_tfdt) {
5566  dts = frag_stream_info->tfdt_dts - sc->time_offset;
5567  av_log(c->fc, AV_LOG_DEBUG, "found tfdt time %"PRId64
5568  ", using it for dts\n", dts);
5569  } else if (has_sidx && !c->use_tfdt || fallback_sidx) {
5570  // FIXME: sidx earliest_presentation_time is *PTS*, s.b.
5571  // pts = frag_stream_info->sidx_pts;
5572  dts = frag_stream_info->sidx_pts - sc->time_offset;
5573  av_log(c->fc, AV_LOG_DEBUG, "found sidx time %"PRId64
5574  ", using it for dts\n", frag_stream_info->sidx_pts);
5575  } else {
5576  dts = sc->track_end - sc->time_offset;
5577  av_log(c->fc, AV_LOG_DEBUG, "found track end time %"PRId64
5578  ", using it for dts\n", dts);
5579  }
5580  }
5581  } else {
5582  dts = sc->track_end - sc->time_offset;
5583  av_log(c->fc, AV_LOG_DEBUG, "found track end time %"PRId64
5584  ", using it for dts\n", dts);
5585  }
5586  offset = frag->base_data_offset + data_offset;
5587  distance = 0;
5588  av_log(c->fc, AV_LOG_TRACE, "first sample flags 0x%x\n", first_sample_flags);
5589 
5590  // realloc space for new index entries
5591  if ((uint64_t)sti->nb_index_entries + entries >= UINT_MAX / sizeof(AVIndexEntry)) {
5592  entries = UINT_MAX / sizeof(AVIndexEntry) - sti->nb_index_entries;
5593  av_log(c->fc, AV_LOG_ERROR, "Failed to add index entry\n");
5594  }
5595  if (entries == 0)
5596  return 0;
5597 
5598  requested_size = (sti->nb_index_entries + entries) * sizeof(AVIndexEntry);
5599  new_entries = av_fast_realloc(sti->index_entries,
5601  requested_size);
5602  if (!new_entries)
5603  return AVERROR(ENOMEM);
5604  sti->index_entries= new_entries;
5605 
5606  requested_size = (sti->nb_index_entries + entries) * sizeof(*sc->ctts_data);
5607  old_ctts_allocated_size = sc->ctts_allocated_size;
5608  ctts_data = av_fast_realloc(sc->ctts_data, &sc->ctts_allocated_size,
5609  requested_size);
5610  if (!ctts_data)
5611  return AVERROR(ENOMEM);
5612  sc->ctts_data = ctts_data;
5613 
5614  // In case there were samples without ctts entries, ensure they get
5615  // zero valued entries. This ensures clips which mix boxes with and
5616  // without ctts entries don't pickup uninitialized data.
5617  memset((uint8_t*)(sc->ctts_data) + old_ctts_allocated_size, 0,
5618  sc->ctts_allocated_size - old_ctts_allocated_size);
5619 
5620  if (index_entry_pos < sti->nb_index_entries) {
5621  // Make hole in index_entries and ctts_data for new samples
5622  memmove(sti->index_entries + index_entry_pos + entries,
5623  sti->index_entries + index_entry_pos,
5624  sizeof(*sti->index_entries) *
5625  (sti->nb_index_entries - index_entry_pos));
5626  memmove(sc->ctts_data + index_entry_pos + entries,
5627  sc->ctts_data + index_entry_pos,
5628  sizeof(*sc->ctts_data) * (sc->ctts_count - index_entry_pos));
5629  if (index_entry_pos < sc->current_sample) {
5630  sc->current_sample += entries;
5631  }
5632  }
5633 
5634  sti->nb_index_entries += entries;
5635  sc->ctts_count = sti->nb_index_entries;
5636 
5637  // Record the index_entry position in frag_index of this fragment
5638  if (frag_stream_info) {
5639  frag_stream_info->index_entry = index_entry_pos;
5640  if (frag_stream_info->index_base < 0)
5641  frag_stream_info->index_base = index_entry_pos;
5642  }
5643 
5644  if (index_entry_pos > 0)
5645  prev_dts = sti->index_entries[index_entry_pos-1].timestamp;
5646 
5647  for (i = 0; i < entries && !pb->eof_reached; i++) {
5648  unsigned sample_size = frag->size;
5649  int sample_flags = i ? frag->flags : first_sample_flags;
5650  unsigned sample_duration = frag->duration;
5651  unsigned ctts_duration = 0;
5652  int keyframe = 0;
5653  int index_entry_flags = 0;
5654 
5655  if (flags & MOV_TRUN_SAMPLE_DURATION) sample_duration = avio_rb32(pb);
5656  if (flags & MOV_TRUN_SAMPLE_SIZE) sample_size = avio_rb32(pb);
5657  if (flags & MOV_TRUN_SAMPLE_FLAGS) sample_flags = avio_rb32(pb);
5658  if (flags & MOV_TRUN_SAMPLE_CTS) ctts_duration = avio_rb32(pb);
5659 
5660  mov_update_dts_shift(sc, ctts_duration, c->fc);
5661  if (pts != AV_NOPTS_VALUE) {
5662  dts = pts - sc->dts_shift;
5663  if (flags & MOV_TRUN_SAMPLE_CTS) {
5664  dts -= ctts_duration;
5665  } else {
5666  dts -= sc->time_offset;
5667  }
5668  av_log(c->fc, AV_LOG_DEBUG,
5669  "pts %"PRId64" calculated dts %"PRId64
5670  " sc->dts_shift %d ctts.duration %d"
5671  " sc->time_offset %"PRId64
5672  " flags & MOV_TRUN_SAMPLE_CTS %d\n",
5673  pts, dts,
5674  sc->dts_shift, ctts_duration,
5676  pts = AV_NOPTS_VALUE;
5677  }
5678 
5680  keyframe = 1;
5681  else
5682  keyframe =
5683  !(sample_flags & (MOV_FRAG_SAMPLE_FLAG_IS_NON_SYNC |
5685  if (keyframe) {
5686  distance = 0;
5687  index_entry_flags |= AVINDEX_KEYFRAME;
5688  }
5689  // Fragments can overlap in time. Discard overlapping frames after
5690  // decoding.
5691  if (prev_dts >= dts)
5692  index_entry_flags |= AVINDEX_DISCARD_FRAME;
5693 
5694  sti->index_entries[index_entry_pos].pos = offset;
5695  sti->index_entries[index_entry_pos].timestamp = dts;
5696  sti->index_entries[index_entry_pos].size = sample_size;
5697  sti->index_entries[index_entry_pos].min_distance = distance;
5698  sti->index_entries[index_entry_pos].flags = index_entry_flags;
5699 
5700  sc->ctts_data[index_entry_pos].count = 1;
5701  sc->ctts_data[index_entry_pos].duration = ctts_duration;
5702  index_entry_pos++;
5703 
5704  av_log(c->fc, AV_LOG_TRACE, "AVIndex stream %d, sample %d, offset %"PRIx64", dts %"PRId64", "
5705  "size %u, distance %d, keyframe %d\n", st->index,
5706  index_entry_pos, offset, dts, sample_size, distance, keyframe);
5707  distance++;
5708  if (av_sat_add64(dts, sample_duration) != dts + (uint64_t)sample_duration)
5709  return AVERROR_INVALIDDATA;
5710  if (!sample_size)
5711  return AVERROR_INVALIDDATA;
5712  dts += sample_duration;
5713  offset += sample_size;
5714  sc->data_size += sample_size;
5715 
5716  if (sample_duration <= INT64_MAX - sc->duration_for_fps &&
5717  1 <= INT_MAX - sc->nb_frames_for_fps
5718  ) {
5719  sc->duration_for_fps += sample_duration;
5720  sc->nb_frames_for_fps ++;
5721  }
5722  }
5723  if (frag_stream_info)
5724  frag_stream_info->next_trun_dts = dts + sc->time_offset;
5725  if (i < entries) {
5726  // EOF found before reading all entries. Fix the hole this would
5727  // leave in index_entries and ctts_data
5728  int gap = entries - i;
5729  memmove(sti->index_entries + index_entry_pos,
5730  sti->index_entries + index_entry_pos + gap,
5731  sizeof(*sti->index_entries) *
5732  (sti->nb_index_entries - (index_entry_pos + gap)));
5733  memmove(sc->ctts_data + index_entry_pos,
5734  sc->ctts_data + index_entry_pos + gap,
5735  sizeof(*sc->ctts_data) *
5736  (sc->ctts_count - (index_entry_pos + gap)));
5737 
5738  sti->nb_index_entries -= gap;
5739  sc->ctts_count -= gap;
5740  if (index_entry_pos < sc->current_sample) {
5741  sc->current_sample -= gap;
5742  }
5743  entries = i;
5744  }
5745 
5746  // The end of this new fragment may overlap in time with the start
5747  // of the next fragment in index_entries. Mark the samples in the next
5748  // fragment that overlap with AVINDEX_DISCARD_FRAME
5749  prev_dts = AV_NOPTS_VALUE;
5750  if (index_entry_pos > 0)
5751  prev_dts = sti->index_entries[index_entry_pos-1].timestamp;
5752  for (int i = index_entry_pos; i < sti->nb_index_entries; i++) {
5753  if (prev_dts < sti->index_entries[i].timestamp)
5754  break;
5756  }
5757 
5758  // If a hole was created to insert the new index_entries into,
5759  // the index_entry recorded for all subsequent moof must
5760  // be incremented by the number of entries inserted.
5761  fix_frag_index_entries(&c->frag_index, next_frag_index,
5762  frag->track_id, entries);
5763 
5764  if (pb->eof_reached) {
5765  av_log(c->fc, AV_LOG_WARNING, "reached eof, corrupted TRUN atom\n");
5766  return AVERROR_EOF;
5767  }
5768 
5769  frag->implicit_offset = offset;
5770 
5771  sc->track_end = dts + sc->time_offset;
5772  if (st->duration < sc->track_end)
5773  st->duration = sc->track_end;
5774 
5775  return 0;
5776 }
5777 
5779 {
5780  int64_t stream_size = avio_size(pb);
5781  int64_t offset = av_sat_add64(avio_tell(pb), atom.size), pts, timestamp;
5782  uint8_t version, is_complete;
5783  int64_t offadd;
5784  unsigned i, j, track_id, item_count;
5785  AVStream *st = NULL;
5786  AVStream *ref_st = NULL;
5787  MOVStreamContext *sc, *ref_sc = NULL;
5788  AVRational timescale;
5789 
5790  version = avio_r8(pb);
5791  if (version > 1) {
5792  avpriv_request_sample(c->fc, "sidx version %u", version);
5793  return 0;
5794  }
5795 
5796  avio_rb24(pb); // flags
5797 
5798  track_id = avio_rb32(pb); // Reference ID
5799  for (i = 0; i < c->fc->nb_streams; i++) {
5800  sc = c->fc->streams[i]->priv_data;
5801  if (sc->id == track_id) {
5802  st = c->fc->streams[i];
5803  break;
5804  }
5805  }
5806  if (!st) {
5807  av_log(c->fc, AV_LOG_WARNING, "could not find corresponding track id %d\n", track_id);
5808  return 0;
5809  }
5810 
5811  sc = st->priv_data;
5812 
5813  timescale = av_make_q(1, avio_rb32(pb));
5814 
5815  if (timescale.den <= 0) {
5816  av_log(c->fc, AV_LOG_ERROR, "Invalid sidx timescale 1/%d\n", timescale.den);
5817  return AVERROR_INVALIDDATA;
5818  }
5819 
5820  if (version == 0) {
5821  pts = avio_rb32(pb);
5822  offadd= avio_rb32(pb);
5823  } else {
5824  pts = avio_rb64(pb);
5825  offadd= avio_rb64(pb);
5826  }
5827  if (av_sat_add64(offset, offadd) != offset + (uint64_t)offadd)
5828  return AVERROR_INVALIDDATA;
5829 
5830  offset += (uint64_t)offadd;
5831 
5832  avio_rb16(pb); // reserved
5833 
5834  item_count = avio_rb16(pb);
5835  if (item_count == 0)
5836  return AVERROR_INVALIDDATA;
5837 
5838  for (i = 0; i < item_count; i++) {
5839  int index;
5840  MOVFragmentStreamInfo * frag_stream_info;
5841  uint32_t size = avio_rb32(pb);
5842  uint32_t duration = avio_rb32(pb);
5843  if (size & 0x80000000) {
5844  avpriv_request_sample(c->fc, "sidx reference_type 1");
5845  return AVERROR_PATCHWELCOME;
5846  }
5847  avio_rb32(pb); // sap_flags
5848  timestamp = av_rescale_q(pts, timescale, st->time_base);
5849 
5851  frag_stream_info = get_frag_stream_info(&c->frag_index, index, track_id);
5852  if (frag_stream_info)
5853  frag_stream_info->sidx_pts = timestamp;
5854 
5855  if (av_sat_add64(offset, size) != offset + (uint64_t)size ||
5856  av_sat_add64(pts, duration) != pts + (uint64_t)duration
5857  )
5858  return AVERROR_INVALIDDATA;
5859  offset += size;
5860  pts += duration;
5861  }
5862 
5863  st->duration = sc->track_end = pts;
5864 
5865  sc->has_sidx = 1;
5866 
5867  // See if the remaining bytes are just an mfra which we can ignore.
5868  is_complete = offset == stream_size;
5869  if (!is_complete && (pb->seekable & AVIO_SEEKABLE_NORMAL) && stream_size > 0 ) {
5870  int64_t ret;
5871  int64_t original_pos = avio_tell(pb);
5872  if (!c->have_read_mfra_size) {
5873  if ((ret = avio_seek(pb, stream_size - 4, SEEK_SET)) < 0)
5874  return ret;
5875  c->mfra_size = avio_rb32(pb);
5876  c->have_read_mfra_size = 1;
5877  if ((ret = avio_seek(pb, original_pos, SEEK_SET)) < 0)
5878  return ret;
5879  }
5880  if (offset == stream_size - c->mfra_size)
5881  is_complete = 1;
5882  }
5883 
5884  if (is_complete) {
5885  // Find first entry in fragment index that came from an sidx.
5886  // This will pretty much always be the first entry.
5887  for (i = 0; i < c->frag_index.nb_items; i++) {
5888  MOVFragmentIndexItem * item = &c->frag_index.item[i];
5889  for (j = 0; ref_st == NULL && j < item->nb_stream_info; j++) {
5890  MOVFragmentStreamInfo * si;
5891  si = &item->stream_info[j];
5892  if (si->sidx_pts != AV_NOPTS_VALUE) {
5893  ref_st = c->fc->streams[j];
5894  ref_sc = ref_st->priv_data;
5895  break;
5896  }
5897  }
5898  }
5899  if (ref_st) for (i = 0; i < c->fc->nb_streams; i++) {
5900  st = c->fc->streams[i];
5901  sc = st->priv_data;
5902  if (!sc->has_sidx) {
5903  st->duration = sc->track_end = av_rescale(ref_st->duration, sc->time_scale, ref_sc->time_scale);
5904  }
5905  }
5906 
5907  c->frag_index.complete = 1;
5908  }
5909 
5910  return 0;
5911 }
5912 
5913 /* this atom should be null (from specs), but some buggy files put the 'moov' atom inside it... */
5914 /* like the files created with Adobe Premiere 5.0, for samples see */
5915 /* http://graphics.tudelft.nl/~wouter/publications/soundtests/ */
5917 {
5918  int err;
5919 
5920  if (atom.size < 8)
5921  return 0; /* continue */
5922  if (avio_rb32(pb) != 0) { /* 0 sized mdat atom... use the 'wide' atom size */
5923  avio_skip(pb, atom.size - 4);
5924  return 0;
5925  }
5926  atom.type = avio_rl32(pb);
5927  atom.size -= 8;
5928  if (atom.type != MKTAG('m','d','a','t')) {
5929  avio_skip(pb, atom.size);
5930  return 0;
5931  }
5932  err = mov_read_mdat(c, pb, atom);
5933  return err;
5934 }
5935 
5937 {
5938 #if CONFIG_ZLIB
5939  FFIOContext ctx;
5940  uint8_t *cmov_data;
5941  uint8_t *moov_data; /* uncompressed data */
5942  long cmov_len, moov_len;
5943  int ret = -1;
5944 
5945  avio_rb32(pb); /* dcom atom */
5946  if (avio_rl32(pb) != MKTAG('d','c','o','m'))
5947  return AVERROR_INVALIDDATA;
5948  if (avio_rl32(pb) != MKTAG('z','l','i','b')) {
5949  av_log(c->fc, AV_LOG_ERROR, "unknown compression for cmov atom !\n");
5950  return AVERROR_INVALIDDATA;
5951  }
5952  avio_rb32(pb); /* cmvd atom */
5953  if (avio_rl32(pb) != MKTAG('c','m','v','d'))
5954  return AVERROR_INVALIDDATA;
5955  moov_len = avio_rb32(pb); /* uncompressed size */
5956  cmov_len = atom.size - 6 * 4;
5957 
5958  cmov_data = av_malloc(cmov_len);
5959  if (!cmov_data)
5960  return AVERROR(ENOMEM);
5961  moov_data = av_malloc(moov_len);
5962  if (!moov_data) {
5963  av_free(cmov_data);
5964  return AVERROR(ENOMEM);
5965  }
5966  ret = ffio_read_size(pb, cmov_data, cmov_len);
5967  if (ret < 0)
5968  goto free_and_return;
5969 
5971  if (uncompress (moov_data, (uLongf *) &moov_len, (const Bytef *)cmov_data, cmov_len) != Z_OK)
5972  goto free_and_return;
5973  ffio_init_read_context(&ctx, moov_data, moov_len);
5974  ctx.pub.seekable = AVIO_SEEKABLE_NORMAL;
5975  atom.type = MKTAG('m','o','o','v');
5976  atom.size = moov_len;
5977  ret = mov_read_default(c, &ctx.pub, atom);
5978 free_and_return:
5979  av_free(moov_data);
5980  av_free(cmov_data);
5981  return ret;
5982 #else
5983  av_log(c->fc, AV_LOG_ERROR, "this file requires zlib support compiled in\n");
5984  return AVERROR(ENOSYS);
5985 #endif
5986 }
5987 
5988 /* edit list atom */
5990 {
5991  MOVStreamContext *sc;
5992  int i, edit_count, version;
5993  int64_t elst_entry_size;
5994 
5995  if (c->fc->nb_streams < 1 || c->ignore_editlist)
5996  return 0;
5997  sc = c->fc->streams[c->fc->nb_streams-1]->priv_data;
5998 
5999  version = avio_r8(pb); /* version */
6000  avio_rb24(pb); /* flags */
6001  edit_count = avio_rb32(pb); /* entries */
6002  atom.size -= 8;
6003 
6004  elst_entry_size = version == 1 ? 20 : 12;
6005  if (atom.size != edit_count * elst_entry_size) {
6006  if (c->fc->strict_std_compliance >= FF_COMPLIANCE_STRICT) {
6007  av_log(c->fc, AV_LOG_ERROR, "Invalid edit list entry_count: %d for elst atom of size: %"PRId64" bytes.\n",
6008  edit_count, atom.size + 8);
6009  return AVERROR_INVALIDDATA;
6010  } else {
6011  edit_count = atom.size / elst_entry_size;
6012  if (edit_count * elst_entry_size != atom.size) {
6013  av_log(c->fc, AV_LOG_WARNING, "ELST atom of %"PRId64" bytes, bigger than %d entries.\n", atom.size, edit_count);
6014  }
6015  }
6016  }
6017 
6018  if (!edit_count)
6019  return 0;
6020  if (sc->elst_data)
6021  av_log(c->fc, AV_LOG_WARNING, "Duplicated ELST atom\n");
6022  av_free(sc->elst_data);
6023  sc->elst_count = 0;
6024  sc->elst_data = av_malloc_array(edit_count, sizeof(*sc->elst_data));
6025  if (!sc->elst_data)
6026  return AVERROR(ENOMEM);
6027 
6028  av_log(c->fc, AV_LOG_TRACE, "track[%u].edit_count = %i\n", c->fc->nb_streams - 1, edit_count);
6029  for (i = 0; i < edit_count && atom.size > 0 && !pb->eof_reached; i++) {
6030  MOVElst *e = &sc->elst_data[i];
6031 
6032  if (version == 1) {
6033  e->duration = avio_rb64(pb);
6034  e->time = avio_rb64(pb);
6035  atom.size -= 16;
6036  } else {
6037  e->duration = avio_rb32(pb); /* segment duration */
6038  e->time = (int32_t)avio_rb32(pb); /* media time */
6039  atom.size -= 8;
6040  }
6041  e->rate = avio_rb32(pb) / 65536.0;
6042  atom.size -= 4;
6043  av_log(c->fc, AV_LOG_TRACE, "duration=%"PRId64" time=%"PRId64" rate=%f\n",
6044  e->duration, e->time, e->rate);
6045 
6046  if (e->time < 0 && e->time != -1 &&
6047  c->fc->strict_std_compliance >= FF_COMPLIANCE_STRICT) {
6048  av_log(c->fc, AV_LOG_ERROR, "Track %d, edit %d: Invalid edit list media time=%"PRId64"\n",
6049  c->fc->nb_streams-1, i, e->time);
6050  return AVERROR_INVALIDDATA;
6051  }
6052  }
6053  sc->elst_count = i;
6054 
6055  return 0;
6056 }
6057 
6059 {
6060  MOVStreamContext *sc;
6061 
6062  if (c->fc->nb_streams < 1)
6063  return AVERROR_INVALIDDATA;
6064  sc = c->fc->streams[c->fc->nb_streams - 1]->priv_data;
6065  sc->timecode_track = avio_rb32(pb);
6066  return 0;
6067 }
6068 
6070 {
6071  AVStream *st;
6072  int version, color_range, color_primaries, color_trc, color_space;
6073 
6074  if (c->fc->nb_streams < 1)
6075  return 0;
6076  st = c->fc->streams[c->fc->nb_streams - 1];
6077 
6078  if (atom.size < 5) {
6079  av_log(c->fc, AV_LOG_ERROR, "Empty VP Codec Configuration box\n");
6080  return AVERROR_INVALIDDATA;
6081  }
6082 
6083  version = avio_r8(pb);
6084  if (version != 1) {
6085  av_log(c->fc, AV_LOG_WARNING, "Unsupported VP Codec Configuration box version %d\n", version);
6086  return 0;
6087  }
6088  avio_skip(pb, 3); /* flags */
6089 
6090  avio_skip(pb, 2); /* profile + level */
6091  color_range = avio_r8(pb); /* bitDepth, chromaSubsampling, videoFullRangeFlag */
6092  color_primaries = avio_r8(pb);
6093  color_trc = avio_r8(pb);
6094  color_space = avio_r8(pb);
6095  if (avio_rb16(pb)) /* codecIntializationDataSize */
6096  return AVERROR_INVALIDDATA;
6097 
6100  if (!av_color_transfer_name(color_trc))
6101  color_trc = AVCOL_TRC_UNSPECIFIED;
6102  if (!av_color_space_name(color_space))
6103  color_space = AVCOL_SPC_UNSPECIFIED;
6104 
6107  st->codecpar->color_trc = color_trc;
6108  st->codecpar->color_space = color_space;
6109 
6110  return 0;
6111 }
6112 
6114 {
6115  MOVStreamContext *sc;
6116  int i, version;
6117 
6118  if (c->fc->nb_streams < 1)
6119  return AVERROR_INVALIDDATA;
6120 
6121  sc = c->fc->streams[c->fc->nb_streams - 1]->priv_data;
6122 
6123  if (atom.size < 5) {
6124  av_log(c->fc, AV_LOG_ERROR, "Empty Mastering Display Metadata box\n");
6125  return AVERROR_INVALIDDATA;
6126  }
6127 
6128  version = avio_r8(pb);
6129  if (version) {
6130  av_log(c->fc, AV_LOG_WARNING, "Unsupported Mastering Display Metadata box version %d\n", version);
6131  return 0;
6132  }
6133  if (sc->mastering) {
6134  av_log(c->fc, AV_LOG_WARNING, "Ignoring duplicate Mastering Display Metadata\n");
6135  return 0;
6136  }
6137 
6138  avio_skip(pb, 3); /* flags */
6139 
6141  if (!sc->mastering)
6142  return AVERROR(ENOMEM);
6143 
6144  for (i = 0; i < 3; i++) {
6145  sc->mastering->display_primaries[i][0] = av_make_q(avio_rb16(pb), 1 << 16);
6146  sc->mastering->display_primaries[i][1] = av_make_q(avio_rb16(pb), 1 << 16);
6147  }
6148  sc->mastering->white_point[0] = av_make_q(avio_rb16(pb), 1 << 16);
6149  sc->mastering->white_point[1] = av_make_q(avio_rb16(pb), 1 << 16);
6150 
6151  sc->mastering->max_luminance = av_make_q(avio_rb32(pb), 1 << 8);
6152  sc->mastering->min_luminance = av_make_q(avio_rb32(pb), 1 << 14);
6153 
6154  sc->mastering->has_primaries = 1;
6155  sc->mastering->has_luminance = 1;
6156 
6157  return 0;
6158 }
6159 
6161 {
6162  MOVStreamContext *sc;
6163  const int mapping[3] = {1, 2, 0};
6164  const int chroma_den = 50000;
6165  const int luma_den = 10000;
6166  int i;
6167 
6168  if (c->fc->nb_streams < 1)
6169  return AVERROR_INVALIDDATA;
6170 
6171  sc = c->fc->streams[c->fc->nb_streams - 1]->priv_data;
6172 
6173  if (atom.size < 24) {
6174  av_log(c->fc, AV_LOG_ERROR, "Invalid Mastering Display Color Volume box\n");
6175  return AVERROR_INVALIDDATA;
6176  }
6177 
6178  if (sc->mastering) {
6179  av_log(c->fc, AV_LOG_WARNING, "Ignoring duplicate Mastering Display Color Volume\n");
6180  return 0;
6181  }
6182 
6184  if (!sc->mastering)
6185  return AVERROR(ENOMEM);
6186 
6187  for (i = 0; i < 3; i++) {
6188  const int j = mapping[i];
6189  sc->mastering->display_primaries[j][0] = av_make_q(avio_rb16(pb), chroma_den);
6190  sc->mastering->display_primaries[j][1] = av_make_q(avio_rb16(pb), chroma_den);
6191  }
6192  sc->mastering->white_point[0] = av_make_q(avio_rb16(pb), chroma_den);
6193  sc->mastering->white_point[1] = av_make_q(avio_rb16(pb), chroma_den);
6194 
6195  sc->mastering->max_luminance = av_make_q(avio_rb32(pb), luma_den);
6196  sc->mastering->min_luminance = av_make_q(avio_rb32(pb), luma_den);
6197 
6198  sc->mastering->has_luminance = 1;
6199  sc->mastering->has_primaries = 1;
6200 
6201  return 0;
6202 }
6203 
6205 {
6206  MOVStreamContext *sc;
6207  int version;
6208 
6209  if (c->fc->nb_streams < 1)
6210  return AVERROR_INVALIDDATA;
6211 
6212  sc = c->fc->streams[c->fc->nb_streams - 1]->priv_data;
6213 
6214  if (atom.size < 5) {
6215  av_log(c->fc, AV_LOG_ERROR, "Empty Content Light Level box\n");
6216  return AVERROR_INVALIDDATA;
6217  }
6218 
6219  version = avio_r8(pb);
6220  if (version) {
6221  av_log(c->fc, AV_LOG_WARNING, "Unsupported Content Light Level box version %d\n", version);
6222  return 0;
6223  }
6224  avio_skip(pb, 3); /* flags */
6225 
6226  if (sc->coll){
6227  av_log(c->fc, AV_LOG_WARNING, "Ignoring duplicate COLL\n");
6228  return 0;
6229  }
6230 
6232  if (!sc->coll)
6233  return AVERROR(ENOMEM);
6234 
6235  sc->coll->MaxCLL = avio_rb16(pb);
6236  sc->coll->MaxFALL = avio_rb16(pb);
6237 
6238  return 0;
6239 }
6240 
6242 {
6243  MOVStreamContext *sc;
6244 
6245  if (c->fc->nb_streams < 1)
6246  return AVERROR_INVALIDDATA;
6247 
6248  sc = c->fc->streams[c->fc->nb_streams - 1]->priv_data;
6249 
6250  if (atom.size < 4) {
6251  av_log(c->fc, AV_LOG_ERROR, "Empty Content Light Level Info box\n");
6252  return AVERROR_INVALIDDATA;
6253  }
6254 
6255  if (sc->coll){
6256  av_log(c->fc, AV_LOG_WARNING, "Ignoring duplicate CLLI/COLL\n");
6257  return 0;
6258  }
6259 
6261  if (!sc->coll)
6262  return AVERROR(ENOMEM);
6263 
6264  sc->coll->MaxCLL = avio_rb16(pb);
6265  sc->coll->MaxFALL = avio_rb16(pb);
6266 
6267  return 0;
6268 }
6269 
6271 {
6272  MOVStreamContext *sc;
6273  const int illuminance_den = 10000;
6274  const int ambient_den = 50000;
6275  if (c->fc->nb_streams < 1)
6276  return AVERROR_INVALIDDATA;
6277  sc = c->fc->streams[c->fc->nb_streams - 1]->priv_data;
6278  if (atom.size < 6) {
6279  av_log(c->fc, AV_LOG_ERROR, "Empty Ambient Viewing Environment Info box\n");
6280  return AVERROR_INVALIDDATA;
6281  }
6282  if (sc->ambient){
6283  av_log(c->fc, AV_LOG_WARNING, "Ignoring duplicate AMVE\n");
6284  return 0;
6285  }
6287  if (!sc->ambient)
6288  return AVERROR(ENOMEM);
6289  sc->ambient->ambient_illuminance = av_make_q(avio_rb32(pb), illuminance_den);
6290  sc->ambient->ambient_light_x = av_make_q(avio_rb16(pb), ambient_den);
6291  sc->ambient->ambient_light_y = av_make_q(avio_rb16(pb), ambient_den);
6292  return 0;
6293 }
6294 
6296 {
6297  AVStream *st;
6298  MOVStreamContext *sc;
6299  enum AVStereo3DType type;
6300  int mode;
6301 
6302  if (c->fc->nb_streams < 1)
6303  return 0;
6304 
6305  st = c->fc->streams[c->fc->nb_streams - 1];
6306  sc = st->priv_data;
6307 
6308  if (atom.size < 5) {
6309  av_log(c->fc, AV_LOG_ERROR, "Empty stereoscopic video box\n");
6310  return AVERROR_INVALIDDATA;
6311  }
6312 
6313  if (sc->stereo3d)
6314  return AVERROR_INVALIDDATA;
6315 
6316  avio_skip(pb, 4); /* version + flags */
6317 
6318  mode = avio_r8(pb);
6319  switch (mode) {
6320  case 0:
6321  type = AV_STEREO3D_2D;
6322  break;
6323  case 1:
6325  break;
6326  case 2:
6328  break;
6329  default:
6330  av_log(c->fc, AV_LOG_WARNING, "Unknown st3d mode value %d\n", mode);
6331  return 0;
6332  }
6333 
6334  sc->stereo3d = av_stereo3d_alloc();
6335  if (!sc->stereo3d)
6336  return AVERROR(ENOMEM);
6337 
6338  sc->stereo3d->type = type;
6339  return 0;
6340 }
6341 
6343 {
6344  AVStream *st;
6345  MOVStreamContext *sc;
6346  int size, version, layout;
6347  int32_t yaw, pitch, roll;
6348  uint32_t l = 0, t = 0, r = 0, b = 0;
6349  uint32_t tag, padding = 0;
6350  enum AVSphericalProjection projection;
6351 
6352  if (c->fc->nb_streams < 1)
6353  return 0;
6354 
6355  st = c->fc->streams[c->fc->nb_streams - 1];
6356  sc = st->priv_data;
6357 
6358  if (atom.size < 8) {
6359  av_log(c->fc, AV_LOG_ERROR, "Empty spherical video box\n");
6360  return AVERROR_INVALIDDATA;
6361  }
6362 
6363  size = avio_rb32(pb);
6364  if (size <= 12 || size > atom.size)
6365  return AVERROR_INVALIDDATA;
6366 
6367  tag = avio_rl32(pb);
6368  if (tag != MKTAG('s','v','h','d')) {
6369  av_log(c->fc, AV_LOG_ERROR, "Missing spherical video header\n");
6370  return 0;
6371  }
6372  version = avio_r8(pb);
6373  if (version != 0) {
6374  av_log(c->fc, AV_LOG_WARNING, "Unknown spherical version %d\n",
6375  version);
6376  return 0;
6377  }
6378  avio_skip(pb, 3); /* flags */
6379  avio_skip(pb, size - 12); /* metadata_source */
6380 
6381  size = avio_rb32(pb);
6382  if (size > atom.size)
6383  return AVERROR_INVALIDDATA;
6384 
6385  tag = avio_rl32(pb);
6386  if (tag != MKTAG('p','r','o','j')) {
6387  av_log(c->fc, AV_LOG_ERROR, "Missing projection box\n");
6388  return 0;
6389  }
6390 
6391  size = avio_rb32(pb);
6392  if (size > atom.size)
6393  return AVERROR_INVALIDDATA;
6394 
6395  tag = avio_rl32(pb);
6396  if (tag != MKTAG('p','r','h','d')) {
6397  av_log(c->fc, AV_LOG_ERROR, "Missing projection header box\n");
6398  return 0;
6399  }
6400  version = avio_r8(pb);
6401  if (version != 0) {
6402  av_log(c->fc, AV_LOG_WARNING, "Unknown spherical version %d\n",
6403  version);
6404  return 0;
6405  }
6406  avio_skip(pb, 3); /* flags */
6407 
6408  /* 16.16 fixed point */
6409  yaw = avio_rb32(pb);
6410  pitch = avio_rb32(pb);
6411  roll = avio_rb32(pb);
6412 
6413  size = avio_rb32(pb);
6414  if (size > atom.size)
6415  return AVERROR_INVALIDDATA;
6416 
6417  tag = avio_rl32(pb);
6418  version = avio_r8(pb);
6419  if (version != 0) {
6420  av_log(c->fc, AV_LOG_WARNING, "Unknown spherical version %d\n",
6421  version);
6422  return 0;
6423  }
6424  avio_skip(pb, 3); /* flags */
6425  switch (tag) {
6426  case MKTAG('c','b','m','p'):
6427  layout = avio_rb32(pb);
6428  if (layout) {
6429  av_log(c->fc, AV_LOG_WARNING,
6430  "Unsupported cubemap layout %d\n", layout);
6431  return 0;
6432  }
6433  projection = AV_SPHERICAL_CUBEMAP;
6434  padding = avio_rb32(pb);
6435  break;
6436  case MKTAG('e','q','u','i'):
6437  t = avio_rb32(pb);
6438  b = avio_rb32(pb);
6439  l = avio_rb32(pb);
6440  r = avio_rb32(pb);
6441 
6442  if (b >= UINT_MAX - t || r >= UINT_MAX - l) {
6443  av_log(c->fc, AV_LOG_ERROR,
6444  "Invalid bounding rectangle coordinates "
6445  "%"PRIu32",%"PRIu32",%"PRIu32",%"PRIu32"\n", l, t, r, b);
6446  return AVERROR_INVALIDDATA;
6447  }
6448 
6449  if (l || t || r || b)
6450  projection = AV_SPHERICAL_EQUIRECTANGULAR_TILE;
6451  else
6452  projection = AV_SPHERICAL_EQUIRECTANGULAR;
6453  break;
6454  default:
6455  av_log(c->fc, AV_LOG_ERROR, "Unknown projection type: %s\n", av_fourcc2str(tag));
6456  return 0;
6457  }
6458 
6460  if (!sc->spherical)
6461  return AVERROR(ENOMEM);
6462 
6463  sc->spherical->projection = projection;
6464 
6465  sc->spherical->yaw = yaw;
6466  sc->spherical->pitch = pitch;
6467  sc->spherical->roll = roll;
6468 
6469  sc->spherical->padding = padding;
6470 
6471  sc->spherical->bound_left = l;
6472  sc->spherical->bound_top = t;
6473  sc->spherical->bound_right = r;
6474  sc->spherical->bound_bottom = b;
6475 
6476  return 0;
6477 }
6478 
6480 {
6481  int ret = 0;
6482  uint8_t *buffer = av_malloc(len + 1);
6483  const char *val;
6484 
6485  if (!buffer)
6486  return AVERROR(ENOMEM);
6487  buffer[len] = '\0';
6488 
6489  ret = ffio_read_size(pb, buffer, len);
6490  if (ret < 0)
6491  goto out;
6492 
6493  /* Check for mandatory keys and values, try to support XML as best-effort */
6494  if (!sc->spherical &&
6495  av_stristr(buffer, "<GSpherical:StitchingSoftware>") &&
6496  (val = av_stristr(buffer, "<GSpherical:Spherical>")) &&
6497  av_stristr(val, "true") &&
6498  (val = av_stristr(buffer, "<GSpherical:Stitched>")) &&
6499  av_stristr(val, "true") &&
6500  (val = av_stristr(buffer, "<GSpherical:ProjectionType>")) &&
6501  av_stristr(val, "equirectangular")) {
6503  if (!sc->spherical)
6504  goto out;
6505 
6507 
6508  if (av_stristr(buffer, "<GSpherical:StereoMode>") && !sc->stereo3d) {
6509  enum AVStereo3DType mode;
6510 
6511  if (av_stristr(buffer, "left-right"))
6513  else if (av_stristr(buffer, "top-bottom"))
6515  else
6516  mode = AV_STEREO3D_2D;
6517 
6518  sc->stereo3d = av_stereo3d_alloc();
6519  if (!sc->stereo3d)
6520  goto out;
6521 
6522  sc->stereo3d->type = mode;
6523  }
6524 
6525  /* orientation */
6526  val = av_stristr(buffer, "<GSpherical:InitialViewHeadingDegrees>");
6527  if (val)
6528  sc->spherical->yaw = strtol(val, NULL, 10) * (1 << 16);
6529  val = av_stristr(buffer, "<GSpherical:InitialViewPitchDegrees>");
6530  if (val)
6531  sc->spherical->pitch = strtol(val, NULL, 10) * (1 << 16);
6532  val = av_stristr(buffer, "<GSpherical:InitialViewRollDegrees>");
6533  if (val)
6534  sc->spherical->roll = strtol(val, NULL, 10) * (1 << 16);
6535  }
6536 
6537 out:
6538  av_free(buffer);
6539  return ret;
6540 }
6541 
6543 {
6544  AVStream *st;
6545  MOVStreamContext *sc;
6546  int64_t ret;
6547  AVUUID uuid;
6548  static const AVUUID uuid_isml_manifest = {
6549  0xa5, 0xd4, 0x0b, 0x30, 0xe8, 0x14, 0x11, 0xdd,
6550  0xba, 0x2f, 0x08, 0x00, 0x20, 0x0c, 0x9a, 0x66
6551  };
6552  static const AVUUID uuid_xmp = {
6553  0xbe, 0x7a, 0xcf, 0xcb, 0x97, 0xa9, 0x42, 0xe8,
6554  0x9c, 0x71, 0x99, 0x94, 0x91, 0xe3, 0xaf, 0xac
6555  };
6556  static const AVUUID uuid_spherical = {
6557  0xff, 0xcc, 0x82, 0x63, 0xf8, 0x55, 0x4a, 0x93,
6558  0x88, 0x14, 0x58, 0x7a, 0x02, 0x52, 0x1f, 0xdd,
6559  };
6560 
6561  if (atom.size < AV_UUID_LEN || atom.size >= FFMIN(INT_MAX, SIZE_MAX))
6562  return AVERROR_INVALIDDATA;
6563 
6564  if (c->fc->nb_streams < 1)
6565  return 0;
6566  st = c->fc->streams[c->fc->nb_streams - 1];
6567  sc = st->priv_data;
6568 
6569  ret = ffio_read_size(pb, uuid, AV_UUID_LEN);
6570  if (ret < 0)
6571  return ret;
6572  if (av_uuid_equal(uuid, uuid_isml_manifest)) {
6573  uint8_t *buffer, *ptr;
6574  char *endptr;
6575  size_t len = atom.size - AV_UUID_LEN;
6576 
6577  if (len < 4) {
6578  return AVERROR_INVALIDDATA;
6579  }
6580  ret = avio_skip(pb, 4); // zeroes
6581  len -= 4;
6582 
6583  buffer = av_mallocz(len + 1);
6584  if (!buffer) {
6585  return AVERROR(ENOMEM);
6586  }
6587  ret = ffio_read_size(pb, buffer, len);
6588  if (ret < 0) {
6589  av_free(buffer);
6590  return ret;
6591  }
6592 
6593  ptr = buffer;
6594  while ((ptr = av_stristr(ptr, "systemBitrate=\""))) {
6595  ptr += sizeof("systemBitrate=\"") - 1;
6596  c->bitrates_count++;
6597  c->bitrates = av_realloc_f(c->bitrates, c->bitrates_count, sizeof(*c->bitrates));
6598  if (!c->bitrates) {
6599  c->bitrates_count = 0;
6600  av_free(buffer);
6601  return AVERROR(ENOMEM);
6602  }
6603  errno = 0;
6604  ret = strtol(ptr, &endptr, 10);
6605  if (ret < 0 || errno || *endptr != '"') {
6606  c->bitrates[c->bitrates_count - 1] = 0;
6607  } else {
6608  c->bitrates[c->bitrates_count - 1] = ret;
6609  }
6610  }
6611 
6612  av_free(buffer);
6613  } else if (av_uuid_equal(uuid, uuid_xmp)) {
6614  uint8_t *buffer;
6615  size_t len = atom.size - AV_UUID_LEN;
6616  if (c->export_xmp) {
6617  buffer = av_mallocz(len + 1);
6618  if (!buffer) {
6619  return AVERROR(ENOMEM);
6620  }
6621  ret = ffio_read_size(pb, buffer, len);
6622  if (ret < 0) {
6623  av_free(buffer);
6624  return ret;
6625  }
6626  buffer[len] = '\0';
6627  av_dict_set(&c->fc->metadata, "xmp",
6629  } else {
6630  // skip all uuid atom, which makes it fast for long uuid-xmp file
6631  ret = avio_skip(pb, len);
6632  if (ret < 0)
6633  return ret;
6634  }
6635  } else if (av_uuid_equal(uuid, uuid_spherical)) {
6636  size_t len = atom.size - AV_UUID_LEN;
6637  ret = mov_parse_uuid_spherical(sc, pb, len);
6638  if (ret < 0)
6639  return ret;
6640  if (!sc->spherical)
6641  av_log(c->fc, AV_LOG_WARNING, "Invalid spherical metadata found\n");
6642  }
6643 
6644  return 0;
6645 }
6646 
6648 {
6649  int ret;
6650  uint8_t content[16];
6651 
6652  if (atom.size < 8)
6653  return 0;
6654 
6655  ret = avio_read(pb, content, FFMIN(sizeof(content), atom.size));
6656  if (ret < 0)
6657  return ret;
6658 
6659  if ( !c->found_moov
6660  && !c->found_mdat
6661  && !memcmp(content, "Anevia\x1A\x1A", 8)
6662  && c->use_mfra_for == FF_MOV_FLAG_MFRA_AUTO) {
6663  c->use_mfra_for = FF_MOV_FLAG_MFRA_PTS;
6664  }
6665 
6666  return 0;
6667 }
6668 
6670 {
6671  uint32_t format = avio_rl32(pb);
6672  MOVStreamContext *sc;
6673  enum AVCodecID id;
6674  AVStream *st;
6675 
6676  if (c->fc->nb_streams < 1)
6677  return 0;
6678  st = c->fc->streams[c->fc->nb_streams - 1];
6679  sc = st->priv_data;
6680 
6681  switch (sc->format)
6682  {
6683  case MKTAG('e','n','c','v'): // encrypted video
6684  case MKTAG('e','n','c','a'): // encrypted audio
6685  id = mov_codec_id(st, format);
6686  if (st->codecpar->codec_id != AV_CODEC_ID_NONE &&
6687  st->codecpar->codec_id != id) {
6688  av_log(c->fc, AV_LOG_WARNING,
6689  "ignoring 'frma' atom of '%.4s', stream has codec id %d\n",
6690  (char*)&format, st->codecpar->codec_id);
6691  break;
6692  }
6693 
6694  st->codecpar->codec_id = id;
6695  sc->format = format;
6696  break;
6697 
6698  default:
6699  if (format != sc->format) {
6700  av_log(c->fc, AV_LOG_WARNING,
6701  "ignoring 'frma' atom of '%.4s', stream format is '%.4s'\n",
6702  (char*)&format, (char*)&sc->format);
6703  }
6704  break;
6705  }
6706 
6707  return 0;
6708 }
6709 
6710 /**
6711  * Gets the current encryption info and associated current stream context. If
6712  * we are parsing a track fragment, this will return the specific encryption
6713  * info for this fragment; otherwise this will return the global encryption
6714  * info for the current stream.
6715  */
6717 {
6718  MOVFragmentStreamInfo *frag_stream_info;
6719  AVStream *st;
6720  int i;
6721 
6722  frag_stream_info = get_current_frag_stream_info(&c->frag_index);
6723  if (frag_stream_info) {
6724  for (i = 0; i < c->fc->nb_streams; i++) {
6725  *sc = c->fc->streams[i]->priv_data;
6726  if ((*sc)->id == frag_stream_info->id) {
6727  st = c->fc->streams[i];
6728  break;
6729  }
6730  }
6731  if (i == c->fc->nb_streams)
6732  return 0;
6733  *sc = st->priv_data;
6734 
6735  if (!frag_stream_info->encryption_index) {
6736  // If this stream isn't encrypted, don't create the index.
6737  if (!(*sc)->cenc.default_encrypted_sample)
6738  return 0;
6739  frag_stream_info->encryption_index = av_mallocz(sizeof(*frag_stream_info->encryption_index));
6740  if (!frag_stream_info->encryption_index)
6741  return AVERROR(ENOMEM);
6742  }
6743  *encryption_index = frag_stream_info->encryption_index;
6744  return 1;
6745  } else {
6746  // No current track fragment, using stream level encryption info.
6747 
6748  if (c->fc->nb_streams < 1)
6749  return 0;
6750  st = c->fc->streams[c->fc->nb_streams - 1];
6751  *sc = st->priv_data;
6752 
6753  if (!(*sc)->cenc.encryption_index) {
6754  // If this stream isn't encrypted, don't create the index.
6755  if (!(*sc)->cenc.default_encrypted_sample)
6756  return 0;
6757  (*sc)->cenc.encryption_index = av_mallocz(sizeof(*frag_stream_info->encryption_index));
6758  if (!(*sc)->cenc.encryption_index)
6759  return AVERROR(ENOMEM);
6760  }
6761 
6762  *encryption_index = (*sc)->cenc.encryption_index;
6763  return 1;
6764  }
6765 }
6766 
6768 {
6769  int i, ret;
6770  unsigned int subsample_count;
6771  AVSubsampleEncryptionInfo *subsamples;
6772 
6773  if (!sc->cenc.default_encrypted_sample) {
6774  av_log(c->fc, AV_LOG_ERROR, "Missing schm or tenc\n");
6775  return AVERROR_INVALIDDATA;
6776  }
6777 
6778  if (sc->cenc.per_sample_iv_size || use_subsamples) {
6780  if (!*sample)
6781  return AVERROR(ENOMEM);
6782  } else
6783  *sample = NULL;
6784 
6785  if (sc->cenc.per_sample_iv_size != 0) {
6786  if ((ret = ffio_read_size(pb, (*sample)->iv, sc->cenc.per_sample_iv_size)) < 0) {
6787  av_log(c->fc, AV_LOG_ERROR, "failed to read the initialization vector\n");
6789  *sample = NULL;
6790  return ret;
6791  }
6792  }
6793 
6794  if (use_subsamples) {
6795  subsample_count = avio_rb16(pb);
6796  av_free((*sample)->subsamples);
6797  (*sample)->subsamples = av_calloc(subsample_count, sizeof(*subsamples));
6798  if (!(*sample)->subsamples) {
6800  *sample = NULL;
6801  return AVERROR(ENOMEM);
6802  }
6803 
6804  for (i = 0; i < subsample_count && !pb->eof_reached; i++) {
6805  (*sample)->subsamples[i].bytes_of_clear_data = avio_rb16(pb);
6806  (*sample)->subsamples[i].bytes_of_protected_data = avio_rb32(pb);
6807  }
6808 
6809  if (pb->eof_reached) {
6810  av_log(c->fc, AV_LOG_ERROR, "hit EOF while reading sub-sample encryption info\n");
6812  *sample = NULL;
6813  return AVERROR_INVALIDDATA;
6814  }
6815  (*sample)->subsample_count = subsample_count;
6816  }
6817 
6818  return 0;
6819 }
6820 
6822 {
6823  AVEncryptionInfo **encrypted_samples;
6824  MOVEncryptionIndex *encryption_index;
6825  MOVStreamContext *sc;
6826  int use_subsamples, ret;
6827  unsigned int sample_count, i, alloc_size = 0;
6828 
6829  ret = get_current_encryption_info(c, &encryption_index, &sc);
6830  if (ret != 1)
6831  return ret;
6832 
6833  if (encryption_index->nb_encrypted_samples) {
6834  // This can happen if we have both saio/saiz and senc atoms.
6835  av_log(c->fc, AV_LOG_DEBUG, "Ignoring duplicate encryption info in senc\n");
6836  return 0;
6837  }
6838 
6839  avio_r8(pb); /* version */
6840  use_subsamples = avio_rb24(pb) & 0x02; /* flags */
6841 
6842  sample_count = avio_rb32(pb);
6843  if (sample_count >= INT_MAX / sizeof(*encrypted_samples))
6844  return AVERROR(ENOMEM);
6845 
6846  for (i = 0; i < sample_count; i++) {
6847  unsigned int min_samples = FFMIN(FFMAX(i + 1, 1024 * 1024), sample_count);
6848  encrypted_samples = av_fast_realloc(encryption_index->encrypted_samples, &alloc_size,
6849  min_samples * sizeof(*encrypted_samples));
6850  if (encrypted_samples) {
6851  encryption_index->encrypted_samples = encrypted_samples;
6852 
6854  c, pb, sc, &encryption_index->encrypted_samples[i], use_subsamples);
6855  } else {
6856  ret = AVERROR(ENOMEM);
6857  }
6858  if (pb->eof_reached) {
6859  av_log(c->fc, AV_LOG_ERROR, "Hit EOF while reading senc\n");
6860  if (ret >= 0)
6861  av_encryption_info_free(encryption_index->encrypted_samples[i]);
6863  }
6864 
6865  if (ret < 0) {
6866  for (; i > 0; i--)
6867  av_encryption_info_free(encryption_index->encrypted_samples[i - 1]);
6868  av_freep(&encryption_index->encrypted_samples);
6869  return ret;
6870  }
6871  }
6872  encryption_index->nb_encrypted_samples = sample_count;
6873 
6874  return 0;
6875 }
6876 
6878 {
6879  AVEncryptionInfo **sample, **encrypted_samples;
6880  int64_t prev_pos;
6881  size_t sample_count, sample_info_size, i;
6882  int ret = 0;
6883  unsigned int alloc_size = 0;
6884 
6885  if (encryption_index->nb_encrypted_samples)
6886  return 0;
6887  sample_count = encryption_index->auxiliary_info_sample_count;
6888  if (encryption_index->auxiliary_offsets_count != 1) {
6889  av_log(c->fc, AV_LOG_ERROR, "Multiple auxiliary info chunks are not supported\n");
6890  return AVERROR_PATCHWELCOME;
6891  }
6892  if (sample_count >= INT_MAX / sizeof(*encrypted_samples))
6893  return AVERROR(ENOMEM);
6894 
6895  prev_pos = avio_tell(pb);
6896  if (!(pb->seekable & AVIO_SEEKABLE_NORMAL) ||
6897  avio_seek(pb, encryption_index->auxiliary_offsets[0], SEEK_SET) != encryption_index->auxiliary_offsets[0]) {
6898  av_log(c->fc, AV_LOG_INFO, "Failed to seek for auxiliary info, will only parse senc atoms for encryption info\n");
6899  goto finish;
6900  }
6901 
6902  for (i = 0; i < sample_count && !pb->eof_reached; i++) {
6903  unsigned int min_samples = FFMIN(FFMAX(i + 1, 1024 * 1024), sample_count);
6904  encrypted_samples = av_fast_realloc(encryption_index->encrypted_samples, &alloc_size,
6905  min_samples * sizeof(*encrypted_samples));
6906  if (!encrypted_samples) {
6907  ret = AVERROR(ENOMEM);
6908  goto finish;
6909  }
6910  encryption_index->encrypted_samples = encrypted_samples;
6911 
6912  sample = &encryption_index->encrypted_samples[i];
6913  sample_info_size = encryption_index->auxiliary_info_default_size
6914  ? encryption_index->auxiliary_info_default_size
6915  : encryption_index->auxiliary_info_sizes[i];
6916 
6917  ret = mov_read_sample_encryption_info(c, pb, sc, sample, sample_info_size > sc->cenc.per_sample_iv_size);
6918  if (ret < 0)
6919  goto finish;
6920  }
6921  if (pb->eof_reached) {
6922  av_log(c->fc, AV_LOG_ERROR, "Hit EOF while reading auxiliary info\n");
6924  } else {
6925  encryption_index->nb_encrypted_samples = sample_count;
6926  }
6927 
6928 finish:
6929  avio_seek(pb, prev_pos, SEEK_SET);
6930  if (ret < 0) {
6931  for (; i > 0; i--) {
6932  av_encryption_info_free(encryption_index->encrypted_samples[i - 1]);
6933  }
6934  av_freep(&encryption_index->encrypted_samples);
6935  }
6936  return ret;
6937 }
6938 
6940 {
6941  MOVEncryptionIndex *encryption_index;
6942  MOVStreamContext *sc;
6943  int ret;
6944  unsigned int sample_count, aux_info_type, aux_info_param;
6945 
6946  ret = get_current_encryption_info(c, &encryption_index, &sc);
6947  if (ret != 1)
6948  return ret;
6949 
6950  if (encryption_index->nb_encrypted_samples) {
6951  // This can happen if we have both saio/saiz and senc atoms.
6952  av_log(c->fc, AV_LOG_DEBUG, "Ignoring duplicate encryption info in saiz\n");
6953  return 0;
6954  }
6955 
6956  if (encryption_index->auxiliary_info_sample_count) {
6957  av_log(c->fc, AV_LOG_ERROR, "Duplicate saiz atom\n");
6958  return AVERROR_INVALIDDATA;
6959  }
6960 
6961  avio_r8(pb); /* version */
6962  if (avio_rb24(pb) & 0x01) { /* flags */
6963  aux_info_type = avio_rb32(pb);
6964  aux_info_param = avio_rb32(pb);
6965  if (sc->cenc.default_encrypted_sample) {
6966  if (aux_info_type != sc->cenc.default_encrypted_sample->scheme) {
6967  av_log(c->fc, AV_LOG_DEBUG, "Ignoring saiz box with non-zero aux_info_type\n");
6968  return 0;
6969  }
6970  if (aux_info_param != 0) {
6971  av_log(c->fc, AV_LOG_DEBUG, "Ignoring saiz box with non-zero aux_info_type_parameter\n");
6972  return 0;
6973  }
6974  } else {
6975  // Didn't see 'schm' or 'tenc', so this isn't encrypted.
6976  if ((aux_info_type == MKBETAG('c','e','n','c') ||
6977  aux_info_type == MKBETAG('c','e','n','s') ||
6978  aux_info_type == MKBETAG('c','b','c','1') ||
6979  aux_info_type == MKBETAG('c','b','c','s')) &&
6980  aux_info_param == 0) {
6981  av_log(c->fc, AV_LOG_ERROR, "Saw encrypted saiz without schm/tenc\n");
6982  return AVERROR_INVALIDDATA;
6983  } else {
6984  return 0;
6985  }
6986  }
6987  } else if (!sc->cenc.default_encrypted_sample) {
6988  // Didn't see 'schm' or 'tenc', so this isn't encrypted.
6989  return 0;
6990  }
6991 
6992  encryption_index->auxiliary_info_default_size = avio_r8(pb);
6993  sample_count = avio_rb32(pb);
6994 
6995  if (encryption_index->auxiliary_info_default_size == 0) {
6996  if (sample_count == 0)
6997  return AVERROR_INVALIDDATA;
6998 
6999  encryption_index->auxiliary_info_sizes = av_malloc(sample_count);
7000  if (!encryption_index->auxiliary_info_sizes)
7001  return AVERROR(ENOMEM);
7002 
7003  ret = avio_read(pb, encryption_index->auxiliary_info_sizes, sample_count);
7004  if (ret != sample_count) {
7005  av_freep(&encryption_index->auxiliary_info_sizes);
7006 
7007  if (ret >= 0)
7009  av_log(c->fc, AV_LOG_ERROR, "Failed to read the auxiliary info, %s\n",
7010  av_err2str(ret));
7011  return ret;
7012  }
7013  }
7014  encryption_index->auxiliary_info_sample_count = sample_count;
7015 
7016  if (encryption_index->auxiliary_offsets_count) {
7017  return mov_parse_auxiliary_info(c, sc, pb, encryption_index);
7018  }
7019 
7020  return 0;
7021 }
7022 
7024 {
7025  uint64_t *auxiliary_offsets;
7026  MOVEncryptionIndex *encryption_index;
7027  MOVStreamContext *sc;
7028  int i, ret;
7029  unsigned int version, entry_count, aux_info_type, aux_info_param;
7030  unsigned int alloc_size = 0;
7031 
7032  ret = get_current_encryption_info(c, &encryption_index, &sc);
7033  if (ret != 1)
7034  return ret;
7035 
7036  if (encryption_index->nb_encrypted_samples) {
7037  // This can happen if we have both saio/saiz and senc atoms.
7038  av_log(c->fc, AV_LOG_DEBUG, "Ignoring duplicate encryption info in saio\n");
7039  return 0;
7040  }
7041 
7042  if (encryption_index->auxiliary_offsets_count) {
7043  av_log(c->fc, AV_LOG_ERROR, "Duplicate saio atom\n");
7044  return AVERROR_INVALIDDATA;
7045  }
7046 
7047  version = avio_r8(pb); /* version */
7048  if (avio_rb24(pb) & 0x01) { /* flags */
7049  aux_info_type = avio_rb32(pb);
7050  aux_info_param = avio_rb32(pb);
7051  if (sc->cenc.default_encrypted_sample) {
7052  if (aux_info_type != sc->cenc.default_encrypted_sample->scheme) {
7053  av_log(c->fc, AV_LOG_DEBUG, "Ignoring saio box with non-zero aux_info_type\n");
7054  return 0;
7055  }
7056  if (aux_info_param != 0) {
7057  av_log(c->fc, AV_LOG_DEBUG, "Ignoring saio box with non-zero aux_info_type_parameter\n");
7058  return 0;
7059  }
7060  } else {
7061  // Didn't see 'schm' or 'tenc', so this isn't encrypted.
7062  if ((aux_info_type == MKBETAG('c','e','n','c') ||
7063  aux_info_type == MKBETAG('c','e','n','s') ||
7064  aux_info_type == MKBETAG('c','b','c','1') ||
7065  aux_info_type == MKBETAG('c','b','c','s')) &&
7066  aux_info_param == 0) {
7067  av_log(c->fc, AV_LOG_ERROR, "Saw encrypted saio without schm/tenc\n");
7068  return AVERROR_INVALIDDATA;
7069  } else {
7070  return 0;
7071  }
7072  }
7073  } else if (!sc->cenc.default_encrypted_sample) {
7074  // Didn't see 'schm' or 'tenc', so this isn't encrypted.
7075  return 0;
7076  }
7077 
7078  entry_count = avio_rb32(pb);
7079  if (entry_count >= INT_MAX / sizeof(*auxiliary_offsets))
7080  return AVERROR(ENOMEM);
7081 
7082  for (i = 0; i < entry_count && !pb->eof_reached; i++) {
7083  unsigned int min_offsets = FFMIN(FFMAX(i + 1, 1024), entry_count);
7084  auxiliary_offsets = av_fast_realloc(
7085  encryption_index->auxiliary_offsets, &alloc_size,
7086  min_offsets * sizeof(*auxiliary_offsets));
7087  if (!auxiliary_offsets) {
7088  av_freep(&encryption_index->auxiliary_offsets);
7089  return AVERROR(ENOMEM);
7090  }
7091  encryption_index->auxiliary_offsets = auxiliary_offsets;
7092 
7093  if (version == 0) {
7094  encryption_index->auxiliary_offsets[i] = avio_rb32(pb);
7095  } else {
7096  encryption_index->auxiliary_offsets[i] = avio_rb64(pb);
7097  }
7098  if (c->frag_index.current >= 0) {
7099  encryption_index->auxiliary_offsets[i] += c->fragment.base_data_offset;
7100  }
7101  }
7102 
7103  if (pb->eof_reached) {
7104  av_log(c->fc, AV_LOG_ERROR, "Hit EOF while reading saio\n");
7105  av_freep(&encryption_index->auxiliary_offsets);
7106  return AVERROR_INVALIDDATA;
7107  }
7108 
7109  encryption_index->auxiliary_offsets_count = entry_count;
7110 
7111  if (encryption_index->auxiliary_info_sample_count) {
7112  return mov_parse_auxiliary_info(c, sc, pb, encryption_index);
7113  }
7114 
7115  return 0;
7116 }
7117 
7119 {
7120  AVEncryptionInitInfo *info, *old_init_info;
7121  uint8_t **key_ids;
7122  AVStream *st;
7123  const AVPacketSideData *old_side_data;
7124  uint8_t *side_data, *extra_data;
7125  size_t side_data_size;
7126  int ret = 0;
7127  unsigned int version, kid_count, extra_data_size, alloc_size = 0;
7128 
7129  if (c->fc->nb_streams < 1)
7130  return 0;
7131  st = c->fc->streams[c->fc->nb_streams-1];
7132 
7133  version = avio_r8(pb); /* version */
7134  avio_rb24(pb); /* flags */
7135 
7136  info = av_encryption_init_info_alloc(/* system_id_size */ 16, /* num_key_ids */ 0,
7137  /* key_id_size */ 16, /* data_size */ 0);
7138  if (!info)
7139  return AVERROR(ENOMEM);
7140 
7141  if ((ret = ffio_read_size(pb, info->system_id, 16)) < 0) {
7142  av_log(c->fc, AV_LOG_ERROR, "Failed to read the system id\n");
7143  goto finish;
7144  }
7145 
7146  if (version > 0) {
7147  kid_count = avio_rb32(pb);
7148  if (kid_count >= INT_MAX / sizeof(*key_ids)) {
7149  ret = AVERROR(ENOMEM);
7150  goto finish;
7151  }
7152 
7153  for (unsigned int i = 0; i < kid_count && !pb->eof_reached; i++) {
7154  unsigned int min_kid_count = FFMIN(FFMAX(i + 1, 1024), kid_count);
7155  key_ids = av_fast_realloc(info->key_ids, &alloc_size,
7156  min_kid_count * sizeof(*key_ids));
7157  if (!key_ids) {
7158  ret = AVERROR(ENOMEM);
7159  goto finish;
7160  }
7161  info->key_ids = key_ids;
7162 
7163  info->key_ids[i] = av_mallocz(16);
7164  if (!info->key_ids[i]) {
7165  ret = AVERROR(ENOMEM);
7166  goto finish;
7167  }
7168  info->num_key_ids = i + 1;
7169 
7170  if ((ret = ffio_read_size(pb, info->key_ids[i], 16)) < 0) {
7171  av_log(c->fc, AV_LOG_ERROR, "Failed to read the key id\n");
7172  goto finish;
7173  }
7174  }
7175 
7176  if (pb->eof_reached) {
7177  av_log(c->fc, AV_LOG_ERROR, "Hit EOF while reading pssh\n");
7179  goto finish;
7180  }
7181  }
7182 
7183  extra_data_size = avio_rb32(pb);
7184  extra_data = av_malloc(extra_data_size);
7185  if (!extra_data) {
7186  ret = AVERROR(ENOMEM);
7187  goto finish;
7188  }
7189  ret = avio_read(pb, extra_data, extra_data_size);
7190  if (ret != extra_data_size) {
7191  av_free(extra_data);
7192 
7193  if (ret >= 0)
7195  goto finish;
7196  }
7197 
7198  av_freep(&info->data); // malloc(0) may still allocate something.
7199  info->data = extra_data;
7200  info->data_size = extra_data_size;
7201 
7202  // If there is existing initialization data, append to the list.
7205  if (old_side_data) {
7206  old_init_info = av_encryption_init_info_get_side_data(old_side_data->data, old_side_data->size);
7207  if (old_init_info) {
7208  // Append to the end of the list.
7209  for (AVEncryptionInitInfo *cur = old_init_info;; cur = cur->next) {
7210  if (!cur->next) {
7211  cur->next = info;
7212  break;
7213  }
7214  }
7215  info = old_init_info;
7216  } else {
7217  // Assume existing side-data will be valid, so the only error we could get is OOM.
7218  ret = AVERROR(ENOMEM);
7219  goto finish;
7220  }
7221  }
7222 
7223  side_data = av_encryption_init_info_add_side_data(info, &side_data_size);
7224  if (!side_data) {
7225  ret = AVERROR(ENOMEM);
7226  goto finish;
7227  }
7231  side_data, side_data_size, 0))
7232  av_free(side_data);
7233 
7234 finish:
7236  return ret;
7237 }
7238 
7240 {
7241  AVStream *st;
7242  MOVStreamContext *sc;
7243 
7244  if (c->fc->nb_streams < 1)
7245  return 0;
7246  st = c->fc->streams[c->fc->nb_streams-1];
7247  sc = st->priv_data;
7248 
7249  if (sc->pseudo_stream_id != 0) {
7250  av_log(c->fc, AV_LOG_ERROR, "schm boxes are only supported in first sample descriptor\n");
7251  return AVERROR_PATCHWELCOME;
7252  }
7253 
7254  if (atom.size < 8)
7255  return AVERROR_INVALIDDATA;
7256 
7257  avio_rb32(pb); /* version and flags */
7258 
7259  if (!sc->cenc.default_encrypted_sample) {
7261  if (!sc->cenc.default_encrypted_sample) {
7262  return AVERROR(ENOMEM);
7263  }
7264  }
7265 
7267  return 0;
7268 }
7269 
7271 {
7272  AVStream *st;
7273  MOVStreamContext *sc;
7274  unsigned int version, pattern, is_protected, iv_size;
7275 
7276  if (c->fc->nb_streams < 1)
7277  return 0;
7278  st = c->fc->streams[c->fc->nb_streams-1];
7279  sc = st->priv_data;
7280 
7281  if (sc->pseudo_stream_id != 0) {
7282  av_log(c->fc, AV_LOG_ERROR, "tenc atom are only supported in first sample descriptor\n");
7283  return AVERROR_PATCHWELCOME;
7284  }
7285 
7286  if (!sc->cenc.default_encrypted_sample) {
7288  if (!sc->cenc.default_encrypted_sample) {
7289  return AVERROR(ENOMEM);
7290  }
7291  }
7292 
7293  if (atom.size < 20)
7294  return AVERROR_INVALIDDATA;
7295 
7296  version = avio_r8(pb); /* version */
7297  avio_rb24(pb); /* flags */
7298 
7299  avio_r8(pb); /* reserved */
7300  pattern = avio_r8(pb);
7301 
7302  if (version > 0) {
7303  sc->cenc.default_encrypted_sample->crypt_byte_block = pattern >> 4;
7304  sc->cenc.default_encrypted_sample->skip_byte_block = pattern & 0xf;
7305  }
7306 
7307  is_protected = avio_r8(pb);
7308  if (is_protected && !sc->cenc.encryption_index) {
7309  // The whole stream should be by-default encrypted.
7311  if (!sc->cenc.encryption_index)
7312  return AVERROR(ENOMEM);
7313  }
7314  sc->cenc.per_sample_iv_size = avio_r8(pb);
7315  if (sc->cenc.per_sample_iv_size != 0 && sc->cenc.per_sample_iv_size != 8 &&
7316  sc->cenc.per_sample_iv_size != 16) {
7317  av_log(c->fc, AV_LOG_ERROR, "invalid per-sample IV size value\n");
7318  return AVERROR_INVALIDDATA;
7319  }
7320  if (avio_read(pb, sc->cenc.default_encrypted_sample->key_id, 16) != 16) {
7321  av_log(c->fc, AV_LOG_ERROR, "failed to read the default key ID\n");
7322  return AVERROR_INVALIDDATA;
7323  }
7324 
7325  if (is_protected && !sc->cenc.per_sample_iv_size) {
7326  iv_size = avio_r8(pb);
7327  if (iv_size != 8 && iv_size != 16) {
7328  av_log(c->fc, AV_LOG_ERROR, "invalid default_constant_IV_size in tenc atom\n");
7329  return AVERROR_INVALIDDATA;
7330  }
7331 
7332  if (avio_read(pb, sc->cenc.default_encrypted_sample->iv, iv_size) != iv_size) {
7333  av_log(c->fc, AV_LOG_ERROR, "failed to read the default IV\n");
7334  return AVERROR_INVALIDDATA;
7335  }
7336  }
7337 
7338  return 0;
7339 }
7340 
7342 {
7343  AVStream *st;
7344  int last, type, size, ret;
7345  uint8_t buf[4];
7346 
7347  if (c->fc->nb_streams < 1)
7348  return 0;
7349  st = c->fc->streams[c->fc->nb_streams-1];
7350 
7351  if ((uint64_t)atom.size > (1<<30) || atom.size < 42)
7352  return AVERROR_INVALIDDATA;
7353 
7354  /* Check FlacSpecificBox version. */
7355  if (avio_r8(pb) != 0)
7356  return AVERROR_INVALIDDATA;
7357 
7358  avio_rb24(pb); /* Flags */
7359 
7360  if (avio_read(pb, buf, sizeof(buf)) != sizeof(buf)) {
7361  av_log(c->fc, AV_LOG_ERROR, "failed to read FLAC metadata block header\n");
7362  return pb->error < 0 ? pb->error : AVERROR_INVALIDDATA;
7363  }
7364  flac_parse_block_header(buf, &last, &type, &size);
7365 
7367  av_log(c->fc, AV_LOG_ERROR, "STREAMINFO must be first FLACMetadataBlock\n");
7368  return AVERROR_INVALIDDATA;
7369  }
7370 
7371  ret = ff_get_extradata(c->fc, st->codecpar, pb, size);
7372  if (ret < 0)
7373  return ret;
7374 
7375  if (!last)
7376  av_log(c->fc, AV_LOG_WARNING, "non-STREAMINFO FLACMetadataBlock(s) ignored\n");
7377 
7378  return 0;
7379 }
7380 
7382 {
7383  int i, ret;
7384  int bytes_of_protected_data;
7385 
7386  if (!sc->cenc.aes_ctr) {
7387  /* initialize the cipher */
7388  sc->cenc.aes_ctr = av_aes_ctr_alloc();
7389  if (!sc->cenc.aes_ctr) {
7390  return AVERROR(ENOMEM);
7391  }
7392 
7393  ret = av_aes_ctr_init(sc->cenc.aes_ctr, c->decryption_key);
7394  if (ret < 0) {
7395  return ret;
7396  }
7397  }
7398 
7400 
7401  if (!sample->subsample_count) {
7402  /* decrypt the whole packet */
7404  return 0;
7405  }
7406 
7407  for (i = 0; i < sample->subsample_count; i++) {
7408  if (sample->subsamples[i].bytes_of_clear_data + sample->subsamples[i].bytes_of_protected_data > size) {
7409  av_log(c->fc, AV_LOG_ERROR, "subsample size exceeds the packet size left\n");
7410  return AVERROR_INVALIDDATA;
7411  }
7412 
7413  /* skip the clear bytes */
7414  input += sample->subsamples[i].bytes_of_clear_data;
7415  size -= sample->subsamples[i].bytes_of_clear_data;
7416 
7417  /* decrypt the encrypted bytes */
7418 
7419  bytes_of_protected_data = sample->subsamples[i].bytes_of_protected_data;
7420  av_aes_ctr_crypt(sc->cenc.aes_ctr, input, input, bytes_of_protected_data);
7421 
7422  input += bytes_of_protected_data;
7423  size -= bytes_of_protected_data;
7424  }
7425 
7426  if (size > 0) {
7427  av_log(c->fc, AV_LOG_ERROR, "leftover packet bytes after subsample processing\n");
7428  return AVERROR_INVALIDDATA;
7429  }
7430 
7431  return 0;
7432 }
7433 
7435 {
7436  int i, ret;
7437  int num_of_encrypted_blocks;
7438  uint8_t iv[16];
7439 
7440  if (!sc->cenc.aes_ctx) {
7441  /* initialize the cipher */
7442  sc->cenc.aes_ctx = av_aes_alloc();
7443  if (!sc->cenc.aes_ctx) {
7444  return AVERROR(ENOMEM);
7445  }
7446 
7447  ret = av_aes_init(sc->cenc.aes_ctx, c->decryption_key, 16 * 8, 1);
7448  if (ret < 0) {
7449  return ret;
7450  }
7451  }
7452 
7453  memcpy(iv, sample->iv, 16);
7454 
7455  /* whole-block full sample encryption */
7456  if (!sample->subsample_count) {
7457  /* decrypt the whole packet */
7458  av_aes_crypt(sc->cenc.aes_ctx, input, input, size/16, iv, 1);
7459  return 0;
7460  }
7461 
7462  for (i = 0; i < sample->subsample_count; i++) {
7463  if (sample->subsamples[i].bytes_of_clear_data + sample->subsamples[i].bytes_of_protected_data > size) {
7464  av_log(c->fc, AV_LOG_ERROR, "subsample size exceeds the packet size left\n");
7465  return AVERROR_INVALIDDATA;
7466  }
7467 
7468  if (sample->subsamples[i].bytes_of_protected_data % 16) {
7469  av_log(c->fc, AV_LOG_ERROR, "subsample BytesOfProtectedData is not a multiple of 16\n");
7470  return AVERROR_INVALIDDATA;
7471  }
7472 
7473  /* skip the clear bytes */
7474  input += sample->subsamples[i].bytes_of_clear_data;
7475  size -= sample->subsamples[i].bytes_of_clear_data;
7476 
7477  /* decrypt the encrypted bytes */
7478  num_of_encrypted_blocks = sample->subsamples[i].bytes_of_protected_data/16;
7479  if (num_of_encrypted_blocks > 0) {
7480  av_aes_crypt(sc->cenc.aes_ctx, input, input, num_of_encrypted_blocks, iv, 1);
7481  }
7482  input += sample->subsamples[i].bytes_of_protected_data;
7483  size -= sample->subsamples[i].bytes_of_protected_data;
7484  }
7485 
7486  if (size > 0) {
7487  av_log(c->fc, AV_LOG_ERROR, "leftover packet bytes after subsample processing\n");
7488  return AVERROR_INVALIDDATA;
7489  }
7490 
7491  return 0;
7492 }
7493 
7495 {
7496  int i, ret, rem_bytes;
7497  uint8_t *data;
7498 
7499  if (!sc->cenc.aes_ctr) {
7500  /* initialize the cipher */
7501  sc->cenc.aes_ctr = av_aes_ctr_alloc();
7502  if (!sc->cenc.aes_ctr) {
7503  return AVERROR(ENOMEM);
7504  }
7505 
7506  ret = av_aes_ctr_init(sc->cenc.aes_ctr, c->decryption_key);
7507  if (ret < 0) {
7508  return ret;
7509  }
7510  }
7511 
7513 
7514  /* whole-block full sample encryption */
7515  if (!sample->subsample_count) {
7516  /* decrypt the whole packet */
7518  return 0;
7519  } else if (!sample->crypt_byte_block && !sample->skip_byte_block) {
7520  av_log(c->fc, AV_LOG_ERROR, "pattern encryption is not present in 'cens' scheme\n");
7521  return AVERROR_INVALIDDATA;
7522  }
7523 
7524  for (i = 0; i < sample->subsample_count; i++) {
7525  if (sample->subsamples[i].bytes_of_clear_data + sample->subsamples[i].bytes_of_protected_data > size) {
7526  av_log(c->fc, AV_LOG_ERROR, "subsample size exceeds the packet size left\n");
7527  return AVERROR_INVALIDDATA;
7528  }
7529 
7530  /* skip the clear bytes */
7531  input += sample->subsamples[i].bytes_of_clear_data;
7532  size -= sample->subsamples[i].bytes_of_clear_data;
7533 
7534  /* decrypt the encrypted bytes */
7535  data = input;
7536  rem_bytes = sample->subsamples[i].bytes_of_protected_data;
7537  while (rem_bytes > 0) {
7538  if (rem_bytes < 16*sample->crypt_byte_block) {
7539  break;
7540  }
7541  av_aes_ctr_crypt(sc->cenc.aes_ctr, data, data, 16*sample->crypt_byte_block);
7542  data += 16*sample->crypt_byte_block;
7543  rem_bytes -= 16*sample->crypt_byte_block;
7544  data += FFMIN(16*sample->skip_byte_block, rem_bytes);
7545  rem_bytes -= FFMIN(16*sample->skip_byte_block, rem_bytes);
7546  }
7547  input += sample->subsamples[i].bytes_of_protected_data;
7548  size -= sample->subsamples[i].bytes_of_protected_data;
7549  }
7550 
7551  if (size > 0) {
7552  av_log(c->fc, AV_LOG_ERROR, "leftover packet bytes after subsample processing\n");
7553  return AVERROR_INVALIDDATA;
7554  }
7555 
7556  return 0;
7557 }
7558 
7560 {
7561  int i, ret, rem_bytes;
7562  uint8_t iv[16];
7563  uint8_t *data;
7564 
7565  if (!sc->cenc.aes_ctx) {
7566  /* initialize the cipher */
7567  sc->cenc.aes_ctx = av_aes_alloc();
7568  if (!sc->cenc.aes_ctx) {
7569  return AVERROR(ENOMEM);
7570  }
7571 
7572  ret = av_aes_init(sc->cenc.aes_ctx, c->decryption_key, 16 * 8, 1);
7573  if (ret < 0) {
7574  return ret;
7575  }
7576  }
7577 
7578  /* whole-block full sample encryption */
7579  if (!sample->subsample_count) {
7580  /* decrypt the whole packet */
7581  memcpy(iv, sample->iv, 16);
7582  av_aes_crypt(sc->cenc.aes_ctx, input, input, size/16, iv, 1);
7583  return 0;
7584  } else if (!sample->crypt_byte_block && !sample->skip_byte_block) {
7585  av_log(c->fc, AV_LOG_ERROR, "pattern encryption is not present in 'cbcs' scheme\n");
7586  return AVERROR_INVALIDDATA;
7587  }
7588 
7589  for (i = 0; i < sample->subsample_count; i++) {
7590  if (sample->subsamples[i].bytes_of_clear_data + sample->subsamples[i].bytes_of_protected_data > size) {
7591  av_log(c->fc, AV_LOG_ERROR, "subsample size exceeds the packet size left\n");
7592  return AVERROR_INVALIDDATA;
7593  }
7594 
7595  /* skip the clear bytes */
7596  input += sample->subsamples[i].bytes_of_clear_data;
7597  size -= sample->subsamples[i].bytes_of_clear_data;
7598 
7599  /* decrypt the encrypted bytes */
7600  memcpy(iv, sample->iv, 16);
7601  data = input;
7602  rem_bytes = sample->subsamples[i].bytes_of_protected_data;
7603  while (rem_bytes > 0) {
7604  if (rem_bytes < 16*sample->crypt_byte_block) {
7605  break;
7606  }
7607  av_aes_crypt(sc->cenc.aes_ctx, data, data, sample->crypt_byte_block, iv, 1);
7608  data += 16*sample->crypt_byte_block;
7609  rem_bytes -= 16*sample->crypt_byte_block;
7610  data += FFMIN(16*sample->skip_byte_block, rem_bytes);
7611  rem_bytes -= FFMIN(16*sample->skip_byte_block, rem_bytes);
7612  }
7613  input += sample->subsamples[i].bytes_of_protected_data;
7614  size -= sample->subsamples[i].bytes_of_protected_data;
7615  }
7616 
7617  if (size > 0) {
7618  av_log(c->fc, AV_LOG_ERROR, "leftover packet bytes after subsample processing\n");
7619  return AVERROR_INVALIDDATA;
7620  }
7621 
7622  return 0;
7623 }
7624 
7626 {
7627  if (sample->scheme == MKBETAG('c','e','n','c') && !sample->crypt_byte_block && !sample->skip_byte_block) {
7628  return cenc_scheme_decrypt(c, sc, sample, input, size);
7629  } else if (sample->scheme == MKBETAG('c','b','c','1') && !sample->crypt_byte_block && !sample->skip_byte_block) {
7630  return cbc1_scheme_decrypt(c, sc, sample, input, size);
7631  } else if (sample->scheme == MKBETAG('c','e','n','s')) {
7632  return cens_scheme_decrypt(c, sc, sample, input, size);
7633  } else if (sample->scheme == MKBETAG('c','b','c','s')) {
7634  return cbcs_scheme_decrypt(c, sc, sample, input, size);
7635  } else {
7636  av_log(c->fc, AV_LOG_ERROR, "invalid encryption scheme\n");
7637  return AVERROR_INVALIDDATA;
7638  }
7639 }
7640 
7642 {
7643  int current = frag_index->current;
7644 
7645  if (!frag_index->nb_items)
7646  return NULL;
7647 
7648  // Check frag_index->current is the right one for pkt. It can out of sync.
7649  if (current >= 0 && current < frag_index->nb_items) {
7650  if (frag_index->item[current].moof_offset < pkt->pos &&
7651  (current + 1 == frag_index->nb_items ||
7652  frag_index->item[current + 1].moof_offset > pkt->pos))
7653  return get_frag_stream_info(frag_index, current, id);
7654  }
7655 
7656 
7657  for (int i = 0; i < frag_index->nb_items; i++) {
7658  if (frag_index->item[i].moof_offset > pkt->pos)
7659  break;
7660  current = i;
7661  }
7662  frag_index->current = current;
7663  return get_frag_stream_info(frag_index, current, id);
7664 }
7665 
7666 static int cenc_filter(MOVContext *mov, AVStream* st, MOVStreamContext *sc, AVPacket *pkt, int current_index)
7667 {
7668  MOVFragmentStreamInfo *frag_stream_info;
7669  MOVEncryptionIndex *encryption_index;
7670  AVEncryptionInfo *encrypted_sample;
7671  int encrypted_index, ret;
7672 
7673  frag_stream_info = get_frag_stream_info_from_pkt(&mov->frag_index, pkt, sc->id);
7674  encrypted_index = current_index;
7675  encryption_index = NULL;
7676  if (frag_stream_info) {
7677  // Note this only supports encryption info in the first sample descriptor.
7678  if (frag_stream_info->stsd_id == 1) {
7679  if (frag_stream_info->encryption_index) {
7680  encrypted_index = current_index - frag_stream_info->index_base;
7681  encryption_index = frag_stream_info->encryption_index;
7682  } else {
7683  encryption_index = sc->cenc.encryption_index;
7684  }
7685  }
7686  } else {
7687  encryption_index = sc->cenc.encryption_index;
7688  }
7689 
7690  if (encryption_index) {
7691  if (encryption_index->auxiliary_info_sample_count &&
7692  !encryption_index->nb_encrypted_samples) {
7693  av_log(mov->fc, AV_LOG_ERROR, "saiz atom found without saio\n");
7694  return AVERROR_INVALIDDATA;
7695  }
7696  if (encryption_index->auxiliary_offsets_count &&
7697  !encryption_index->nb_encrypted_samples) {
7698  av_log(mov->fc, AV_LOG_ERROR, "saio atom found without saiz\n");
7699  return AVERROR_INVALIDDATA;
7700  }
7701 
7702  if (!encryption_index->nb_encrypted_samples) {
7703  // Full-sample encryption with default settings.
7704  encrypted_sample = sc->cenc.default_encrypted_sample;
7705  } else if (encrypted_index >= 0 && encrypted_index < encryption_index->nb_encrypted_samples) {
7706  // Per-sample setting override.
7707  encrypted_sample = encryption_index->encrypted_samples[encrypted_index];
7708  if (!encrypted_sample)
7709  encrypted_sample = sc->cenc.default_encrypted_sample;
7710  } else {
7711  av_log(mov->fc, AV_LOG_ERROR, "Incorrect number of samples in encryption info\n");
7712  return AVERROR_INVALIDDATA;
7713  }
7714 
7715  if (mov->decryption_key) {
7716  return cenc_decrypt(mov, sc, encrypted_sample, pkt->data, pkt->size);
7717  } else {
7718  size_t size;
7719  uint8_t *side_data = av_encryption_info_add_side_data(encrypted_sample, &size);
7720  if (!side_data)
7721  return AVERROR(ENOMEM);
7723  if (ret < 0)
7724  av_free(side_data);
7725  return ret;
7726  }
7727  }
7728 
7729  return 0;
7730 }
7731 
7733 {
7734  const int OPUS_SEEK_PREROLL_MS = 80;
7735  int ret;
7736  AVStream *st;
7737  size_t size;
7738  uint16_t pre_skip;
7739 
7740  if (c->fc->nb_streams < 1)
7741  return 0;
7742  st = c->fc->streams[c->fc->nb_streams-1];
7743 
7744  if ((uint64_t)atom.size > (1<<30) || atom.size < 11)
7745  return AVERROR_INVALIDDATA;
7746 
7747  /* Check OpusSpecificBox version. */
7748  if (avio_r8(pb) != 0) {
7749  av_log(c->fc, AV_LOG_ERROR, "unsupported OpusSpecificBox version\n");
7750  return AVERROR_INVALIDDATA;
7751  }
7752 
7753  /* OpusSpecificBox size plus magic for Ogg OpusHead header. */
7754  size = atom.size + 8;
7755 
7756  if ((ret = ff_alloc_extradata(st->codecpar, size)) < 0)
7757  return ret;
7758 
7759  AV_WL32(st->codecpar->extradata, MKTAG('O','p','u','s'));
7760  AV_WL32(st->codecpar->extradata + 4, MKTAG('H','e','a','d'));
7761  AV_WB8(st->codecpar->extradata + 8, 1); /* OpusHead version */
7762  avio_read(pb, st->codecpar->extradata + 9, size - 9);
7763 
7764  /* OpusSpecificBox is stored in big-endian, but OpusHead is
7765  little-endian; aside from the preceeding magic and version they're
7766  otherwise currently identical. Data after output gain at offset 16
7767  doesn't need to be bytewapped. */
7768  pre_skip = AV_RB16(st->codecpar->extradata + 10);
7769  AV_WL16(st->codecpar->extradata + 10, pre_skip);
7770  AV_WL32(st->codecpar->extradata + 12, AV_RB32(st->codecpar->extradata + 12));
7771  AV_WL16(st->codecpar->extradata + 16, AV_RB16(st->codecpar->extradata + 16));
7772 
7773  st->codecpar->initial_padding = pre_skip;
7775  (AVRational){1, 1000},
7776  (AVRational){1, 48000});
7777 
7778  return 0;
7779 }
7780 
7782 {
7783  AVStream *st;
7784  unsigned format_info;
7785  int channel_assignment, channel_assignment1, channel_assignment2;
7786  int ratebits;
7787  uint64_t chmask;
7788 
7789  if (c->fc->nb_streams < 1)
7790  return 0;
7791  st = c->fc->streams[c->fc->nb_streams-1];
7792 
7793  if (atom.size < 10)
7794  return AVERROR_INVALIDDATA;
7795 
7796  format_info = avio_rb32(pb);
7797 
7798  ratebits = (format_info >> 28) & 0xF;
7799  channel_assignment1 = (format_info >> 15) & 0x1F;
7800  channel_assignment2 = format_info & 0x1FFF;
7801  if (channel_assignment2)
7802  channel_assignment = channel_assignment2;
7803  else
7804  channel_assignment = channel_assignment1;
7805 
7806  st->codecpar->frame_size = 40 << (ratebits & 0x7);
7807  st->codecpar->sample_rate = mlp_samplerate(ratebits);
7808 
7810  chmask = truehd_layout(channel_assignment);
7812 
7813  return 0;
7814 }
7815 
7817 {
7818  AVStream *st;
7819  uint8_t buf[ISOM_DVCC_DVVC_SIZE];
7820  int ret;
7821  int64_t read_size = atom.size;
7822 
7823  if (c->fc->nb_streams < 1)
7824  return 0;
7825  st = c->fc->streams[c->fc->nb_streams-1];
7826 
7827  // At most 24 bytes
7828  read_size = FFMIN(read_size, ISOM_DVCC_DVVC_SIZE);
7829 
7830  if ((ret = ffio_read_size(pb, buf, read_size)) < 0)
7831  return ret;
7832 
7833  return ff_isom_parse_dvcc_dvvc(c->fc, st, buf, read_size);
7834 }
7835 
7837 {
7838  AVFormatContext *ctx = c->fc;
7839  AVStream *st = NULL;
7840  AVBPrint scheme_buf, value_buf;
7841  int64_t scheme_str_len = 0, value_str_len = 0;
7842  int version, flags, ret = AVERROR_BUG;
7843  int64_t size = atom.size;
7844 
7845  if (atom.size < 6)
7846  // 4 bytes for version + flags, 2x 1 byte for null
7847  return AVERROR_INVALIDDATA;
7848 
7849  if (c->fc->nb_streams < 1)
7850  return 0;
7851  st = c->fc->streams[c->fc->nb_streams-1];
7852 
7853  version = avio_r8(pb);
7854  flags = avio_rb24(pb);
7855  size -= 4;
7856 
7857  if (version != 0 || flags != 0) {
7859  "Unsupported 'kind' box with version %d, flags: %x",
7860  version, flags);
7861  return AVERROR_INVALIDDATA;
7862  }
7863 
7864  av_bprint_init(&scheme_buf, 0, AV_BPRINT_SIZE_UNLIMITED);
7865  av_bprint_init(&value_buf, 0, AV_BPRINT_SIZE_UNLIMITED);
7866 
7867  if ((scheme_str_len = ff_read_string_to_bprint_overwrite(pb, &scheme_buf,
7868  size)) < 0) {
7869  ret = scheme_str_len;
7870  goto cleanup;
7871  }
7872 
7873  if (scheme_str_len + 1 >= size) {
7874  // we need to have another string, even if nullptr.
7875  // we check with + 1 since we expect that if size was not hit,
7876  // an additional null was read.
7878  goto cleanup;
7879  }
7880 
7881  size -= scheme_str_len + 1;
7882 
7883  if ((value_str_len = ff_read_string_to_bprint_overwrite(pb, &value_buf,
7884  size)) < 0) {
7885  ret = value_str_len;
7886  goto cleanup;
7887  }
7888 
7889  if (value_str_len == size) {
7890  // in case of no trailing null, box is not valid.
7892  goto cleanup;
7893  }
7894 
7896  "%s stream %d KindBox(scheme: %s, value: %s)\n",
7898  st->index,
7899  scheme_buf.str, value_buf.str);
7900 
7901  for (int i = 0; ff_mov_track_kind_table[i].scheme_uri; i++) {
7903  if (!av_strstart(scheme_buf.str, map.scheme_uri, NULL))
7904  continue;
7905 
7906  for (int j = 0; map.value_maps[j].disposition; j++) {
7907  const struct MP4TrackKindValueMapping value_map = map.value_maps[j];
7908  if (!av_strstart(value_buf.str, value_map.value, NULL))
7909  continue;
7910 
7911  st->disposition |= value_map.disposition;
7912  }
7913  }
7914 
7915  ret = 0;
7916 
7917 cleanup:
7918 
7919  av_bprint_finalize(&scheme_buf, NULL);
7920  av_bprint_finalize(&value_buf, NULL);
7921 
7922  return ret;
7923 }
7924 
7926 {
7927  AVStream *st;
7928  int i, version, type;
7929  int ambisonic_order, channel_order, normalization, channel_count;
7930 
7931  if (c->fc->nb_streams < 1)
7932  return 0;
7933 
7934  st = c->fc->streams[c->fc->nb_streams - 1];
7935 
7936  if (atom.size < 16) {
7937  av_log(c->fc, AV_LOG_ERROR, "SA3D audio box too small\n");
7938  return AVERROR_INVALIDDATA;
7939  }
7940 
7941  version = avio_r8(pb);
7942  if (version) {
7943  av_log(c->fc, AV_LOG_WARNING, "Unsupported SA3D box version %d\n", version);
7944  return 0;
7945  }
7946 
7947  type = avio_r8(pb);
7948  if (type) {
7949  av_log(c->fc, AV_LOG_WARNING,
7950  "Unsupported ambisonic type %d\n", type);
7951  return 0;
7952  }
7953 
7954  ambisonic_order = avio_rb32(pb);
7955 
7956  channel_order = avio_r8(pb);
7957  if (channel_order) {
7958  av_log(c->fc, AV_LOG_WARNING,
7959  "Unsupported channel_order %d\n", channel_order);
7960  return 0;
7961  }
7962 
7963  normalization = avio_r8(pb);
7964  if (normalization) {
7965  av_log(c->fc, AV_LOG_WARNING,
7966  "Unsupported normalization %d\n", normalization);
7967  return 0;
7968  }
7969 
7970  channel_count = avio_rb32(pb);
7971  if (ambisonic_order < 0 || channel_count != (ambisonic_order + 1LL) * (ambisonic_order + 1LL)) {
7972  av_log(c->fc, AV_LOG_ERROR,
7973  "Invalid number of channels (%d / %d)\n",
7974  channel_count, ambisonic_order);
7975  return 0;
7976  }
7977 
7978  for (i = 0; i < channel_count; i++) {
7979  if (i != avio_rb32(pb)) {
7980  av_log(c->fc, AV_LOG_WARNING,
7981  "Ambisonic channel reordering is not supported\n");
7982  return 0;
7983  }
7984  }
7985 
7988  st->codecpar->ch_layout.nb_channels = channel_count;
7989 
7990  return 0;
7991 }
7992 
7994 {
7995  AVStream *st;
7996  int version;
7997 
7998  if (c->fc->nb_streams < 1)
7999  return 0;
8000 
8001  st = c->fc->streams[c->fc->nb_streams - 1];
8002 
8003  if (atom.size < 5) {
8004  av_log(c->fc, AV_LOG_ERROR, "Empty SAND audio box\n");
8005  return AVERROR_INVALIDDATA;
8006  }
8007 
8008  version = avio_r8(pb);
8009  if (version) {
8010  av_log(c->fc, AV_LOG_WARNING, "Unsupported SAND box version %d\n", version);
8011  return 0;
8012  }
8013 
8015 
8016  return 0;
8017 }
8018 
8019 static int rb_size(AVIOContext *pb, uint64_t* value, int size)
8020 {
8021  if (size == 0)
8022  *value = 0;
8023  else if (size == 1)
8024  *value = avio_r8(pb);
8025  else if (size == 2)
8026  *value = avio_rb16(pb);
8027  else if (size == 4)
8028  *value = avio_rb32(pb);
8029  else if (size == 8)
8030  *value = avio_rb64(pb);
8031  else
8032  return -1;
8033  return size;
8034 }
8035 
8037 {
8038  avio_rb32(pb); // version & flags.
8039  c->primary_item_id = avio_rb16(pb);
8040  av_log(c->fc, AV_LOG_TRACE, "pitm: primary_item_id %d\n", c->primary_item_id);
8041  return atom.size;
8042 }
8043 
8045 {
8046  c->idat_offset = avio_tell(pb);
8047  return 0;
8048 }
8049 
8051 {
8052  HEIFItem *heif_item;
8053  int version, offset_size, length_size, base_offset_size, index_size;
8054  int item_count, extent_count;
8055  int64_t base_offset, extent_offset, extent_length;
8056  uint8_t value;
8057 
8058  if (c->found_iloc) {
8059  av_log(c->fc, AV_LOG_INFO, "Duplicate iloc box found\n");
8060  return 0;
8061  }
8062 
8063  version = avio_r8(pb);
8064  avio_rb24(pb); // flags.
8065 
8066  value = avio_r8(pb);
8067  offset_size = (value >> 4) & 0xF;
8068  length_size = value & 0xF;
8069  value = avio_r8(pb);
8070  base_offset_size = (value >> 4) & 0xF;
8071  index_size = !version ? 0 : (value & 0xF);
8072  if (index_size) {
8073  avpriv_report_missing_feature(c->fc, "iloc: index_size != 0");
8074  return AVERROR_PATCHWELCOME;
8075  }
8076  item_count = (version < 2) ? avio_rb16(pb) : avio_rb32(pb);
8077 
8078  heif_item = av_realloc_array(c->heif_item, FFMAX(item_count, c->nb_heif_item), sizeof(*c->heif_item));
8079  if (!heif_item)
8080  return AVERROR(ENOMEM);
8081  c->heif_item = heif_item;
8082  if (item_count > c->nb_heif_item)
8083  memset(c->heif_item + c->nb_heif_item, 0,
8084  sizeof(*c->heif_item) * (item_count - c->nb_heif_item));
8085  c->nb_heif_item = FFMAX(c->nb_heif_item, item_count);
8086 
8087  av_log(c->fc, AV_LOG_TRACE, "iloc: item_count %d\n", item_count);
8088  for (int i = 0; i < item_count; i++) {
8089  int item_id = (version < 2) ? avio_rb16(pb) : avio_rb32(pb);
8090  int offset_type = (version > 0) ? avio_rb16(pb) & 0xf : 0;
8091 
8092  if (avio_feof(pb))
8093  return AVERROR_INVALIDDATA;
8094  if (offset_type > 1) {
8095  avpriv_report_missing_feature(c->fc, "iloc offset type %d", offset_type);
8096  return AVERROR_PATCHWELCOME;
8097  }
8098  c->heif_item[i].item_id = item_id;
8099 
8100  avio_rb16(pb); // data_reference_index.
8101  if (rb_size(pb, &base_offset, base_offset_size) < 0)
8102  return AVERROR_INVALIDDATA;
8103  extent_count = avio_rb16(pb);
8104  if (extent_count > 1) {
8105  // For still AVIF images, we only support one extent item.
8106  avpriv_report_missing_feature(c->fc, "iloc: extent_count > 1");
8107  return AVERROR_PATCHWELCOME;
8108  }
8109  for (int j = 0; j < extent_count; j++) {
8110  if (rb_size(pb, &extent_offset, offset_size) < 0 ||
8111  rb_size(pb, &extent_length, length_size) < 0)
8112  return AVERROR_INVALIDDATA;
8113  if (offset_type == 1)
8114  c->heif_item[i].is_idat_relative = 1;
8115  c->heif_item[i].extent_length = extent_length;
8116  c->heif_item[i].extent_offset = base_offset + extent_offset;
8117  av_log(c->fc, AV_LOG_TRACE, "iloc: item_idx %d, offset_type %d, "
8118  "extent_offset %"PRId64", extent_length %"PRId64"\n",
8119  i, offset_type, c->heif_item[i].extent_offset, c->heif_item[i].extent_length);
8120  }
8121  }
8122 
8123  c->found_iloc = 1;
8124  return atom.size;
8125 }
8126 
8127 static int mov_read_infe(MOVContext *c, AVIOContext *pb, MOVAtom atom, int idx)
8128 {
8129  AVBPrint item_name;
8130  int64_t size = atom.size;
8131  uint32_t item_type;
8132  int item_id;
8133  int version, ret;
8134 
8135  version = avio_r8(pb);
8136  avio_rb24(pb); // flags.
8137  size -= 4;
8138 
8139  if (version < 2) {
8140  avpriv_report_missing_feature(c->fc, "infe version < 2");
8141  return 1;
8142  }
8143 
8144  item_id = version > 2 ? avio_rb32(pb) : avio_rb16(pb);
8145  avio_rb16(pb); // item_protection_index
8146  item_type = avio_rl32(pb);
8147  size -= 8;
8148 
8151  if (ret < 0) {
8153  return ret;
8154  }
8155 
8156  av_log(c->fc, AV_LOG_TRACE, "infe: item_id %d, item_type %s, item_name %s\n",
8157  item_id, av_fourcc2str(item_type), item_name.str);
8158 
8159  size -= ret + 1;
8160  if (size > 0)
8161  avio_skip(pb, size);
8162 
8163  if (ret)
8164  av_bprint_finalize(&item_name, &c->heif_item[idx].name);
8165  c->heif_item[idx].item_id = item_id;
8166  c->heif_item[idx].type = item_type;
8167 
8168  switch (item_type) {
8169  case MKTAG('a','v','0','1'):
8170  case MKTAG('h','v','c','1'):
8171  ret = heif_add_stream(c, &c->heif_item[idx]);
8172  if (ret < 0)
8173  return ret;
8174  break;
8175  }
8176 
8177  return 0;
8178 }
8179 
8181 {
8182  HEIFItem *heif_item;
8183  int entry_count;
8184  int version, ret;
8185 
8186  if (c->found_iinf) {
8187  av_log(c->fc, AV_LOG_WARNING, "Duplicate iinf box found\n");
8188  return 0;
8189  }
8190 
8191  version = avio_r8(pb);
8192  avio_rb24(pb); // flags.
8193  entry_count = version ? avio_rb32(pb) : avio_rb16(pb);
8194 
8195  heif_item = av_realloc_array(c->heif_item, FFMAX(entry_count, c->nb_heif_item), sizeof(*c->heif_item));
8196  if (!heif_item)
8197  return AVERROR(ENOMEM);
8198  c->heif_item = heif_item;
8199  if (entry_count > c->nb_heif_item)
8200  memset(c->heif_item + c->nb_heif_item, 0,
8201  sizeof(*c->heif_item) * (entry_count - c->nb_heif_item));
8202  c->nb_heif_item = FFMAX(c->nb_heif_item, entry_count);
8203 
8204  for (int i = 0; i < entry_count; i++) {
8205  MOVAtom infe;
8206 
8207  infe.size = avio_rb32(pb) - 8;
8208  infe.type = avio_rl32(pb);
8209  ret = mov_read_infe(c, pb, infe, i);
8210  if (ret < 0)
8211  return ret;
8212  if (ret)
8213  return 0;
8214  }
8215 
8216  c->found_iinf = 1;
8217  return 0;
8218 }
8219 
8221 {
8222  HEIFItem *item = NULL;
8223  HEIFGrid *grid;
8224  int entries, i;
8225  int from_item_id = version ? avio_rb32(pb) : avio_rb16(pb);
8226 
8227  for (int i = 0; i < c->nb_heif_grid; i++) {
8228  if (c->heif_grid[i].item->item_id == from_item_id) {
8229  av_log(c->fc, AV_LOG_ERROR, "More than one 'dimg' box "
8230  "referencing the same Derived Image item\n");
8231  return AVERROR_INVALIDDATA;
8232  }
8233  }
8234  for (int i = 0; i < c->nb_heif_item; i++) {
8235  if (c->heif_item[i].item_id != from_item_id)
8236  continue;
8237  item = &c->heif_item[i];
8238 
8239  switch (item->type) {
8240  case MKTAG('g','r','i','d'):
8241  case MKTAG('i','o','v','l'):
8242  break;
8243  default:
8244  avpriv_report_missing_feature(c->fc, "Derived Image item of type %s",
8245  av_fourcc2str(item->type));
8246  return 0;
8247  }
8248  break;
8249  }
8250  if (!item) {
8251  av_log(c->fc, AV_LOG_ERROR, "Missing grid information\n");
8252  return AVERROR_INVALIDDATA;
8253  }
8254 
8255  grid = av_realloc_array(c->heif_grid, c->nb_heif_grid + 1U,
8256  sizeof(*c->heif_grid));
8257  if (!grid)
8258  return AVERROR(ENOMEM);
8259  c->heif_grid = grid;
8260  grid = &grid[c->nb_heif_grid++];
8261 
8262  entries = avio_rb16(pb);
8263  grid->tile_id_list = av_malloc_array(entries, sizeof(*grid->tile_id_list));
8264  grid->tile_item_list = av_calloc(entries, sizeof(*grid->tile_item_list));
8265  if (!grid->tile_id_list || !grid->tile_item_list)
8266  return AVERROR(ENOMEM);
8267  /* 'to' item ids */
8268  for (i = 0; i < entries; i++)
8269  grid->tile_id_list[i] = version ? avio_rb32(pb) : avio_rb16(pb);
8270  grid->nb_tiles = entries;
8271  grid->item = item;
8272 
8273  av_log(c->fc, AV_LOG_TRACE, "dimg: from_item_id %d, entries %d\n",
8274  from_item_id, entries);
8275 
8276  return 0;
8277 }
8278 
8280 {
8281  int entries;
8282  int to_item_id, from_item_id = version ? avio_rb32(pb) : avio_rb16(pb);
8283 
8284  entries = avio_rb16(pb);
8285  if (entries > 1) {
8286  avpriv_request_sample(c->fc, "thmb in iref referencing several items");
8287  return AVERROR_PATCHWELCOME;
8288  }
8289  /* 'to' item ids */
8290  to_item_id = version ? avio_rb32(pb) : avio_rb16(pb);
8291 
8292  if (to_item_id != c->primary_item_id)
8293  return 0;
8294 
8295  c->thmb_item_id = from_item_id;
8296 
8297  av_log(c->fc, AV_LOG_TRACE, "thmb: from_item_id %d, entries %d\n",
8298  from_item_id, entries);
8299 
8300  return 0;
8301 }
8302 
8304 {
8305  int version = avio_r8(pb);
8306  avio_rb24(pb); // flags
8307  atom.size -= 4;
8308 
8309  if (version > 1) {
8310  av_log(c->fc, AV_LOG_WARNING, "Unknown iref box version %d\n", version);
8311  return 0;
8312  }
8313 
8314  while (atom.size) {
8315  uint32_t type, size = avio_rb32(pb);
8316  int64_t next = avio_tell(pb);
8317 
8318  if (size < 14 || next < 0 || next > INT64_MAX - size)
8319  return AVERROR_INVALIDDATA;
8320 
8321  next += size - 4;
8322  type = avio_rl32(pb);
8323  switch (type) {
8324  case MKTAG('d','i','m','g'):
8326  break;
8327  case MKTAG('t','h','m','b'):
8329  break;
8330  default:
8331  av_log(c->fc, AV_LOG_DEBUG, "Unknown iref type %s size %"PRIu32"\n",
8332  av_fourcc2str(type), size);
8333  }
8334 
8335  atom.size -= size;
8336  avio_seek(pb, next, SEEK_SET);
8337  }
8338  return 0;
8339 }
8340 
8342 {
8343  uint32_t width, height;
8344 
8345  avio_r8(pb); /* version */
8346  avio_rb24(pb); /* flags */
8347  width = avio_rb32(pb);
8348  height = avio_rb32(pb);
8349 
8350  av_log(c->fc, AV_LOG_TRACE, "ispe: item_id %d, width %u, height %u\n",
8351  c->cur_item_id, width, height);
8352 
8353  for (int i = 0; i < c->nb_heif_item; i++) {
8354  if (c->heif_item[i].item_id == c->cur_item_id) {
8355  c->heif_item[i].width = width;
8356  c->heif_item[i].height = height;
8357  break;
8358  }
8359  }
8360 
8361  return 0;
8362 }
8363 
8365 {
8366  typedef struct MOVAtoms {
8367  FFIOContext b;
8368  uint32_t type;
8369  int64_t size;
8370  uint8_t *data;
8371  } MOVAtoms;
8372  MOVAtoms *atoms = NULL;
8373  MOVAtom a;
8374  unsigned count;
8375  int nb_atoms = 0;
8376  int version, flags;
8377  int ret;
8378 
8379  a.size = avio_rb32(pb);
8380  a.type = avio_rl32(pb);
8381 
8382  if (a.size < 8 || a.type != MKTAG('i','p','c','o'))
8383  return AVERROR_INVALIDDATA;
8384 
8385  a.size -= 8;
8386  while (a.size >= 8) {
8387  MOVAtoms *ref = av_dynarray2_add((void**)&atoms, &nb_atoms, sizeof(MOVAtoms), NULL);
8388  if (!ref) {
8389  ret = AVERROR(ENOMEM);
8390  goto fail;
8391  }
8392  ref->data = NULL;
8393  ref->size = avio_rb32(pb);
8394  ref->type = avio_rl32(pb);
8395  if (ref->size > a.size || ref->size < 8)
8396  break;
8397  ref->data = av_malloc(ref->size);
8398  if (!ref->data) {
8400  goto fail;
8401  }
8402  av_log(c->fc, AV_LOG_TRACE, "ipco: index %d, box type %s\n", nb_atoms, av_fourcc2str(ref->type));
8403  avio_seek(pb, -8, SEEK_CUR);
8404  if (avio_read(pb, ref->data, ref->size) != ref->size) {
8406  goto fail;
8407  }
8408  ffio_init_read_context(&ref->b, ref->data, ref->size);
8409  a.size -= ref->size;
8410  }
8411 
8412  if (a.size) {
8414  goto fail;
8415  }
8416 
8417  a.size = avio_rb32(pb);
8418  a.type = avio_rl32(pb);
8419 
8420  if (a.size < 8 || a.type != MKTAG('i','p','m','a')) {
8422  goto fail;
8423  }
8424 
8425  version = avio_r8(pb);
8426  flags = avio_rb24(pb);
8427  count = avio_rb32(pb);
8428 
8429  for (int i = 0; i < count; i++) {
8430  int item_id = version ? avio_rb32(pb) : avio_rb16(pb);
8431  int assoc_count = avio_r8(pb);
8432 
8433  for (int j = 0; j < assoc_count; j++) {
8434  MOVAtoms *ref;
8435  int index = avio_r8(pb) & 0x7f;
8436  if (flags & 1) {
8437  index <<= 8;
8438  index |= avio_r8(pb);
8439  }
8440  if (index > nb_atoms || index <= 0) {
8442  goto fail;
8443  }
8444  ref = &atoms[--index];
8445 
8446  av_log(c->fc, AV_LOG_TRACE, "ipma: property_index %d, item_id %d, item_type %s\n",
8447  index + 1, item_id, av_fourcc2str(ref->type));
8448 
8449  c->cur_item_id = item_id;
8450 
8451  ret = mov_read_default(c, &ref->b.pub,
8452  (MOVAtom) { .size = ref->size,
8453  .type = MKTAG('i','p','c','o') });
8454  if (ret < 0)
8455  goto fail;
8456  ffio_init_read_context(&ref->b, ref->data, ref->size);
8457  }
8458  }
8459 
8460  ret = 0;
8461 fail:
8462  c->cur_item_id = -1;
8463  for (int i = 0; i < nb_atoms; i++)
8464  av_free(atoms[i].data);
8465  av_free(atoms);
8466 
8467  return ret;
8468 }
8469 
8471 { MKTAG('A','C','L','R'), mov_read_aclr },
8472 { MKTAG('A','P','R','G'), mov_read_avid },
8473 { MKTAG('A','A','L','P'), mov_read_avid },
8474 { MKTAG('A','R','E','S'), mov_read_ares },
8475 { MKTAG('a','v','s','s'), mov_read_avss },
8476 { MKTAG('a','v','1','C'), mov_read_glbl },
8477 { MKTAG('c','h','p','l'), mov_read_chpl },
8478 { MKTAG('c','o','6','4'), mov_read_stco },
8479 { MKTAG('c','o','l','r'), mov_read_colr },
8480 { MKTAG('c','t','t','s'), mov_read_ctts }, /* composition time to sample */
8481 { MKTAG('d','i','n','f'), mov_read_default },
8482 { MKTAG('D','p','x','E'), mov_read_dpxe },
8483 { MKTAG('d','r','e','f'), mov_read_dref },
8484 { MKTAG('e','d','t','s'), mov_read_default },
8485 { MKTAG('e','l','s','t'), mov_read_elst },
8486 { MKTAG('e','n','d','a'), mov_read_enda },
8487 { MKTAG('f','i','e','l'), mov_read_fiel },
8488 { MKTAG('a','d','r','m'), mov_read_adrm },
8489 { MKTAG('f','t','y','p'), mov_read_ftyp },
8490 { MKTAG('g','l','b','l'), mov_read_glbl },
8491 { MKTAG('h','d','l','r'), mov_read_hdlr },
8492 { MKTAG('i','l','s','t'), mov_read_ilst },
8493 { MKTAG('j','p','2','h'), mov_read_jp2h },
8494 { MKTAG('m','d','a','t'), mov_read_mdat },
8495 { MKTAG('m','d','h','d'), mov_read_mdhd },
8496 { MKTAG('m','d','i','a'), mov_read_default },
8497 { MKTAG('m','e','t','a'), mov_read_meta },
8498 { MKTAG('m','i','n','f'), mov_read_default },
8499 { MKTAG('m','o','o','f'), mov_read_moof },
8500 { MKTAG('m','o','o','v'), mov_read_moov },
8501 { MKTAG('m','v','e','x'), mov_read_default },
8502 { MKTAG('m','v','h','d'), mov_read_mvhd },
8503 { MKTAG('S','M','I',' '), mov_read_svq3 },
8504 { MKTAG('a','l','a','c'), mov_read_alac }, /* alac specific atom */
8505 { MKTAG('a','v','c','C'), mov_read_glbl },
8506 { MKTAG('p','a','s','p'), mov_read_pasp },
8507 { MKTAG('s','i','d','x'), mov_read_sidx },
8508 { MKTAG('s','t','b','l'), mov_read_default },
8509 { MKTAG('s','t','c','o'), mov_read_stco },
8510 { MKTAG('s','t','p','s'), mov_read_stps },
8511 { MKTAG('s','t','r','f'), mov_read_strf },
8512 { MKTAG('s','t','s','c'), mov_read_stsc },
8513 { MKTAG('s','t','s','d'), mov_read_stsd }, /* sample description */
8514 { MKTAG('s','t','s','s'), mov_read_stss }, /* sync sample */
8515 { MKTAG('s','t','s','z'), mov_read_stsz }, /* sample size */
8516 { MKTAG('s','t','t','s'), mov_read_stts },
8517 { MKTAG('s','t','z','2'), mov_read_stsz }, /* compact sample size */
8518 { MKTAG('s','d','t','p'), mov_read_sdtp }, /* independent and disposable samples */
8519 { MKTAG('t','k','h','d'), mov_read_tkhd }, /* track header */
8520 { MKTAG('t','f','d','t'), mov_read_tfdt },
8521 { MKTAG('t','f','h','d'), mov_read_tfhd }, /* track fragment header */
8522 { MKTAG('t','r','a','k'), mov_read_trak },
8523 { MKTAG('t','r','a','f'), mov_read_default },
8524 { MKTAG('t','r','e','f'), mov_read_default },
8525 { MKTAG('t','m','c','d'), mov_read_tmcd },
8526 { MKTAG('c','h','a','p'), mov_read_chap },
8527 { MKTAG('t','r','e','x'), mov_read_trex },
8528 { MKTAG('t','r','u','n'), mov_read_trun },
8529 { MKTAG('u','d','t','a'), mov_read_default },
8530 { MKTAG('w','a','v','e'), mov_read_wave },
8531 { MKTAG('e','s','d','s'), mov_read_esds },
8532 { MKTAG('d','a','c','3'), mov_read_dac3 }, /* AC-3 info */
8533 { MKTAG('d','e','c','3'), mov_read_dec3 }, /* EAC-3 info */
8534 { MKTAG('d','d','t','s'), mov_read_ddts }, /* DTS audio descriptor */
8535 { MKTAG('w','i','d','e'), mov_read_wide }, /* place holder */
8536 { MKTAG('w','f','e','x'), mov_read_wfex },
8537 { MKTAG('c','m','o','v'), mov_read_cmov },
8538 { MKTAG('c','h','a','n'), mov_read_chan }, /* channel layout from quicktime */
8539 { MKTAG('c','h','n','l'), mov_read_chnl }, /* channel layout from ISO-14496-12 */
8540 { MKTAG('d','v','c','1'), mov_read_dvc1 },
8541 { MKTAG('s','g','p','d'), mov_read_sgpd },
8542 { MKTAG('s','b','g','p'), mov_read_sbgp },
8543 { MKTAG('h','v','c','C'), mov_read_glbl },
8544 { MKTAG('v','v','c','C'), mov_read_glbl },
8545 { MKTAG('u','u','i','d'), mov_read_uuid },
8546 { MKTAG('C','i','n', 0x8e), mov_read_targa_y216 },
8547 { MKTAG('f','r','e','e'), mov_read_free },
8548 { MKTAG('-','-','-','-'), mov_read_custom },
8549 { MKTAG('s','i','n','f'), mov_read_default },
8550 { MKTAG('f','r','m','a'), mov_read_frma },
8551 { MKTAG('s','e','n','c'), mov_read_senc },
8552 { MKTAG('s','a','i','z'), mov_read_saiz },
8553 { MKTAG('s','a','i','o'), mov_read_saio },
8554 { MKTAG('p','s','s','h'), mov_read_pssh },
8555 { MKTAG('s','c','h','m'), mov_read_schm },
8556 { MKTAG('s','c','h','i'), mov_read_default },
8557 { MKTAG('t','e','n','c'), mov_read_tenc },
8558 { MKTAG('d','f','L','a'), mov_read_dfla },
8559 { MKTAG('s','t','3','d'), mov_read_st3d }, /* stereoscopic 3D video box */
8560 { MKTAG('s','v','3','d'), mov_read_sv3d }, /* spherical video box */
8561 { MKTAG('d','O','p','s'), mov_read_dops },
8562 { MKTAG('d','m','l','p'), mov_read_dmlp },
8563 { MKTAG('S','m','D','m'), mov_read_smdm },
8564 { MKTAG('C','o','L','L'), mov_read_coll },
8565 { MKTAG('v','p','c','C'), mov_read_vpcc },
8566 { MKTAG('m','d','c','v'), mov_read_mdcv },
8567 { MKTAG('c','l','l','i'), mov_read_clli },
8568 { MKTAG('d','v','c','C'), mov_read_dvcc_dvvc },
8569 { MKTAG('d','v','v','C'), mov_read_dvcc_dvvc },
8570 { MKTAG('d','v','w','C'), mov_read_dvcc_dvvc },
8571 { MKTAG('k','i','n','d'), mov_read_kind },
8572 { MKTAG('S','A','3','D'), mov_read_SA3D }, /* ambisonic audio box */
8573 { MKTAG('S','A','N','D'), mov_read_SAND }, /* non diegetic audio box */
8574 { MKTAG('i','l','o','c'), mov_read_iloc },
8575 { MKTAG('p','c','m','C'), mov_read_pcmc }, /* PCM configuration box */
8576 { MKTAG('p','i','t','m'), mov_read_pitm },
8577 { MKTAG('e','v','c','C'), mov_read_glbl },
8578 { MKTAG('i','d','a','t'), mov_read_idat },
8579 { MKTAG('i','r','e','f'), mov_read_iref },
8580 { MKTAG('i','s','p','e'), mov_read_ispe },
8581 { MKTAG('i','p','r','p'), mov_read_iprp },
8582 { MKTAG('i','i','n','f'), mov_read_iinf },
8583 { MKTAG('a','m','v','e'), mov_read_amve }, /* ambient viewing environment box */
8584 #if CONFIG_IAMFDEC
8585 { MKTAG('i','a','c','b'), mov_read_iacb },
8586 #endif
8587 { 0, NULL }
8588 };
8589 
8591 {
8592  int64_t total_size = 0;
8593  MOVAtom a;
8594  int i;
8595 
8596  if (c->atom_depth > 10) {
8597  av_log(c->fc, AV_LOG_ERROR, "Atoms too deeply nested\n");
8598  return AVERROR_INVALIDDATA;
8599  }
8600  c->atom_depth ++;
8601 
8602  if (atom.size < 0)
8603  atom.size = INT64_MAX;
8604  while (total_size <= atom.size - 8) {
8606  a.size = avio_rb32(pb);
8607  a.type = avio_rl32(pb);
8608  if (avio_feof(pb))
8609  break;
8610  if (((a.type == MKTAG('f','r','e','e') && c->moov_retry) ||
8611  a.type == MKTAG('h','o','o','v')) &&
8612  a.size >= 8 &&
8613  c->fc->strict_std_compliance < FF_COMPLIANCE_STRICT) {
8614  uint32_t type;
8615  avio_skip(pb, 4);
8616  type = avio_rl32(pb);
8617  if (avio_feof(pb))
8618  break;
8619  avio_seek(pb, -8, SEEK_CUR);
8620  if (type == MKTAG('m','v','h','d') ||
8621  type == MKTAG('c','m','o','v')) {
8622  av_log(c->fc, AV_LOG_ERROR, "Detected moov in a free or hoov atom.\n");
8623  a.type = MKTAG('m','o','o','v');
8624  }
8625  }
8626  if (atom.type != MKTAG('r','o','o','t') &&
8627  atom.type != MKTAG('m','o','o','v')) {
8628  if (a.type == MKTAG('t','r','a','k') ||
8629  a.type == MKTAG('m','d','a','t')) {
8630  av_log(c->fc, AV_LOG_ERROR, "Broken file, trak/mdat not at top-level\n");
8631  avio_skip(pb, -8);
8632  c->atom_depth --;
8633  return 0;
8634  }
8635  }
8636  total_size += 8;
8637  if (a.size == 1 && total_size + 8 <= atom.size) { /* 64 bit extended size */
8638  a.size = avio_rb64(pb) - 8;
8639  total_size += 8;
8640  }
8641  av_log(c->fc, AV_LOG_TRACE, "type:'%s' parent:'%s' sz: %"PRId64" %"PRId64" %"PRId64"\n",
8642  av_fourcc2str(a.type), av_fourcc2str(atom.type), a.size, total_size, atom.size);
8643  if (a.size == 0) {
8644  a.size = atom.size - total_size + 8;
8645  }
8646  if (a.size < 0)
8647  break;
8648  a.size -= 8;
8649  if (a.size < 0)
8650  break;
8651  a.size = FFMIN(a.size, atom.size - total_size);
8652 
8653  for (i = 0; mov_default_parse_table[i].type; i++)
8654  if (mov_default_parse_table[i].type == a.type) {
8656  break;
8657  }
8658 
8659  // container is user data
8660  if (!parse && (atom.type == MKTAG('u','d','t','a') ||
8661  atom.type == MKTAG('i','l','s','t')))
8663 
8664  // Supports parsing the QuickTime Metadata Keys.
8665  // https://developer.apple.com/library/mac/documentation/QuickTime/QTFF/Metadata/Metadata.html
8666  if (!parse && c->found_hdlr_mdta &&
8667  atom.type == MKTAG('m','e','t','a') &&
8668  a.type == MKTAG('k','e','y','s') &&
8669  c->meta_keys_count == 0) {
8670  parse = mov_read_keys;
8671  }
8672 
8673  if (!parse) { /* skip leaf atoms data */
8674  avio_skip(pb, a.size);
8675  } else {
8676  int64_t start_pos = avio_tell(pb);
8677  int64_t left;
8678  int err = parse(c, pb, a);
8679  if (err < 0) {
8680  c->atom_depth --;
8681  return err;
8682  }
8683  if (c->found_moov && c->found_mdat && a.size <= INT64_MAX - start_pos &&
8684  ((!(pb->seekable & AVIO_SEEKABLE_NORMAL) || c->fc->flags & AVFMT_FLAG_IGNIDX || c->frag_index.complete) ||
8685  start_pos + a.size == avio_size(pb))) {
8686  if (!(pb->seekable & AVIO_SEEKABLE_NORMAL) || c->fc->flags & AVFMT_FLAG_IGNIDX || c->frag_index.complete)
8687  c->next_root_atom = start_pos + a.size;
8688  c->atom_depth --;
8689  return 0;
8690  }
8691  left = a.size - avio_tell(pb) + start_pos;
8692  if (left > 0) /* skip garbage at atom end */
8693  avio_skip(pb, left);
8694  else if (left < 0) {
8695  av_log(c->fc, AV_LOG_WARNING,
8696  "overread end of atom '%s' by %"PRId64" bytes\n",
8697  av_fourcc2str(a.type), -left);
8698  avio_seek(pb, left, SEEK_CUR);
8699  }
8700  }
8701 
8702  total_size += a.size;
8703  }
8704 
8705  if (total_size < atom.size && atom.size < 0x7ffff)
8706  avio_skip(pb, atom.size - total_size);
8707 
8708  c->atom_depth --;
8709  return 0;
8710 }
8711 
8712 static int mov_probe(const AVProbeData *p)
8713 {
8714  int64_t offset;
8715  uint32_t tag;
8716  int score = 0;
8717  int moov_offset = -1;
8718 
8719  /* check file header */
8720  offset = 0;
8721  for (;;) {
8722  int64_t size;
8723  int minsize = 8;
8724  /* ignore invalid offset */
8725  if ((offset + 8ULL) > (unsigned int)p->buf_size)
8726  break;
8727  size = AV_RB32(p->buf + offset);
8728  if (size == 1 && offset + 16 <= (unsigned int)p->buf_size) {
8729  size = AV_RB64(p->buf+offset + 8);
8730  minsize = 16;
8731  } else if (size == 0) {
8732  size = p->buf_size - offset;
8733  }
8734  if (size < minsize) {
8735  offset += 4;
8736  continue;
8737  }
8738  tag = AV_RL32(p->buf + offset + 4);
8739  switch(tag) {
8740  /* check for obvious tags */
8741  case MKTAG('m','o','o','v'):
8742  moov_offset = offset + 4;
8743  case MKTAG('m','d','a','t'):
8744  case MKTAG('p','n','o','t'): /* detect movs with preview pics like ew.mov and april.mov */
8745  case MKTAG('u','d','t','a'): /* Packet Video PVAuthor adds this and a lot of more junk */
8746  case MKTAG('f','t','y','p'):
8747  if (tag == MKTAG('f','t','y','p') &&
8748  ( AV_RL32(p->buf + offset + 8) == MKTAG('j','p','2',' ')
8749  || AV_RL32(p->buf + offset + 8) == MKTAG('j','p','x',' ')
8750  || AV_RL32(p->buf + offset + 8) == MKTAG('j','x','l',' ')
8751  )) {
8752  score = FFMAX(score, 5);
8753  } else {
8754  score = AVPROBE_SCORE_MAX;
8755  }
8756  break;
8757  /* those are more common words, so rate then a bit less */
8758  case MKTAG('e','d','i','w'): /* xdcam files have reverted first tags */
8759  case MKTAG('w','i','d','e'):
8760  case MKTAG('f','r','e','e'):
8761  case MKTAG('j','u','n','k'):
8762  case MKTAG('p','i','c','t'):
8763  score = FFMAX(score, AVPROBE_SCORE_MAX - 5);
8764  break;
8765  case MKTAG(0x82,0x82,0x7f,0x7d):
8766  score = FFMAX(score, AVPROBE_SCORE_EXTENSION - 5);
8767  break;
8768  case MKTAG('s','k','i','p'):
8769  case MKTAG('u','u','i','d'):
8770  case MKTAG('p','r','f','l'):
8771  /* if we only find those cause probedata is too small at least rate them */
8772  score = FFMAX(score, AVPROBE_SCORE_EXTENSION);
8773  break;
8774  }
8775  if (size > INT64_MAX - offset)
8776  break;
8777  offset += size;
8778  }
8779  if (score > AVPROBE_SCORE_MAX - 50 && moov_offset != -1) {
8780  /* moov atom in the header - we should make sure that this is not a
8781  * MOV-packed MPEG-PS */
8782  offset = moov_offset;
8783 
8784  while (offset < (p->buf_size - 16)) { /* Sufficient space */
8785  /* We found an actual hdlr atom */
8786  if (AV_RL32(p->buf + offset ) == MKTAG('h','d','l','r') &&
8787  AV_RL32(p->buf + offset + 8) == MKTAG('m','h','l','r') &&
8788  AV_RL32(p->buf + offset + 12) == MKTAG('M','P','E','G')) {
8789  av_log(NULL, AV_LOG_WARNING, "Found media data tag MPEG indicating this is a MOV-packed MPEG-PS.\n");
8790  /* We found a media handler reference atom describing an
8791  * MPEG-PS-in-MOV, return a
8792  * low score to force expanding the probe window until
8793  * mpegps_probe finds what it needs */
8794  return 5;
8795  } else {
8796  /* Keep looking */
8797  offset += 2;
8798  }
8799  }
8800  }
8801 
8802  return score;
8803 }
8804 
8805 // must be done after parsing all trak because there's no order requirement
8807 {
8808  MOVContext *mov = s->priv_data;
8809  MOVStreamContext *sc;
8810  int64_t cur_pos;
8811  int i, j;
8812  int chapter_track;
8813 
8814  for (j = 0; j < mov->nb_chapter_tracks; j++) {
8815  AVStream *st = NULL;
8816  FFStream *sti = NULL;
8817  chapter_track = mov->chapter_tracks[j];
8818  for (i = 0; i < s->nb_streams; i++) {
8819  sc = mov->fc->streams[i]->priv_data;
8820  if (sc->id == chapter_track) {
8821  st = s->streams[i];
8822  break;
8823  }
8824  }
8825  if (!st) {
8826  av_log(s, AV_LOG_ERROR, "Referenced QT chapter track not found\n");
8827  continue;
8828  }
8829  sti = ffstream(st);
8830 
8831  sc = st->priv_data;
8832  cur_pos = avio_tell(sc->pb);
8833 
8834  if (st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO) {
8836  if (!st->attached_pic.data && sti->nb_index_entries) {
8837  // Retrieve the first frame, if possible
8838  AVIndexEntry *sample = &sti->index_entries[0];
8839  if (avio_seek(sc->pb, sample->pos, SEEK_SET) != sample->pos) {
8840  av_log(s, AV_LOG_ERROR, "Failed to retrieve first frame\n");
8841  goto finish;
8842  }
8843 
8844  if (ff_add_attached_pic(s, st, sc->pb, NULL, sample->size) < 0)
8845  goto finish;
8846  }
8847  } else {
8850  st->discard = AVDISCARD_ALL;
8851  for (int i = 0; i < sti->nb_index_entries; i++) {
8852  AVIndexEntry *sample = &sti->index_entries[i];
8853  int64_t end = i+1 < sti->nb_index_entries ? sti->index_entries[i+1].timestamp : st->duration;
8854  uint8_t *title;
8855  uint16_t ch;
8856  int len, title_len;
8857 
8858  if (end < sample->timestamp) {
8859  av_log(s, AV_LOG_WARNING, "ignoring stream duration which is shorter than chapters\n");
8860  end = AV_NOPTS_VALUE;
8861  }
8862 
8863  if (avio_seek(sc->pb, sample->pos, SEEK_SET) != sample->pos) {
8864  av_log(s, AV_LOG_ERROR, "Chapter %d not found in file\n", i);
8865  goto finish;
8866  }
8867 
8868  // the first two bytes are the length of the title
8869  len = avio_rb16(sc->pb);
8870  if (len > sample->size-2)
8871  continue;
8872  title_len = 2*len + 1;
8873  if (!(title = av_mallocz(title_len)))
8874  goto finish;
8875 
8876  // The samples could theoretically be in any encoding if there's an encd
8877  // atom following, but in practice are only utf-8 or utf-16, distinguished
8878  // instead by the presence of a BOM
8879  if (!len) {
8880  title[0] = 0;
8881  } else {
8882  ch = avio_rb16(sc->pb);
8883  if (ch == 0xfeff)
8884  avio_get_str16be(sc->pb, len, title, title_len);
8885  else if (ch == 0xfffe)
8886  avio_get_str16le(sc->pb, len, title, title_len);
8887  else {
8888  AV_WB16(title, ch);
8889  if (len == 1 || len == 2)
8890  title[len] = 0;
8891  else
8892  avio_get_str(sc->pb, INT_MAX, title + 2, len - 1);
8893  }
8894  }
8895 
8896  avpriv_new_chapter(s, i, st->time_base, sample->timestamp, end, title);
8897  av_freep(&title);
8898  }
8899  }
8900 finish:
8901  avio_seek(sc->pb, cur_pos, SEEK_SET);
8902  }
8903 }
8904 
8906  int64_t value, int flags)
8907 {
8908  AVTimecode tc;
8909  char buf[AV_TIMECODE_STR_SIZE];
8910  AVRational rate = st->avg_frame_rate;
8911  int ret = av_timecode_init(&tc, rate, flags, 0, s);
8912  if (ret < 0)
8913  return ret;
8914  av_dict_set(&st->metadata, "timecode",
8915  av_timecode_make_string(&tc, buf, value), 0);
8916  return 0;
8917 }
8918 
8920 {
8921  MOVStreamContext *sc = st->priv_data;
8922  FFStream *const sti = ffstream(st);
8923  char buf[AV_TIMECODE_STR_SIZE];
8924  int64_t cur_pos = avio_tell(sc->pb);
8925  int hh, mm, ss, ff, drop;
8926 
8927  if (!sti->nb_index_entries)
8928  return -1;
8929 
8930  avio_seek(sc->pb, sti->index_entries->pos, SEEK_SET);
8931  avio_skip(s->pb, 13);
8932  hh = avio_r8(s->pb);
8933  mm = avio_r8(s->pb);
8934  ss = avio_r8(s->pb);
8935  drop = avio_r8(s->pb);
8936  ff = avio_r8(s->pb);
8937  snprintf(buf, AV_TIMECODE_STR_SIZE, "%02d:%02d:%02d%c%02d",
8938  hh, mm, ss, drop ? ';' : ':', ff);
8939  av_dict_set(&st->metadata, "timecode", buf, 0);
8940 
8941  avio_seek(sc->pb, cur_pos, SEEK_SET);
8942  return 0;
8943 }
8944 
8946 {
8947  MOVStreamContext *sc = st->priv_data;
8948  FFStream *const sti = ffstream(st);
8949  int flags = 0;
8950  int64_t cur_pos = avio_tell(sc->pb);
8951  int64_t value;
8952  AVRational tc_rate = st->avg_frame_rate;
8953  int tmcd_nb_frames = sc->tmcd_nb_frames;
8954  int rounded_tc_rate;
8955 
8956  if (!sti->nb_index_entries)
8957  return -1;
8958 
8959  if (!tc_rate.num || !tc_rate.den || !tmcd_nb_frames)
8960  return -1;
8961 
8962  avio_seek(sc->pb, sti->index_entries->pos, SEEK_SET);
8963  value = avio_rb32(s->pb);
8964 
8965  if (sc->tmcd_flags & 0x0001) flags |= AV_TIMECODE_FLAG_DROPFRAME;
8966  if (sc->tmcd_flags & 0x0002) flags |= AV_TIMECODE_FLAG_24HOURSMAX;
8967  if (sc->tmcd_flags & 0x0004) flags |= AV_TIMECODE_FLAG_ALLOWNEGATIVE;
8968 
8969  /* Assume Counter flag is set to 1 in tmcd track (even though it is likely
8970  * not the case) and thus assume "frame number format" instead of QT one.
8971  * No sample with tmcd track can be found with a QT timecode at the moment,
8972  * despite what the tmcd track "suggests" (Counter flag set to 0 means QT
8973  * format). */
8974 
8975  /* 60 fps content have tmcd_nb_frames set to 30 but tc_rate set to 60, so
8976  * we multiply the frame number with the quotient.
8977  * See tickets #9492, #9710. */
8978  rounded_tc_rate = (tc_rate.num + tc_rate.den / 2LL) / tc_rate.den;
8979  /* Work around files where tmcd_nb_frames is rounded down from frame rate
8980  * instead of up. See ticket #5978. */
8981  if (tmcd_nb_frames == tc_rate.num / tc_rate.den &&
8982  s->strict_std_compliance < FF_COMPLIANCE_STRICT)
8983  tmcd_nb_frames = rounded_tc_rate;
8984  value = av_rescale(value, rounded_tc_rate, tmcd_nb_frames);
8985 
8987 
8988  avio_seek(sc->pb, cur_pos, SEEK_SET);
8989  return 0;
8990 }
8991 
8993  int i;
8994  if (!index || !*index) return;
8995  for (i = 0; i < (*index)->nb_encrypted_samples; i++) {
8996  av_encryption_info_free((*index)->encrypted_samples[i]);
8997  }
8998  av_freep(&(*index)->encrypted_samples);
8999  av_freep(&(*index)->auxiliary_info_sizes);
9000  av_freep(&(*index)->auxiliary_offsets);
9001  av_freep(index);
9002 }
9003 
9005 {
9006  MOVStreamContext *sc = st->priv_data;
9007 
9008  if (!sc || --sc->refcount) {
9009  st->priv_data = NULL;
9010  return;
9011  }
9012 
9013  av_freep(&sc->ctts_data);
9014  for (int i = 0; i < sc->drefs_count; i++) {
9015  av_freep(&sc->drefs[i].path);
9016  av_freep(&sc->drefs[i].dir);
9017  }
9018  av_freep(&sc->drefs);
9019 
9020  sc->drefs_count = 0;
9021 
9022  if (!sc->pb_is_copied)
9023  ff_format_io_close(s, &sc->pb);
9024 
9025  sc->pb = NULL;
9026  av_freep(&sc->chunk_offsets);
9027  av_freep(&sc->stsc_data);
9028  av_freep(&sc->sample_sizes);
9029  av_freep(&sc->keyframes);
9030  av_freep(&sc->stts_data);
9031  av_freep(&sc->sdtp_data);
9032  av_freep(&sc->stps_data);
9033  av_freep(&sc->elst_data);
9034  av_freep(&sc->rap_group);
9035  av_freep(&sc->sync_group);
9036  av_freep(&sc->sgpd_sync);
9037  av_freep(&sc->sample_offsets);
9038  av_freep(&sc->open_key_samples);
9039  av_freep(&sc->display_matrix);
9040  av_freep(&sc->index_ranges);
9041 
9042  if (sc->extradata)
9043  for (int i = 0; i < sc->stsd_count; i++)
9044  av_free(sc->extradata[i]);
9045  av_freep(&sc->extradata);
9046  av_freep(&sc->extradata_size);
9047 
9051 
9052  av_freep(&sc->stereo3d);
9053  av_freep(&sc->spherical);
9054  av_freep(&sc->mastering);
9055  av_freep(&sc->coll);
9056  av_freep(&sc->ambient);
9057 
9058 #if CONFIG_IAMFDEC
9059  if (sc->iamf)
9061 #endif
9062  av_freep(&sc->iamf);
9063 }
9064 
9066 {
9067  MOVContext *mov = s->priv_data;
9068  int i, j;
9069 
9070  for (i = 0; i < s->nb_streams; i++) {
9071  AVStream *st = s->streams[i];
9072 
9074  }
9075 
9076  av_freep(&mov->dv_demux);
9078  mov->dv_fctx = NULL;
9079 
9080  if (mov->meta_keys) {
9081  for (i = 1; i < mov->meta_keys_count; i++) {
9082  av_freep(&mov->meta_keys[i]);
9083  }
9084  av_freep(&mov->meta_keys);
9085  }
9086 
9087  av_freep(&mov->trex_data);
9088  av_freep(&mov->bitrates);
9089 
9090  for (i = 0; i < mov->frag_index.nb_items; i++) {
9092  for (j = 0; j < mov->frag_index.item[i].nb_stream_info; j++) {
9093  mov_free_encryption_index(&frag[j].encryption_index);
9094  }
9096  }
9097  av_freep(&mov->frag_index.item);
9098 
9099  av_freep(&mov->aes_decrypt);
9100  av_freep(&mov->chapter_tracks);
9101  for (i = 0; i < mov->nb_heif_item; i++)
9102  av_freep(&mov->heif_item[i].name);
9103  av_freep(&mov->heif_item);
9104  for (i = 0; i < mov->nb_heif_grid; i++) {
9105  av_freep(&mov->heif_grid[i].tile_id_list);
9107  }
9108  av_freep(&mov->heif_grid);
9109 
9110  return 0;
9111 }
9112 
9113 static int tmcd_is_referenced(AVFormatContext *s, int tmcd_id)
9114 {
9115  int i;
9116 
9117  for (i = 0; i < s->nb_streams; i++) {
9118  AVStream *st = s->streams[i];
9119  MOVStreamContext *sc = st->priv_data;
9120 
9121  if (st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO &&
9122  sc->timecode_track == tmcd_id)
9123  return 1;
9124  }
9125  return 0;
9126 }
9127 
9128 /* look for a tmcd track not referenced by any video track, and export it globally */
9130 {
9131  int i;
9132 
9133  for (i = 0; i < s->nb_streams; i++) {
9134  AVStream *st = s->streams[i];
9135 
9136  if (st->codecpar->codec_tag == MKTAG('t','m','c','d') &&
9137  !tmcd_is_referenced(s, i + 1)) {
9138  AVDictionaryEntry *tcr = av_dict_get(st->metadata, "timecode", NULL, 0);
9139  if (tcr) {
9140  av_dict_set(&s->metadata, "timecode", tcr->value, 0);
9141  break;
9142  }
9143  }
9144  }
9145 }
9146 
9147 static int read_tfra(MOVContext *mov, AVIOContext *f)
9148 {
9149  int version, fieldlength, i, j;
9150  int64_t pos = avio_tell(f);
9151  uint32_t size = avio_rb32(f);
9152  unsigned track_id, item_count;
9153 
9154  if (avio_rb32(f) != MKBETAG('t', 'f', 'r', 'a')) {
9155  return 1;
9156  }
9157  av_log(mov->fc, AV_LOG_VERBOSE, "found tfra\n");
9158 
9159  version = avio_r8(f);
9160  avio_rb24(f);
9161  track_id = avio_rb32(f);
9162  fieldlength = avio_rb32(f);
9163  item_count = avio_rb32(f);
9164  for (i = 0; i < item_count; i++) {
9165  int64_t time, offset;
9166  int index;
9167  MOVFragmentStreamInfo * frag_stream_info;
9168 
9169  if (avio_feof(f)) {
9170  return AVERROR_INVALIDDATA;
9171  }
9172 
9173  if (version == 1) {
9174  time = avio_rb64(f);
9175  offset = avio_rb64(f);
9176  } else {
9177  time = avio_rb32(f);
9178  offset = avio_rb32(f);
9179  }
9180 
9181  // The first sample of each stream in a fragment is always a random
9182  // access sample. So it's entry in the tfra can be used as the
9183  // initial PTS of the fragment.
9184  index = update_frag_index(mov, offset);
9185  frag_stream_info = get_frag_stream_info(&mov->frag_index, index, track_id);
9186  if (frag_stream_info &&
9187  frag_stream_info->first_tfra_pts == AV_NOPTS_VALUE)
9188  frag_stream_info->first_tfra_pts = time;
9189 
9190  for (j = 0; j < ((fieldlength >> 4) & 3) + 1; j++)
9191  avio_r8(f);
9192  for (j = 0; j < ((fieldlength >> 2) & 3) + 1; j++)
9193  avio_r8(f);
9194  for (j = 0; j < ((fieldlength >> 0) & 3) + 1; j++)
9195  avio_r8(f);
9196  }
9197 
9198  avio_seek(f, pos + size, SEEK_SET);
9199  return 0;
9200 }
9201 
9203 {
9204  int64_t stream_size = avio_size(f);
9205  int64_t original_pos = avio_tell(f);
9206  int64_t seek_ret;
9207  int ret = -1;
9208  if ((seek_ret = avio_seek(f, stream_size - 4, SEEK_SET)) < 0) {
9209  ret = seek_ret;
9210  goto fail;
9211  }
9212  c->mfra_size = avio_rb32(f);
9213  c->have_read_mfra_size = 1;
9214  if (!c->mfra_size || c->mfra_size > stream_size) {
9215  av_log(c->fc, AV_LOG_DEBUG, "doesn't look like mfra (unreasonable size)\n");
9216  goto fail;
9217  }
9218  if ((seek_ret = avio_seek(f, -((int64_t) c->mfra_size), SEEK_CUR)) < 0) {
9219  ret = seek_ret;
9220  goto fail;
9221  }
9222  if (avio_rb32(f) != c->mfra_size) {
9223  av_log(c->fc, AV_LOG_DEBUG, "doesn't look like mfra (size mismatch)\n");
9224  goto fail;
9225  }
9226  if (avio_rb32(f) != MKBETAG('m', 'f', 'r', 'a')) {
9227  av_log(c->fc, AV_LOG_DEBUG, "doesn't look like mfra (tag mismatch)\n");
9228  goto fail;
9229  }
9230  av_log(c->fc, AV_LOG_VERBOSE, "stream has mfra\n");
9231  do {
9232  ret = read_tfra(c, f);
9233  if (ret < 0)
9234  goto fail;
9235  } while (!ret);
9236  ret = 0;
9237  c->frag_index.complete = 1;
9238 fail:
9239  seek_ret = avio_seek(f, original_pos, SEEK_SET);
9240  if (seek_ret < 0) {
9241  av_log(c->fc, AV_LOG_ERROR,
9242  "failed to seek back after looking for mfra\n");
9243  ret = seek_ret;
9244  }
9245  return ret;
9246 }
9247 
9248 static int read_image_grid(AVFormatContext *s, const HEIFGrid *grid,
9249  AVStreamGroupTileGrid *tile_grid)
9250 {
9251  MOVContext *c = s->priv_data;
9252  const HEIFItem *item = grid->item;
9253  int64_t offset = 0, pos = avio_tell(s->pb);
9254  int x = 0, y = 0, i = 0;
9255  int tile_rows, tile_cols;
9256  int flags, size;
9257 
9258  if (!(s->pb->seekable & AVIO_SEEKABLE_NORMAL)) {
9259  av_log(c->fc, AV_LOG_INFO, "grid box with non seekable input\n");
9260  return AVERROR_PATCHWELCOME;
9261  }
9262  if (item->is_idat_relative) {
9263  if (!c->idat_offset) {
9264  av_log(c->fc, AV_LOG_ERROR, "missing idat box required by the image grid\n");
9265  return AVERROR_INVALIDDATA;
9266  }
9267  offset = c->idat_offset;
9268  }
9269 
9270  avio_seek(s->pb, item->extent_offset + offset, SEEK_SET);
9271 
9272  avio_r8(s->pb); /* version */
9273  flags = avio_r8(s->pb);
9274 
9275  tile_rows = avio_r8(s->pb) + 1;
9276  tile_cols = avio_r8(s->pb) + 1;
9277  /* actual width and height of output image */
9278  tile_grid->width = (flags & 1) ? avio_rb32(s->pb) : avio_rb16(s->pb);
9279  tile_grid->height = (flags & 1) ? avio_rb32(s->pb) : avio_rb16(s->pb);
9280 
9281  av_log(c->fc, AV_LOG_TRACE, "grid: grid_rows %d grid_cols %d output_width %d output_height %d\n",
9282  tile_rows, tile_cols, tile_grid->width, tile_grid->height);
9283 
9284  avio_seek(s->pb, pos, SEEK_SET);
9285 
9286  size = tile_rows * tile_cols;
9287  tile_grid->nb_tiles = grid->nb_tiles;
9288 
9289  if (tile_grid->nb_tiles != size)
9290  return AVERROR_INVALIDDATA;
9291 
9292  for (int i = 0; i < tile_cols; i++)
9293  tile_grid->coded_width += grid->tile_item_list[i]->width;
9294  for (int i = 0; i < size; i += tile_cols)
9295  tile_grid->coded_height += grid->tile_item_list[i]->height;
9296 
9297  tile_grid->offsets = av_calloc(tile_grid->nb_tiles, sizeof(*tile_grid->offsets));
9298  if (!tile_grid->offsets)
9299  return AVERROR(ENOMEM);
9300 
9301  while (y < tile_grid->coded_height) {
9302  int left_col = i;
9303 
9304  while (x < tile_grid->coded_width) {
9305  if (i == tile_grid->nb_tiles)
9306  return AVERROR_INVALIDDATA;
9307 
9308  tile_grid->offsets[i].idx = i;
9309  tile_grid->offsets[i].horizontal = x;
9310  tile_grid->offsets[i].vertical = y;
9311 
9312  x += grid->tile_item_list[i++]->width;
9313  }
9314 
9315  if (x > tile_grid->coded_width) {
9316  av_log(c->fc, AV_LOG_ERROR, "Non uniform HEIF tiles\n");
9317  return AVERROR_INVALIDDATA;
9318  }
9319 
9320  x = 0;
9321  y += grid->tile_item_list[left_col]->height;
9322  }
9323 
9324  if (y > tile_grid->coded_height || i != tile_grid->nb_tiles) {
9325  av_log(c->fc, AV_LOG_ERROR, "Non uniform HEIF tiles\n");
9326  return AVERROR_INVALIDDATA;
9327  }
9328 
9329  return 0;
9330 }
9331 
9332 static int read_image_iovl(AVFormatContext *s, const HEIFGrid *grid,
9333  AVStreamGroupTileGrid *tile_grid)
9334 {
9335  MOVContext *c = s->priv_data;
9336  const HEIFItem *item = grid->item;
9337  uint16_t canvas_fill_value[4];
9338  int64_t offset = 0, pos = avio_tell(s->pb);
9339  int ret = 0, flags;
9340 
9341  if (!(s->pb->seekable & AVIO_SEEKABLE_NORMAL)) {
9342  av_log(c->fc, AV_LOG_INFO, "iovl box with non seekable input\n");
9343  return AVERROR_PATCHWELCOME;
9344  }
9345  if (item->is_idat_relative) {
9346  if (!c->idat_offset) {
9347  av_log(c->fc, AV_LOG_ERROR, "missing idat box required by the image overlay\n");
9348  return AVERROR_INVALIDDATA;
9349  }
9350  offset = c->idat_offset;
9351  }
9352 
9353  avio_seek(s->pb, item->extent_offset + offset, SEEK_SET);
9354 
9355  avio_r8(s->pb); /* version */
9356  flags = avio_r8(s->pb);
9357 
9358  for (int i = 0; i < 4; i++)
9359  canvas_fill_value[i] = avio_rb16(s->pb);
9360  av_log(c->fc, AV_LOG_TRACE, "iovl: canvas_fill_value { %u, %u, %u, %u }\n",
9361  canvas_fill_value[0], canvas_fill_value[1],
9362  canvas_fill_value[2], canvas_fill_value[3]);
9363  for (int i = 0; i < 4; i++)
9364  tile_grid->background[i] = canvas_fill_value[i];
9365 
9366  /* actual width and height of output image */
9367  tile_grid->width =
9368  tile_grid->coded_width = (flags & 1) ? avio_rb32(s->pb) : avio_rb16(s->pb);
9369  tile_grid->height =
9370  tile_grid->coded_height = (flags & 1) ? avio_rb32(s->pb) : avio_rb16(s->pb);
9371  av_log(c->fc, AV_LOG_TRACE, "iovl: output_width %d, output_height %d\n",
9372  tile_grid->width, tile_grid->height);
9373 
9374  tile_grid->nb_tiles = grid->nb_tiles;
9375  tile_grid->offsets = av_malloc_array(tile_grid->nb_tiles, sizeof(*tile_grid->offsets));
9376  if (!tile_grid->offsets) {
9377  ret = AVERROR(ENOMEM);
9378  goto fail;
9379  }
9380 
9381  for (int i = 0; i < tile_grid->nb_tiles; i++) {
9382  tile_grid->offsets[i].idx = grid->tile_item_list[i]->st->index;
9383  tile_grid->offsets[i].horizontal = (flags & 1) ? avio_rb32(s->pb) : avio_rb16(s->pb);
9384  tile_grid->offsets[i].vertical = (flags & 1) ? avio_rb32(s->pb) : avio_rb16(s->pb);
9385  av_log(c->fc, AV_LOG_TRACE, "iovl: stream_idx[%d] %u, "
9386  "horizontal_offset[%d] %d, vertical_offset[%d] %d\n",
9387  i, tile_grid->offsets[i].idx,
9388  i, tile_grid->offsets[i].horizontal, i, tile_grid->offsets[i].vertical);
9389  }
9390 
9391 fail:
9392  avio_seek(s->pb, pos, SEEK_SET);
9393 
9394  return ret;
9395 }
9396 
9398 {
9399  MOVContext *mov = s->priv_data;
9400 
9401  for (int i = 0; i < mov->nb_heif_grid; i++) {
9403  AVStreamGroupTileGrid *tile_grid;
9404  const HEIFGrid *grid = &mov->heif_grid[i];
9405  int err, loop = 1;
9406 
9407  if (!stg)
9408  return AVERROR(ENOMEM);
9409 
9410  stg->id = grid->item->item_id;
9411  tile_grid = stg->params.tile_grid;
9412 
9413  for (int j = 0; j < grid->nb_tiles; j++) {
9414  int tile_id = grid->tile_id_list[j];
9415  int k;
9416 
9417  for (k = 0; k < mov->nb_heif_item; k++) {
9418  HEIFItem *item = &mov->heif_item[k];
9419  AVStream *st = item->st;
9420 
9421  if (item->item_id != tile_id)
9422  continue;
9423  if (!st) {
9424  av_log(s, AV_LOG_WARNING, "HEIF item id %d from grid id %d doesn't "
9425  "reference a stream\n",
9426  tile_id, grid->item->item_id);
9427  ff_remove_stream_group(s, stg);
9428  loop = 0;
9429  break;
9430  }
9431 
9432  grid->tile_item_list[j] = item;
9433 
9434  err = avformat_stream_group_add_stream(stg, st);
9435  if (err < 0 && err != AVERROR(EEXIST))
9436  return err;
9437 
9438  if (item->item_id != mov->primary_item_id)
9440  break;
9441  }
9442 
9443  if (k == grid->nb_tiles) {
9444  av_log(s, AV_LOG_WARNING, "HEIF item id %d referenced by grid id %d doesn't "
9445  "exist\n",
9446  tile_id, grid->item->item_id);
9447  ff_remove_stream_group(s, stg);
9448  loop = 0;
9449  }
9450  if (!loop)
9451  break;
9452  }
9453 
9454  if (!loop)
9455  continue;
9456 
9457  switch (grid->item->type) {
9458  case MKTAG('g','r','i','d'):
9459  err = read_image_grid(s, grid, tile_grid);
9460  break;
9461  case MKTAG('i','o','v','l'):
9462  err = read_image_iovl(s, grid, tile_grid);
9463  break;
9464  default:
9465  av_assert0(0);
9466  }
9467  if (err < 0)
9468  return err;
9469 
9470 
9471  if (grid->item->name)
9472  av_dict_set(&stg->metadata, "title", grid->item->name, 0);
9473  if (grid->item->item_id == mov->primary_item_id)
9475  }
9476 
9477  return 0;
9478 }
9479 
9481 {
9482  MOVContext *mov = s->priv_data;
9483  AVIOContext *pb = s->pb;
9484  int j, err;
9485  MOVAtom atom = { AV_RL32("root") };
9486  int i;
9487 
9488  if (mov->decryption_key_len != 0 && mov->decryption_key_len != AES_CTR_KEY_SIZE) {
9489  av_log(s, AV_LOG_ERROR, "Invalid decryption key len %d expected %d\n",
9491  return AVERROR(EINVAL);
9492  }
9493 
9494  mov->fc = s;
9495  mov->trak_index = -1;
9496  mov->thmb_item_id = -1;
9497  mov->primary_item_id = -1;
9498  mov->cur_item_id = -1;
9499  /* .mov and .mp4 aren't streamable anyway (only progressive download if moov is before mdat) */
9500  if (pb->seekable & AVIO_SEEKABLE_NORMAL)
9501  atom.size = avio_size(pb);
9502  else
9503  atom.size = INT64_MAX;
9504 
9505  /* check MOV header */
9506  do {
9507  if (mov->moov_retry)
9508  avio_seek(pb, 0, SEEK_SET);
9509  if ((err = mov_read_default(mov, pb, atom)) < 0) {
9510  av_log(s, AV_LOG_ERROR, "error reading header\n");
9511  return err;
9512  }
9513  } while ((pb->seekable & AVIO_SEEKABLE_NORMAL) &&
9514  !mov->found_moov && (!mov->found_iloc || !mov->found_iinf) && !mov->moov_retry++);
9515  if (!mov->found_moov && !mov->found_iloc && !mov->found_iinf) {
9516  av_log(s, AV_LOG_ERROR, "moov atom not found\n");
9517  return AVERROR_INVALIDDATA;
9518  }
9519  av_log(mov->fc, AV_LOG_TRACE, "on_parse_exit_offset=%"PRId64"\n", avio_tell(pb));
9520 
9521  if (mov->found_iloc && mov->found_iinf) {
9522  for (i = 0; i < mov->nb_heif_item; i++) {
9523  HEIFItem *item = &mov->heif_item[i];
9524  MOVStreamContext *sc;
9525  AVStream *st;
9526  int64_t offset = 0;
9527 
9528  if (!item->st) {
9529  if (item->item_id == mov->thmb_item_id) {
9530  av_log(s, AV_LOG_ERROR, "HEIF thumbnail doesn't reference a stream\n");
9531  return AVERROR_INVALIDDATA;
9532  }
9533  continue;
9534  }
9535  if (item->is_idat_relative) {
9536  if (!mov->idat_offset) {
9537  av_log(s, AV_LOG_ERROR, "Missing idat box for item %d\n", item->item_id);
9538  return AVERROR_INVALIDDATA;
9539  }
9540  offset = mov->idat_offset;
9541  }
9542 
9543  st = item->st;
9544  sc = st->priv_data;
9545  st->codecpar->width = item->width;
9546  st->codecpar->height = item->height;
9547 
9548  sc->sample_sizes[0] = item->extent_length;
9549  sc->chunk_offsets[0] = item->extent_offset + offset;
9550 
9551  if (item->item_id == mov->primary_item_id)
9553 
9554  mov_build_index(mov, st);
9555  }
9556 
9557  if (mov->nb_heif_grid) {
9558  err = mov_parse_tiles(s);
9559  if (err < 0)
9560  return err;
9561  }
9562  }
9563 
9564  if (pb->seekable & AVIO_SEEKABLE_NORMAL) {
9565  if (mov->nb_chapter_tracks > 0 && !mov->ignore_chapters)
9567  for (i = 0; i < s->nb_streams; i++)
9568  if (s->streams[i]->codecpar->codec_tag == AV_RL32("tmcd")) {
9569  mov_read_timecode_track(s, s->streams[i]);
9570  } else if (s->streams[i]->codecpar->codec_tag == AV_RL32("rtmd")) {
9571  mov_read_rtmd_track(s, s->streams[i]);
9572  }
9573  }
9574 
9575  /* copy timecode metadata from tmcd tracks to the related video streams */
9576  for (i = 0; i < s->nb_streams; i++) {
9577  AVStream *st = s->streams[i];
9578  MOVStreamContext *sc = st->priv_data;
9579  if (sc->timecode_track > 0) {
9580  AVDictionaryEntry *tcr;
9581  int tmcd_st_id = -1;
9582 
9583  for (j = 0; j < s->nb_streams; j++) {
9584  MOVStreamContext *sc2 = s->streams[j]->priv_data;
9585  if (sc2->id == sc->timecode_track)
9586  tmcd_st_id = j;
9587  }
9588 
9589  if (tmcd_st_id < 0 || tmcd_st_id == i)
9590  continue;
9591  tcr = av_dict_get(s->streams[tmcd_st_id]->metadata, "timecode", NULL, 0);
9592  if (tcr)
9593  av_dict_set(&st->metadata, "timecode", tcr->value, 0);
9594  }
9595  }
9597 
9598  for (i = 0; i < s->nb_streams; i++) {
9599  AVStream *st = s->streams[i];
9600  FFStream *const sti = ffstream(st);
9601  MOVStreamContext *sc = st->priv_data;
9602  fix_timescale(mov, sc);
9603  if (st->codecpar->codec_type == AVMEDIA_TYPE_AUDIO &&
9604  st->codecpar->codec_id == AV_CODEC_ID_AAC) {
9605  sti->skip_samples = sc->start_pad;
9606  }
9607  if (st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO && sc->nb_frames_for_fps > 0 && sc->duration_for_fps > 0)
9609  sc->time_scale*(int64_t)sc->nb_frames_for_fps, sc->duration_for_fps, INT_MAX);
9611  if (st->codecpar->width <= 0 || st->codecpar->height <= 0) {
9612  st->codecpar->width = sc->width;
9613  st->codecpar->height = sc->height;
9614  }
9616  if ((err = mov_rewrite_dvd_sub_extradata(st)) < 0)
9617  return err;
9618  }
9619  }
9620  if (mov->handbrake_version &&
9621  mov->handbrake_version <= 1000000*0 + 1000*10 + 2 && // 0.10.2
9622  st->codecpar->codec_id == AV_CODEC_ID_MP3) {
9623  av_log(s, AV_LOG_VERBOSE, "Forcing full parsing for mp3 stream\n");
9625  }
9626  }
9627 
9628  if (mov->trex_data) {
9629  for (i = 0; i < s->nb_streams; i++) {
9630  AVStream *st = s->streams[i];
9631  MOVStreamContext *sc = st->priv_data;
9632  if (st->duration > 0) {
9633  /* Akin to sc->data_size * 8 * sc->time_scale / st->duration but accounting for overflows. */
9634  st->codecpar->bit_rate = av_rescale(sc->data_size, ((int64_t) sc->time_scale) * 8, st->duration);
9635  if (st->codecpar->bit_rate == INT64_MIN) {
9636  av_log(s, AV_LOG_WARNING, "Overflow during bit rate calculation %"PRId64" * 8 * %d\n",
9637  sc->data_size, sc->time_scale);
9638  st->codecpar->bit_rate = 0;
9639  if (s->error_recognition & AV_EF_EXPLODE)
9640  return AVERROR_INVALIDDATA;
9641  }
9642  }
9643  }
9644  }
9645 
9646  if (mov->use_mfra_for > 0) {
9647  for (i = 0; i < s->nb_streams; i++) {
9648  AVStream *st = s->streams[i];
9649  MOVStreamContext *sc = st->priv_data;
9650  if (sc->duration_for_fps > 0) {
9651  /* Akin to sc->data_size * 8 * sc->time_scale / sc->duration_for_fps but accounting for overflows. */
9652  st->codecpar->bit_rate = av_rescale(sc->data_size, ((int64_t) sc->time_scale) * 8, sc->duration_for_fps);
9653  if (st->codecpar->bit_rate == INT64_MIN) {
9654  av_log(s, AV_LOG_WARNING, "Overflow during bit rate calculation %"PRId64" * 8 * %d\n",
9655  sc->data_size, sc->time_scale);
9656  st->codecpar->bit_rate = 0;
9657  if (s->error_recognition & AV_EF_EXPLODE)
9658  return AVERROR_INVALIDDATA;
9659  }
9660  }
9661  }
9662  }
9663 
9664  for (i = 0; i < mov->bitrates_count && i < s->nb_streams; i++) {
9665  if (mov->bitrates[i]) {
9666  s->streams[i]->codecpar->bit_rate = mov->bitrates[i];
9667  }
9668  }
9669 
9671 
9672  for (i = 0; i < s->nb_streams; i++) {
9673  AVStream *st = s->streams[i];
9674  MOVStreamContext *sc = st->priv_data;
9675 
9676  switch (st->codecpar->codec_type) {
9677  case AVMEDIA_TYPE_AUDIO:
9678  err = ff_replaygain_export(st, s->metadata);
9679  if (err < 0)
9680  return err;
9681  break;
9682  case AVMEDIA_TYPE_VIDEO:
9683  if (sc->display_matrix) {
9686  (uint8_t*)sc->display_matrix, sizeof(int32_t) * 9, 0))
9687  return AVERROR(ENOMEM);
9688 
9689  sc->display_matrix = NULL;
9690  }
9691  if (sc->stereo3d) {
9694  (uint8_t *)sc->stereo3d, sizeof(*sc->stereo3d), 0))
9695  return AVERROR(ENOMEM);
9696 
9697  sc->stereo3d = NULL;
9698  }
9699  if (sc->spherical) {
9702  (uint8_t *)sc->spherical, sc->spherical_size, 0))
9703  return AVERROR(ENOMEM);
9704 
9705  sc->spherical = NULL;
9706  }
9707  if (sc->mastering) {
9710  (uint8_t *)sc->mastering, sizeof(*sc->mastering), 0))
9711  return AVERROR(ENOMEM);
9712 
9713  sc->mastering = NULL;
9714  }
9715  if (sc->coll) {
9718  (uint8_t *)sc->coll, sc->coll_size, 0))
9719  return AVERROR(ENOMEM);
9720 
9721  sc->coll = NULL;
9722  }
9723  if (sc->ambient) {
9726  (uint8_t *) sc->ambient, sc->ambient_size, 0))
9727  return AVERROR(ENOMEM);
9728 
9729  sc->ambient = NULL;
9730  }
9731  break;
9732  }
9733  }
9735 
9736  for (i = 0; i < mov->frag_index.nb_items; i++)
9737  if (mov->frag_index.item[i].moof_offset <= mov->fragment.moof_offset)
9738  mov->frag_index.item[i].headers_read = 1;
9739 
9740  return 0;
9741 }
9742 
9744 {
9746  int64_t best_dts = INT64_MAX;
9747  int i;
9748  MOVContext *mov = s->priv_data;
9749  int no_interleave = !mov->interleaved_read || !(s->pb->seekable & AVIO_SEEKABLE_NORMAL);
9750  for (i = 0; i < s->nb_streams; i++) {
9751  AVStream *avst = s->streams[i];
9752  FFStream *const avsti = ffstream(avst);
9753  MOVStreamContext *msc = avst->priv_data;
9754  if (msc->pb && msc->current_sample < avsti->nb_index_entries) {
9755  AVIndexEntry *current_sample = &avsti->index_entries[msc->current_sample];
9756  int64_t dts = av_rescale(current_sample->timestamp, AV_TIME_BASE, msc->time_scale);
9757  uint64_t dtsdiff = best_dts > dts ? best_dts - (uint64_t)dts : ((uint64_t)dts - best_dts);
9758  av_log(s, AV_LOG_TRACE, "stream %d, sample %d, dts %"PRId64"\n", i, msc->current_sample, dts);
9759  if (!sample || (no_interleave && current_sample->pos < sample->pos) ||
9760  ((s->pb->seekable & AVIO_SEEKABLE_NORMAL) &&
9761  ((msc->pb != s->pb && dts < best_dts) || (msc->pb == s->pb && dts != AV_NOPTS_VALUE &&
9762  ((dtsdiff <= AV_TIME_BASE && current_sample->pos < sample->pos) ||
9763  (dtsdiff > AV_TIME_BASE && dts < best_dts)))))) {
9764  sample = current_sample;
9765  best_dts = dts;
9766  *st = avst;
9767  }
9768  }
9769  }
9770  return sample;
9771 }
9772 
9773 static int should_retry(AVIOContext *pb, int error_code) {
9774  if (error_code == AVERROR_EOF || avio_feof(pb))
9775  return 0;
9776 
9777  return 1;
9778 }
9779 
9780 static int mov_switch_root(AVFormatContext *s, int64_t target, int index)
9781 {
9782  int ret;
9783  MOVContext *mov = s->priv_data;
9784 
9785  if (index >= 0 && index < mov->frag_index.nb_items)
9786  target = mov->frag_index.item[index].moof_offset;
9787  if (avio_seek(s->pb, target, SEEK_SET) != target) {
9788  av_log(mov->fc, AV_LOG_ERROR, "root atom offset 0x%"PRIx64": partial file\n", target);
9789  return AVERROR_INVALIDDATA;
9790  }
9791 
9792  mov->next_root_atom = 0;
9793  if (index < 0 || index >= mov->frag_index.nb_items)
9794  index = search_frag_moof_offset(&mov->frag_index, target);
9795  if (index < mov->frag_index.nb_items &&
9796  mov->frag_index.item[index].moof_offset == target) {
9797  if (index + 1 < mov->frag_index.nb_items)
9798  mov->next_root_atom = mov->frag_index.item[index + 1].moof_offset;
9799  if (mov->frag_index.item[index].headers_read)
9800  return 0;
9801  mov->frag_index.item[index].headers_read = 1;
9802  }
9803 
9804  mov->found_mdat = 0;
9805 
9806  ret = mov_read_default(mov, s->pb, (MOVAtom){ AV_RL32("root"), INT64_MAX });
9807  if (ret < 0)
9808  return ret;
9809  if (avio_feof(s->pb))
9810  return AVERROR_EOF;
9811  av_log(s, AV_LOG_TRACE, "read fragments, offset 0x%"PRIx64"\n", avio_tell(s->pb));
9812 
9813  return 1;
9814 }
9815 
9817 {
9818  MOVStreamContext *sc = st->priv_data;
9819  uint8_t *side, *extradata;
9820  int extradata_size;
9821 
9822  /* Save the current index. */
9823  sc->last_stsd_index = sc->stsc_data[sc->stsc_index].id - 1;
9824 
9825  /* Notify the decoder that extradata changed. */
9826  extradata_size = sc->extradata_size[sc->last_stsd_index];
9827  extradata = sc->extradata[sc->last_stsd_index];
9828  if (st->discard != AVDISCARD_ALL && extradata_size > 0 && extradata) {
9831  extradata_size);
9832  if (!side)
9833  return AVERROR(ENOMEM);
9834  memcpy(side, extradata, extradata_size);
9835  }
9836 
9837  return 0;
9838 }
9839 
9841 {
9842  int new_size, ret;
9843 
9844  if (size <= 8)
9845  return AVERROR_INVALIDDATA;
9846  new_size = ((size - 8) / 2) * 3;
9847  ret = av_new_packet(pkt, new_size);
9848  if (ret < 0)
9849  return ret;
9850 
9851  avio_skip(pb, 8);
9852  for (int j = 0; j < new_size; j += 3) {
9853  pkt->data[j] = 0xFC;
9854  pkt->data[j+1] = avio_r8(pb);
9855  pkt->data[j+2] = avio_r8(pb);
9856  }
9857 
9858  return 0;
9859 }
9860 
9862  int64_t current_index, AVPacket *pkt)
9863 {
9864  MOVStreamContext *sc = st->priv_data;
9865 
9866  pkt->stream_index = sc->ffindex;
9867  pkt->dts = sample->timestamp;
9868  if (sample->flags & AVINDEX_DISCARD_FRAME) {
9870  }
9871  if (sc->ctts_data && sc->ctts_index < sc->ctts_count) {
9873  /* update ctts context */
9874  sc->ctts_sample++;
9875  if (sc->ctts_index < sc->ctts_count &&
9876  sc->ctts_data[sc->ctts_index].count == sc->ctts_sample) {
9877  sc->ctts_index++;
9878  sc->ctts_sample = 0;
9879  }
9880  } else {
9881  int64_t next_dts = (sc->current_sample < ffstream(st)->nb_index_entries) ?
9883 
9884  if (next_dts >= pkt->dts)
9885  pkt->duration = next_dts - pkt->dts;
9886  pkt->pts = pkt->dts;
9887  }
9888 
9889  if (sc->sdtp_data && sc->current_sample <= sc->sdtp_count) {
9890  uint8_t sample_flags = sc->sdtp_data[sc->current_sample - 1];
9891  uint8_t sample_is_depended_on = (sample_flags >> 2) & 0x3;
9892  pkt->flags |= sample_is_depended_on == MOV_SAMPLE_DEPENDENCY_NO ? AV_PKT_FLAG_DISPOSABLE : 0;
9893  }
9894  pkt->flags |= sample->flags & AVINDEX_KEYFRAME ? AV_PKT_FLAG_KEY : 0;
9895  pkt->pos = sample->pos;
9896 
9897  /* Multiple stsd handling. */
9898  if (sc->stsc_data) {
9899  if (sc->stsc_data[sc->stsc_index].id > 0 &&
9900  sc->stsc_data[sc->stsc_index].id - 1 < sc->stsd_count &&
9901  sc->stsc_data[sc->stsc_index].id - 1 != sc->last_stsd_index) {
9902  int ret = mov_change_extradata(st, pkt);
9903  if (ret < 0)
9904  return ret;
9905  }
9906 
9907  /* Update the stsc index for the next sample */
9908  sc->stsc_sample++;
9909  if (mov_stsc_index_valid(sc->stsc_index, sc->stsc_count) &&
9910  mov_get_stsc_samples(sc, sc->stsc_index) == sc->stsc_sample) {
9911  sc->stsc_index++;
9912  sc->stsc_sample = 0;
9913  }
9914  }
9915 
9916  return 0;
9917 }
9918 
9920 {
9921  MOVContext *mov = s->priv_data;
9922  MOVStreamContext *sc;
9924  AVStream *st = NULL;
9925  int64_t current_index;
9926  int ret;
9927  mov->fc = s;
9928  retry:
9929  sample = mov_find_next_sample(s, &st);
9930  if (!sample || (mov->next_root_atom && sample->pos > mov->next_root_atom)) {
9931  if (!mov->next_root_atom)
9932  return AVERROR_EOF;
9933  if ((ret = mov_switch_root(s, mov->next_root_atom, -1)) < 0)
9934  return ret;
9935  goto retry;
9936  }
9937  sc = st->priv_data;
9938  /* must be done just before reading, to avoid infinite loop on sample */
9939  current_index = sc->current_index;
9941 
9942  if (mov->next_root_atom) {
9943  sample->pos = FFMIN(sample->pos, mov->next_root_atom);
9944  sample->size = FFMIN(sample->size, (mov->next_root_atom - sample->pos));
9945  }
9946 
9947  if (st->discard != AVDISCARD_ALL) {
9948  int64_t ret64 = avio_seek(sc->pb, sample->pos, SEEK_SET);
9949  if (ret64 != sample->pos) {
9950  av_log(mov->fc, AV_LOG_ERROR, "stream %d, offset 0x%"PRIx64": partial file\n",
9951  sc->ffindex, sample->pos);
9952  if (should_retry(sc->pb, ret64)) {
9954  } else if (ret64 < 0) {
9955  return (int)ret64;
9956  }
9957  return AVERROR_INVALIDDATA;
9958  }
9959 
9960  if (st->discard == AVDISCARD_NONKEY && !(sample->flags & AVINDEX_KEYFRAME)) {
9961  av_log(mov->fc, AV_LOG_DEBUG, "Nonkey frame from stream %d discarded due to AVDISCARD_NONKEY\n", sc->ffindex);
9962  goto retry;
9963  }
9964 
9965  if (st->codecpar->codec_id == AV_CODEC_ID_EIA_608 && sample->size > 8)
9966  ret = get_eia608_packet(sc->pb, pkt, sample->size);
9967 #if CONFIG_IAMFDEC
9968  else if (sc->iamf) {
9969  int64_t pts, dts, pos, duration;
9970  int flags, size = sample->size;
9971  ret = mov_finalize_packet(s, st, sample, current_index, pkt);
9972  pts = pkt->pts; dts = pkt->dts;
9973  pos = pkt->pos; flags = pkt->flags;
9974  duration = pkt->duration;
9975  while (!ret && size > 0) {
9976  ret = ff_iamf_read_packet(s, sc->iamf, sc->pb, size, pkt);
9977  if (ret < 0) {
9978  if (should_retry(sc->pb, ret))
9980  return ret;
9981  }
9982  size -= ret;
9983  pkt->pts = pts; pkt->dts = dts;
9984  pkt->pos = pos; pkt->flags |= flags;
9985  pkt->duration = duration;
9986  ret = ff_buffer_packet(s, pkt);
9987  }
9988  if (!ret)
9989  return FFERROR_REDO;
9990  }
9991 #endif
9992  else
9993  ret = av_get_packet(sc->pb, pkt, sample->size);
9994  if (ret < 0) {
9995  if (should_retry(sc->pb, ret)) {
9997  }
9998  return ret;
9999  }
10000 #if CONFIG_DV_DEMUXER
10001  if (mov->dv_demux && sc->dv_audio_container) {
10004  if (ret < 0)
10005  return ret;
10007  if (ret < 0)
10008  return ret;
10009  }
10010 #endif
10011  if (sc->has_palette) {
10012  uint8_t *pal;
10013 
10015  if (!pal) {
10016  av_log(mov->fc, AV_LOG_ERROR, "Cannot append palette to packet\n");
10017  } else {
10018  memcpy(pal, sc->palette, AVPALETTE_SIZE);
10019  sc->has_palette = 0;
10020  }
10021  }
10022  if (st->codecpar->codec_id == AV_CODEC_ID_MP3 && !ffstream(st)->need_parsing && pkt->size > 4) {
10023  if (ff_mpa_check_header(AV_RB32(pkt->data)) < 0)
10025  }
10026  }
10027 
10028  ret = mov_finalize_packet(s, st, sample, current_index, pkt);
10029  if (ret < 0)
10030  return ret;
10031 
10032  if (st->discard == AVDISCARD_ALL)
10033  goto retry;
10034 
10035  if (mov->aax_mode)
10036  aax_filter(pkt->data, pkt->size, mov);
10037 
10038  ret = cenc_filter(mov, st, sc, pkt, current_index);
10039  if (ret < 0) {
10040  return ret;
10041  }
10042 
10043  return 0;
10044 }
10045 
10046 static int mov_seek_fragment(AVFormatContext *s, AVStream *st, int64_t timestamp)
10047 {
10048  MOVContext *mov = s->priv_data;
10049  int index;
10050 
10051  if (!mov->frag_index.complete)
10052  return 0;
10053 
10054  index = search_frag_timestamp(s, &mov->frag_index, st, timestamp);
10055  if (index < 0)
10056  index = 0;
10057  if (!mov->frag_index.item[index].headers_read)
10058  return mov_switch_root(s, -1, index);
10059  if (index + 1 < mov->frag_index.nb_items)
10060  mov->next_root_atom = mov->frag_index.item[index + 1].moof_offset;
10061 
10062  return 0;
10063 }
10064 
10065 static int is_open_key_sample(const MOVStreamContext *sc, int sample)
10066 {
10067  // TODO: a bisect search would scale much better
10068  for (int i = 0; i < sc->open_key_samples_count; i++) {
10069  const int oks = sc->open_key_samples[i];
10070  if (oks == sample)
10071  return 1;
10072  if (oks > sample) /* list is monotically increasing so we can stop early */
10073  break;
10074  }
10075  return 0;
10076 }
10077 
10078 /*
10079  * Some key sample may be key frames but not IDR frames, so a random access to
10080  * them may not be allowed.
10081  */
10082 static int can_seek_to_key_sample(AVStream *st, int sample, int64_t requested_pts)
10083 {
10084  MOVStreamContext *sc = st->priv_data;
10085  FFStream *const sti = ffstream(st);
10086  int64_t key_sample_dts, key_sample_pts;
10087 
10088  if (st->codecpar->codec_id != AV_CODEC_ID_HEVC)
10089  return 1;
10090 
10091  if (sample >= sc->sample_offsets_count)
10092  return 1;
10093 
10094  key_sample_dts = sti->index_entries[sample].timestamp;
10095  key_sample_pts = key_sample_dts + sc->sample_offsets[sample] + sc->dts_shift;
10096 
10097  /*
10098  * If the sample needs to be presented before an open key sample, they may
10099  * not be decodable properly, even though they come after in decoding
10100  * order.
10101  */
10102  if (is_open_key_sample(sc, sample) && key_sample_pts > requested_pts)
10103  return 0;
10104 
10105  return 1;
10106 }
10107 
10108 static int mov_seek_stream(AVFormatContext *s, AVStream *st, int64_t timestamp, int flags)
10109 {
10110  MOVStreamContext *sc = st->priv_data;
10111  FFStream *const sti = ffstream(st);
10112  int sample, time_sample, ret;
10113  unsigned int i;
10114 
10115  // Here we consider timestamp to be PTS, hence try to offset it so that we
10116  // can search over the DTS timeline.
10117  timestamp -= (sc->min_corrected_pts + sc->dts_shift);
10118 
10119  ret = mov_seek_fragment(s, st, timestamp);
10120  if (ret < 0)
10121  return ret;
10122 
10123  for (;;) {
10124  sample = av_index_search_timestamp(st, timestamp, flags);
10125  av_log(s, AV_LOG_TRACE, "stream %d, timestamp %"PRId64", sample %d\n", st->index, timestamp, sample);
10126  if (sample < 0 && sti->nb_index_entries && timestamp < sti->index_entries[0].timestamp)
10127  sample = 0;
10128  if (sample < 0) /* not sure what to do */
10129  return AVERROR_INVALIDDATA;
10130 
10131  if (!sample || can_seek_to_key_sample(st, sample, timestamp))
10132  break;
10133  timestamp -= FFMAX(sc->min_sample_duration, 1);
10134  }
10135 
10137  av_log(s, AV_LOG_TRACE, "stream %d, found sample %d\n", st->index, sc->current_sample);
10138  /* adjust ctts index */
10139  if (sc->ctts_data) {
10140  time_sample = 0;
10141  for (i = 0; i < sc->ctts_count; i++) {
10142  int next = time_sample + sc->ctts_data[i].count;
10143  if (next > sc->current_sample) {
10144  sc->ctts_index = i;
10145  sc->ctts_sample = sc->current_sample - time_sample;
10146  break;
10147  }
10148  time_sample = next;
10149  }
10150  }
10151 
10152  /* adjust stsd index */
10153  if (sc->chunk_count) {
10154  time_sample = 0;
10155  for (i = 0; i < sc->stsc_count; i++) {
10156  int64_t next = time_sample + mov_get_stsc_samples(sc, i);
10157  if (next > sc->current_sample) {
10158  sc->stsc_index = i;
10159  sc->stsc_sample = sc->current_sample - time_sample;
10160  break;
10161  }
10162  av_assert0(next == (int)next);
10163  time_sample = next;
10164  }
10165  }
10166 
10167  return sample;
10168 }
10169 
10170 static int64_t mov_get_skip_samples(AVStream *st, int sample)
10171 {
10172  MOVStreamContext *sc = st->priv_data;
10173  FFStream *const sti = ffstream(st);
10174  int64_t first_ts = sti->index_entries[0].timestamp;
10175  int64_t ts = sti->index_entries[sample].timestamp;
10176  int64_t off;
10177 
10179  return 0;
10180 
10181  /* compute skip samples according to stream start_pad, seek ts and first ts */
10182  off = av_rescale_q(ts - first_ts, st->time_base,
10183  (AVRational){1, st->codecpar->sample_rate});
10184  return FFMAX(sc->start_pad - off, 0);
10185 }
10186 
10187 static int mov_read_seek(AVFormatContext *s, int stream_index, int64_t sample_time, int flags)
10188 {
10189  MOVContext *mc = s->priv_data;
10190  AVStream *st;
10191  FFStream *sti;
10192  int sample;
10193  int i;
10194 
10195  if (stream_index >= s->nb_streams)
10196  return AVERROR_INVALIDDATA;
10197 
10198  st = s->streams[stream_index];
10199  sti = ffstream(st);
10200  sample = mov_seek_stream(s, st, sample_time, flags);
10201  if (sample < 0)
10202  return sample;
10203 
10204  if (mc->seek_individually) {
10205  /* adjust seek timestamp to found sample timestamp */
10206  int64_t seek_timestamp = sti->index_entries[sample].timestamp;
10208 
10209  for (i = 0; i < s->nb_streams; i++) {
10210  AVStream *const st = s->streams[i];
10211  FFStream *const sti = ffstream(st);
10212  int64_t timestamp;
10213 
10214  if (stream_index == i)
10215  continue;
10216 
10217  timestamp = av_rescale_q(seek_timestamp, s->streams[stream_index]->time_base, st->time_base);
10218  sample = mov_seek_stream(s, st, timestamp, flags);
10219  if (sample >= 0)
10221  }
10222  } else {
10223  for (i = 0; i < s->nb_streams; i++) {
10224  MOVStreamContext *sc;
10225  st = s->streams[i];
10226  sc = st->priv_data;
10227  mov_current_sample_set(sc, 0);
10228  }
10229  while (1) {
10230  MOVStreamContext *sc;
10232  if (!entry)
10233  return AVERROR_INVALIDDATA;
10234  sc = st->priv_data;
10235  if (sc->ffindex == stream_index && sc->current_sample == sample)
10236  break;
10238  }
10239  }
10240  return 0;
10241 }
10242 
10243 #define OFFSET(x) offsetof(MOVContext, x)
10244 #define FLAGS AV_OPT_FLAG_VIDEO_PARAM | AV_OPT_FLAG_DECODING_PARAM
10245 static const AVOption mov_options[] = {
10246  {"use_absolute_path",
10247  "allow using absolute path when opening alias, this is a possible security issue",
10248  OFFSET(use_absolute_path), AV_OPT_TYPE_BOOL, {.i64 = 0},
10249  0, 1, FLAGS},
10250  {"seek_streams_individually",
10251  "Seek each stream individually to the closest point",
10252  OFFSET(seek_individually), AV_OPT_TYPE_BOOL, { .i64 = 1 },
10253  0, 1, FLAGS},
10254  {"ignore_editlist", "Ignore the edit list atom.", OFFSET(ignore_editlist), AV_OPT_TYPE_BOOL, {.i64 = 0},
10255  0, 1, FLAGS},
10256  {"advanced_editlist",
10257  "Modify the AVIndex according to the editlists. Use this option to decode in the order specified by the edits.",
10258  OFFSET(advanced_editlist), AV_OPT_TYPE_BOOL, {.i64 = 1},
10259  0, 1, FLAGS},
10260  {"ignore_chapters", "", OFFSET(ignore_chapters), AV_OPT_TYPE_BOOL, {.i64 = 0},
10261  0, 1, FLAGS},
10262  {"use_mfra_for",
10263  "use mfra for fragment timestamps",
10264  OFFSET(use_mfra_for), AV_OPT_TYPE_INT, {.i64 = FF_MOV_FLAG_MFRA_AUTO},
10266  .unit = "use_mfra_for"},
10267  {"auto", "auto", 0, AV_OPT_TYPE_CONST, {.i64 = FF_MOV_FLAG_MFRA_AUTO}, 0, 0,
10268  FLAGS, .unit = "use_mfra_for" },
10269  {"dts", "dts", 0, AV_OPT_TYPE_CONST, {.i64 = FF_MOV_FLAG_MFRA_DTS}, 0, 0,
10270  FLAGS, .unit = "use_mfra_for" },
10271  {"pts", "pts", 0, AV_OPT_TYPE_CONST, {.i64 = FF_MOV_FLAG_MFRA_PTS}, 0, 0,
10272  FLAGS, .unit = "use_mfra_for" },
10273  {"use_tfdt", "use tfdt for fragment timestamps", OFFSET(use_tfdt), AV_OPT_TYPE_BOOL, {.i64 = 1},
10274  0, 1, FLAGS},
10275  { "export_all", "Export unrecognized metadata entries", OFFSET(export_all),
10276  AV_OPT_TYPE_BOOL, { .i64 = 0 }, 0, 1, .flags = FLAGS },
10277  { "export_xmp", "Export full XMP metadata", OFFSET(export_xmp),
10278  AV_OPT_TYPE_BOOL, { .i64 = 0 }, 0, 1, .flags = FLAGS },
10279  { "activation_bytes", "Secret bytes for Audible AAX files", OFFSET(activation_bytes),
10281  { "audible_key", "AES-128 Key for Audible AAXC files", OFFSET(audible_key),
10283  { "audible_iv", "AES-128 IV for Audible AAXC files", OFFSET(audible_iv),
10285  { "audible_fixed_key", // extracted from libAAX_SDK.so and AAXSDKWin.dll files!
10286  "Fixed key used for handling Audible AAX files", OFFSET(audible_fixed_key),
10287  AV_OPT_TYPE_BINARY, {.str="77214d4b196a87cd520045fd20a51d67"},
10288  .flags = AV_OPT_FLAG_DECODING_PARAM },
10289  { "decryption_key", "The media decryption key (hex)", OFFSET(decryption_key), AV_OPT_TYPE_BINARY, .flags = AV_OPT_FLAG_DECODING_PARAM },
10290  { "enable_drefs", "Enable external track support.", OFFSET(enable_drefs), AV_OPT_TYPE_BOOL,
10291  {.i64 = 0}, 0, 1, FLAGS },
10292  { "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 },
10293  { "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 },
10294 
10295  { NULL },
10296 };
10297 
10298 static const AVClass mov_class = {
10299  .class_name = "mov,mp4,m4a,3gp,3g2,mj2",
10300  .item_name = av_default_item_name,
10301  .option = mov_options,
10302  .version = LIBAVUTIL_VERSION_INT,
10303 };
10304 
10306  .p.name = "mov,mp4,m4a,3gp,3g2,mj2",
10307  .p.long_name = NULL_IF_CONFIG_SMALL("QuickTime / MOV"),
10308  .p.priv_class = &mov_class,
10309  .p.extensions = "mov,mp4,m4a,3gp,3g2,mj2,psp,m4b,ism,ismv,isma,f4v,avif,heic,heif",
10311  .priv_data_size = sizeof(MOVContext),
10312  .flags_internal = FF_INFMT_FLAG_INIT_CLEANUP,
10313  .read_probe = mov_probe,
10318 };
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:574
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:6669
mov_read_meta
static int mov_read_meta(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:5207
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:2274
read_image_iovl
static int read_image_iovl(AVFormatContext *s, const HEIFGrid *grid, AVStreamGroupTileGrid *tile_grid)
Definition: mov.c:9332
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:7732
can_seek_to_key_sample
static int can_seek_to_key_sample(AVStream *st, int sample, int64_t requested_pts)
Definition: mov.c:10082
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:10298
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:2117
mov_read_chnl
static int mov_read_chnl(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:1163
mov_read_moof
static int mov_read_moof(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:1671
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:9113
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:10245
mov_codec_id
static int mov_codec_id(AVStream *st, uint32_t format)
Definition: mov.c:2442
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:8050
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
AVStreamGroupTileGrid::offsets
struct AVStreamGroupTileGrid::@308 * offsets
An nb_tiles sized array of offsets in pixels from the topleft edge of the canvas, indicating where ea...
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:2089
test_same_origin
static int test_same_origin(const char *src, const char *ref)
Definition: mov.c:4704
cbcs_scheme_decrypt
static int cbcs_scheme_decrypt(MOVContext *c, MOVStreamContext *sc, AVEncryptionInfo *sample, uint8_t *input, int size)
Definition: mov.c:7559
MOVFragment::base_data_offset
uint64_t base_data_offset
Definition: isom.h:98
MOVStreamContext
Definition: isom.h:167
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:5225
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:3474
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:2094
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:5069
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:2063
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:1773
mov_read_idat
static int mov_read_idat(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:8044
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:2109
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:346
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:3151
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:5233
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:1927
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:1812
mov_read_strf
static int mov_read_strf(MOVContext *c, AVIOContext *pb, MOVAtom atom)
An strf atom is a BITMAPINFOHEADER struct.
Definition: mov.c:2355
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:2673
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:6877
mov_seek_stream
static int mov_seek_stream(AVFormatContext *s, AVStream *st, int64_t timestamp, int flags)
Definition: mov.c:10108
mov_read_saio
static int mov_read_saio(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:7023
mov_get_stsc_samples
static int64_t mov_get_stsc_samples(MOVStreamContext *sc, unsigned int index)
Definition: mov.c:3136
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:518
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:3668
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:9816
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:3972
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:1425
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:823
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:2377
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:7666
mov_read_sdtp
static int mov_read_sdtp(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:3440
mov_read_jp2h
static int mov_read_jp2h(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:2099
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:5338
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:5916
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
OFFSET
#define OFFSET(x)
Definition: mov.c:10243
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:1363
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:241
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:1727
mov_read_ctts
static int mov_read_ctts(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:3485
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:179
mov_read_aclr
static int mov_read_aclr(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:2174
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:1482
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:8019
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:6270
mov_read_enda
static int mov_read_enda(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:1841
mov_read_chap
static int mov_read_chap(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:5385
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:1595
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:6939
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:2131
mov_read_adrm
static int mov_read_adrm(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:1239
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
AVStreamGroup::params
union AVStreamGroup::@309 params
Group type-specific parameters.
mov_free_encryption_index
static void mov_free_encryption_index(MOVEncryptionIndex **index)
Definition: mov.c:8992
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:90
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:6204
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:4861
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:1237
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
FLAC_METADATA_TYPE_STREAMINFO
@ FLAC_METADATA_TYPE_STREAMINFO
Definition: flac.h:46
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:3892
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:5778
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:9743
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:7816
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:328
mov_read_stss
static int mov_read_stss(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:3187
mov_read_ddts
static int mov_read_ddts(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:1091
mov_read_uuid
static int mov_read_uuid(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:6542
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:3891
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:9065
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:5936
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:6767
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:7993
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:3325
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:1462
mov_read_free
static int mov_read_free(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:6647
mov_realloc_extradata
static int mov_realloc_extradata(AVCodecParameters *par, MOVAtom atom)
Definition: mov.c:2026
AVStream::codecpar
AVCodecParameters * codecpar
Codec parameters associated with this stream.
Definition: avformat.h:766
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
AV_CHANNEL_ORDER_AMBISONIC
@ AV_CHANNEL_ORDER_AMBISONIC
The audio is represented as the decomposition of the sound field into spherical harmonics.
Definition: channel_layout.h:148
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:1377
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:9248
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:3551
mov_probe
static int mov_probe(const AVProbeData *p)
Definition: mov.c:8712
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:6113
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:4733
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:7239
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:8279
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:5014
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
get_frag_stream_info_from_pkt
static MOVFragmentStreamInfo * get_frag_stream_info_from_pkt(MOVFragmentIndex *frag_index, AVPacket *pkt, int id)
Definition: mov.c:7641
get_sgpd_sync_index
static uint32_t get_sgpd_sync_index(const MOVStreamContext *sc, int nal_unit_type)
Definition: mov.c:4305
mov_read_fiel
static int mov_read_fiel(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:1992
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:1195
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:2657
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:2867
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:9773
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:1211
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:7925
mov_read_elst
static int mov_read_elst(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:5989
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:9480
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:7434
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:2222
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:7494
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:9004
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:6716
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:613
mov_current_sample_dec
static void mov_current_sample_dec(MOVStreamContext *sc)
Definition: mov.c:3960
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:3710
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:121
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:5471
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:8364
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:1144
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:3055
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:3807
MOVDref::path
char * path
Definition: isom.h:81
mov_current_sample_inc
static void mov_current_sample_inc(MOVStreamContext *sc)
Definition: mov.c:3948
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:4805
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_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:8590
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:9919
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:2335
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:6241
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
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:7341
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:8470
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:1697
mov_metadata_hmmt
static int mov_metadata_hmmt(MOVContext *c, AVIOContext *pb, unsigned len)
Definition: mov.c:307
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:7270
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:3130
mov_finalize_packet
static int mov_finalize_packet(AVFormatContext *s, AVStream *st, AVIndexEntry *sample, int64_t current_index, AVPacket *pkt)
Definition: mov.c:9861
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:10187
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:149
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:5406
search_frag_timestamp
static int search_frag_timestamp(AVFormatContext *s, MOVFragmentIndex *frag_index, AVStream *st, int64_t timestamp)
Definition: mov.c:1570
HEIFItem::width
int width
Definition: isom.h:278
FLAGS
#define FLAGS
Definition: mov.c:10244
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:4000
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:7118
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:2990
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:2689
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:2893
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:6069
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:1656
mov_finalize_stsd_codec
static int mov_finalize_stsd_codec(MOVContext *c, AVIOContext *pb, AVStream *st, MOVStreamContext *sc)
Definition: mov.c:2767
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:6160
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:1229
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:5023
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:4376
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:2217
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:8180
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:1522
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:3848
AV_WB8
#define AV_WB8(p, d)
Definition: intreadwrite.h:394
MOVStreamContext::cenc
struct MOVStreamContext::@330 cenc
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:6058
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:1787
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:6821
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:7781
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:5432
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:5150
search_frag_moof_offset
static int search_frag_moof_offset(MOVFragmentIndex *frag_index, int64_t offset)
Definition: mov.c:1498
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:9780
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:3864
MOVStreamContext::encryption_index
MOVEncryptionIndex * encryption_index
Definition: isom.h:266
MIN_DATA_ENTRY_BOX_SIZE
#define MIN_DATA_ENTRY_BOX_SIZE
Definition: mov.c:612
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:10046
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:2482
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:1048
get_frag_time
static int64_t get_frag_time(AVFormatContext *s, AVStream *dst_st, MOVFragmentIndex *frag_index, int index)
Definition: mov.c:1532
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:3607
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:2279
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:6479
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:235
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
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:6342
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:1338
mov_get_skip_samples
static int64_t mov_get_skip_samples(AVStream *st, int sample)
Definition: mov.c:10170
MOVFragmentIndex
Definition: isom.h:154
mov_read_infe
static int mov_read_infe(MOVContext *c, AVIOContext *pb, MOVAtom atom, int idx)
Definition: mov.c:8127
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:110
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:214
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:9129
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:133
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:2104
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:273
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:8919
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:9397
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:8220
mov_read_pcmc
static int mov_read_pcmc(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:1850
build_open_gop_key_points
static int build_open_gop_key_points(AVStream *st)
Definition: mov.c:4313
mov_parse_stsd_audio
static void mov_parse_stsd_audio(MOVContext *c, AVIOContext *pb, AVStream *st, MOVStreamContext *sc)
Definition: mov.c:2540
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:8945
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:168
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:9147
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
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:251
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:257
AV_CODEC_ID_ILBC
@ AV_CODEC_ID_ILBC
Definition: codec_id.h:499
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:8905
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:10305
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:190
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:7625
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:8341
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:8303
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:9202
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:124
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:1443
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:7836
int
int
Definition: ffmpeg_filter.c:424
MOVStreamContext::stts_count
unsigned int stts_count
Definition: isom.h:176
MOV_TRUN_SAMPLE_CTS
#define MOV_TRUN_SAMPLE_CTS
Definition: isom.h:386
AV_OPT_TYPE_CONST
@ AV_OPT_TYPE_CONST
Definition: opt.h:244
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:9840
mov_read_st3d
static int mov_read_st3d(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:6295
is_open_key_sample
static int is_open_key_sample(const MOVStreamContext *sc, int sample)
Definition: mov.c:10065
mov_read_dvc1
static int mov_read_dvc1(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:2325
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
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:2041
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:8806
AV_CODEC_ID_DNXHD
@ AV_CODEC_ID_DNXHD
Definition: codec_id.h:151
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:7381
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:757
mov_parse_stsd_data
static int mov_parse_stsd_data(MOVContext *c, AVIOContext *pb, AVStream *st, MOVStreamContext *sc, int64_t size)
Definition: mov.c:2721
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:327
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:8036
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:828
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:3237