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