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