FFmpeg
mov.c
Go to the documentation of this file.
1 /*
2  * MOV demuxer
3  * Copyright (c) 2001 Fabrice Bellard
4  * Copyright (c) 2009 Baptiste Coudurier <baptiste dot coudurier at gmail dot com>
5  *
6  * first version by Francois Revol <revol@free.fr>
7  * seek function by Gael Chardon <gael.dev@4now.net>
8  *
9  * This file is part of FFmpeg.
10  *
11  * FFmpeg is free software; you can redistribute it and/or
12  * modify it under the terms of the GNU Lesser General Public
13  * License as published by the Free Software Foundation; either
14  * version 2.1 of the License, or (at your option) any later version.
15  *
16  * FFmpeg is distributed in the hope that it will be useful,
17  * but WITHOUT ANY WARRANTY; without even the implied warranty of
18  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
19  * Lesser General Public License for more details.
20  *
21  * You should have received a copy of the GNU Lesser General Public
22  * License along with FFmpeg; if not, write to the Free Software
23  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
24  */
25 
26 #include "config_components.h"
27 
28 #include <inttypes.h>
29 #include <limits.h>
30 #include <stdint.h>
31 
32 #include "libavutil/attributes.h"
33 #include "libavutil/bprint.h"
36 #include "libavutil/internal.h"
37 #include "libavutil/intreadwrite.h"
38 #include "libavutil/intfloat.h"
39 #include "libavutil/mathematics.h"
40 #include "libavutil/avassert.h"
41 #include "libavutil/avstring.h"
42 #include "libavutil/dict.h"
43 #include "libavutil/display.h"
44 #include "libavutil/mem.h"
45 #include "libavutil/opt.h"
46 #include "libavutil/aes.h"
47 #include "libavutil/aes_ctr.h"
48 #include "libavutil/pixdesc.h"
49 #include "libavutil/sha.h"
50 #include "libavutil/spherical.h"
51 #include "libavutil/stereo3d.h"
52 #include "libavutil/timecode.h"
53 #include "libavutil/uuid.h"
54 #include "libavcodec/ac3tab.h"
55 #include "libavcodec/flac.h"
56 #include "libavcodec/hevc/hevc.h"
58 #include "libavcodec/mlp_parse.h"
59 #include "avformat.h"
60 #include "internal.h"
61 #include "avio_internal.h"
62 #include "demux.h"
63 #include "dvdclut.h"
64 #include "iamf_parse.h"
65 #include "iamf_reader.h"
66 #include "dovi_isom.h"
67 #include "riff.h"
68 #include "isom.h"
69 #include "libavcodec/get_bits.h"
70 #include "id3v1.h"
71 #include "mov_chan.h"
72 #include "replaygain.h"
73 
74 #if CONFIG_ZLIB
75 #include <zlib.h>
76 #endif
77 
78 #include "qtpalette.h"
79 
80 /* those functions parse an atom */
81 /* links atom IDs to parse functions */
82 typedef struct MOVParseTableEntry {
83  uint32_t type;
84  int (*parse)(MOVContext *ctx, AVIOContext *pb, MOVAtom atom);
86 
87 static int mov_read_default(MOVContext *c, AVIOContext *pb, MOVAtom atom);
88 static int mov_read_mfra(MOVContext *c, AVIOContext *f);
90 
92  unsigned len, const char *key)
93 {
94  char buf[16];
95 
96  short current, total = 0;
97  avio_rb16(pb); // unknown
98  current = avio_rb16(pb);
99  if (len >= 6)
100  total = avio_rb16(pb);
101  if (!total)
102  snprintf(buf, sizeof(buf), "%d", current);
103  else
104  snprintf(buf, sizeof(buf), "%d/%d", current, total);
105  c->fc->event_flags |= AVFMT_EVENT_FLAG_METADATA_UPDATED;
106  av_dict_set(&c->fc->metadata, key, buf, 0);
107 
108  return 0;
109 }
110 
112  unsigned len, const char *key)
113 {
114  /* bypass padding bytes */
115  avio_r8(pb);
116  avio_r8(pb);
117  avio_r8(pb);
118 
119  c->fc->event_flags |= AVFMT_EVENT_FLAG_METADATA_UPDATED;
120  av_dict_set_int(&c->fc->metadata, key, avio_r8(pb), 0);
121 
122  return 0;
123 }
124 
126  unsigned len, const char *key)
127 {
128  c->fc->event_flags |= AVFMT_EVENT_FLAG_METADATA_UPDATED;
129  av_dict_set_int(&c->fc->metadata, key, avio_r8(pb), 0);
130 
131  return 0;
132 }
133 
135  unsigned len, const char *key)
136 {
137  short genre;
138 
139  avio_r8(pb); // unknown
140 
141  genre = avio_r8(pb);
142  if (genre < 1 || genre > ID3v1_GENRE_MAX)
143  return 0;
144  c->fc->event_flags |= AVFMT_EVENT_FLAG_METADATA_UPDATED;
145  av_dict_set(&c->fc->metadata, key, ff_id3v1_genre_str[genre-1], 0);
146 
147  return 0;
148 }
149 
150 static const uint32_t mac_to_unicode[128] = {
151  0x00C4,0x00C5,0x00C7,0x00C9,0x00D1,0x00D6,0x00DC,0x00E1,
152  0x00E0,0x00E2,0x00E4,0x00E3,0x00E5,0x00E7,0x00E9,0x00E8,
153  0x00EA,0x00EB,0x00ED,0x00EC,0x00EE,0x00EF,0x00F1,0x00F3,
154  0x00F2,0x00F4,0x00F6,0x00F5,0x00FA,0x00F9,0x00FB,0x00FC,
155  0x2020,0x00B0,0x00A2,0x00A3,0x00A7,0x2022,0x00B6,0x00DF,
156  0x00AE,0x00A9,0x2122,0x00B4,0x00A8,0x2260,0x00C6,0x00D8,
157  0x221E,0x00B1,0x2264,0x2265,0x00A5,0x00B5,0x2202,0x2211,
158  0x220F,0x03C0,0x222B,0x00AA,0x00BA,0x03A9,0x00E6,0x00F8,
159  0x00BF,0x00A1,0x00AC,0x221A,0x0192,0x2248,0x2206,0x00AB,
160  0x00BB,0x2026,0x00A0,0x00C0,0x00C3,0x00D5,0x0152,0x0153,
161  0x2013,0x2014,0x201C,0x201D,0x2018,0x2019,0x00F7,0x25CA,
162  0x00FF,0x0178,0x2044,0x20AC,0x2039,0x203A,0xFB01,0xFB02,
163  0x2021,0x00B7,0x201A,0x201E,0x2030,0x00C2,0x00CA,0x00C1,
164  0x00CB,0x00C8,0x00CD,0x00CE,0x00CF,0x00CC,0x00D3,0x00D4,
165  0xF8FF,0x00D2,0x00DA,0x00DB,0x00D9,0x0131,0x02C6,0x02DC,
166  0x00AF,0x02D8,0x02D9,0x02DA,0x00B8,0x02DD,0x02DB,0x02C7,
167 };
168 
170  char *dst, int dstlen)
171 {
172  char *p = dst;
173  char *end = dst+dstlen-1;
174  int i;
175 
176  for (i = 0; i < len; i++) {
177  uint8_t t, c = avio_r8(pb);
178 
179  if (p >= end)
180  continue;
181 
182  if (c < 0x80)
183  *p++ = c;
184  else if (p < end)
185  PUT_UTF8(mac_to_unicode[c-0x80], t, if (p < end) *p++ = t;);
186  }
187  *p = 0;
188  return p - dst;
189 }
190 
191 /**
192  * Get the current item in the parsing process.
193  */
195 {
196  HEIFItem *item = NULL;
197 
198  for (int i = 0; i < c->nb_heif_item; i++) {
199  if (!c->heif_item[i] || c->heif_item[i]->item_id != c->cur_item_id)
200  continue;
201 
202  item = c->heif_item[i];
203  break;
204  }
205 
206  return item;
207 }
208 
209 /**
210  * Get the current stream in the parsing process. This can either be the
211  * latest stream added to the context, or the stream referenced by an item.
212  */
214 {
215  AVStream *st = NULL;
216  HEIFItem *item;
217 
218  if (c->fc->nb_streams < 1)
219  return NULL;
220 
221  if (c->cur_item_id == -1)
222  return c->fc->streams[c->fc->nb_streams-1];
223 
224  item = heif_cur_item(c);
225  if (item)
226  st = item->st;
227 
228  return st;
229 }
230 
231 static int mov_read_covr(MOVContext *c, AVIOContext *pb, int type, int len)
232 {
233  AVStream *st;
234  MOVStreamContext *sc;
235  enum AVCodecID id;
236  int ret;
237 
238  switch (type) {
239  case 0xd: id = AV_CODEC_ID_MJPEG; break;
240  case 0xe: id = AV_CODEC_ID_PNG; break;
241  case 0x1b: id = AV_CODEC_ID_BMP; break;
242  default:
243  av_log(c->fc, AV_LOG_WARNING, "Unknown cover type: 0x%x.\n", type);
244  avio_skip(pb, len);
245  return 0;
246  }
247 
248  sc = av_mallocz(sizeof(*sc));
249  if (!sc)
250  return AVERROR(ENOMEM);
251  ret = ff_add_attached_pic(c->fc, NULL, pb, NULL, len);
252  if (ret < 0) {
253  av_free(sc);
254  return ret;
255  }
256  st = c->fc->streams[c->fc->nb_streams - 1];
257  st->priv_data = sc;
258  sc->id = st->id;
259  sc->refcount = 1;
260 
261  if (st->attached_pic.size >= 8 && id != AV_CODEC_ID_BMP) {
262  if (AV_RB64(st->attached_pic.data) == 0x89504e470d0a1a0a) {
263  id = AV_CODEC_ID_PNG;
264  } else {
265  id = AV_CODEC_ID_MJPEG;
266  }
267  }
268  st->codecpar->codec_id = id;
269 
270  return 0;
271 }
272 
273 // 3GPP TS 26.244
274 static int mov_metadata_loci(MOVContext *c, AVIOContext *pb, unsigned len)
275 {
276  char language[4] = { 0 };
277  char buf[200], place[100];
278  uint16_t langcode = 0;
279  double longitude, latitude, altitude;
280  const char *key = "location";
281 
282  if (len < 4 + 2 + 1 + 1 + 4 + 4 + 4) {
283  av_log(c->fc, AV_LOG_ERROR, "loci too short\n");
284  return AVERROR_INVALIDDATA;
285  }
286 
287  avio_skip(pb, 4); // version+flags
288  langcode = avio_rb16(pb);
289  ff_mov_lang_to_iso639(langcode, language);
290  len -= 6;
291 
292  len -= avio_get_str(pb, len, place, sizeof(place));
293  if (len < 1) {
294  av_log(c->fc, AV_LOG_ERROR, "place name too long\n");
295  return AVERROR_INVALIDDATA;
296  }
297  avio_skip(pb, 1); // role
298  len -= 1;
299 
300  if (len < 12) {
301  av_log(c->fc, AV_LOG_ERROR,
302  "loci too short (%u bytes left, need at least %d)\n", len, 12);
303  return AVERROR_INVALIDDATA;
304  }
305  longitude = ((int32_t) avio_rb32(pb)) / (float) (1 << 16);
306  latitude = ((int32_t) avio_rb32(pb)) / (float) (1 << 16);
307  altitude = ((int32_t) avio_rb32(pb)) / (float) (1 << 16);
308 
309  // Try to output in the same format as the ?xyz field
310  snprintf(buf, sizeof(buf), "%+08.4f%+09.4f", latitude, longitude);
311  if (altitude)
312  av_strlcatf(buf, sizeof(buf), "%+f", altitude);
313  av_strlcatf(buf, sizeof(buf), "/%s", place);
314 
315  if (*language && strcmp(language, "und")) {
316  char key2[16];
317  snprintf(key2, sizeof(key2), "%s-%s", key, language);
318  av_dict_set(&c->fc->metadata, key2, buf, 0);
319  }
320  c->fc->event_flags |= AVFMT_EVENT_FLAG_METADATA_UPDATED;
321  return av_dict_set(&c->fc->metadata, key, buf, 0);
322 }
323 
324 static int mov_metadata_hmmt(MOVContext *c, AVIOContext *pb, unsigned len)
325 {
326  int i, n_hmmt;
327 
328  if (len < 2)
329  return 0;
330  if (c->ignore_chapters)
331  return 0;
332 
333  n_hmmt = avio_rb32(pb);
334  if (n_hmmt > len / 4)
335  return AVERROR_INVALIDDATA;
336  for (i = 0; i < n_hmmt && !pb->eof_reached; i++) {
337  int moment_time = avio_rb32(pb);
338  avpriv_new_chapter(c->fc, i, av_make_q(1, 1000), moment_time, AV_NOPTS_VALUE, NULL);
339  }
340  if (avio_feof(pb))
341  return AVERROR_INVALIDDATA;
342  return 0;
343 }
344 
346 {
347  char tmp_key[AV_FOURCC_MAX_STRING_SIZE] = {0};
348  char key2[32], language[4] = {0};
349  char *str = NULL;
350  const char *key = NULL;
351  uint16_t langcode = 0;
352  uint32_t data_type = 0, str_size_alloc;
353  uint64_t str_size;
354  int (*parse)(MOVContext*, AVIOContext*, unsigned, const char*) = NULL;
355  int raw = 0;
356  int num = 0;
357 
358  switch (atom.type) {
359  case MKTAG( '@','P','R','M'): key = "premiere_version"; raw = 1; break;
360  case MKTAG( '@','P','R','Q'): key = "quicktime_version"; raw = 1; break;
361  case MKTAG( 'X','M','P','_'):
362  if (c->export_xmp) { key = "xmp"; raw = 1; } break;
363  case MKTAG( 'a','A','R','T'): key = "album_artist"; break;
364  case MKTAG( 'a','k','I','D'): key = "account_type";
366  case MKTAG( 'a','p','I','D'): key = "account_id"; break;
367  case MKTAG( 'c','a','t','g'): key = "category"; break;
368  case MKTAG( 'c','p','i','l'): key = "compilation";
370  case MKTAG( 'c','p','r','t'): key = "copyright"; break;
371  case MKTAG( 'd','e','s','c'): key = "description"; break;
372  case MKTAG( 'd','i','s','k'): key = "disc";
374  case MKTAG( 'e','g','i','d'): key = "episode_uid";
376  case MKTAG( 'F','I','R','M'): key = "firmware"; raw = 1; break;
377  case MKTAG( 'g','n','r','e'): key = "genre";
378  parse = mov_metadata_gnre; break;
379  case MKTAG( 'h','d','v','d'): key = "hd_video";
381  case MKTAG( 'H','M','M','T'):
382  return mov_metadata_hmmt(c, pb, atom.size);
383  case MKTAG( 'k','e','y','w'): key = "keywords"; break;
384  case MKTAG( 'l','d','e','s'): key = "synopsis"; break;
385  case MKTAG( 'l','o','c','i'):
386  return mov_metadata_loci(c, pb, atom.size);
387  case MKTAG( 'm','a','n','u'): key = "make"; break;
388  case MKTAG( 'm','o','d','l'): key = "model"; break;
389  case MKTAG( 'p','c','s','t'): key = "podcast";
391  case MKTAG( 'p','g','a','p'): key = "gapless_playback";
393  case MKTAG( 'p','u','r','d'): key = "purchase_date"; break;
394  case MKTAG( 'r','t','n','g'): key = "rating";
396  case MKTAG( 's','o','a','a'): key = "sort_album_artist"; break;
397  case MKTAG( 's','o','a','l'): key = "sort_album"; break;
398  case MKTAG( 's','o','a','r'): key = "sort_artist"; break;
399  case MKTAG( 's','o','c','o'): key = "sort_composer"; break;
400  case MKTAG( 's','o','n','m'): key = "sort_name"; break;
401  case MKTAG( 's','o','s','n'): key = "sort_show"; break;
402  case MKTAG( 's','t','i','k'): key = "media_type";
404  case MKTAG( 't','r','k','n'): key = "track";
406  case MKTAG( 't','v','e','n'): key = "episode_id"; break;
407  case MKTAG( 't','v','e','s'): key = "episode_sort";
409  case MKTAG( 't','v','n','n'): key = "network"; break;
410  case MKTAG( 't','v','s','h'): key = "show"; break;
411  case MKTAG( 't','v','s','n'): key = "season_number";
413  case MKTAG(0xa9,'A','R','T'): key = "artist"; break;
414  case MKTAG(0xa9,'P','R','D'): key = "producer"; break;
415  case MKTAG(0xa9,'a','l','b'): key = "album"; break;
416  case MKTAG(0xa9,'a','u','t'): key = "artist"; break;
417  case MKTAG(0xa9,'c','h','p'): key = "chapter"; break;
418  case MKTAG(0xa9,'c','m','t'): key = "comment"; break;
419  case MKTAG(0xa9,'c','o','m'): key = "composer"; break;
420  case MKTAG(0xa9,'c','p','y'): key = "copyright"; break;
421  case MKTAG(0xa9,'d','a','y'): key = "date"; break;
422  case MKTAG(0xa9,'d','i','r'): key = "director"; break;
423  case MKTAG(0xa9,'d','i','s'): key = "disclaimer"; break;
424  case MKTAG(0xa9,'e','d','1'): key = "edit_date"; break;
425  case MKTAG(0xa9,'e','n','c'): key = "encoder"; break;
426  case MKTAG(0xa9,'f','m','t'): key = "original_format"; break;
427  case MKTAG(0xa9,'g','e','n'): key = "genre"; break;
428  case MKTAG(0xa9,'g','r','p'): key = "grouping"; break;
429  case MKTAG(0xa9,'h','s','t'): key = "host_computer"; break;
430  case MKTAG(0xa9,'i','n','f'): key = "comment"; break;
431  case MKTAG(0xa9,'l','y','r'): key = "lyrics"; break;
432  case MKTAG(0xa9,'m','a','k'): key = "make"; break;
433  case MKTAG(0xa9,'m','o','d'): key = "model"; break;
434  case MKTAG(0xa9,'n','a','m'): key = "title"; break;
435  case MKTAG(0xa9,'o','p','e'): key = "original_artist"; break;
436  case MKTAG(0xa9,'p','r','d'): key = "producer"; break;
437  case MKTAG(0xa9,'p','r','f'): key = "performers"; break;
438  case MKTAG(0xa9,'r','e','q'): key = "playback_requirements"; break;
439  case MKTAG(0xa9,'s','r','c'): key = "original_source"; break;
440  case MKTAG(0xa9,'s','t','3'): key = "subtitle"; break;
441  case MKTAG(0xa9,'s','w','r'): key = "encoder"; break;
442  case MKTAG(0xa9,'t','o','o'): key = "encoder"; break;
443  case MKTAG(0xa9,'t','r','k'): key = "track"; break;
444  case MKTAG(0xa9,'u','r','l'): key = "URL"; break;
445  case MKTAG(0xa9,'w','r','n'): key = "warning"; break;
446  case MKTAG(0xa9,'w','r','t'): key = "composer"; break;
447  case MKTAG(0xa9,'x','y','z'): key = "location"; break;
448  }
449 retry:
450  if (c->itunes_metadata && atom.size > 8) {
451  int data_size = avio_rb32(pb);
452  int tag = avio_rl32(pb);
453  if (tag == MKTAG('d','a','t','a') && data_size <= atom.size && data_size >= 16) {
454  data_type = avio_rb32(pb); // type
455  avio_rb32(pb); // unknown
456  str_size = data_size - 16;
457  atom.size -= 16;
458 
459  if (!key && c->found_hdlr_mdta && c->meta_keys) {
460  uint32_t index = av_bswap32(atom.type); // BE number has been read as LE
461  if (index < c->meta_keys_count && index > 0) {
462  key = c->meta_keys[index];
463  } else if (atom.type != MKTAG('c', 'o', 'v', 'r')) {
464  av_log(c->fc, AV_LOG_WARNING,
465  "The index of 'data' is out of range: %"PRId32" < 1 or >= %d.\n",
466  index, c->meta_keys_count);
467  }
468  }
469  if (atom.type == MKTAG('c', 'o', 'v', 'r') ||
470  (key && !strcmp(key, "com.apple.quicktime.artwork"))) {
471  int ret = mov_read_covr(c, pb, data_type, str_size);
472  if (ret < 0) {
473  av_log(c->fc, AV_LOG_ERROR, "Error parsing cover art.\n");
474  return ret;
475  }
476  atom.size -= str_size;
477  if (atom.size > 8)
478  goto retry;
479  return ret;
480  }
481  } else return 0;
482  } else if (atom.size > 4 && key && !c->itunes_metadata && !raw) {
483  str_size = avio_rb16(pb); // string length
484  if (str_size > atom.size) {
485  raw = 1;
486  avio_seek(pb, -2, SEEK_CUR);
487  av_log(c->fc, AV_LOG_WARNING, "UDTA parsing failed retrying raw\n");
488  goto retry;
489  }
490  langcode = avio_rb16(pb);
491  ff_mov_lang_to_iso639(langcode, language);
492  atom.size -= 4;
493  } else
494  str_size = atom.size;
495 
496  if (c->export_all && !key) {
497  key = av_fourcc_make_string(tmp_key, atom.type);
498  }
499 
500  if (!key)
501  return 0;
502  if (atom.size < 0 || str_size >= INT_MAX/2)
503  return AVERROR_INVALIDDATA;
504 
505  // Allocates enough space if data_type is a int32 or float32 number, otherwise
506  // worst-case requirement for output string in case of utf8 coded input
507  num = (data_type >= 21 && data_type <= 23);
508  str_size_alloc = (num ? 512 : (raw ? str_size : str_size * 2)) + 1;
509  str = av_mallocz(str_size_alloc);
510  if (!str)
511  return AVERROR(ENOMEM);
512 
513  if (parse)
514  parse(c, pb, str_size, key);
515  else {
516  if (!raw && (data_type == 3 || (data_type == 0 && (langcode < 0x400 || langcode == 0x7fff)))) { // MAC Encoded
517  mov_read_mac_string(c, pb, str_size, str, str_size_alloc);
518  } else if (data_type == 21) { // BE signed integer, variable size
519  int val = 0;
520  if (str_size == 1)
521  val = (int8_t)avio_r8(pb);
522  else if (str_size == 2)
523  val = (int16_t)avio_rb16(pb);
524  else if (str_size == 3)
525  val = ((int32_t)(avio_rb24(pb)<<8))>>8;
526  else if (str_size == 4)
527  val = (int32_t)avio_rb32(pb);
528  if (snprintf(str, str_size_alloc, "%d", val) >= str_size_alloc) {
529  av_log(c->fc, AV_LOG_ERROR,
530  "Failed to store the number (%d) in string.\n", val);
531  av_free(str);
532  return AVERROR_INVALIDDATA;
533  }
534  } else if (data_type == 22) { // BE unsigned integer, variable size
535  unsigned int val = 0;
536  if (str_size == 1)
537  val = avio_r8(pb);
538  else if (str_size == 2)
539  val = avio_rb16(pb);
540  else if (str_size == 3)
541  val = avio_rb24(pb);
542  else if (str_size == 4)
543  val = avio_rb32(pb);
544  if (snprintf(str, str_size_alloc, "%u", val) >= str_size_alloc) {
545  av_log(c->fc, AV_LOG_ERROR,
546  "Failed to store the number (%u) in string.\n", val);
547  av_free(str);
548  return AVERROR_INVALIDDATA;
549  }
550  } else if (data_type == 23 && str_size >= 4) { // BE float32
551  float val = av_int2float(avio_rb32(pb));
552  if (snprintf(str, str_size_alloc, "%f", val) >= str_size_alloc) {
553  av_log(c->fc, AV_LOG_ERROR,
554  "Failed to store the float32 number (%f) in string.\n", val);
555  av_free(str);
556  return AVERROR_INVALIDDATA;
557  }
558  } else if (data_type > 1 && data_type != 4) {
559  // data_type can be 0 if not set at all above. data_type 1 means
560  // UTF8 and 4 means "UTF8 sort". For any other type (UTF16 or e.g.
561  // a picture), don't return it blindly in a string that is supposed
562  // to be UTF8 text.
563  av_log(c->fc, AV_LOG_WARNING, "Skipping unhandled metadata %s of type %d\n", key, data_type);
564  av_free(str);
565  return 0;
566  } else {
567  int ret = ffio_read_size(pb, str, str_size);
568  if (ret < 0) {
569  av_free(str);
570  return ret;
571  }
572  str[str_size] = 0;
573  }
574  c->fc->event_flags |= AVFMT_EVENT_FLAG_METADATA_UPDATED;
575  av_dict_set(&c->fc->metadata, key, str, 0);
576  if (*language && strcmp(language, "und")) {
577  snprintf(key2, sizeof(key2), "%s-%s", key, language);
578  av_dict_set(&c->fc->metadata, key2, str, 0);
579  }
580  if (!strcmp(key, "encoder")) {
581  int major, minor, micro;
582  if (sscanf(str, "HandBrake %d.%d.%d", &major, &minor, &micro) == 3) {
583  c->handbrake_version = 1000000*major + 1000*minor + micro;
584  }
585  }
586  }
587 
588  av_freep(&str);
589  return 0;
590 }
591 
593 {
594  int64_t start;
595  int i, nb_chapters, str_len, version;
596  char str[256+1];
597  int ret;
598 
599  if (c->ignore_chapters)
600  return 0;
601 
602  if ((atom.size -= 5) < 0)
603  return 0;
604 
605  version = avio_r8(pb);
606  avio_rb24(pb);
607  if (version)
608  avio_rb32(pb); // ???
609  nb_chapters = avio_r8(pb);
610 
611  for (i = 0; i < nb_chapters; i++) {
612  if (atom.size < 9)
613  return 0;
614 
615  start = avio_rb64(pb);
616  str_len = avio_r8(pb);
617 
618  if ((atom.size -= 9+str_len) < 0)
619  return 0;
620 
621  ret = ffio_read_size(pb, str, str_len);
622  if (ret < 0)
623  return ret;
624  str[str_len] = 0;
625  avpriv_new_chapter(c->fc, i, (AVRational){1,10000000}, start, AV_NOPTS_VALUE, str);
626  }
627  return 0;
628 }
629 
630 #define MIN_DATA_ENTRY_BOX_SIZE 12
632 {
633  AVStream *st;
634  MOVStreamContext *sc;
635  int entries, i, j;
636 
637  if (c->fc->nb_streams < 1)
638  return 0;
639  st = c->fc->streams[c->fc->nb_streams-1];
640  sc = st->priv_data;
641 
642  avio_rb32(pb); // version + flags
643  entries = avio_rb32(pb);
644  if (!entries ||
645  entries > (atom.size - 1) / MIN_DATA_ENTRY_BOX_SIZE + 1 ||
646  entries >= UINT_MAX / sizeof(*sc->drefs))
647  return AVERROR_INVALIDDATA;
648 
649  for (i = 0; i < sc->drefs_count; i++) {
650  MOVDref *dref = &sc->drefs[i];
651  av_freep(&dref->path);
652  av_freep(&dref->dir);
653  }
654  av_free(sc->drefs);
655  sc->drefs_count = 0;
656  sc->drefs = av_mallocz(entries * sizeof(*sc->drefs));
657  if (!sc->drefs)
658  return AVERROR(ENOMEM);
659  sc->drefs_count = entries;
660 
661  for (i = 0; i < entries; i++) {
662  MOVDref *dref = &sc->drefs[i];
663  uint32_t size = avio_rb32(pb);
664  int64_t next = avio_tell(pb);
665 
666  if (size < 12 || next < 0 || next > INT64_MAX - size)
667  return AVERROR_INVALIDDATA;
668 
669  next += size - 4;
670 
671  dref->type = avio_rl32(pb);
672  avio_rb32(pb); // version + flags
673 
674  if (dref->type == MKTAG('a','l','i','s') && size > 150) {
675  /* macintosh alias record */
676  uint16_t volume_len, len;
677  int16_t type;
678  int ret;
679 
680  avio_skip(pb, 10);
681 
682  volume_len = avio_r8(pb);
683  volume_len = FFMIN(volume_len, 27);
684  ret = ffio_read_size(pb, dref->volume, 27);
685  if (ret < 0)
686  return ret;
687  dref->volume[volume_len] = 0;
688  av_log(c->fc, AV_LOG_DEBUG, "volume %s, len %d\n", dref->volume, volume_len);
689 
690  avio_skip(pb, 12);
691 
692  len = avio_r8(pb);
693  len = FFMIN(len, 63);
694  ret = ffio_read_size(pb, dref->filename, 63);
695  if (ret < 0)
696  return ret;
697  dref->filename[len] = 0;
698  av_log(c->fc, AV_LOG_DEBUG, "filename %s, len %d\n", dref->filename, len);
699 
700  avio_skip(pb, 16);
701 
702  /* read next level up_from_alias/down_to_target */
703  dref->nlvl_from = avio_rb16(pb);
704  dref->nlvl_to = avio_rb16(pb);
705  av_log(c->fc, AV_LOG_DEBUG, "nlvl from %d, nlvl to %d\n",
706  dref->nlvl_from, dref->nlvl_to);
707 
708  avio_skip(pb, 16);
709 
710  for (type = 0; type != -1 && avio_tell(pb) < next; ) {
711  if (avio_feof(pb))
712  return AVERROR_EOF;
713  type = avio_rb16(pb);
714  len = avio_rb16(pb);
715  av_log(c->fc, AV_LOG_DEBUG, "type %d, len %d\n", type, len);
716  if (len&1)
717  len += 1;
718  if (type == 2) { // absolute path
719  av_free(dref->path);
720  dref->path = av_mallocz(len+1);
721  if (!dref->path)
722  return AVERROR(ENOMEM);
723 
724  ret = ffio_read_size(pb, dref->path, len);
725  if (ret < 0) {
726  av_freep(&dref->path);
727  return ret;
728  }
729  if (len > volume_len && !strncmp(dref->path, dref->volume, volume_len)) {
730  len -= volume_len;
731  memmove(dref->path, dref->path+volume_len, len);
732  dref->path[len] = 0;
733  }
734  // trim string of any ending zeros
735  for (j = len - 1; j >= 0; j--) {
736  if (dref->path[j] == 0)
737  len--;
738  else
739  break;
740  }
741  for (j = 0; j < len; j++)
742  if (dref->path[j] == ':' || dref->path[j] == 0)
743  dref->path[j] = '/';
744  av_log(c->fc, AV_LOG_DEBUG, "path %s\n", dref->path);
745  } else if (type == 0) { // directory name
746  av_free(dref->dir);
747  dref->dir = av_malloc(len+1);
748  if (!dref->dir)
749  return AVERROR(ENOMEM);
750 
751  ret = ffio_read_size(pb, dref->dir, len);
752  if (ret < 0) {
753  av_freep(&dref->dir);
754  return ret;
755  }
756  dref->dir[len] = 0;
757  for (j = 0; j < len; j++)
758  if (dref->dir[j] == ':')
759  dref->dir[j] = '/';
760  av_log(c->fc, AV_LOG_DEBUG, "dir %s\n", dref->dir);
761  } else
762  avio_skip(pb, len);
763  }
764  } else {
765  av_log(c->fc, AV_LOG_DEBUG, "Unknown dref type 0x%08"PRIx32" size %"PRIu32"\n",
766  dref->type, size);
767  entries--;
768  i--;
769  }
770  avio_seek(pb, next, SEEK_SET);
771  }
772  return 0;
773 }
774 
776 {
777  AVStream *st;
778  uint32_t type;
779  uint32_t ctype;
780  int64_t title_size;
781  char *title_str;
782  int ret;
783 
784  avio_r8(pb); /* version */
785  avio_rb24(pb); /* flags */
786 
787  /* component type */
788  ctype = avio_rl32(pb);
789  type = avio_rl32(pb); /* component subtype */
790 
791  av_log(c->fc, AV_LOG_TRACE, "ctype=%s\n", av_fourcc2str(ctype));
792  av_log(c->fc, AV_LOG_TRACE, "stype=%s\n", av_fourcc2str(type));
793 
794  if (c->trak_index < 0) { // meta not inside a trak
795  if (type == MKTAG('m','d','t','a')) {
796  c->found_hdlr_mdta = 1;
797  }
798  return 0;
799  }
800 
801  st = c->fc->streams[c->fc->nb_streams-1];
802 
803  if (type == MKTAG('v','i','d','e'))
805  else if (type == MKTAG('s','o','u','n'))
807  else if (type == MKTAG('m','1','a',' '))
809  else if ((type == MKTAG('s','u','b','p')) || (type == MKTAG('c','l','c','p')))
811 
812  avio_rb32(pb); /* component manufacture */
813  avio_rb32(pb); /* component flags */
814  avio_rb32(pb); /* component flags mask */
815 
816  title_size = atom.size - 24;
817  if (title_size > 0) {
818  if (title_size > FFMIN(INT_MAX, SIZE_MAX-1))
819  return AVERROR_INVALIDDATA;
820  title_str = av_malloc(title_size + 1); /* Add null terminator */
821  if (!title_str)
822  return AVERROR(ENOMEM);
823 
824  ret = ffio_read_size(pb, title_str, title_size);
825  if (ret < 0) {
826  av_freep(&title_str);
827  return ret;
828  }
829  title_str[title_size] = 0;
830  if (title_str[0]) {
831  int off = (!c->isom && title_str[0] == title_size - 1);
832  // flag added so as to not set stream handler name if already set from mdia->hdlr
833  av_dict_set(&st->metadata, "handler_name", title_str + off, AV_DICT_DONT_OVERWRITE);
834  }
835  av_freep(&title_str);
836  }
837 
838  return 0;
839 }
840 
842 {
843  return ff_mov_read_esds(c->fc, pb);
844 }
845 
847 {
848  AVStream *st;
849  AVPacketSideData *sd;
850  enum AVAudioServiceType *ast;
851  int ac3info, acmod, lfeon, bsmod;
852  uint64_t mask;
853 
854  if (c->fc->nb_streams < 1)
855  return 0;
856  st = c->fc->streams[c->fc->nb_streams-1];
857 
861  sizeof(*ast), 0);
862  if (!sd)
863  return AVERROR(ENOMEM);
864 
865  ast = (enum AVAudioServiceType*)sd->data;
866  ac3info = avio_rb24(pb);
867  bsmod = (ac3info >> 14) & 0x7;
868  acmod = (ac3info >> 11) & 0x7;
869  lfeon = (ac3info >> 10) & 0x1;
870 
872  if (lfeon)
876 
877  *ast = bsmod;
878  if (st->codecpar->ch_layout.nb_channels > 1 && bsmod == 0x7)
880 
881  return 0;
882 }
883 
884 #if CONFIG_IAMFDEC
885 static int mov_read_iacb(MOVContext *c, AVIOContext *pb, MOVAtom atom)
886 {
887  AVStream *st;
888  MOVStreamContext *sc;
889  FFIOContext b;
890  AVIOContext *descriptor_pb;
891  AVDictionary *metadata;
892  IAMFContext *iamf;
894  unsigned descriptors_size;
895  int nb_frames, disposition;
896  int version, ret;
897 
898  if (atom.size < 5)
899  return AVERROR_INVALIDDATA;
900 
901  if (c->fc->nb_streams < 1)
902  return 0;
903 
904  version = avio_r8(pb);
905  if (version != 1) {
906  av_log(c->fc, AV_LOG_ERROR, "%s configurationVersion %d",
907  version < 1 ? "invalid" : "unsupported", version);
908  return AVERROR_INVALIDDATA;
909  }
910 
911  descriptors_size = ffio_read_leb(pb);
912  if (!descriptors_size || descriptors_size > INT_MAX)
913  return AVERROR_INVALIDDATA;
914 
915  st = c->fc->streams[c->fc->nb_streams - 1];
916  sc = st->priv_data;
917 
918  if (st->codecpar->extradata) {
919  av_log(c->fc, AV_LOG_WARNING, "ignoring iacb\n");
920  return 0;
921  }
922 
923  sc->iamf = av_mallocz(sizeof(*sc->iamf));
924  if (!sc->iamf)
925  return AVERROR(ENOMEM);
926  iamf = &sc->iamf->iamf;
927 
928  st->codecpar->extradata = av_malloc(descriptors_size);
929  if (!st->codecpar->extradata)
930  return AVERROR(ENOMEM);
931  st->codecpar->extradata_size = descriptors_size;
932 
933  ret = avio_read(pb, st->codecpar->extradata, descriptors_size);
934  if (ret != descriptors_size)
935  return ret < 0 ? ret : AVERROR_INVALIDDATA;
936 
937  ffio_init_read_context(&b, st->codecpar->extradata, descriptors_size);
938  descriptor_pb = &b.pub;
939 
940  ret = ff_iamfdec_read_descriptors(iamf, descriptor_pb, descriptors_size, c->fc);
941  if (ret < 0)
942  return ret;
943 
944  metadata = st->metadata;
945  st->metadata = NULL;
946  start_time = st->start_time;
947  nb_frames = st->nb_frames;
948  duration = st->duration;
949  disposition = st->disposition;
950 
951  for (int i = 0; i < iamf->nb_audio_elements; i++) {
952  IAMFAudioElement *audio_element = iamf->audio_elements[i];
953  const AVIAMFAudioElement *element;
954  AVStreamGroup *stg =
956 
957  if (!stg) {
958  ret = AVERROR(ENOMEM);
959  goto fail;
960  }
961 
963  stg->id = audio_element->audio_element_id;
964  /* Transfer ownership */
965  element = stg->params.iamf_audio_element = audio_element->element;
966  audio_element->element = NULL;
967 
968  for (int j = 0; j < audio_element->nb_substreams; j++) {
969  IAMFSubStream *substream = &audio_element->substreams[j];
970  AVStream *stream;
971 
972  if (!i && !j) {
973  if (audio_element->layers[0].substream_count != 1)
974  disposition &= ~AV_DISPOSITION_DEFAULT;
975  stream = st;
976  } else
977  stream = avformat_new_stream(c->fc, NULL);
978  if (!stream) {
979  ret = AVERROR(ENOMEM);
980  goto fail;
981  }
982 
983  stream->start_time = start_time;
984  stream->nb_frames = nb_frames;
985  stream->duration = duration;
986  stream->disposition = disposition;
987  if (stream != st) {
988  stream->priv_data = sc;
989  sc->refcount++;
990  }
991 
994  if (i || j) {
996  if (audio_element->layers[0].substream_count == 1)
998  }
999 
1000  ret = avcodec_parameters_copy(stream->codecpar, substream->codecpar);
1001  if (ret < 0)
1002  goto fail;
1003 
1004  stream->id = substream->audio_substream_id;
1005 
1006  avpriv_set_pts_info(st, 64, 1, sc->time_scale);
1007 
1008  ret = avformat_stream_group_add_stream(stg, stream);
1009  if (ret < 0)
1010  goto fail;
1011  }
1012 
1013  ret = av_dict_copy(&stg->metadata, metadata, 0);
1014  if (ret < 0)
1015  goto fail;
1016  }
1017 
1018  for (int i = 0; i < iamf->nb_mix_presentations; i++) {
1019  IAMFMixPresentation *mix_presentation = iamf->mix_presentations[i];
1020  const AVIAMFMixPresentation *mix = mix_presentation->cmix;
1021  AVStreamGroup *stg =
1023 
1024  if (!stg) {
1025  ret = AVERROR(ENOMEM);
1026  goto fail;
1027  }
1028 
1030  stg->id = mix_presentation->mix_presentation_id;
1031  /* Transfer ownership */
1032  stg->params.iamf_mix_presentation = mix_presentation->mix;
1033  mix_presentation->mix = NULL;
1034 
1035  for (int j = 0; j < mix->nb_submixes; j++) {
1036  const AVIAMFSubmix *submix = mix->submixes[j];
1037 
1038  for (int k = 0; k < submix->nb_elements; k++) {
1039  const AVIAMFSubmixElement *submix_element = submix->elements[k];
1040  const AVStreamGroup *audio_element = NULL;
1041 
1042  for (int l = 0; l < c->fc->nb_stream_groups; l++)
1043  if (c->fc->stream_groups[l]->type == AV_STREAM_GROUP_PARAMS_IAMF_AUDIO_ELEMENT &&
1044  c->fc->stream_groups[l]->id == submix_element->audio_element_id) {
1045  audio_element = c->fc->stream_groups[l];
1046  break;
1047  }
1048  av_assert0(audio_element);
1049 
1050  for (int l = 0; l < audio_element->nb_streams; l++) {
1051  ret = avformat_stream_group_add_stream(stg, audio_element->streams[l]);
1052  if (ret < 0 && ret != AVERROR(EEXIST))
1053  goto fail;
1054  }
1055  }
1056  }
1057 
1058  ret = av_dict_copy(&stg->metadata, metadata, 0);
1059  if (ret < 0)
1060  goto fail;
1061  }
1062 
1063  ret = 0;
1064 fail:
1065  av_dict_free(&metadata);
1066 
1067  return ret;
1068 }
1069 #endif
1070 
1072 {
1073  AVStream *st;
1074  AVPacketSideData *sd;
1075  enum AVAudioServiceType *ast;
1076  int eac3info, acmod, lfeon, bsmod;
1077  uint64_t mask;
1078 
1079  if (c->fc->nb_streams < 1)
1080  return 0;
1081  st = c->fc->streams[c->fc->nb_streams-1];
1082 
1086  sizeof(*ast), 0);
1087  if (!sd)
1088  return AVERROR(ENOMEM);
1089 
1090  ast = (enum AVAudioServiceType*)sd->data;
1091 
1092  /* No need to parse fields for additional independent substreams and its
1093  * associated dependent substreams since libavcodec's E-AC-3 decoder
1094  * does not support them yet. */
1095  avio_rb16(pb); /* data_rate and num_ind_sub */
1096  eac3info = avio_rb24(pb);
1097  bsmod = (eac3info >> 12) & 0x1f;
1098  acmod = (eac3info >> 9) & 0x7;
1099  lfeon = (eac3info >> 8) & 0x1;
1100 
1102  if (lfeon)
1106 
1107  *ast = bsmod;
1108  if (st->codecpar->ch_layout.nb_channels > 1 && bsmod == 0x7)
1110 
1111  return 0;
1112 }
1113 
1115 {
1116 #define DDTS_SIZE 20
1117  uint8_t buf[DDTS_SIZE + AV_INPUT_BUFFER_PADDING_SIZE];
1118  AVStream *st = NULL;
1119  uint32_t frame_duration_code = 0;
1120  uint32_t channel_layout_code = 0;
1121  GetBitContext gb;
1122  int ret;
1123 
1124  if ((ret = ffio_read_size(pb, buf, DDTS_SIZE)) < 0)
1125  return ret;
1126 
1127  init_get_bits(&gb, buf, 8 * DDTS_SIZE);
1128 
1129  if (c->fc->nb_streams < 1) {
1130  return 0;
1131  }
1132  st = c->fc->streams[c->fc->nb_streams-1];
1133 
1134  st->codecpar->sample_rate = get_bits_long(&gb, 32);
1135  if (st->codecpar->sample_rate <= 0) {
1136  av_log(c->fc, AV_LOG_ERROR, "Invalid sample rate %d\n", st->codecpar->sample_rate);
1137  return AVERROR_INVALIDDATA;
1138  }
1139  skip_bits_long(&gb, 32); /* max bitrate */
1140  st->codecpar->bit_rate = get_bits_long(&gb, 32);
1141  st->codecpar->bits_per_coded_sample = get_bits(&gb, 8);
1142  frame_duration_code = get_bits(&gb, 2);
1143  skip_bits(&gb, 30); /* various fields */
1144  channel_layout_code = get_bits(&gb, 16);
1145 
1146  st->codecpar->frame_size =
1147  (frame_duration_code == 0) ? 512 :
1148  (frame_duration_code == 1) ? 1024 :
1149  (frame_duration_code == 2) ? 2048 :
1150  (frame_duration_code == 3) ? 4096 : 0;
1151 
1152  if (channel_layout_code > 0xff) {
1153  av_log(c->fc, AV_LOG_WARNING, "Unsupported DTS audio channel layout\n");
1154  }
1157  ((channel_layout_code & 0x1) ? AV_CH_FRONT_CENTER : 0) |
1158  ((channel_layout_code & 0x2) ? AV_CH_FRONT_LEFT : 0) |
1159  ((channel_layout_code & 0x2) ? AV_CH_FRONT_RIGHT : 0) |
1160  ((channel_layout_code & 0x4) ? AV_CH_SIDE_LEFT : 0) |
1161  ((channel_layout_code & 0x4) ? AV_CH_SIDE_RIGHT : 0) |
1162  ((channel_layout_code & 0x8) ? AV_CH_LOW_FREQUENCY : 0));
1163 
1164  return 0;
1165 }
1166 
1168 {
1169  AVStream *st;
1170 
1171  if (c->fc->nb_streams < 1)
1172  return 0;
1173  st = c->fc->streams[c->fc->nb_streams-1];
1174 
1175  if (atom.size < 16)
1176  return 0;
1177 
1178  /* skip version and flags */
1179  avio_skip(pb, 4);
1180 
1181  ff_mov_read_chan(c->fc, pb, st, atom.size - 4);
1182 
1183  return 0;
1184 }
1185 
1187 {
1188  int64_t end = av_sat_add64(avio_tell(pb), atom.size);
1189  int version, flags;
1190  int ret;
1191  AVStream *st;
1192 
1193  if (c->fc->nb_streams < 1)
1194  return 0;
1195  st = c->fc->streams[c->fc->nb_streams-1];
1196 
1197  version = avio_r8(pb);
1198  flags = avio_rb24(pb);
1199  if (version != 0 || flags != 0) {
1200  av_log(c->fc, AV_LOG_ERROR,
1201  "Unsupported 'chnl' box with version %d, flags: %#x",
1202  version, flags);
1203  return AVERROR_INVALIDDATA;
1204  }
1205 
1206  ret = ff_mov_read_chnl(c->fc, pb, st);
1207  if (ret < 0)
1208  return ret;
1209 
1210  if (avio_tell(pb) != end) {
1211  av_log(c->fc, AV_LOG_WARNING, "skip %" PRId64 " bytes of unknown data inside chnl\n",
1212  end - avio_tell(pb));
1213  avio_seek(pb, end, SEEK_SET);
1214  }
1215  return ret;
1216 }
1217 
1219 {
1220  AVStream *st;
1221  int ret;
1222 
1223  if (c->fc->nb_streams < 1)
1224  return 0;
1225  st = c->fc->streams[c->fc->nb_streams-1];
1226 
1227  if ((ret = ff_get_wav_header(c->fc, pb, st->codecpar, atom.size, 0)) < 0)
1228  av_log(c->fc, AV_LOG_WARNING, "get_wav_header failed\n");
1229 
1230  return ret;
1231 }
1232 
1234 {
1235  AVStream *st;
1236  HEIFItem *item;
1237  AVPacketSideData *sd;
1238  int width, height, err = 0;
1239  AVRational aperture_width, aperture_height, horiz_off, vert_off;
1240  AVRational pc_x, pc_y;
1241  uint64_t top, bottom, left, right;
1242 
1243  item = heif_cur_item(c);
1244  st = get_curr_st(c);
1245  if (!st)
1246  return 0;
1247 
1248  width = st->codecpar->width;
1249  height = st->codecpar->height;
1250  if ((!width || !height) && item) {
1251  width = item->width;
1252  height = item->height;
1253  }
1254  if (!width || !height) {
1255  err = AVERROR_INVALIDDATA;
1256  goto fail;
1257  }
1258 
1259  aperture_width.num = avio_rb32(pb);
1260  aperture_width.den = avio_rb32(pb);
1261  aperture_height.num = avio_rb32(pb);
1262  aperture_height.den = avio_rb32(pb);
1263 
1264  horiz_off.num = avio_rb32(pb);
1265  horiz_off.den = avio_rb32(pb);
1266  vert_off.num = avio_rb32(pb);
1267  vert_off.den = avio_rb32(pb);
1268 
1269  if (aperture_width.num < 0 || aperture_width.den < 0 ||
1270  aperture_height.num < 0 || aperture_height.den < 0 ||
1271  horiz_off.den < 0 || vert_off.den < 0) {
1272  err = AVERROR_INVALIDDATA;
1273  goto fail;
1274  }
1275  av_log(c->fc, AV_LOG_TRACE, "clap: apertureWidth %d/%d, apertureHeight %d/%d "
1276  "horizOff %d/%d vertOff %d/%d\n",
1277  aperture_width.num, aperture_width.den, aperture_height.num, aperture_height.den,
1278  horiz_off.num, horiz_off.den, vert_off.num, vert_off.den);
1279 
1280  pc_x = av_mul_q((AVRational) { width - 1, 1 }, (AVRational) { 1, 2 });
1281  pc_x = av_add_q(pc_x, horiz_off);
1282  pc_y = av_mul_q((AVRational) { height - 1, 1 }, (AVRational) { 1, 2 });
1283  pc_y = av_add_q(pc_y, vert_off);
1284 
1285  aperture_width = av_sub_q(aperture_width, (AVRational) { 1, 1 });
1286  aperture_width = av_mul_q(aperture_width, (AVRational) { 1, 2 });
1287  aperture_height = av_sub_q(aperture_height, (AVRational) { 1, 1 });
1288  aperture_height = av_mul_q(aperture_height, (AVRational) { 1, 2 });
1289 
1290  left = av_q2d(av_sub_q(pc_x, aperture_width));
1291  right = av_q2d(av_add_q(pc_x, aperture_width));
1292  top = av_q2d(av_sub_q(pc_y, aperture_height));
1293  bottom = av_q2d(av_add_q(pc_y, aperture_height));
1294 
1295  if (bottom > (height - 1) ||
1296  right > (width - 1)) {
1297  err = AVERROR_INVALIDDATA;
1298  goto fail;
1299  }
1300 
1301  bottom = height - 1 - bottom;
1302  right = width - 1 - right;
1303 
1304  if (!(left | right | top | bottom))
1305  return 0;
1306 
1307  if ((left + right) >= width ||
1308  (top + bottom) >= height) {
1309  err = AVERROR_INVALIDDATA;
1310  goto fail;
1311  }
1312 
1316  sizeof(uint32_t) * 4, 0);
1317  if (!sd)
1318  return AVERROR(ENOMEM);
1319 
1320  AV_WL32A(sd->data, top);
1321  AV_WL32A(sd->data + 4, bottom);
1322  AV_WL32A(sd->data + 8, left);
1323  AV_WL32A(sd->data + 12, right);
1324 
1325 fail:
1326  if (err < 0) {
1327  int explode = !!(c->fc->error_recognition & AV_EF_EXPLODE);
1328  av_log(c->fc, explode ? AV_LOG_ERROR : AV_LOG_WARNING, "Invalid clap box\n");
1329  if (!explode)
1330  err = 0;
1331  }
1332 
1333  return err;
1334 }
1335 
1336 /* This atom overrides any previously set aspect ratio */
1338 {
1339  const int num = avio_rb32(pb);
1340  const int den = avio_rb32(pb);
1341  AVStream *st;
1342  MOVStreamContext *sc;
1343 
1344  if (c->fc->nb_streams < 1)
1345  return 0;
1346  st = c->fc->streams[c->fc->nb_streams-1];
1347  sc = st->priv_data;
1348 
1349  av_log(c->fc, AV_LOG_TRACE, "pasp: hSpacing %d, vSpacing %d\n", num, den);
1350 
1351  if (den != 0) {
1352  sc->h_spacing = num;
1353  sc->v_spacing = den;
1354  }
1355  return 0;
1356 }
1357 
1358 /* this atom contains actual media data */
1360 {
1361  if (atom.size == 0) /* wrong one (MP4) */
1362  return 0;
1363  c->found_mdat=1;
1364  return 0; /* now go for moov */
1365 }
1366 
1367 #define DRM_BLOB_SIZE 56
1368 
1370 {
1371  uint8_t intermediate_key[20];
1372  uint8_t intermediate_iv[20];
1373  uint8_t input[64];
1374  uint8_t output[64];
1375  uint8_t file_checksum[20];
1376  uint8_t calculated_checksum[20];
1377  char checksum_string[2 * sizeof(file_checksum) + 1];
1378  struct AVSHA *sha;
1379  int i;
1380  int ret = 0;
1381  uint8_t *activation_bytes = c->activation_bytes;
1382  uint8_t *fixed_key = c->audible_fixed_key;
1383 
1384  c->aax_mode = 1;
1385 
1386  sha = av_sha_alloc();
1387  if (!sha)
1388  return AVERROR(ENOMEM);
1389  av_free(c->aes_decrypt);
1390  c->aes_decrypt = av_aes_alloc();
1391  if (!c->aes_decrypt) {
1392  ret = AVERROR(ENOMEM);
1393  goto fail;
1394  }
1395 
1396  /* drm blob processing */
1397  avio_read(pb, output, 8); // go to offset 8, absolute position 0x251
1399  avio_read(pb, output, 4); // go to offset 4, absolute position 0x28d
1400  avio_read(pb, file_checksum, 20);
1401 
1402  // required by external tools
1403  ff_data_to_hex(checksum_string, file_checksum, sizeof(file_checksum), 1);
1404  av_log(c->fc, AV_LOG_INFO, "[aax] file checksum == %s\n", checksum_string);
1405 
1406  /* verify activation data */
1407  if (!activation_bytes) {
1408  av_log(c->fc, AV_LOG_WARNING, "[aax] activation_bytes option is missing!\n");
1409  ret = 0; /* allow ffprobe to continue working on .aax files */
1410  goto fail;
1411  }
1412  if (c->activation_bytes_size != 4) {
1413  av_log(c->fc, AV_LOG_FATAL, "[aax] activation_bytes value needs to be 4 bytes!\n");
1414  ret = AVERROR(EINVAL);
1415  goto fail;
1416  }
1417 
1418  /* verify fixed key */
1419  if (c->audible_fixed_key_size != 16) {
1420  av_log(c->fc, AV_LOG_FATAL, "[aax] audible_fixed_key value needs to be 16 bytes!\n");
1421  ret = AVERROR(EINVAL);
1422  goto fail;
1423  }
1424 
1425  /* AAX (and AAX+) key derivation */
1426  av_sha_init(sha, 160);
1427  av_sha_update(sha, fixed_key, 16);
1428  av_sha_update(sha, activation_bytes, 4);
1429  av_sha_final(sha, intermediate_key);
1430  av_sha_init(sha, 160);
1431  av_sha_update(sha, fixed_key, 16);
1432  av_sha_update(sha, intermediate_key, 20);
1433  av_sha_update(sha, activation_bytes, 4);
1434  av_sha_final(sha, intermediate_iv);
1435  av_sha_init(sha, 160);
1436  av_sha_update(sha, intermediate_key, 16);
1437  av_sha_update(sha, intermediate_iv, 16);
1438  av_sha_final(sha, calculated_checksum);
1439  if (memcmp(calculated_checksum, file_checksum, 20)) { // critical error
1440  av_log(c->fc, AV_LOG_ERROR, "[aax] mismatch in checksums!\n");
1442  goto fail;
1443  }
1444  av_aes_init(c->aes_decrypt, intermediate_key, 128, 1);
1445  av_aes_crypt(c->aes_decrypt, output, input, DRM_BLOB_SIZE >> 4, intermediate_iv, 1);
1446  for (i = 0; i < 4; i++) {
1447  // file data (in output) is stored in big-endian mode
1448  if (activation_bytes[i] != output[3 - i]) { // critical error
1449  av_log(c->fc, AV_LOG_ERROR, "[aax] error in drm blob decryption!\n");
1451  goto fail;
1452  }
1453  }
1454  memcpy(c->file_key, output + 8, 16);
1455  memcpy(input, output + 26, 16);
1456  av_sha_init(sha, 160);
1457  av_sha_update(sha, input, 16);
1458  av_sha_update(sha, c->file_key, 16);
1459  av_sha_update(sha, fixed_key, 16);
1460  av_sha_final(sha, c->file_iv);
1461 
1462 fail:
1463  av_free(sha);
1464 
1465  return ret;
1466 }
1467 
1469 {
1470  if (c->audible_key_size != 16) {
1471  av_log(c->fc, AV_LOG_FATAL, "[aaxc] audible_key value needs to be 16 bytes!\n");
1472  return AVERROR(EINVAL);
1473  }
1474 
1475  if (c->audible_iv_size != 16) {
1476  av_log(c->fc, AV_LOG_FATAL, "[aaxc] audible_iv value needs to be 16 bytes!\n");
1477  return AVERROR(EINVAL);
1478  }
1479 
1480  c->aes_decrypt = av_aes_alloc();
1481  if (!c->aes_decrypt) {
1482  return AVERROR(ENOMEM);
1483  }
1484 
1485  memcpy(c->file_key, c->audible_key, 16);
1486  memcpy(c->file_iv, c->audible_iv, 16);
1487  c->aax_mode = 1;
1488 
1489  return 0;
1490 }
1491 
1492 // Audible AAX (and AAX+) bytestream decryption
1493 static int aax_filter(uint8_t *input, int size, MOVContext *c)
1494 {
1495  int blocks = 0;
1496  unsigned char iv[16];
1497 
1498  memcpy(iv, c->file_iv, 16); // iv is overwritten
1499  blocks = size >> 4; // trailing bytes are not encrypted!
1500  av_aes_init(c->aes_decrypt, c->file_key, 128, 1);
1501  av_aes_crypt(c->aes_decrypt, input, input, blocks, iv, 1);
1502 
1503  return 0;
1504 }
1505 
1506 /* read major brand, minor version and compatible brands and store them as metadata */
1508 {
1509  uint32_t minor_ver;
1510  int comp_brand_size;
1511  char* comp_brands_str;
1512  uint8_t type[5] = {0};
1513  int ret = ffio_read_size(pb, type, 4);
1514  if (ret < 0)
1515  return ret;
1516  if (c->fc->nb_streams) {
1517  if (c->fc->strict_std_compliance >= FF_COMPLIANCE_STRICT)
1518  return AVERROR_INVALIDDATA;
1519  av_log(c->fc, AV_LOG_DEBUG, "Ignoring duplicate FTYP\n");
1520  return 0;
1521  }
1522 
1523  if (strcmp(type, "qt "))
1524  c->isom = 1;
1525  av_log(c->fc, AV_LOG_DEBUG, "ISO: File Type Major Brand: %.4s\n",(char *)&type);
1526  av_dict_set(&c->fc->metadata, "major_brand", type, 0);
1527  minor_ver = avio_rb32(pb); /* minor version */
1528  av_dict_set_int(&c->fc->metadata, "minor_version", minor_ver, 0);
1529 
1530  comp_brand_size = atom.size - 8;
1531  if (comp_brand_size < 0 || comp_brand_size == INT_MAX)
1532  return AVERROR_INVALIDDATA;
1533  comp_brands_str = av_malloc(comp_brand_size + 1); /* Add null terminator */
1534  if (!comp_brands_str)
1535  return AVERROR(ENOMEM);
1536 
1537  ret = ffio_read_size(pb, comp_brands_str, comp_brand_size);
1538  if (ret < 0) {
1539  av_freep(&comp_brands_str);
1540  return ret;
1541  }
1542  comp_brands_str[comp_brand_size] = 0;
1543  av_dict_set(&c->fc->metadata, "compatible_brands",
1544  comp_brands_str, AV_DICT_DONT_STRDUP_VAL);
1545 
1546  // Logic for handling Audible's .aaxc files
1547  if (!strcmp(type, "aaxc")) {
1548  mov_aaxc_crypto(c);
1549  }
1550 
1551  return 0;
1552 }
1553 
1554 /* this atom should contain all header atoms */
1556 {
1557  int ret;
1558 
1559  if (c->found_moov) {
1560  av_log(c->fc, AV_LOG_WARNING, "Found duplicated MOOV Atom. Skipped it\n");
1561  avio_skip(pb, atom.size);
1562  return 0;
1563  }
1564 
1565  if ((ret = mov_read_default(c, pb, atom)) < 0)
1566  return ret;
1567  /* we parsed the 'moov' atom, we can terminate the parsing as soon as we find the 'mdat' */
1568  /* so we don't parse the whole file if over a network */
1569  c->found_moov=1;
1570  return 0; /* now go for mdat */
1571 }
1572 
1574  MOVFragmentIndex *frag_index,
1575  int index,
1576  int id)
1577 {
1578  int i;
1579  MOVFragmentIndexItem * item;
1580 
1581  if (index < 0 || index >= frag_index->nb_items)
1582  return NULL;
1583  item = &frag_index->item[index];
1584  for (i = 0; i < item->nb_stream_info; i++)
1585  if (item->stream_info[i].id == id)
1586  return &item->stream_info[i];
1587 
1588  // This shouldn't happen
1589  return NULL;
1590 }
1591 
1592 static void set_frag_stream(MOVFragmentIndex *frag_index, int id)
1593 {
1594  int i;
1595  MOVFragmentIndexItem * item;
1596 
1597  if (frag_index->current < 0 ||
1598  frag_index->current >= frag_index->nb_items)
1599  return;
1600 
1601  item = &frag_index->item[frag_index->current];
1602  for (i = 0; i < item->nb_stream_info; i++)
1603  if (item->stream_info[i].id == id) {
1604  item->current = i;
1605  return;
1606  }
1607 
1608  // id not found. This shouldn't happen.
1609  item->current = -1;
1610 }
1611 
1613  MOVFragmentIndex *frag_index)
1614 {
1615  MOVFragmentIndexItem *item;
1616  if (frag_index->current < 0 ||
1617  frag_index->current >= frag_index->nb_items)
1618  return NULL;
1619 
1620  item = &frag_index->item[frag_index->current];
1621  if (item->current >= 0 && item->current < item->nb_stream_info)
1622  return &item->stream_info[item->current];
1623 
1624  // This shouldn't happen
1625  return NULL;
1626 }
1627 
1629 {
1630  int a, b, m;
1631  int64_t moof_offset;
1632 
1633  // Optimize for appending new entries
1634  if (!frag_index->nb_items ||
1635  frag_index->item[frag_index->nb_items - 1].moof_offset < offset)
1636  return frag_index->nb_items;
1637 
1638  a = -1;
1639  b = frag_index->nb_items;
1640 
1641  while (b - a > 1) {
1642  m = (a + b) >> 1;
1643  moof_offset = frag_index->item[m].moof_offset;
1644  if (moof_offset >= offset)
1645  b = m;
1646  if (moof_offset <= offset)
1647  a = m;
1648  }
1649  return b;
1650 }
1651 
1653 {
1654  av_assert0(frag_stream_info);
1655  if (frag_stream_info->sidx_pts != AV_NOPTS_VALUE)
1656  return frag_stream_info->sidx_pts;
1657  if (frag_stream_info->first_tfra_pts != AV_NOPTS_VALUE)
1658  return frag_stream_info->first_tfra_pts;
1659  return frag_stream_info->tfdt_dts;
1660 }
1661 
1663  MOVFragmentIndex *frag_index, int index)
1664 {
1665  MOVFragmentStreamInfo * frag_stream_info;
1666  MOVStreamContext *sc = dst_st->priv_data;
1667  int64_t timestamp;
1668  int i, j;
1669 
1670  // If the stream is referenced by any sidx, limit the search
1671  // to fragments that referenced this stream in the sidx
1672  if (sc->has_sidx) {
1673  frag_stream_info = get_frag_stream_info(frag_index, index, sc->id);
1674  if (!frag_stream_info)
1675  return AV_NOPTS_VALUE;
1676  if (frag_stream_info->sidx_pts != AV_NOPTS_VALUE)
1677  return frag_stream_info->sidx_pts;
1678  if (frag_stream_info->first_tfra_pts != AV_NOPTS_VALUE)
1679  return frag_stream_info->first_tfra_pts;
1680  return frag_stream_info->sidx_pts;
1681  }
1682 
1683  for (i = 0; i < frag_index->item[index].nb_stream_info; i++) {
1684  AVStream *frag_stream = NULL;
1685  frag_stream_info = &frag_index->item[index].stream_info[i];
1686  for (j = 0; j < s->nb_streams; j++) {
1687  MOVStreamContext *sc2 = s->streams[j]->priv_data;
1688  if (sc2->id == frag_stream_info->id)
1689  frag_stream = s->streams[j];
1690  }
1691  if (!frag_stream) {
1692  av_log(s, AV_LOG_WARNING, "No stream matching sidx ID found.\n");
1693  continue;
1694  }
1695  timestamp = get_stream_info_time(frag_stream_info);
1696  if (timestamp != AV_NOPTS_VALUE)
1697  return av_rescale_q(timestamp, frag_stream->time_base, dst_st->time_base);
1698  }
1699  return AV_NOPTS_VALUE;
1700 }
1701 
1703  AVStream *st, int64_t timestamp)
1704 {
1705  int a, b, m, m0;
1706  int64_t frag_time;
1707 
1708  a = -1;
1709  b = frag_index->nb_items;
1710 
1711  while (b - a > 1) {
1712  m0 = m = (a + b) >> 1;
1713 
1714  while (m < b &&
1715  (frag_time = get_frag_time(s, st, frag_index, m)) == AV_NOPTS_VALUE)
1716  m++;
1717 
1718  if (m < b && frag_time <= timestamp)
1719  a = m;
1720  else
1721  b = m0;
1722  }
1723 
1724  return a;
1725 }
1726 
1728 {
1729  int index, i;
1730  MOVFragmentIndexItem * item;
1731  MOVFragmentStreamInfo * frag_stream_info;
1732 
1733  // If moof_offset already exists in frag_index, return index to it
1734  index = search_frag_moof_offset(&c->frag_index, offset);
1735  if (index < c->frag_index.nb_items &&
1736  c->frag_index.item[index].moof_offset == offset)
1737  return index;
1738 
1739  // offset is not yet in frag index.
1740  // Insert new item at index (sorted by moof offset)
1741  item = av_fast_realloc(c->frag_index.item,
1742  &c->frag_index.allocated_size,
1743  (c->frag_index.nb_items + 1) *
1744  sizeof(*c->frag_index.item));
1745  if (!item)
1746  return -1;
1747  c->frag_index.item = item;
1748 
1749  frag_stream_info = av_realloc_array(NULL, c->fc->nb_streams,
1750  sizeof(*item->stream_info));
1751  if (!frag_stream_info)
1752  return -1;
1753 
1754  for (i = 0; i < c->fc->nb_streams; i++) {
1755  // Avoid building frag index if streams lack track id.
1756  MOVStreamContext *sc = c->fc->streams[i]->priv_data;
1757  if (sc->id < 0) {
1758  av_free(frag_stream_info);
1759  return AVERROR_INVALIDDATA;
1760  }
1761 
1762  frag_stream_info[i].id = sc->id;
1763  frag_stream_info[i].sidx_pts = AV_NOPTS_VALUE;
1764  frag_stream_info[i].tfdt_dts = AV_NOPTS_VALUE;
1765  frag_stream_info[i].next_trun_dts = AV_NOPTS_VALUE;
1766  frag_stream_info[i].first_tfra_pts = AV_NOPTS_VALUE;
1767  frag_stream_info[i].index_base = -1;
1768  frag_stream_info[i].index_entry = -1;
1769  frag_stream_info[i].encryption_index = NULL;
1770  frag_stream_info[i].stsd_id = -1;
1771  }
1772 
1773  if (index < c->frag_index.nb_items)
1774  memmove(c->frag_index.item + index + 1, c->frag_index.item + index,
1775  (c->frag_index.nb_items - index) * sizeof(*c->frag_index.item));
1776 
1777  item = &c->frag_index.item[index];
1778  item->headers_read = 0;
1779  item->current = 0;
1780  item->nb_stream_info = c->fc->nb_streams;
1781  item->moof_offset = offset;
1782  item->stream_info = frag_stream_info;
1783  c->frag_index.nb_items++;
1784 
1785  return index;
1786 }
1787 
1788 static void fix_frag_index_entries(MOVFragmentIndex *frag_index, int index,
1789  int id, int entries)
1790 {
1791  int i;
1792  MOVFragmentStreamInfo * frag_stream_info;
1793 
1794  if (index < 0)
1795  return;
1796  for (i = index; i < frag_index->nb_items; i++) {
1797  frag_stream_info = get_frag_stream_info(frag_index, i, id);
1798  if (frag_stream_info && frag_stream_info->index_entry >= 0)
1799  frag_stream_info->index_entry += entries;
1800  }
1801 }
1802 
1804 {
1805  // Set by mov_read_tfhd(). mov_read_trun() will reject files missing tfhd.
1806  c->fragment.found_tfhd = 0;
1807 
1808  if (!c->has_looked_for_mfra && c->use_mfra_for > 0) {
1809  c->has_looked_for_mfra = 1;
1810  if (pb->seekable & AVIO_SEEKABLE_NORMAL) {
1811  int ret;
1812  av_log(c->fc, AV_LOG_VERBOSE, "stream has moof boxes, will look "
1813  "for a mfra\n");
1814  if ((ret = mov_read_mfra(c, pb)) < 0) {
1815  av_log(c->fc, AV_LOG_VERBOSE, "found a moof box but failed to "
1816  "read the mfra (may be a live ismv)\n");
1817  }
1818  } else {
1819  av_log(c->fc, AV_LOG_VERBOSE, "found a moof box but stream is not "
1820  "seekable, can not look for mfra\n");
1821  }
1822  }
1823  c->fragment.moof_offset = c->fragment.implicit_offset = avio_tell(pb) - 8;
1824  av_log(c->fc, AV_LOG_TRACE, "moof offset %"PRIx64"\n", c->fragment.moof_offset);
1825  c->frag_index.current = update_frag_index(c, c->fragment.moof_offset);
1826  return mov_read_default(c, pb, atom);
1827 }
1828 
1830 {
1831  int64_t time;
1832  if (version == 1) {
1833  time = avio_rb64(pb);
1834  avio_rb64(pb);
1835  if (time < 0) {
1836  av_log(c->fc, AV_LOG_DEBUG, "creation_time is negative\n");
1837  return;
1838  }
1839  } else {
1840  time = avio_rb32(pb);
1841  avio_rb32(pb); /* modification time */
1842  if (time > 0 && time < 2082844800) {
1843  av_log(c->fc, AV_LOG_WARNING, "Detected creation time before 1970, parsing as unix timestamp.\n");
1844  time += 2082844800;
1845  }
1846  }
1847  if (time) {
1848  time -= 2082844800; /* seconds between 1904-01-01 and Epoch */
1849 
1850  if ((int64_t)(time * 1000000ULL) / 1000000 != time) {
1851  av_log(c->fc, AV_LOG_DEBUG, "creation_time is not representable\n");
1852  return;
1853  }
1854 
1855  avpriv_dict_set_timestamp(metadata, "creation_time", time * 1000000);
1856  }
1857 }
1858 
1860 {
1861  AVStream *st;
1862  MOVStreamContext *sc;
1863  int version;
1864  char language[4] = {0};
1865  unsigned lang;
1866 
1867  if (c->fc->nb_streams < 1)
1868  return 0;
1869  st = c->fc->streams[c->fc->nb_streams-1];
1870  sc = st->priv_data;
1871 
1872  if (sc->time_scale) {
1873  av_log(c->fc, AV_LOG_ERROR, "Multiple mdhd?\n");
1874  return AVERROR_INVALIDDATA;
1875  }
1876 
1877  version = avio_r8(pb);
1878  if (version > 1) {
1879  avpriv_request_sample(c->fc, "Version %d", version);
1880  return AVERROR_PATCHWELCOME;
1881  }
1882  avio_rb24(pb); /* flags */
1884 
1885  sc->time_scale = avio_rb32(pb);
1886  if (sc->time_scale <= 0) {
1887  av_log(c->fc, AV_LOG_ERROR, "Invalid mdhd time scale %d, defaulting to 1\n", sc->time_scale);
1888  sc->time_scale = 1;
1889  }
1890  st->duration = (version == 1) ? avio_rb64(pb) : avio_rb32(pb); /* duration */
1891 
1892  if ((version == 1 && st->duration == UINT64_MAX) ||
1893  (version != 1 && st->duration == UINT32_MAX)) {
1894  st->duration = 0;
1895  }
1896 
1897  lang = avio_rb16(pb); /* language */
1898  if (ff_mov_lang_to_iso639(lang, language))
1899  av_dict_set(&st->metadata, "language", language, 0);
1900  avio_rb16(pb); /* quality */
1901 
1902  return 0;
1903 }
1904 
1906 {
1907  int i;
1908  int version = avio_r8(pb); /* version */
1909  avio_rb24(pb); /* flags */
1910 
1911  mov_metadata_creation_time(c, pb, &c->fc->metadata, version);
1912  c->time_scale = avio_rb32(pb); /* time scale */
1913  if (c->time_scale <= 0) {
1914  av_log(c->fc, AV_LOG_ERROR, "Invalid mvhd time scale %d, defaulting to 1\n", c->time_scale);
1915  c->time_scale = 1;
1916  }
1917  av_log(c->fc, AV_LOG_TRACE, "time scale = %i\n", c->time_scale);
1918 
1919  c->duration = (version == 1) ? avio_rb64(pb) : avio_rb32(pb); /* duration */
1920  avio_rb32(pb); /* preferred scale */
1921 
1922  avio_rb16(pb); /* preferred volume */
1923 
1924  avio_skip(pb, 10); /* reserved */
1925 
1926  /* movie display matrix, store it in main context and use it later on */
1927  for (i = 0; i < 3; i++) {
1928  c->movie_display_matrix[i][0] = avio_rb32(pb); // 16.16 fixed point
1929  c->movie_display_matrix[i][1] = avio_rb32(pb); // 16.16 fixed point
1930  c->movie_display_matrix[i][2] = avio_rb32(pb); // 2.30 fixed point
1931  }
1932 
1933  avio_rb32(pb); /* preview time */
1934  avio_rb32(pb); /* preview duration */
1935  avio_rb32(pb); /* poster time */
1936  avio_rb32(pb); /* selection time */
1937  avio_rb32(pb); /* selection duration */
1938  avio_rb32(pb); /* current time */
1939  avio_rb32(pb); /* next track ID */
1940 
1941  return 0;
1942 }
1943 
1945 {
1946  AVStream *st;
1947 
1948  if (fc->nb_streams < 1)
1949  return;
1950  st = fc->streams[fc->nb_streams-1];
1951 
1952  switch (st->codecpar->codec_id) {
1953  case AV_CODEC_ID_PCM_S16BE:
1955  break;
1956  case AV_CODEC_ID_PCM_S24BE:
1958  break;
1959  case AV_CODEC_ID_PCM_S32BE:
1961  break;
1962  case AV_CODEC_ID_PCM_F32BE:
1964  break;
1965  case AV_CODEC_ID_PCM_F64BE:
1967  break;
1968  default:
1969  break;
1970  }
1971 }
1972 
1974 {
1975  int little_endian = avio_rb16(pb) & 0xFF;
1976  av_log(c->fc, AV_LOG_TRACE, "enda %d\n", little_endian);
1977  if (little_endian == 1)
1979  return 0;
1980 }
1981 
1983 {
1984  int format_flags;
1985  int version, flags;
1986  int pcm_sample_size;
1987  AVFormatContext *fc = c->fc;
1988  AVStream *st;
1989  MOVStreamContext *sc;
1990 
1991  if (atom.size < 6) {
1992  av_log(c->fc, AV_LOG_ERROR, "Empty pcmC box\n");
1993  return AVERROR_INVALIDDATA;
1994  }
1995 
1996  version = avio_r8(pb);
1997  flags = avio_rb24(pb);
1998 
1999  if (version != 0 || flags != 0) {
2000  av_log(c->fc, AV_LOG_ERROR,
2001  "Unsupported 'pcmC' box with version %d, flags: %x",
2002  version, flags);
2003  return AVERROR_INVALIDDATA;
2004  }
2005 
2006  format_flags = avio_r8(pb);
2007  pcm_sample_size = avio_r8(pb);
2008 
2009  if (fc->nb_streams < 1)
2010  return AVERROR_INVALIDDATA;
2011 
2012  st = fc->streams[fc->nb_streams - 1];
2013  sc = st->priv_data;
2014 
2015  if (sc->format == MOV_MP4_FPCM_TAG) {
2016  switch (pcm_sample_size) {
2017  case 32:
2019  break;
2020  case 64:
2022  break;
2023  default:
2024  av_log(fc, AV_LOG_ERROR, "invalid pcm_sample_size %d for %s\n",
2025  pcm_sample_size,
2026  av_fourcc2str(sc->format));
2027  return AVERROR_INVALIDDATA;
2028  }
2029  } else if (sc->format == MOV_MP4_IPCM_TAG) {
2030  switch (pcm_sample_size) {
2031  case 16:
2033  break;
2034  case 24:
2036  break;
2037  case 32:
2039  break;
2040  default:
2041  av_log(fc, AV_LOG_ERROR, "invalid pcm_sample_size %d for %s\n",
2042  pcm_sample_size,
2043  av_fourcc2str(sc->format));
2044  return AVERROR_INVALIDDATA;
2045  }
2046  } else {
2047  av_log(fc, AV_LOG_ERROR, "'pcmC' with invalid sample entry '%s'\n",
2048  av_fourcc2str(sc->format));
2049  return AVERROR_INVALIDDATA;
2050  }
2051 
2052  if (format_flags & 1) // indicates little-endian format. If not present, big-endian format is used
2055 
2056  return 0;
2057 }
2058 
2060 {
2061  AVStream *st;
2062  HEIFItem *item = NULL;
2063  char color_parameter_type[5] = { 0 };
2064  uint16_t color_primaries, color_trc, color_matrix;
2065  int ret;
2066 
2067  st = get_curr_st(c);
2068  if (!st) {
2069  item = heif_cur_item(c);
2070  if (!item)
2071  return 0;
2072  }
2073 
2074  ret = ffio_read_size(pb, color_parameter_type, 4);
2075  if (ret < 0)
2076  return ret;
2077  if (strncmp(color_parameter_type, "nclx", 4) &&
2078  strncmp(color_parameter_type, "nclc", 4) &&
2079  strncmp(color_parameter_type, "prof", 4)) {
2080  av_log(c->fc, AV_LOG_WARNING, "unsupported color_parameter_type %s\n",
2081  color_parameter_type);
2082  return 0;
2083  }
2084 
2085  if (!strncmp(color_parameter_type, "prof", 4)) {
2086  AVPacketSideData *sd;
2087  uint8_t *icc_profile;
2088  if (st) {
2092  atom.size - 4, 0);
2093  if (!sd)
2094  return AVERROR(ENOMEM);
2095  icc_profile = sd->data;
2096  } else {
2097  av_freep(&item->icc_profile);
2098  icc_profile = item->icc_profile = av_malloc(atom.size - 4);
2099  if (!icc_profile) {
2100  item->icc_profile_size = 0;
2101  return AVERROR(ENOMEM);
2102  }
2103  item->icc_profile_size = atom.size - 4;
2104  }
2105  ret = ffio_read_size(pb, icc_profile, atom.size - 4);
2106  if (ret < 0)
2107  return ret;
2108  } else if (st) {
2109  color_primaries = avio_rb16(pb);
2110  color_trc = avio_rb16(pb);
2111  color_matrix = avio_rb16(pb);
2112 
2113  av_log(c->fc, AV_LOG_TRACE,
2114  "%s: pri %d trc %d matrix %d",
2115  color_parameter_type, color_primaries, color_trc, color_matrix);
2116 
2117  if (!strncmp(color_parameter_type, "nclx", 4)) {
2118  uint8_t color_range = avio_r8(pb) >> 7;
2119  av_log(c->fc, AV_LOG_TRACE, " full %"PRIu8"", color_range);
2120  if (color_range)
2122  else
2124  }
2125 
2128  if (!av_color_transfer_name(color_trc))
2129  color_trc = AVCOL_TRC_UNSPECIFIED;
2130  if (!av_color_space_name(color_matrix))
2131  color_matrix = AVCOL_SPC_UNSPECIFIED;
2132 
2134  st->codecpar->color_trc = color_trc;
2135  st->codecpar->color_space = color_matrix;
2136  av_log(c->fc, AV_LOG_TRACE, "\n");
2137  }
2138  return 0;
2139 }
2140 
2142 {
2143  AVStream *st;
2144  unsigned mov_field_order;
2145  enum AVFieldOrder decoded_field_order = AV_FIELD_UNKNOWN;
2146 
2147  if (c->fc->nb_streams < 1) // will happen with jp2 files
2148  return 0;
2149  st = c->fc->streams[c->fc->nb_streams-1];
2150  if (atom.size < 2)
2151  return AVERROR_INVALIDDATA;
2152  mov_field_order = avio_rb16(pb);
2153  if ((mov_field_order & 0xFF00) == 0x0100)
2154  decoded_field_order = AV_FIELD_PROGRESSIVE;
2155  else if ((mov_field_order & 0xFF00) == 0x0200) {
2156  switch (mov_field_order & 0xFF) {
2157  case 0x01: decoded_field_order = AV_FIELD_TT;
2158  break;
2159  case 0x06: decoded_field_order = AV_FIELD_BB;
2160  break;
2161  case 0x09: decoded_field_order = AV_FIELD_TB;
2162  break;
2163  case 0x0E: decoded_field_order = AV_FIELD_BT;
2164  break;
2165  }
2166  }
2167  if (decoded_field_order == AV_FIELD_UNKNOWN && mov_field_order) {
2168  av_log(c->fc, AV_LOG_ERROR, "Unknown MOV field order 0x%04x\n", mov_field_order);
2169  }
2170  st->codecpar->field_order = decoded_field_order;
2171 
2172  return 0;
2173 }
2174 
2176 {
2177  int err = 0;
2178  uint64_t size = (uint64_t)par->extradata_size + atom.size + 8 + AV_INPUT_BUFFER_PADDING_SIZE;
2179  if (size > INT_MAX || (uint64_t)atom.size > INT_MAX)
2180  return AVERROR_INVALIDDATA;
2181  if ((err = av_reallocp(&par->extradata, size)) < 0) {
2182  par->extradata_size = 0;
2183  return err;
2184  }
2186  return 0;
2187 }
2188 
2189 /* Read a whole atom into the extradata return the size of the atom read, possibly truncated if != atom.size */
2191  AVCodecParameters *par, uint8_t *buf)
2192 {
2193  int64_t result = atom.size;
2194  int err;
2195 
2196  AV_WB32(buf , atom.size + 8);
2197  AV_WL32(buf + 4, atom.type);
2198  err = ffio_read_size(pb, buf + 8, atom.size);
2199  if (err < 0) {
2200  par->extradata_size -= atom.size;
2201  return err;
2202  } else if (err < atom.size) {
2203  av_log(c->fc, AV_LOG_WARNING, "truncated extradata\n");
2204  par->extradata_size -= atom.size - err;
2205  result = err;
2206  }
2207  memset(buf + 8 + err, 0, AV_INPUT_BUFFER_PADDING_SIZE);
2208  return result;
2209 }
2210 
2211 /* FIXME modify QDM2/SVQ3/H.264 decoders to take full atom as extradata */
2213  enum AVCodecID codec_id)
2214 {
2215  AVStream *st;
2216  uint64_t original_size;
2217  int err;
2218 
2219  if (c->fc->nb_streams < 1) // will happen with jp2 files
2220  return 0;
2221  st = c->fc->streams[c->fc->nb_streams-1];
2222 
2223  if (st->codecpar->codec_id != codec_id)
2224  return 0; /* unexpected codec_id - don't mess with extradata */
2225 
2226  original_size = st->codecpar->extradata_size;
2227  err = mov_realloc_extradata(st->codecpar, atom);
2228  if (err)
2229  return err;
2230 
2231  err = mov_read_atom_into_extradata(c, pb, atom, st->codecpar, st->codecpar->extradata + original_size);
2232  if (err < 0)
2233  return err;
2234  return 0; // Note: this is the original behavior to ignore truncation.
2235 }
2236 
2237 /* wrapper functions for reading ALAC/AVS/MJPEG/MJPEG2000 extradata atoms only for those codecs */
2239 {
2240  return mov_read_extradata(c, pb, atom, AV_CODEC_ID_ALAC);
2241 }
2242 
2244 {
2245  return mov_read_extradata(c, pb, atom, AV_CODEC_ID_CAVS);
2246 }
2247 
2249 {
2250  return mov_read_extradata(c, pb, atom, AV_CODEC_ID_JPEG2000);
2251 }
2252 
2254 {
2255  return mov_read_extradata(c, pb, atom, AV_CODEC_ID_R10K);
2256 }
2257 
2259 {
2260  int ret = mov_read_extradata(c, pb, atom, AV_CODEC_ID_AVUI);
2261  if (!ret)
2262  ret = mov_read_extradata(c, pb, atom, AV_CODEC_ID_DNXHD);
2263  return ret;
2264 }
2265 
2267 {
2268  int ret = mov_read_extradata(c, pb, atom, AV_CODEC_ID_TARGA_Y216);
2269 
2270  if (!ret && c->fc->nb_streams >= 1) {
2271  AVCodecParameters *par = c->fc->streams[c->fc->nb_streams-1]->codecpar;
2272  if (par->extradata_size >= 40) {
2273  par->height = AV_RB16(&par->extradata[36]);
2274  par->width = AV_RB16(&par->extradata[38]);
2275  }
2276  }
2277  return ret;
2278 }
2279 
2281 {
2282  if (c->fc->nb_streams >= 1) {
2283  AVStream *const st = c->fc->streams[c->fc->nb_streams - 1];
2284  FFStream *const sti = ffstream(st);
2285  AVCodecParameters *par = st->codecpar;
2286 
2287  if (par->codec_tag == MKTAG('A', 'V', 'i', 'n') &&
2288  par->codec_id == AV_CODEC_ID_H264 &&
2289  atom.size > 11) {
2290  int cid;
2291  avio_skip(pb, 10);
2292  cid = avio_rb16(pb);
2293  /* For AVID AVCI50, force width of 1440 to be able to select the correct SPS and PPS */
2294  if (cid == 0xd4d || cid == 0xd4e)
2295  par->width = 1440;
2296  return 0;
2297  } else if ((par->codec_tag == MKTAG('A', 'V', 'd', '1') ||
2298  par->codec_tag == MKTAG('A', 'V', 'j', '2') ||
2299  par->codec_tag == MKTAG('A', 'V', 'd', 'n')) &&
2300  atom.size >= 24) {
2301  int num, den;
2302  avio_skip(pb, 12);
2303  num = avio_rb32(pb);
2304  den = avio_rb32(pb);
2305  if (num <= 0 || den <= 0)
2306  return 0;
2307  switch (avio_rb32(pb)) {
2308  case 2:
2309  if (den >= INT_MAX / 2)
2310  return 0;
2311  den *= 2;
2312  case 1:
2313  sti->display_aspect_ratio = (AVRational){ num, den };
2314  default:
2315  return 0;
2316  }
2317  }
2318  }
2319 
2320  return mov_read_avid(c, pb, atom);
2321 }
2322 
2324 {
2325  int ret = 0;
2326  int length = 0;
2327  uint64_t original_size;
2328  if (c->fc->nb_streams >= 1) {
2329  AVCodecParameters *par = c->fc->streams[c->fc->nb_streams-1]->codecpar;
2330  if (par->codec_id == AV_CODEC_ID_H264)
2331  return 0;
2332  if (atom.size == 16) {
2333  original_size = par->extradata_size;
2334  ret = mov_realloc_extradata(par, atom);
2335  if (!ret) {
2336  length = mov_read_atom_into_extradata(c, pb, atom, par, par->extradata + original_size);
2337  if (length == atom.size) {
2338  const uint8_t range_value = par->extradata[original_size + 19];
2339  switch (range_value) {
2340  case 1:
2342  break;
2343  case 2:
2345  break;
2346  default:
2347  av_log(c->fc, AV_LOG_WARNING, "ignored unknown aclr value (%d)\n", range_value);
2348  break;
2349  }
2350  ff_dlog(c->fc, "color_range: %d\n", par->color_range);
2351  } else {
2352  /* For some reason the whole atom was not added to the extradata */
2353  av_log(c->fc, AV_LOG_ERROR, "aclr not decoded - incomplete atom\n");
2354  }
2355  } else {
2356  av_log(c->fc, AV_LOG_ERROR, "aclr not decoded - unable to add atom to extradata\n");
2357  }
2358  } else {
2359  av_log(c->fc, AV_LOG_WARNING, "aclr not decoded - unexpected size %"PRId64"\n", atom.size);
2360  }
2361  }
2362 
2363  return ret;
2364 }
2365 
2367 {
2368  return mov_read_extradata(c, pb, atom, AV_CODEC_ID_SVQ3);
2369 }
2370 
2372 {
2373  AVStream *st;
2374  int ret;
2375 
2376  if (c->fc->nb_streams < 1)
2377  return 0;
2378  st = c->fc->streams[c->fc->nb_streams-1];
2379 
2380  if ((uint64_t)atom.size > (1<<30))
2381  return AVERROR_INVALIDDATA;
2382 
2383  if (st->codecpar->codec_id == AV_CODEC_ID_QDM2 ||
2386  // pass all frma atom to codec, needed at least for QDMC and QDM2
2387  ret = ff_get_extradata(c->fc, st->codecpar, pb, atom.size);
2388  if (ret < 0)
2389  return ret;
2390  } else if (atom.size > 8) { /* to read frma, esds atoms */
2391  if (st->codecpar->codec_id == AV_CODEC_ID_ALAC && atom.size >= 24) {
2392  uint64_t buffer;
2393  ret = ffio_ensure_seekback(pb, 8);
2394  if (ret < 0)
2395  return ret;
2396  buffer = avio_rb64(pb);
2397  atom.size -= 8;
2398  if ( (buffer & 0xFFFFFFFF) == MKBETAG('f','r','m','a')
2399  && buffer >> 32 <= atom.size
2400  && buffer >> 32 >= 8) {
2401  avio_skip(pb, -8);
2402  atom.size += 8;
2403  } else if (!st->codecpar->extradata_size) {
2404 #define ALAC_EXTRADATA_SIZE 36
2406  if (!st->codecpar->extradata)
2407  return AVERROR(ENOMEM);
2410  AV_WB32(st->codecpar->extradata + 4, MKTAG('a','l','a','c'));
2411  AV_WB64(st->codecpar->extradata + 12, buffer);
2412  avio_read(pb, st->codecpar->extradata + 20, 16);
2413  avio_skip(pb, atom.size - 24);
2414  return 0;
2415  }
2416  }
2417  if ((ret = mov_read_default(c, pb, atom)) < 0)
2418  return ret;
2419  } else
2420  avio_skip(pb, atom.size);
2421  return 0;
2422 }
2423 
2424 /**
2425  * This function reads atom content and puts data in extradata without tag
2426  * nor size unlike mov_read_extradata.
2427  */
2429 {
2430  AVStream *st;
2431  int ret;
2432 
2433  st = get_curr_st(c);
2434  if (!st)
2435  return 0;
2436 
2437  if ((uint64_t)atom.size > (1<<30))
2438  return AVERROR_INVALIDDATA;
2439 
2440  if (atom.type == MKTAG('v','v','c','C')) {
2441  avio_skip(pb, 4);
2442  atom.size -= 4;
2443  }
2444 
2445  if (atom.size >= 10) {
2446  // Broken files created by legacy versions of libavformat will
2447  // wrap a whole fiel atom inside of a glbl atom.
2448  unsigned size = avio_rb32(pb);
2449  unsigned type = avio_rl32(pb);
2450  if (avio_feof(pb))
2451  return AVERROR_INVALIDDATA;
2452  avio_seek(pb, -8, SEEK_CUR);
2453  if (type == MKTAG('f','i','e','l') && size == atom.size)
2454  return mov_read_default(c, pb, atom);
2455  }
2456  if (st->codecpar->extradata_size > 1 && st->codecpar->extradata) {
2457  av_log(c->fc, AV_LOG_WARNING, "ignoring multiple glbl\n");
2458  return 0;
2459  }
2460  ret = ff_get_extradata(c->fc, st->codecpar, pb, atom.size);
2461  if (ret < 0)
2462  return ret;
2463  if (atom.type == MKTAG('h','v','c','C') && st->codecpar->codec_tag == MKTAG('d','v','h','1'))
2464  /* HEVC-based Dolby Vision derived from hvc1.
2465  Happens to match with an identifier
2466  previously utilized for DV. Thus, if we have
2467  the hvcC extradata box available as specified,
2468  set codec to HEVC */
2470 
2471  return 0;
2472 }
2473 
2475 {
2476  AVStream *st;
2477  uint8_t profile_level;
2478  int ret;
2479 
2480  if (c->fc->nb_streams < 1)
2481  return 0;
2482  st = c->fc->streams[c->fc->nb_streams-1];
2483 
2484  if (atom.size >= (1<<28) || atom.size < 7)
2485  return AVERROR_INVALIDDATA;
2486 
2487  profile_level = avio_r8(pb);
2488  if ((profile_level & 0xf0) != 0xc0)
2489  return 0;
2490 
2491  avio_seek(pb, 6, SEEK_CUR);
2492  ret = ff_get_extradata(c->fc, st->codecpar, pb, atom.size - 7);
2493  if (ret < 0)
2494  return ret;
2495 
2496  return 0;
2497 }
2498 
2500 {
2501  AVStream* st;
2502  MOVStreamContext* sc;
2503 
2504  if (c->fc->nb_streams < 1)
2505  return 0;
2506 
2507  /* For SBAS this should be fine - though beware if someone implements a
2508  * tref atom processor that doesn't drop down to default then this may
2509  * be lost. */
2510  if (atom.size > 4) {
2511  av_log(c->fc, AV_LOG_ERROR, "Only a single tref of type sbas is supported\n");
2512  return AVERROR_PATCHWELCOME;
2513  }
2514 
2515  st = c->fc->streams[c->fc->nb_streams - 1];
2516  sc = st->priv_data;
2517  sc->tref_id = avio_rb32(pb);
2519 
2520  return 0;
2521 }
2522 
2523 /**
2524  * An strf atom is a BITMAPINFOHEADER struct. This struct is 40 bytes itself,
2525  * but can have extradata appended at the end after the 40 bytes belonging
2526  * to the struct.
2527  */
2529 {
2530  AVStream *st;
2531  int ret;
2532 
2533  if (c->fc->nb_streams < 1)
2534  return 0;
2535  if (atom.size <= 40)
2536  return 0;
2537  st = c->fc->streams[c->fc->nb_streams-1];
2538 
2539  if ((uint64_t)atom.size > (1<<30))
2540  return AVERROR_INVALIDDATA;
2541 
2542  avio_skip(pb, 40);
2543  ret = ff_get_extradata(c->fc, st->codecpar, pb, atom.size - 40);
2544  if (ret < 0)
2545  return ret;
2546 
2547  return 0;
2548 }
2549 
2551 {
2552  AVStream *st;
2553  MOVStreamContext *sc;
2554  unsigned int i, entries;
2555 
2556  if (c->trak_index < 0) {
2557  av_log(c->fc, AV_LOG_WARNING, "STCO outside TRAK\n");
2558  return 0;
2559  }
2560  if (c->fc->nb_streams < 1)
2561  return 0;
2562  st = c->fc->streams[c->fc->nb_streams-1];
2563  sc = st->priv_data;
2564 
2565  avio_r8(pb); /* version */
2566  avio_rb24(pb); /* flags */
2567 
2568  // Clamp allocation size for `chunk_offsets` -- don't throw an error for an
2569  // invalid count since the EOF path doesn't throw either.
2570  entries = avio_rb32(pb);
2571  entries =
2572  FFMIN(entries,
2573  FFMAX(0, (atom.size - 8) /
2574  (atom.type == MKTAG('s', 't', 'c', 'o') ? 4 : 8)));
2575 
2576  if (!entries)
2577  return 0;
2578 
2579  if (sc->chunk_offsets) {
2580  av_log(c->fc, AV_LOG_WARNING, "Ignoring duplicated STCO atom\n");
2581  return 0;
2582  }
2583 
2584  av_free(sc->chunk_offsets);
2585  sc->chunk_count = 0;
2586  sc->chunk_offsets = av_malloc_array(entries, sizeof(*sc->chunk_offsets));
2587  if (!sc->chunk_offsets)
2588  return AVERROR(ENOMEM);
2589  sc->chunk_count = entries;
2590 
2591  if (atom.type == MKTAG('s','t','c','o'))
2592  for (i = 0; i < entries && !pb->eof_reached; i++)
2593  sc->chunk_offsets[i] = avio_rb32(pb);
2594  else if (atom.type == MKTAG('c','o','6','4'))
2595  for (i = 0; i < entries && !pb->eof_reached; i++) {
2596  sc->chunk_offsets[i] = avio_rb64(pb);
2597  if (sc->chunk_offsets[i] < 0) {
2598  av_log(c->fc, AV_LOG_WARNING, "Impossible chunk_offset\n");
2599  sc->chunk_offsets[i] = 0;
2600  }
2601  }
2602  else
2603  return AVERROR_INVALIDDATA;
2604 
2605  sc->chunk_count = i;
2606 
2607  if (pb->eof_reached) {
2608  av_log(c->fc, AV_LOG_WARNING, "reached eof, corrupted STCO atom\n");
2609  return AVERROR_EOF;
2610  }
2611 
2612  return 0;
2613 }
2614 
2615 static int mov_codec_id(AVStream *st, uint32_t format)
2616 {
2618 
2619  if (id <= 0 &&
2620  ((format & 0xFFFF) == 'm' + ('s' << 8) ||
2621  (format & 0xFFFF) == 'T' + ('S' << 8)))
2623 
2624  if (st->codecpar->codec_type != AVMEDIA_TYPE_VIDEO && id > 0) {
2626  } else if (st->codecpar->codec_type != AVMEDIA_TYPE_AUDIO &&
2627  /* skip old ASF MPEG-4 tag */
2628  format && format != MKTAG('m','p','4','s')) {
2630  if (id <= 0)
2632  if (id > 0)
2634  else if (st->codecpar->codec_type == AVMEDIA_TYPE_DATA ||
2636  st->codecpar->codec_id == AV_CODEC_ID_NONE)) {
2638  if (id <= 0) {
2640  AV_CODEC_ID_TTML : id;
2641  }
2642 
2643  if (id > 0)
2645  else
2647  }
2648  }
2649 
2650  st->codecpar->codec_tag = format;
2651 
2652  return id;
2653 }
2654 
2656  AVStream *st, MOVStreamContext *sc)
2657 {
2658  uint8_t codec_name[32] = { 0 };
2659  int64_t stsd_start;
2660  unsigned int len;
2661  uint32_t id = 0;
2662 
2663  /* The first 16 bytes of the video sample description are already
2664  * read in ff_mov_read_stsd_entries() */
2665  stsd_start = avio_tell(pb) - 16;
2666 
2667  avio_rb16(pb); /* version */
2668  avio_rb16(pb); /* revision level */
2669  id = avio_rl32(pb); /* vendor */
2670  av_dict_set(&st->metadata, "vendor_id", av_fourcc2str(id), 0);
2671  avio_rb32(pb); /* temporal quality */
2672  avio_rb32(pb); /* spatial quality */
2673 
2674  st->codecpar->width = avio_rb16(pb); /* width */
2675  st->codecpar->height = avio_rb16(pb); /* height */
2676 
2677  avio_rb32(pb); /* horiz resolution */
2678  avio_rb32(pb); /* vert resolution */
2679  avio_rb32(pb); /* data size, always 0 */
2680  avio_rb16(pb); /* frames per samples */
2681 
2682  len = avio_r8(pb); /* codec name, pascal string */
2683  if (len > 31)
2684  len = 31;
2685  mov_read_mac_string(c, pb, len, codec_name, sizeof(codec_name));
2686  if (len < 31)
2687  avio_skip(pb, 31 - len);
2688 
2689  if (codec_name[0])
2690  av_dict_set(&st->metadata, "encoder", codec_name, 0);
2691 
2692  /* codec_tag YV12 triggers an UV swap in rawdec.c */
2693  if (!strncmp(codec_name, "Planar Y'CbCr 8-bit 4:2:0", 25)) {
2694  st->codecpar->codec_tag = MKTAG('I', '4', '2', '0');
2695  st->codecpar->width &= ~1;
2696  st->codecpar->height &= ~1;
2697  }
2698  /* Flash Media Server uses tag H.263 with Sorenson Spark */
2699  if (st->codecpar->codec_tag == MKTAG('H','2','6','3') &&
2700  !strncmp(codec_name, "Sorenson H263", 13))
2702 
2703  st->codecpar->bits_per_coded_sample = avio_rb16(pb); /* depth */
2704 
2705  avio_seek(pb, stsd_start, SEEK_SET);
2706 
2707  if (ff_get_qtpalette(st->codecpar->codec_id, pb, sc->palette)) {
2708  st->codecpar->bits_per_coded_sample &= 0x1F;
2709  sc->has_palette = 1;
2710  }
2711 }
2712 
2714  AVStream *st, MOVStreamContext *sc)
2715 {
2716  int bits_per_sample, flags;
2717  uint16_t version = avio_rb16(pb);
2718  uint32_t id = 0;
2719  AVDictionaryEntry *compatible_brands = av_dict_get(c->fc->metadata, "compatible_brands", NULL, AV_DICT_MATCH_CASE);
2720  int channel_count;
2721 
2722  avio_rb16(pb); /* revision level */
2723  id = avio_rl32(pb); /* vendor */
2724  av_dict_set(&st->metadata, "vendor_id", av_fourcc2str(id), 0);
2725 
2726  channel_count = avio_rb16(pb);
2727 
2729  st->codecpar->ch_layout.nb_channels = channel_count;
2730  st->codecpar->bits_per_coded_sample = avio_rb16(pb); /* sample size */
2731  av_log(c->fc, AV_LOG_TRACE, "audio channels %d\n", channel_count);
2732 
2733  sc->audio_cid = avio_rb16(pb);
2734  avio_rb16(pb); /* packet size = 0 */
2735 
2736  st->codecpar->sample_rate = ((avio_rb32(pb) >> 16));
2737 
2738  // Read QT version 1 fields. In version 0 these do not exist.
2739  av_log(c->fc, AV_LOG_TRACE, "version =%d, isom =%d\n", version, c->isom);
2740  if (!c->isom ||
2741  (compatible_brands && strstr(compatible_brands->value, "qt ")) ||
2742  (sc->stsd_version == 0 && version > 0)) {
2743  if (version == 1) {
2744  sc->samples_per_frame = avio_rb32(pb);
2745  avio_rb32(pb); /* bytes per packet */
2746  sc->bytes_per_frame = avio_rb32(pb);
2747  avio_rb32(pb); /* bytes per sample */
2748  } else if (version == 2) {
2749  avio_rb32(pb); /* sizeof struct only */
2751  channel_count = avio_rb32(pb);
2753  st->codecpar->ch_layout.nb_channels = channel_count;
2754  avio_rb32(pb); /* always 0x7F000000 */
2756 
2757  flags = avio_rb32(pb); /* lpcm format specific flag */
2758  sc->bytes_per_frame = avio_rb32(pb);
2759  sc->samples_per_frame = avio_rb32(pb);
2760  if (st->codecpar->codec_tag == MKTAG('l','p','c','m'))
2761  st->codecpar->codec_id =
2763  flags);
2764  }
2765  if (version == 0 || (version == 1 && sc->audio_cid != -2)) {
2766  /* can't correctly handle variable sized packet as audio unit */
2767  switch (st->codecpar->codec_id) {
2768  case AV_CODEC_ID_MP2:
2769  case AV_CODEC_ID_MP3:
2771  break;
2772  }
2773  }
2774  }
2775 
2776  if (sc->format == 0) {
2777  if (st->codecpar->bits_per_coded_sample == 8)
2778  st->codecpar->codec_id = mov_codec_id(st, MKTAG('r','a','w',' '));
2779  else if (st->codecpar->bits_per_coded_sample == 16)
2780  st->codecpar->codec_id = mov_codec_id(st, MKTAG('t','w','o','s'));
2781  }
2782 
2783  switch (st->codecpar->codec_id) {
2784  case AV_CODEC_ID_PCM_S8:
2785  case AV_CODEC_ID_PCM_U8:
2786  if (st->codecpar->bits_per_coded_sample == 16)
2788  break;
2789  case AV_CODEC_ID_PCM_S16LE:
2790  case AV_CODEC_ID_PCM_S16BE:
2791  if (st->codecpar->bits_per_coded_sample == 8)
2793  else if (st->codecpar->bits_per_coded_sample == 24)
2794  st->codecpar->codec_id =
2797  else if (st->codecpar->bits_per_coded_sample == 32)
2798  st->codecpar->codec_id =
2801  break;
2802  /* set values for old format before stsd version 1 appeared */
2803  case AV_CODEC_ID_MACE3:
2804  sc->samples_per_frame = 6;
2806  break;
2807  case AV_CODEC_ID_MACE6:
2808  sc->samples_per_frame = 6;
2810  break;
2812  sc->samples_per_frame = 64;
2814  break;
2815  case AV_CODEC_ID_GSM:
2816  sc->samples_per_frame = 160;
2817  sc->bytes_per_frame = 33;
2818  break;
2819  default:
2820  break;
2821  }
2822 
2823  bits_per_sample = av_get_bits_per_sample(st->codecpar->codec_id);
2824  if (bits_per_sample && (bits_per_sample >> 3) * (uint64_t)st->codecpar->ch_layout.nb_channels <= INT_MAX) {
2825  st->codecpar->bits_per_coded_sample = bits_per_sample;
2826  sc->sample_size = (bits_per_sample >> 3) * st->codecpar->ch_layout.nb_channels;
2827  }
2828 }
2829 
2831  AVStream *st, MOVStreamContext *sc,
2832  int64_t size)
2833 {
2834  // ttxt stsd contains display flags, justification, background
2835  // color, fonts, and default styles, so fake an atom to read it
2836  MOVAtom fake_atom = { .size = size };
2837  // mp4s contains a regular esds atom, dfxp ISMV TTML has no content
2838  // in extradata unlike stpp MP4 TTML.
2839  if (st->codecpar->codec_tag != AV_RL32("mp4s") &&
2841  mov_read_glbl(c, pb, fake_atom);
2842  st->codecpar->width = sc->width;
2843  st->codecpar->height = sc->height;
2844 }
2845 
2847  AVStream *st, MOVStreamContext *sc,
2848  int64_t size)
2849 {
2850  int ret;
2851 
2852  if (st->codecpar->codec_tag == MKTAG('t','m','c','d')) {
2853  if ((int)size != size)
2854  return AVERROR(ENOMEM);
2855 
2856  ret = ff_get_extradata(c->fc, st->codecpar, pb, size);
2857  if (ret < 0)
2858  return ret;
2859  if (size > 16) {
2860  MOVStreamContext *tmcd_ctx = st->priv_data;
2861  int val;
2862  val = AV_RB32(st->codecpar->extradata + 4);
2863  tmcd_ctx->tmcd_flags = val;
2864  st->avg_frame_rate.num = AV_RB32(st->codecpar->extradata + 8); /* timescale */
2865  st->avg_frame_rate.den = AV_RB32(st->codecpar->extradata + 12); /* frameDuration */
2866  tmcd_ctx->tmcd_nb_frames = st->codecpar->extradata[16]; /* number of frames */
2867  if (size > 30) {
2868  uint32_t len = AV_RB32(st->codecpar->extradata + 18); /* name atom length */
2869  uint32_t format = AV_RB32(st->codecpar->extradata + 22);
2870  if (format == AV_RB32("name") && (int64_t)size >= (int64_t)len + 18) {
2871  uint16_t str_size = AV_RB16(st->codecpar->extradata + 26); /* string length */
2872  if (str_size > 0 && size >= (int)str_size + 30 &&
2873  st->codecpar->extradata[30] /* Don't add empty string */) {
2874  char *reel_name = av_malloc(str_size + 1);
2875  if (!reel_name)
2876  return AVERROR(ENOMEM);
2877  memcpy(reel_name, st->codecpar->extradata + 30, str_size);
2878  reel_name[str_size] = 0; /* Add null terminator */
2879  av_dict_set(&st->metadata, "reel_name", reel_name,
2881  }
2882  }
2883  }
2884  }
2885  } else {
2886  /* other codec type, just skip (rtp, mp4s ...) */
2887  avio_skip(pb, size);
2888  }
2889  return 0;
2890 }
2891 
2893  AVStream *st, MOVStreamContext *sc)
2894 {
2895  FFStream *const sti = ffstream(st);
2896 
2897  if (st->codecpar->codec_type == AVMEDIA_TYPE_AUDIO &&
2898  !st->codecpar->sample_rate && sc->time_scale > 1)
2899  st->codecpar->sample_rate = sc->time_scale;
2900 
2901  /* special codec parameters handling */
2902  switch (st->codecpar->codec_id) {
2903 #if CONFIG_DV_DEMUXER
2904  case AV_CODEC_ID_DVAUDIO:
2905  if (c->dv_fctx) {
2906  avpriv_request_sample(c->fc, "multiple DV audio streams");
2907  return AVERROR(ENOSYS);
2908  }
2909 
2910  c->dv_fctx = avformat_alloc_context();
2911  if (!c->dv_fctx) {
2912  av_log(c->fc, AV_LOG_ERROR, "dv demux context alloc error\n");
2913  return AVERROR(ENOMEM);
2914  }
2915  c->dv_demux = avpriv_dv_init_demux(c->dv_fctx);
2916  if (!c->dv_demux) {
2917  av_log(c->fc, AV_LOG_ERROR, "dv demux context init error\n");
2918  return AVERROR(ENOMEM);
2919  }
2920  sc->dv_audio_container = 1;
2922  break;
2923 #endif
2924  /* no ifdef since parameters are always those */
2925  case AV_CODEC_ID_QCELP:
2928  // force sample rate for qcelp when not stored in mov
2929  if (st->codecpar->codec_tag != MKTAG('Q','c','l','p'))
2930  st->codecpar->sample_rate = 8000;
2931  // FIXME: Why is the following needed for some files?
2932  sc->samples_per_frame = 160;
2933  if (!sc->bytes_per_frame)
2934  sc->bytes_per_frame = 35;
2935  break;
2936  case AV_CODEC_ID_AMR_NB:
2939  /* force sample rate for amr, stsd in 3gp does not store sample rate */
2940  st->codecpar->sample_rate = 8000;
2941  break;
2942  case AV_CODEC_ID_AMR_WB:
2945  st->codecpar->sample_rate = 16000;
2946  break;
2947  case AV_CODEC_ID_MP2:
2948  case AV_CODEC_ID_MP3:
2949  /* force type after stsd for m1a hdlr */
2951  break;
2952  case AV_CODEC_ID_GSM:
2953  case AV_CODEC_ID_ADPCM_MS:
2955  case AV_CODEC_ID_ILBC:
2956  case AV_CODEC_ID_MACE3:
2957  case AV_CODEC_ID_MACE6:
2958  case AV_CODEC_ID_QDM2:
2960  break;
2961  case AV_CODEC_ID_ALAC:
2962  if (st->codecpar->extradata_size == 36) {
2963  int channel_count = AV_RB8(st->codecpar->extradata + 21);
2964  if (st->codecpar->ch_layout.nb_channels != channel_count) {
2967  st->codecpar->ch_layout.nb_channels = channel_count;
2968  }
2969  st->codecpar->sample_rate = AV_RB32(st->codecpar->extradata + 32);
2970  }
2971  break;
2972  case AV_CODEC_ID_AC3:
2973  case AV_CODEC_ID_EAC3:
2975  case AV_CODEC_ID_VC1:
2976  case AV_CODEC_ID_VP8:
2977  case AV_CODEC_ID_VP9:
2979  break;
2980  case AV_CODEC_ID_EVC:
2981  case AV_CODEC_ID_AV1:
2982  /* field_order detection of H264 requires parsing */
2983  case AV_CODEC_ID_H264:
2985  break;
2986  default:
2987  break;
2988  }
2989  return 0;
2990 }
2991 
2993  int codec_tag, int format,
2994  int64_t size)
2995 {
2996  if (codec_tag &&
2997  (codec_tag != format &&
2998  // AVID 1:1 samples with differing data format and codec tag exist
2999  (codec_tag != AV_RL32("AV1x") || format != AV_RL32("AVup")) &&
3000  // prores is allowed to have differing data format and codec tag
3001  codec_tag != AV_RL32("apcn") && codec_tag != AV_RL32("apch") &&
3002  // so is dv (sigh)
3003  codec_tag != AV_RL32("dvpp") && codec_tag != AV_RL32("dvcp") &&
3004  (c->fc->video_codec_id ? ff_codec_get_id(ff_codec_movvideo_tags, format) != c->fc->video_codec_id
3005  : codec_tag != MKTAG('j','p','e','g')))) {
3006  /* Multiple fourcc, we skip JPEG. This is not correct, we should
3007  * export it as a separate AVStream but this needs a few changes
3008  * in the MOV demuxer, patch welcome. */
3009 
3010  av_log(c->fc, AV_LOG_WARNING, "multiple fourcc not supported\n");
3011  avio_skip(pb, size);
3012  return 1;
3013  }
3014 
3015  return 0;
3016 }
3017 
3019 {
3020  AVStream *st;
3021  MOVStreamContext *sc;
3022  int pseudo_stream_id;
3023 
3024  av_assert0 (c->fc->nb_streams >= 1);
3025  st = c->fc->streams[c->fc->nb_streams-1];
3026  sc = st->priv_data;
3027 
3028  for (pseudo_stream_id = 0;
3029  pseudo_stream_id < entries && !pb->eof_reached;
3030  pseudo_stream_id++) {
3031  //Parsing Sample description table
3032  enum AVCodecID id;
3033  int ret, dref_id = 1;
3034  MOVAtom a = { AV_RL32("stsd") };
3035  int64_t start_pos = avio_tell(pb);
3036  int64_t size = avio_rb32(pb); /* size */
3037  uint32_t format = avio_rl32(pb); /* data format */
3038 
3039  if (size >= 16) {
3040  avio_rb32(pb); /* reserved */
3041  avio_rb16(pb); /* reserved */
3042  dref_id = avio_rb16(pb);
3043  } else if (size <= 7) {
3044  av_log(c->fc, AV_LOG_ERROR,
3045  "invalid size %"PRId64" in stsd\n", size);
3046  return AVERROR_INVALIDDATA;
3047  }
3048 
3050  size - (avio_tell(pb) - start_pos))) {
3051  sc->stsd_count++;
3052  continue;
3053  }
3054 
3055  sc->pseudo_stream_id = st->codecpar->codec_tag ? -1 : pseudo_stream_id;
3056  sc->dref_id= dref_id;
3057  sc->format = format;
3058 
3059  id = mov_codec_id(st, format);
3060 
3061  av_log(c->fc, AV_LOG_TRACE,
3062  "size=%"PRId64" 4CC=%s codec_type=%d\n", size,
3064 
3065  st->codecpar->codec_id = id;
3067  mov_parse_stsd_video(c, pb, st, sc);
3068  } else if (st->codecpar->codec_type==AVMEDIA_TYPE_AUDIO) {
3069  mov_parse_stsd_audio(c, pb, st, sc);
3070  if (st->codecpar->sample_rate < 0) {
3071  av_log(c->fc, AV_LOG_ERROR, "Invalid sample rate %d\n", st->codecpar->sample_rate);
3072  return AVERROR_INVALIDDATA;
3073  }
3074  if (st->codecpar->ch_layout.nb_channels < 0) {
3075  av_log(c->fc, AV_LOG_ERROR, "Invalid channels %d\n", st->codecpar->ch_layout.nb_channels);
3076  return AVERROR_INVALIDDATA;
3077  }
3078  } else if (st->codecpar->codec_type==AVMEDIA_TYPE_SUBTITLE){
3079  mov_parse_stsd_subtitle(c, pb, st, sc,
3080  size - (avio_tell(pb) - start_pos));
3081  } else {
3082  ret = mov_parse_stsd_data(c, pb, st, sc,
3083  size - (avio_tell(pb) - start_pos));
3084  if (ret < 0)
3085  return ret;
3086  }
3087  /* this will read extra atoms at the end (wave, alac, damr, avcC, hvcC, SMI ...) */
3088  a.size = size - (avio_tell(pb) - start_pos);
3089  if (a.size > 8) {
3090  if ((ret = mov_read_default(c, pb, a)) < 0)
3091  return ret;
3092  } else if (a.size > 0)
3093  avio_skip(pb, a.size);
3094 
3095  if (sc->extradata && st->codecpar->extradata) {
3096  int extra_size = st->codecpar->extradata_size;
3097 
3098  /* Move the current stream extradata to the stream context one. */
3099  sc->extradata_size[pseudo_stream_id] = extra_size;
3100  sc->extradata[pseudo_stream_id] = st->codecpar->extradata;
3101  st->codecpar->extradata = NULL;
3102  st->codecpar->extradata_size = 0;
3103  }
3104  sc->stsd_count++;
3105  }
3106 
3107  if (pb->eof_reached) {
3108  av_log(c->fc, AV_LOG_WARNING, "reached eof, corrupted STSD atom\n");
3109  return AVERROR_EOF;
3110  }
3111 
3112  return 0;
3113 }
3114 
3116 {
3117  AVStream *st;
3118  MOVStreamContext *sc;
3119  int ret, entries;
3120 
3121  if (c->fc->nb_streams < 1)
3122  return 0;
3123  st = c->fc->streams[c->fc->nb_streams - 1];
3124  sc = st->priv_data;
3125 
3126  sc->stsd_version = avio_r8(pb);
3127  avio_rb24(pb); /* flags */
3128  entries = avio_rb32(pb);
3129 
3130  /* Each entry contains a size (4 bytes) and format (4 bytes). */
3131  if (entries <= 0 || entries > atom.size / 8 || entries > 1024) {
3132  av_log(c->fc, AV_LOG_ERROR, "invalid STSD entries %d\n", entries);
3133  return AVERROR_INVALIDDATA;
3134  }
3135 
3136  if (sc->extradata) {
3137  av_log(c->fc, AV_LOG_ERROR,
3138  "Duplicate stsd found in this track.\n");
3139  return AVERROR_INVALIDDATA;
3140  }
3141 
3142  /* Prepare space for hosting multiple extradata. */
3143  sc->extradata = av_calloc(entries, sizeof(*sc->extradata));
3144  if (!sc->extradata)
3145  return AVERROR(ENOMEM);
3146 
3147  sc->extradata_size = av_calloc(entries, sizeof(*sc->extradata_size));
3148  if (!sc->extradata_size) {
3149  ret = AVERROR(ENOMEM);
3150  goto fail;
3151  }
3152 
3153  ret = ff_mov_read_stsd_entries(c, pb, entries);
3154  if (ret < 0)
3155  goto fail;
3156 
3157  /* Restore back the primary extradata. */
3158  av_freep(&st->codecpar->extradata);
3159  st->codecpar->extradata_size = sc->extradata_size[0];
3160  if (sc->extradata_size[0]) {
3162  if (!st->codecpar->extradata)
3163  return AVERROR(ENOMEM);
3164  memcpy(st->codecpar->extradata, sc->extradata[0], sc->extradata_size[0]);
3165  }
3166 
3167  return mov_finalize_stsd_codec(c, pb, st, sc);
3168 fail:
3169  if (sc->extradata) {
3170  int j;
3171  for (j = 0; j < sc->stsd_count; j++)
3172  av_freep(&sc->extradata[j]);
3173  }
3174 
3175  av_freep(&sc->extradata);
3176  av_freep(&sc->extradata_size);
3177  return ret;
3178 }
3179 
3181 {
3182  AVStream *st;
3183  MOVStreamContext *sc;
3184  unsigned int i, entries;
3185 
3186  if (c->trak_index < 0) {
3187  av_log(c->fc, AV_LOG_WARNING, "STSC outside TRAK\n");
3188  return 0;
3189  }
3190 
3191  if (c->fc->nb_streams < 1)
3192  return 0;
3193  st = c->fc->streams[c->fc->nb_streams-1];
3194  sc = st->priv_data;
3195 
3196  avio_r8(pb); /* version */
3197  avio_rb24(pb); /* flags */
3198 
3199  entries = avio_rb32(pb);
3200  if ((uint64_t)entries * 12 + 4 > atom.size)
3201  return AVERROR_INVALIDDATA;
3202 
3203  av_log(c->fc, AV_LOG_TRACE, "track[%u].stsc.entries = %u\n", c->fc->nb_streams - 1, entries);
3204 
3205  if (!entries)
3206  return 0;
3207  if (sc->stsc_data) {
3208  av_log(c->fc, AV_LOG_WARNING, "Ignoring duplicated STSC atom\n");
3209  return 0;
3210  }
3211  av_free(sc->stsc_data);
3212  sc->stsc_count = 0;
3213  sc->stsc_data = av_malloc_array(entries, sizeof(*sc->stsc_data));
3214  if (!sc->stsc_data)
3215  return AVERROR(ENOMEM);
3216 
3217  for (i = 0; i < entries && !pb->eof_reached; i++) {
3218  sc->stsc_data[i].first = avio_rb32(pb);
3219  sc->stsc_data[i].count = avio_rb32(pb);
3220  sc->stsc_data[i].id = avio_rb32(pb);
3221  }
3222 
3223  sc->stsc_count = i;
3224  for (i = sc->stsc_count - 1; i < UINT_MAX; i--) {
3225  int64_t first_min = i + 1;
3226  if ((i+1 < sc->stsc_count && sc->stsc_data[i].first >= sc->stsc_data[i+1].first) ||
3227  (i > 0 && sc->stsc_data[i].first <= sc->stsc_data[i-1].first) ||
3228  sc->stsc_data[i].first < first_min ||
3229  sc->stsc_data[i].count < 1 ||
3230  sc->stsc_data[i].id < 1) {
3231  av_log(c->fc, AV_LOG_WARNING, "STSC entry %d is invalid (first=%d count=%d id=%d)\n", i, sc->stsc_data[i].first, sc->stsc_data[i].count, sc->stsc_data[i].id);
3232  if (i+1 >= sc->stsc_count) {
3233  if (sc->stsc_data[i].count == 0 && i > 0) {
3234  sc->stsc_count --;
3235  continue;
3236  }
3237  sc->stsc_data[i].first = FFMAX(sc->stsc_data[i].first, first_min);
3238  if (i > 0 && sc->stsc_data[i].first <= sc->stsc_data[i-1].first)
3239  sc->stsc_data[i].first = FFMIN(sc->stsc_data[i-1].first + 1LL, INT_MAX);
3240  sc->stsc_data[i].count = FFMAX(sc->stsc_data[i].count, 1);
3241  sc->stsc_data[i].id = FFMAX(sc->stsc_data[i].id, 1);
3242  continue;
3243  }
3244  av_assert0(sc->stsc_data[i+1].first >= 2);
3245  // We replace this entry by the next valid
3246  sc->stsc_data[i].first = sc->stsc_data[i+1].first - 1;
3247  sc->stsc_data[i].count = sc->stsc_data[i+1].count;
3248  sc->stsc_data[i].id = sc->stsc_data[i+1].id;
3249  }
3250  }
3251 
3252  if (pb->eof_reached) {
3253  av_log(c->fc, AV_LOG_WARNING, "reached eof, corrupted STSC atom\n");
3254  return AVERROR_EOF;
3255  }
3256 
3257  return 0;
3258 }
3259 
3260 static inline int mov_stsc_index_valid(unsigned int index, unsigned int count)
3261 {
3262  return index < count - 1;
3263 }
3264 
3265 /* Compute the samples value for the stsc entry at the given index. */
3266 static inline int64_t mov_get_stsc_samples(MOVStreamContext *sc, unsigned int index)
3267 {
3268  int chunk_count;
3269 
3271  chunk_count = sc->stsc_data[index + 1].first - sc->stsc_data[index].first;
3272  else {
3273  // Validation for stsc / stco happens earlier in mov_read_stsc + mov_read_trak.
3275  chunk_count = sc->chunk_count - (sc->stsc_data[index].first - 1);
3276  }
3277 
3278  return sc->stsc_data[index].count * (int64_t)chunk_count;
3279 }
3280 
3282 {
3283  AVStream *st;
3284  MOVStreamContext *sc;
3285  unsigned i, entries;
3286 
3287  if (c->trak_index < 0) {
3288  av_log(c->fc, AV_LOG_WARNING, "STPS outside TRAK\n");
3289  return 0;
3290  }
3291 
3292  if (c->fc->nb_streams < 1)
3293  return 0;
3294  st = c->fc->streams[c->fc->nb_streams-1];
3295  sc = st->priv_data;
3296 
3297  avio_rb32(pb); // version + flags
3298 
3299  entries = avio_rb32(pb);
3300  if (sc->stps_data)
3301  av_log(c->fc, AV_LOG_WARNING, "Duplicated STPS atom\n");
3302  av_free(sc->stps_data);
3303  sc->stps_count = 0;
3304  sc->stps_data = av_malloc_array(entries, sizeof(*sc->stps_data));
3305  if (!sc->stps_data)
3306  return AVERROR(ENOMEM);
3307 
3308  for (i = 0; i < entries && !pb->eof_reached; i++) {
3309  sc->stps_data[i] = avio_rb32(pb);
3310  }
3311 
3312  sc->stps_count = i;
3313 
3314  if (pb->eof_reached) {
3315  av_log(c->fc, AV_LOG_WARNING, "reached eof, corrupted STPS atom\n");
3316  return AVERROR_EOF;
3317  }
3318 
3319  return 0;
3320 }
3321 
3323 {
3324  AVStream *st;
3325  FFStream *sti;
3326  MOVStreamContext *sc;
3327  unsigned int i, entries;
3328 
3329  if (c->trak_index < 0) {
3330  av_log(c->fc, AV_LOG_WARNING, "STSS outside TRAK\n");
3331  return 0;
3332  }
3333 
3334  if (c->fc->nb_streams < 1)
3335  return 0;
3336  st = c->fc->streams[c->fc->nb_streams-1];
3337  sti = ffstream(st);
3338  sc = st->priv_data;
3339 
3340  avio_r8(pb); /* version */
3341  avio_rb24(pb); /* flags */
3342 
3343  entries = avio_rb32(pb);
3344 
3345  av_log(c->fc, AV_LOG_TRACE, "keyframe_count = %u\n", entries);
3346 
3347  if (!entries) {
3348  sc->keyframe_absent = 1;
3349  if (!sti->need_parsing && st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO)
3351  return 0;
3352  }
3353  if (sc->keyframes)
3354  av_log(c->fc, AV_LOG_WARNING, "Duplicated STSS atom\n");
3355  if (entries >= UINT_MAX / sizeof(int))
3356  return AVERROR_INVALIDDATA;
3357  av_freep(&sc->keyframes);
3358  sc->keyframe_count = 0;
3359  sc->keyframes = av_malloc_array(entries, sizeof(*sc->keyframes));
3360  if (!sc->keyframes)
3361  return AVERROR(ENOMEM);
3362 
3363  for (i = 0; i < entries && !pb->eof_reached; i++) {
3364  sc->keyframes[i] = avio_rb32(pb);
3365  }
3366 
3367  sc->keyframe_count = i;
3368 
3369  if (pb->eof_reached) {
3370  av_log(c->fc, AV_LOG_WARNING, "reached eof, corrupted STSS atom\n");
3371  return AVERROR_EOF;
3372  }
3373 
3374  return 0;
3375 }
3376 
3378 {
3379  AVStream *st;
3380  MOVStreamContext *sc;
3381  unsigned int i, entries, sample_size, field_size, num_bytes;
3382  GetBitContext gb;
3383  unsigned char* buf;
3384  int ret;
3385 
3386  if (c->trak_index < 0) {
3387  av_log(c->fc, AV_LOG_WARNING, "STSZ outside TRAK\n");
3388  return 0;
3389  }
3390 
3391  if (c->fc->nb_streams < 1)
3392  return 0;
3393  st = c->fc->streams[c->fc->nb_streams-1];
3394  sc = st->priv_data;
3395 
3396  avio_r8(pb); /* version */
3397  avio_rb24(pb); /* flags */
3398 
3399  if (atom.type == MKTAG('s','t','s','z')) {
3400  sample_size = avio_rb32(pb);
3401  if (!sc->sample_size) /* do not overwrite value computed in stsd */
3402  sc->sample_size = sample_size;
3403  sc->stsz_sample_size = sample_size;
3404  field_size = 32;
3405  } else {
3406  sample_size = 0;
3407  avio_rb24(pb); /* reserved */
3408  field_size = avio_r8(pb);
3409  }
3410  entries = avio_rb32(pb);
3411 
3412  av_log(c->fc, AV_LOG_TRACE, "sample_size = %u sample_count = %u\n", sc->sample_size, entries);
3413 
3414  sc->sample_count = entries;
3415  if (sample_size)
3416  return 0;
3417 
3418  if (field_size != 4 && field_size != 8 && field_size != 16 && field_size != 32) {
3419  av_log(c->fc, AV_LOG_ERROR, "Invalid sample field size %u\n", field_size);
3420  return AVERROR_INVALIDDATA;
3421  }
3422 
3423  if (!entries)
3424  return 0;
3425  if (entries >= (INT_MAX - 4 - 8 * AV_INPUT_BUFFER_PADDING_SIZE) / field_size)
3426  return AVERROR_INVALIDDATA;
3427  if (sc->sample_sizes)
3428  av_log(c->fc, AV_LOG_WARNING, "Duplicated STSZ atom\n");
3429  av_free(sc->sample_sizes);
3430  sc->sample_count = 0;
3431  sc->sample_sizes = av_malloc_array(entries, sizeof(*sc->sample_sizes));
3432  if (!sc->sample_sizes)
3433  return AVERROR(ENOMEM);
3434 
3435  num_bytes = (entries*field_size+4)>>3;
3436 
3437  buf = av_malloc(num_bytes+AV_INPUT_BUFFER_PADDING_SIZE);
3438  if (!buf) {
3439  av_freep(&sc->sample_sizes);
3440  return AVERROR(ENOMEM);
3441  }
3442 
3443  ret = ffio_read_size(pb, buf, num_bytes);
3444  if (ret < 0) {
3445  av_freep(&sc->sample_sizes);
3446  av_free(buf);
3447  av_log(c->fc, AV_LOG_WARNING, "STSZ atom truncated\n");
3448  return 0;
3449  }
3450 
3451  init_get_bits(&gb, buf, 8*num_bytes);
3452 
3453  for (i = 0; i < entries; i++) {
3454  sc->sample_sizes[i] = get_bits_long(&gb, field_size);
3455  if (sc->sample_sizes[i] > INT64_MAX - sc->data_size) {
3456  av_free(buf);
3457  av_log(c->fc, AV_LOG_ERROR, "Sample size overflow in STSZ\n");
3458  return AVERROR_INVALIDDATA;
3459  }
3460  sc->data_size += sc->sample_sizes[i];
3461  }
3462 
3463  sc->sample_count = i;
3464 
3465  av_free(buf);
3466 
3467  return 0;
3468 }
3469 
3471 {
3472  AVStream *st;
3473  MOVStreamContext *sc;
3474  unsigned int i, entries;
3475  int64_t duration = 0;
3476  int64_t total_sample_count = 0;
3477  int64_t current_dts = 0;
3478  int64_t corrected_dts = 0;
3479 
3480  if (c->trak_index < 0) {
3481  av_log(c->fc, AV_LOG_WARNING, "STTS outside TRAK\n");
3482  return 0;
3483  }
3484 
3485  if (c->fc->nb_streams < 1)
3486  return 0;
3487  st = c->fc->streams[c->fc->nb_streams-1];
3488  sc = st->priv_data;
3489 
3490  avio_r8(pb); /* version */
3491  avio_rb24(pb); /* flags */
3492  entries = avio_rb32(pb);
3493 
3494  av_log(c->fc, AV_LOG_TRACE, "track[%u].stts.entries = %u\n",
3495  c->fc->nb_streams-1, entries);
3496 
3497  if (sc->stts_data)
3498  av_log(c->fc, AV_LOG_WARNING, "Duplicated STTS atom\n");
3499  av_freep(&sc->stts_data);
3500  sc->stts_count = 0;
3501  if (entries >= INT_MAX / sizeof(*sc->stts_data))
3502  return AVERROR(ENOMEM);
3503 
3504  for (i = 0; i < entries && !pb->eof_reached; i++) {
3505  unsigned int sample_duration;
3506  unsigned int sample_count;
3507  unsigned int min_entries = FFMIN(FFMAX(i + 1, 1024 * 1024), entries);
3508  MOVStts *stts_data = av_fast_realloc(sc->stts_data, &sc->stts_allocated_size,
3509  min_entries * sizeof(*sc->stts_data));
3510  if (!stts_data) {
3511  av_freep(&sc->stts_data);
3512  sc->stts_count = 0;
3513  return AVERROR(ENOMEM);
3514  }
3515  sc->stts_count = min_entries;
3516  sc->stts_data = stts_data;
3517 
3518  sample_count = avio_rb32(pb);
3519  sample_duration = avio_rb32(pb);
3520 
3521  sc->stts_data[i].count= sample_count;
3522  sc->stts_data[i].duration= sample_duration;
3523 
3524  av_log(c->fc, AV_LOG_TRACE, "sample_count=%u, sample_duration=%u\n",
3525  sample_count, sample_duration);
3526 
3527  /* STTS sample offsets are uint32 but some files store it as int32
3528  * with negative values used to correct DTS delays.
3529  There may be abnormally large values as well. */
3530  if (sample_duration > c->max_stts_delta) {
3531  // assume high delta is a correction if negative when cast as int32
3532  int32_t delta_magnitude = (int32_t)sample_duration;
3533  av_log(c->fc, AV_LOG_WARNING, "Too large sample offset %u in stts entry %u with count %u in st:%d. Clipping to 1.\n",
3534  sample_duration, i, sample_count, st->index);
3535  sc->stts_data[i].duration = 1;
3536  corrected_dts += (delta_magnitude < 0 ? (int64_t)delta_magnitude : 1) * sample_count;
3537  } else {
3538  corrected_dts += sample_duration * (uint64_t)sample_count;
3539  }
3540 
3541  current_dts += sc->stts_data[i].duration * (uint64_t)sample_count;
3542 
3543  if (current_dts > corrected_dts) {
3544  int64_t drift = (current_dts - corrected_dts)/FFMAX(sample_count, 1);
3545  uint32_t correction = (sc->stts_data[i].duration > drift) ? drift : sc->stts_data[i].duration - 1;
3546  current_dts -= correction * (uint64_t)sample_count;
3547  sc->stts_data[i].duration -= correction;
3548  }
3549 
3550  duration+=(int64_t)sc->stts_data[i].duration*(uint64_t)sc->stts_data[i].count;
3551  total_sample_count+=sc->stts_data[i].count;
3552  }
3553 
3554  sc->stts_count = i;
3555 
3556  if (duration > 0 &&
3557  duration <= INT64_MAX - sc->duration_for_fps &&
3558  total_sample_count <= INT_MAX - sc->nb_frames_for_fps) {
3559  sc->duration_for_fps += duration;
3560  sc->nb_frames_for_fps += total_sample_count;
3561  }
3562 
3563  if (pb->eof_reached) {
3564  av_log(c->fc, AV_LOG_WARNING, "reached eof, corrupted STTS atom\n");
3565  return AVERROR_EOF;
3566  }
3567 
3568  st->nb_frames= total_sample_count;
3569  if (duration)
3570  st->duration= FFMIN(st->duration, duration);
3571 
3572  // All samples have zero duration. They have higher chance be chose by
3573  // mov_find_next_sample, which leads to seek again and again.
3574  //
3575  // It's AVERROR_INVALIDDATA actually, but such files exist in the wild.
3576  // So only mark data stream as discarded for safety.
3577  if (!duration && sc->stts_count &&
3579  av_log(c->fc, AV_LOG_WARNING,
3580  "All samples in data stream index:id [%d:%d] have zero "
3581  "duration, stream set to be discarded by default. Override "
3582  "using AVStream->discard or -discard for ffmpeg command.\n",
3583  st->index, sc->id);
3584  st->discard = AVDISCARD_ALL;
3585  }
3586  sc->track_end = duration;
3587  return 0;
3588 }
3589 
3591 {
3592  AVStream *st;
3593  MOVStreamContext *sc;
3594  int64_t i, entries;
3595 
3596  if (c->fc->nb_streams < 1)
3597  return 0;
3598  st = c->fc->streams[c->fc->nb_streams - 1];
3599  sc = st->priv_data;
3600 
3601  avio_r8(pb); /* version */
3602  avio_rb24(pb); /* flags */
3603  entries = atom.size - 4;
3604 
3605  av_log(c->fc, AV_LOG_TRACE, "track[%u].sdtp.entries = %" PRId64 "\n",
3606  c->fc->nb_streams - 1, entries);
3607 
3608  if (sc->sdtp_data)
3609  av_log(c->fc, AV_LOG_WARNING, "Duplicated SDTP atom\n");
3610  av_freep(&sc->sdtp_data);
3611  sc->sdtp_count = 0;
3612 
3613  sc->sdtp_data = av_malloc(entries);
3614  if (!sc->sdtp_data)
3615  return AVERROR(ENOMEM);
3616 
3617  for (i = 0; i < entries && !pb->eof_reached; i++)
3618  sc->sdtp_data[i] = avio_r8(pb);
3619  sc->sdtp_count = i;
3620 
3621  return 0;
3622 }
3623 
3624 static void mov_update_dts_shift(MOVStreamContext *sc, int duration, void *logctx)
3625 {
3626  if (duration < 0) {
3627  if (duration == INT_MIN) {
3628  av_log(logctx, AV_LOG_WARNING, "mov_update_dts_shift(): dts_shift set to %d\n", INT_MAX);
3629  duration++;
3630  }
3631  sc->dts_shift = FFMAX(sc->dts_shift, -duration);
3632  }
3633 }
3634 
3636 {
3637  AVStream *st;
3638  MOVStreamContext *sc;
3639  unsigned int i, entries, ctts_count = 0;
3640 
3641  if (c->trak_index < 0) {
3642  av_log(c->fc, AV_LOG_WARNING, "CTTS outside TRAK\n");
3643  return 0;
3644  }
3645 
3646  if (c->fc->nb_streams < 1)
3647  return 0;
3648  st = c->fc->streams[c->fc->nb_streams-1];
3649  sc = st->priv_data;
3650 
3651  avio_r8(pb); /* version */
3652  avio_rb24(pb); /* flags */
3653  entries = avio_rb32(pb);
3654 
3655  av_log(c->fc, AV_LOG_TRACE, "track[%u].ctts.entries = %u\n", c->fc->nb_streams - 1, entries);
3656 
3657  if (!entries)
3658  return 0;
3659  if (entries >= UINT_MAX / sizeof(*sc->ctts_data))
3660  return AVERROR_INVALIDDATA;
3661  av_freep(&sc->ctts_data);
3662  sc->ctts_data = av_fast_realloc(NULL, &sc->ctts_allocated_size, entries * sizeof(*sc->ctts_data));
3663  if (!sc->ctts_data)
3664  return AVERROR(ENOMEM);
3665 
3666  for (i = 0; i < entries && !pb->eof_reached; i++) {
3667  MOVCtts *ctts_data;
3668  const size_t min_size_needed = (ctts_count + 1) * sizeof(MOVCtts);
3669  const size_t requested_size =
3670  min_size_needed > sc->ctts_allocated_size ?
3671  FFMAX(min_size_needed, 2 * sc->ctts_allocated_size) :
3672  min_size_needed;
3673  int count = avio_rb32(pb);
3674  int duration = avio_rb32(pb);
3675 
3676  if (count <= 0) {
3677  av_log(c->fc, AV_LOG_TRACE,
3678  "ignoring CTTS entry with count=%d duration=%d\n",
3679  count, duration);
3680  continue;
3681  }
3682 
3683  if (ctts_count >= UINT_MAX / sizeof(MOVCtts) - 1)
3684  return AVERROR(ENOMEM);
3685 
3686  ctts_data = av_fast_realloc(sc->ctts_data, &sc->ctts_allocated_size, requested_size);
3687 
3688  if (!ctts_data)
3689  return AVERROR(ENOMEM);
3690 
3691  sc->ctts_data = ctts_data;
3692 
3693  ctts_data[ctts_count].count = count;
3694  ctts_data[ctts_count].offset = duration;
3695  ctts_count++;
3696 
3697  av_log(c->fc, AV_LOG_TRACE, "count=%d, duration=%d\n",
3698  count, duration);
3699 
3700  if (FFNABS(duration) < -(1<<28) && i+2<entries) {
3701  av_log(c->fc, AV_LOG_WARNING, "CTTS invalid\n");
3702  av_freep(&sc->ctts_data);
3703  sc->ctts_count = 0;
3704  return 0;
3705  }
3706 
3707  if (i+2<entries)
3708  mov_update_dts_shift(sc, duration, c->fc);
3709  }
3710 
3711  sc->ctts_count = ctts_count;
3712 
3713  if (pb->eof_reached) {
3714  av_log(c->fc, AV_LOG_WARNING, "reached eof, corrupted CTTS atom\n");
3715  return AVERROR_EOF;
3716  }
3717 
3718  av_log(c->fc, AV_LOG_TRACE, "dts shift %d\n", sc->dts_shift);
3719 
3720  return 0;
3721 }
3722 
3724 {
3725  AVStream *st;
3726  MOVStreamContext *sc;
3727  uint8_t version;
3728  uint32_t grouping_type;
3729  uint32_t default_length;
3730  av_unused uint32_t default_group_description_index;
3731  uint32_t entry_count;
3732 
3733  if (c->fc->nb_streams < 1)
3734  return 0;
3735  st = c->fc->streams[c->fc->nb_streams - 1];
3736  sc = st->priv_data;
3737 
3738  version = avio_r8(pb); /* version */
3739  avio_rb24(pb); /* flags */
3740  grouping_type = avio_rl32(pb);
3741 
3742  /*
3743  * This function only supports "sync" boxes, but the code is able to parse
3744  * other boxes (such as "tscl", "tsas" and "stsa")
3745  */
3746  if (grouping_type != MKTAG('s','y','n','c'))
3747  return 0;
3748 
3749  default_length = version >= 1 ? avio_rb32(pb) : 0;
3750  default_group_description_index = version >= 2 ? avio_rb32(pb) : 0;
3751  entry_count = avio_rb32(pb);
3752 
3753  av_freep(&sc->sgpd_sync);
3754  sc->sgpd_sync_count = entry_count;
3755  sc->sgpd_sync = av_calloc(entry_count, sizeof(*sc->sgpd_sync));
3756  if (!sc->sgpd_sync)
3757  return AVERROR(ENOMEM);
3758 
3759  for (uint32_t i = 0; i < entry_count && !pb->eof_reached; i++) {
3760  uint32_t description_length = default_length;
3761  if (version >= 1 && default_length == 0)
3762  description_length = avio_rb32(pb);
3763  if (grouping_type == MKTAG('s','y','n','c')) {
3764  const uint8_t nal_unit_type = avio_r8(pb) & 0x3f;
3765  sc->sgpd_sync[i] = nal_unit_type;
3766  description_length -= 1;
3767  }
3768  avio_skip(pb, description_length);
3769  }
3770 
3771  if (pb->eof_reached) {
3772  av_log(c->fc, AV_LOG_WARNING, "reached eof, corrupted SGPD atom\n");
3773  return AVERROR_EOF;
3774  }
3775 
3776  return 0;
3777 }
3778 
3780 {
3781  AVStream *st;
3782  MOVStreamContext *sc;
3783  unsigned int i, entries;
3784  uint8_t version;
3785  uint32_t grouping_type;
3786  MOVSbgp *table, **tablep;
3787  int *table_count;
3788 
3789  if (c->fc->nb_streams < 1)
3790  return 0;
3791  st = c->fc->streams[c->fc->nb_streams-1];
3792  sc = st->priv_data;
3793 
3794  version = avio_r8(pb); /* version */
3795  avio_rb24(pb); /* flags */
3796  grouping_type = avio_rl32(pb);
3797 
3798  if (grouping_type == MKTAG('r','a','p',' ')) {
3799  tablep = &sc->rap_group;
3800  table_count = &sc->rap_group_count;
3801  } else if (grouping_type == MKTAG('s','y','n','c')) {
3802  tablep = &sc->sync_group;
3803  table_count = &sc->sync_group_count;
3804  } else {
3805  return 0;
3806  }
3807 
3808  if (version == 1)
3809  avio_rb32(pb); /* grouping_type_parameter */
3810 
3811  entries = avio_rb32(pb);
3812  if (!entries)
3813  return 0;
3814  if (*tablep)
3815  av_log(c->fc, AV_LOG_WARNING, "Duplicated SBGP %s atom\n", av_fourcc2str(grouping_type));
3816  av_freep(tablep);
3817  table = av_malloc_array(entries, sizeof(*table));
3818  if (!table)
3819  return AVERROR(ENOMEM);
3820  *tablep = table;
3821 
3822  for (i = 0; i < entries && !pb->eof_reached; i++) {
3823  table[i].count = avio_rb32(pb); /* sample_count */
3824  table[i].index = avio_rb32(pb); /* group_description_index */
3825  }
3826 
3827  *table_count = i;
3828 
3829  if (pb->eof_reached) {
3830  av_log(c->fc, AV_LOG_WARNING, "reached eof, corrupted SBGP atom\n");
3831  return AVERROR_EOF;
3832  }
3833 
3834  return 0;
3835 }
3836 
3837 /**
3838  * Get ith edit list entry (media time, duration).
3839  */
3841  const MOVStreamContext *msc,
3842  unsigned int edit_list_index,
3843  int64_t *edit_list_media_time,
3844  int64_t *edit_list_duration,
3845  int64_t global_timescale)
3846 {
3847  if (edit_list_index == msc->elst_count) {
3848  return 0;
3849  }
3850  *edit_list_media_time = msc->elst_data[edit_list_index].time;
3851  *edit_list_duration = msc->elst_data[edit_list_index].duration;
3852 
3853  /* duration is in global timescale units;convert to msc timescale */
3854  if (global_timescale == 0) {
3855  avpriv_request_sample(mov->fc, "Support for mvhd.timescale = 0 with editlists");
3856  return 0;
3857  }
3858  *edit_list_duration = av_rescale(*edit_list_duration, msc->time_scale,
3859  global_timescale);
3860 
3861  if (*edit_list_duration + (uint64_t)*edit_list_media_time > INT64_MAX)
3862  *edit_list_duration = 0;
3863 
3864  return 1;
3865 }
3866 
3867 /**
3868  * Find the closest previous frame to the timestamp_pts, in e_old index
3869  * entries. Searching for just any frame / just key frames can be controlled by
3870  * last argument 'flag'.
3871  * Note that if ctts_data is not NULL, we will always search for a key frame
3872  * irrespective of the value of 'flag'. If we don't find any keyframe, we will
3873  * return the first frame of the video.
3874  *
3875  * Here the timestamp_pts is considered to be a presentation timestamp and
3876  * the timestamp of index entries are considered to be decoding timestamps.
3877  *
3878  * Returns 0 if successful in finding a frame, else returns -1.
3879  * Places the found index corresponding output arg.
3880  *
3881  * If ctts_old is not NULL, then refines the searched entry by searching
3882  * backwards from the found timestamp, to find the frame with correct PTS.
3883  *
3884  * Places the found ctts_index and ctts_sample in corresponding output args.
3885  */
3887  AVIndexEntry *e_old,
3888  int nb_old,
3889  MOVTimeToSample *tts_data,
3890  int64_t tts_count,
3891  int64_t timestamp_pts,
3892  int flag,
3893  int64_t* index,
3894  int64_t* tts_index,
3895  int64_t* tts_sample)
3896 {
3897  MOVStreamContext *msc = st->priv_data;
3898  FFStream *const sti = ffstream(st);
3899  AVIndexEntry *e_keep = sti->index_entries;
3900  int nb_keep = sti->nb_index_entries;
3901  int64_t i = 0;
3902 
3903  av_assert0(index);
3904 
3905  // If dts_shift > 0, then all the index timestamps will have to be offset by
3906  // at least dts_shift amount to obtain PTS.
3907  // Hence we decrement the searched timestamp_pts by dts_shift to find the closest index element.
3908  if (msc->dts_shift > 0) {
3909  timestamp_pts -= msc->dts_shift;
3910  }
3911 
3912  sti->index_entries = e_old;
3913  sti->nb_index_entries = nb_old;
3914  *index = av_index_search_timestamp(st, timestamp_pts, flag | AVSEEK_FLAG_BACKWARD);
3915 
3916  // Keep going backwards in the index entries until the timestamp is the same.
3917  if (*index >= 0) {
3918  for (i = *index; i > 0 && e_old[i].timestamp == e_old[i - 1].timestamp;
3919  i--) {
3920  if ((flag & AVSEEK_FLAG_ANY) ||
3921  (e_old[i - 1].flags & AVINDEX_KEYFRAME)) {
3922  *index = i - 1;
3923  }
3924  }
3925  }
3926 
3927  // If we have CTTS then refine the search, by searching backwards over PTS
3928  // computed by adding corresponding CTTS durations to index timestamps.
3929  if (msc->ctts_count && *index >= 0) {
3930  av_assert0(tts_index);
3931  av_assert0(tts_sample);
3932  // Find out the ctts_index for the found frame.
3933  *tts_index = 0;
3934  *tts_sample = 0;
3935  for (int64_t index_tts_count = 0; index_tts_count < *index; index_tts_count++) {
3936  if (*tts_index < tts_count) {
3937  (*tts_sample)++;
3938  if (tts_data[*tts_index].count == *tts_sample) {
3939  (*tts_index)++;
3940  *tts_sample = 0;
3941  }
3942  }
3943  }
3944 
3945  while (*index >= 0 && (*tts_index) >= 0 && (*tts_index) < tts_count) {
3946  // Find a "key frame" with PTS <= timestamp_pts (So that we can decode B-frames correctly).
3947  // No need to add dts_shift to the timestamp here becase timestamp_pts has already been
3948  // compensated by dts_shift above.
3949  if ((e_old[*index].timestamp + tts_data[*tts_index].offset) <= timestamp_pts &&
3950  (e_old[*index].flags & AVINDEX_KEYFRAME)) {
3951  break;
3952  }
3953 
3954  (*index)--;
3955  if (*tts_sample == 0) {
3956  (*tts_index)--;
3957  if (*tts_index >= 0)
3958  *tts_sample = tts_data[*tts_index].count - 1;
3959  } else {
3960  (*tts_sample)--;
3961  }
3962  }
3963  }
3964 
3965  /* restore AVStream state*/
3966  sti->index_entries = e_keep;
3967  sti->nb_index_entries = nb_keep;
3968  return *index >= 0 ? 0 : -1;
3969 }
3970 
3971 /**
3972  * Add index entry with the given values, to the end of ffstream(st)->index_entries.
3973  * Returns the new size ffstream(st)->index_entries if successful, else returns -1.
3974  *
3975  * This function is similar to ff_add_index_entry in libavformat/utils.c
3976  * except that here we are always unconditionally adding an index entry to
3977  * the end, instead of searching the entries list and skipping the add if
3978  * there is an existing entry with the same timestamp.
3979  * This is needed because the mov_fix_index calls this func with the same
3980  * unincremented timestamp for successive discarded frames.
3981  */
3983  int size, int distance, int flags)
3984 {
3985  FFStream *const sti = ffstream(st);
3986  AVIndexEntry *entries, *ie;
3987  int64_t index = -1;
3988  const size_t min_size_needed = (sti->nb_index_entries + 1) * sizeof(AVIndexEntry);
3989 
3990  // Double the allocation each time, to lower memory fragmentation.
3991  // Another difference from ff_add_index_entry function.
3992  const size_t requested_size =
3993  min_size_needed > sti->index_entries_allocated_size ?
3994  FFMAX(min_size_needed, 2 * sti->index_entries_allocated_size) :
3995  min_size_needed;
3996 
3997  if (sti->nb_index_entries + 1U >= UINT_MAX / sizeof(AVIndexEntry))
3998  return -1;
3999 
4000  entries = av_fast_realloc(sti->index_entries,
4002  requested_size);
4003  if (!entries)
4004  return -1;
4005 
4006  sti->index_entries = entries;
4007 
4008  index = sti->nb_index_entries++;
4009  ie= &entries[index];
4010 
4011  ie->pos = pos;
4012  ie->timestamp = timestamp;
4013  ie->min_distance= distance;
4014  ie->size= size;
4015  ie->flags = flags;
4016  return index;
4017 }
4018 
4019 /**
4020  * Rewrite timestamps of index entries in the range [end_index - frame_duration_buffer_size, end_index)
4021  * by subtracting end_ts successively by the amounts given in frame_duration_buffer.
4022  */
4023 static void fix_index_entry_timestamps(AVStream* st, int end_index, int64_t end_ts,
4024  int64_t* frame_duration_buffer,
4025  int frame_duration_buffer_size) {
4026  FFStream *const sti = ffstream(st);
4027  int i = 0;
4028  av_assert0(end_index >= 0 && end_index <= sti->nb_index_entries);
4029  for (i = 0; i < frame_duration_buffer_size; i++) {
4030  end_ts -= frame_duration_buffer[frame_duration_buffer_size - 1 - i];
4031  sti->index_entries[end_index - 1 - i].timestamp = end_ts;
4032  }
4033 }
4034 
4035 static int add_tts_entry(MOVTimeToSample **tts_data, unsigned int *tts_count, unsigned int *allocated_size,
4036  int count, int offset, unsigned int duration)
4037 {
4038  MOVTimeToSample *tts_buf_new;
4039  const size_t min_size_needed = (*tts_count + 1) * sizeof(MOVTimeToSample);
4040  const size_t requested_size =
4041  min_size_needed > *allocated_size ?
4042  FFMAX(min_size_needed, 2 * (*allocated_size)) :
4043  min_size_needed;
4044 
4045  if ((unsigned)(*tts_count) >= UINT_MAX / sizeof(MOVTimeToSample) - 1)
4046  return -1;
4047 
4048  tts_buf_new = av_fast_realloc(*tts_data, allocated_size, requested_size);
4049 
4050  if (!tts_buf_new)
4051  return -1;
4052 
4053  *tts_data = tts_buf_new;
4054 
4055  tts_buf_new[*tts_count].count = count;
4056  tts_buf_new[*tts_count].offset = offset;
4057  tts_buf_new[*tts_count].duration = duration;
4058 
4059  *tts_count = (*tts_count) + 1;
4060  return 0;
4061 }
4062 
4063 #define MAX_REORDER_DELAY 16
4065 {
4066  MOVStreamContext *msc = st->priv_data;
4067  FFStream *const sti = ffstream(st);
4068  int ctts_ind = 0;
4069  int ctts_sample = 0;
4070  int64_t pts_buf[MAX_REORDER_DELAY + 1]; // Circular buffer to sort pts.
4071  int buf_start = 0;
4072  int j, r, num_swaps;
4073 
4074  for (j = 0; j < MAX_REORDER_DELAY + 1; j++)
4075  pts_buf[j] = INT64_MIN;
4076 
4077  if (st->codecpar->video_delay <= 0 && msc->ctts_count &&
4079  st->codecpar->video_delay = 0;
4080  for (int ind = 0; ind < sti->nb_index_entries && ctts_ind < msc->tts_count; ++ind) {
4081  // Point j to the last elem of the buffer and insert the current pts there.
4082  j = buf_start;
4083  buf_start = (buf_start + 1);
4084  if (buf_start == MAX_REORDER_DELAY + 1)
4085  buf_start = 0;
4086 
4087  pts_buf[j] = sti->index_entries[ind].timestamp + msc->tts_data[ctts_ind].offset;
4088 
4089  // The timestamps that are already in the sorted buffer, and are greater than the
4090  // current pts, are exactly the timestamps that need to be buffered to output PTS
4091  // in correct sorted order.
4092  // Hence the video delay (which is the buffer size used to sort DTS and output PTS),
4093  // can be computed as the maximum no. of swaps any particular timestamp needs to
4094  // go through, to keep this buffer in sorted order.
4095  num_swaps = 0;
4096  while (j != buf_start) {
4097  r = j - 1;
4098  if (r < 0) r = MAX_REORDER_DELAY;
4099  if (pts_buf[j] < pts_buf[r]) {
4100  FFSWAP(int64_t, pts_buf[j], pts_buf[r]);
4101  ++num_swaps;
4102  } else {
4103  break;
4104  }
4105  j = r;
4106  }
4107  st->codecpar->video_delay = FFMAX(st->codecpar->video_delay, num_swaps);
4108 
4109  ctts_sample++;
4110  if (ctts_sample == msc->tts_data[ctts_ind].count) {
4111  ctts_ind++;
4112  ctts_sample = 0;
4113  }
4114  }
4115  av_log(c->fc, AV_LOG_DEBUG, "Setting codecpar->delay to %d for stream st: %d\n",
4116  st->codecpar->video_delay, st->index);
4117  }
4118 }
4119 
4121 {
4122  sc->current_sample++;
4123  sc->current_index++;
4124  if (sc->index_ranges &&
4125  sc->current_index >= sc->current_index_range->end &&
4126  sc->current_index_range->end) {
4127  sc->current_index_range++;
4129  }
4130 }
4131 
4133 {
4134  sc->current_sample--;
4135  sc->current_index--;
4136  if (sc->index_ranges &&
4138  sc->current_index_range > sc->index_ranges) {
4139  sc->current_index_range--;
4140  sc->current_index = sc->current_index_range->end - 1;
4141  }
4142 }
4143 
4144 static void mov_current_sample_set(MOVStreamContext *sc, int current_sample)
4145 {
4146  int64_t range_size;
4147 
4148  sc->current_sample = current_sample;
4149  sc->current_index = current_sample;
4150  if (!sc->index_ranges) {
4151  return;
4152  }
4153 
4154  for (sc->current_index_range = sc->index_ranges;
4155  sc->current_index_range->end;
4156  sc->current_index_range++) {
4157  range_size = sc->current_index_range->end - sc->current_index_range->start;
4158  if (range_size > current_sample) {
4159  sc->current_index = sc->current_index_range->start + current_sample;
4160  break;
4161  }
4162  current_sample -= range_size;
4163  }
4164 }
4165 
4166 /**
4167  * Fix ffstream(st)->index_entries, so that it contains only the entries (and the entries
4168  * which are needed to decode them) that fall in the edit list time ranges.
4169  * Also fixes the timestamps of the index entries to match the timeline
4170  * specified the edit lists.
4171  */
4172 static void mov_fix_index(MOVContext *mov, AVStream *st)
4173 {
4174  MOVStreamContext *msc = st->priv_data;
4175  FFStream *const sti = ffstream(st);
4176  AVIndexEntry *e_old = sti->index_entries;
4177  int nb_old = sti->nb_index_entries;
4178  const AVIndexEntry *e_old_end = e_old + nb_old;
4179  const AVIndexEntry *current = NULL;
4180  MOVTimeToSample *tts_data_old = msc->tts_data;
4181  int64_t tts_index_old = 0;
4182  int64_t tts_sample_old = 0;
4183  int64_t tts_count_old = msc->tts_count;
4184  int64_t edit_list_media_time = 0;
4185  int64_t edit_list_duration = 0;
4186  int64_t frame_duration = 0;
4187  int64_t edit_list_dts_counter = 0;
4188  int64_t edit_list_dts_entry_end = 0;
4189  int64_t edit_list_start_tts_sample = 0;
4190  int64_t curr_cts;
4191  int64_t curr_ctts = 0;
4192  int64_t empty_edits_sum_duration = 0;
4193  int64_t edit_list_index = 0;
4194  int64_t index;
4195  int flags;
4196  int64_t start_dts = 0;
4197  int64_t edit_list_start_encountered = 0;
4198  int64_t search_timestamp = 0;
4199  int64_t* frame_duration_buffer = NULL;
4200  int num_discarded_begin = 0;
4201  int first_non_zero_audio_edit = -1;
4202  int packet_skip_samples = 0;
4203  MOVIndexRange *current_index_range = NULL;
4204  int found_keyframe_after_edit = 0;
4205  int found_non_empty_edit = 0;
4206 
4207  if (!msc->elst_data || msc->elst_count <= 0 || nb_old <= 0) {
4208  return;
4209  }
4210 
4211  // allocate the index ranges array
4212  msc->index_ranges = av_malloc_array(msc->elst_count + 1,
4213  sizeof(msc->index_ranges[0]));
4214  if (!msc->index_ranges) {
4215  av_log(mov->fc, AV_LOG_ERROR, "Cannot allocate index ranges buffer\n");
4216  return;
4217  }
4218  msc->current_index_range = msc->index_ranges;
4219 
4220  // Clean AVStream from traces of old index
4221  sti->index_entries = NULL;
4223  sti->nb_index_entries = 0;
4224 
4225  // Clean time to sample fields of MOVStreamContext
4226  msc->tts_data = NULL;
4227  msc->tts_count = 0;
4228  msc->tts_index = 0;
4229  msc->tts_sample = 0;
4230  msc->tts_allocated_size = 0;
4231 
4232  // Reinitialize min_corrected_pts so that it can be computed again.
4233  msc->min_corrected_pts = -1;
4234 
4235  // If the dts_shift is positive (in case of negative ctts values in mov),
4236  // then negate the DTS by dts_shift
4237  if (msc->dts_shift > 0) {
4238  edit_list_dts_entry_end -= msc->dts_shift;
4239  av_log(mov->fc, AV_LOG_DEBUG, "Shifting DTS by %d because of negative CTTS.\n", msc->dts_shift);
4240  }
4241 
4242  start_dts = edit_list_dts_entry_end;
4243 
4244  while (get_edit_list_entry(mov, msc, edit_list_index, &edit_list_media_time,
4245  &edit_list_duration, mov->time_scale)) {
4246  av_log(mov->fc, AV_LOG_DEBUG, "Processing st: %d, edit list %"PRId64" - media time: %"PRId64", duration: %"PRId64"\n",
4247  st->index, edit_list_index, edit_list_media_time, edit_list_duration);
4248  edit_list_index++;
4249  edit_list_dts_counter = edit_list_dts_entry_end;
4250  edit_list_dts_entry_end += edit_list_duration;
4251  num_discarded_begin = 0;
4252  if (!found_non_empty_edit && edit_list_media_time == -1) {
4253  empty_edits_sum_duration += edit_list_duration;
4254  continue;
4255  }
4256  found_non_empty_edit = 1;
4257 
4258  // If we encounter a non-negative edit list reset the skip_samples/start_pad fields and set them
4259  // according to the edit list below.
4260  if (st->codecpar->codec_type == AVMEDIA_TYPE_AUDIO) {
4261  if (first_non_zero_audio_edit < 0) {
4262  first_non_zero_audio_edit = 1;
4263  } else {
4264  first_non_zero_audio_edit = 0;
4265  }
4266 
4267  if (first_non_zero_audio_edit > 0)
4268  sti->skip_samples = msc->start_pad = 0;
4269  }
4270 
4271  // While reordering frame index according to edit list we must handle properly
4272  // the scenario when edit list entry starts from none key frame.
4273  // We find closest previous key frame and preserve it and consequent frames in index.
4274  // All frames which are outside edit list entry time boundaries will be dropped after decoding.
4275  search_timestamp = edit_list_media_time;
4276  if (st->codecpar->codec_type == AVMEDIA_TYPE_AUDIO) {
4277  // Audio decoders like AAC need need a decoder delay samples previous to the current sample,
4278  // to correctly decode this frame. Hence for audio we seek to a frame 1 sec. before the
4279  // edit_list_media_time to cover the decoder delay.
4280  search_timestamp = FFMAX(search_timestamp - msc->time_scale, e_old[0].timestamp);
4281  }
4282 
4283  if (find_prev_closest_index(st, e_old, nb_old, tts_data_old, tts_count_old, search_timestamp, 0,
4284  &index, &tts_index_old, &tts_sample_old) < 0) {
4285  av_log(mov->fc, AV_LOG_WARNING,
4286  "st: %d edit list: %"PRId64" Missing key frame while searching for timestamp: %"PRId64"\n",
4287  st->index, edit_list_index, search_timestamp);
4288  if (find_prev_closest_index(st, e_old, nb_old, tts_data_old, tts_count_old, search_timestamp, AVSEEK_FLAG_ANY,
4289  &index, &tts_index_old, &tts_sample_old) < 0) {
4290  av_log(mov->fc, AV_LOG_WARNING,
4291  "st: %d edit list %"PRId64" Cannot find an index entry before timestamp: %"PRId64".\n",
4292  st->index, edit_list_index, search_timestamp);
4293  index = 0;
4294  tts_index_old = 0;
4295  tts_sample_old = 0;
4296  }
4297  }
4298  current = e_old + index;
4299  edit_list_start_tts_sample = tts_sample_old;
4300 
4301  // Iterate over index and arrange it according to edit list
4302  edit_list_start_encountered = 0;
4303  found_keyframe_after_edit = 0;
4304  for (; current < e_old_end; current++, index++) {
4305  // check if frame outside edit list mark it for discard
4306  frame_duration = (current + 1 < e_old_end) ?
4307  ((current + 1)->timestamp - current->timestamp) : edit_list_duration;
4308 
4309  flags = current->flags;
4310 
4311  // frames (pts) before or after edit list
4312  curr_cts = current->timestamp + msc->dts_shift;
4313  curr_ctts = 0;
4314 
4315  if (tts_data_old && tts_index_old < tts_count_old) {
4316  curr_ctts = tts_data_old[tts_index_old].offset;
4317  av_log(mov->fc, AV_LOG_TRACE, "stts: %"PRId64" ctts: %"PRId64", tts_index: %"PRId64", tts_count: %"PRId64"\n",
4318  curr_cts, curr_ctts, tts_index_old, tts_count_old);
4319  curr_cts += curr_ctts;
4320  tts_sample_old++;
4321  if (tts_sample_old == tts_data_old[tts_index_old].count) {
4322  if (add_tts_entry(&msc->tts_data, &msc->tts_count,
4323  &msc->tts_allocated_size,
4324  tts_data_old[tts_index_old].count - edit_list_start_tts_sample,
4325  tts_data_old[tts_index_old].offset, tts_data_old[tts_index_old].duration) == -1) {
4326  av_log(mov->fc, AV_LOG_ERROR, "Cannot add Time To Sample entry %"PRId64" - {%"PRId64", %d}\n",
4327  tts_index_old,
4328  tts_data_old[tts_index_old].count - edit_list_start_tts_sample,
4329  tts_data_old[tts_index_old].offset);
4330  break;
4331  }
4332  tts_index_old++;
4333  tts_sample_old = 0;
4334  edit_list_start_tts_sample = 0;
4335  }
4336  }
4337 
4338  if (curr_cts < edit_list_media_time || curr_cts >= (edit_list_duration + edit_list_media_time)) {
4340  curr_cts < edit_list_media_time && curr_cts + frame_duration > edit_list_media_time &&
4341  first_non_zero_audio_edit > 0) {
4342  packet_skip_samples = edit_list_media_time - curr_cts;
4343  sti->skip_samples += packet_skip_samples;
4344 
4345  // Shift the index entry timestamp by packet_skip_samples to be correct.
4346  edit_list_dts_counter -= packet_skip_samples;
4347  if (edit_list_start_encountered == 0) {
4348  edit_list_start_encountered = 1;
4349  // Make timestamps strictly monotonically increasing for audio, by rewriting timestamps for
4350  // discarded packets.
4351  if (frame_duration_buffer) {
4352  fix_index_entry_timestamps(st, sti->nb_index_entries, edit_list_dts_counter,
4353  frame_duration_buffer, num_discarded_begin);
4354  av_freep(&frame_duration_buffer);
4355  }
4356  }
4357 
4358  av_log(mov->fc, AV_LOG_DEBUG, "skip %d audio samples from curr_cts: %"PRId64"\n", packet_skip_samples, curr_cts);
4359  } else {
4361  av_log(mov->fc, AV_LOG_DEBUG, "drop a frame at curr_cts: %"PRId64" @ %"PRId64"\n", curr_cts, index);
4362 
4363  if (edit_list_start_encountered == 0) {
4364  num_discarded_begin++;
4365  frame_duration_buffer = av_realloc(frame_duration_buffer,
4366  num_discarded_begin * sizeof(int64_t));
4367  if (!frame_duration_buffer) {
4368  av_log(mov->fc, AV_LOG_ERROR, "Cannot reallocate frame duration buffer\n");
4369  break;
4370  }
4371  frame_duration_buffer[num_discarded_begin - 1] = frame_duration;
4372 
4373  // Increment skip_samples for the first non-zero audio edit list
4374  if (st->codecpar->codec_type == AVMEDIA_TYPE_AUDIO &&
4375  first_non_zero_audio_edit > 0 && st->codecpar->codec_id != AV_CODEC_ID_VORBIS) {
4376  sti->skip_samples += frame_duration;
4377  }
4378  }
4379  }
4380  } else {
4381  if (msc->min_corrected_pts < 0) {
4382  msc->min_corrected_pts = edit_list_dts_counter + curr_ctts + msc->dts_shift;
4383  } else {
4384  msc->min_corrected_pts = FFMIN(msc->min_corrected_pts, edit_list_dts_counter + curr_ctts + msc->dts_shift);
4385  }
4386  if (edit_list_start_encountered == 0) {
4387  edit_list_start_encountered = 1;
4388  // Make timestamps strictly monotonically increasing by rewriting timestamps for
4389  // discarded packets.
4390  if (frame_duration_buffer) {
4391  fix_index_entry_timestamps(st, sti->nb_index_entries, edit_list_dts_counter,
4392  frame_duration_buffer, num_discarded_begin);
4393  av_freep(&frame_duration_buffer);
4394  }
4395  }
4396  }
4397 
4398  if (add_index_entry(st, current->pos, edit_list_dts_counter, current->size,
4399  current->min_distance, flags) == -1) {
4400  av_log(mov->fc, AV_LOG_ERROR, "Cannot add index entry\n");
4401  break;
4402  }
4403 
4404  // Update the index ranges array
4405  if (!current_index_range || index != current_index_range->end) {
4406  current_index_range = current_index_range ? current_index_range + 1
4407  : msc->index_ranges;
4408  current_index_range->start = index;
4409  }
4410  current_index_range->end = index + 1;
4411 
4412  // Only start incrementing DTS in frame_duration amounts, when we encounter a frame in edit list.
4413  if (edit_list_start_encountered > 0) {
4414  edit_list_dts_counter = edit_list_dts_counter + frame_duration;
4415  }
4416 
4417  // Break when found first key frame after edit entry completion
4418  if ((curr_cts + frame_duration >= (edit_list_duration + edit_list_media_time)) &&
4420  if (msc->ctts_count) {
4421  // If we have CTTS and this is the first keyframe after edit elist,
4422  // wait for one more, because there might be trailing B-frames after this I-frame
4423  // that do belong to the edit.
4424  if (st->codecpar->codec_type != AVMEDIA_TYPE_AUDIO && found_keyframe_after_edit == 0) {
4425  found_keyframe_after_edit = 1;
4426  continue;
4427  }
4428  if (tts_sample_old != 0) {
4429  if (add_tts_entry(&msc->tts_data, &msc->tts_count,
4430  &msc->tts_allocated_size,
4431  tts_sample_old - edit_list_start_tts_sample,
4432  tts_data_old[tts_index_old].offset, tts_data_old[tts_index_old].duration) == -1) {
4433  av_log(mov->fc, AV_LOG_ERROR, "Cannot add Time To Sample entry %"PRId64" - {%"PRId64", %d}\n",
4434  tts_index_old, tts_sample_old - edit_list_start_tts_sample,
4435  tts_data_old[tts_index_old].offset);
4436  break;
4437  }
4438  }
4439  }
4440  break;
4441  }
4442  }
4443  }
4444  // If there are empty edits, then msc->min_corrected_pts might be positive
4445  // intentionally. So we subtract the sum duration of emtpy edits here.
4446  msc->min_corrected_pts -= empty_edits_sum_duration;
4447 
4448  // If the minimum pts turns out to be greater than zero after fixing the index, then we subtract the
4449  // dts by that amount to make the first pts zero.
4450  if (st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO) {
4451  if (msc->min_corrected_pts > 0) {
4452  av_log(mov->fc, AV_LOG_DEBUG, "Offset DTS by %"PRId64" to make first pts zero.\n", msc->min_corrected_pts);
4453  for (int i = 0; i < sti->nb_index_entries; ++i)
4455  }
4456  }
4457  // Start time should be equal to zero or the duration of any empty edits.
4458  st->start_time = empty_edits_sum_duration;
4459 
4460  // Update av stream length, if it ends up shorter than the track's media duration
4461  st->duration = FFMIN(st->duration, edit_list_dts_entry_end - start_dts);
4462  msc->start_pad = sti->skip_samples;
4463 
4464  // Free the old index and the old CTTS structures
4465  av_free(e_old);
4466  av_free(tts_data_old);
4467  av_freep(&frame_duration_buffer);
4468 
4469  // Null terminate the index ranges array
4470  current_index_range = current_index_range ? current_index_range + 1
4471  : msc->index_ranges;
4472  current_index_range->start = 0;
4473  current_index_range->end = 0;
4474  msc->current_index = msc->index_ranges[0].start;
4475 }
4476 
4477 static uint32_t get_sgpd_sync_index(const MOVStreamContext *sc, i