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