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 "libavcodec/ac3tab.h"
50 #include "libavcodec/flac.h"
52 #include "avformat.h"
53 #include "internal.h"
54 #include "avio_internal.h"
55 #include "riff.h"
56 #include "isom.h"
57 #include "libavcodec/get_bits.h"
58 #include "id3v1.h"
59 #include "mov_chan.h"
60 #include "replaygain.h"
61 
62 #if CONFIG_ZLIB
63 #include <zlib.h>
64 #endif
65 
66 #include "qtpalette.h"
67 
68 /* those functions parse an atom */
69 /* links atom IDs to parse functions */
70 typedef struct MOVParseTableEntry {
71  uint32_t type;
74 
75 static int mov_read_default(MOVContext *c, AVIOContext *pb, MOVAtom atom);
76 static int mov_read_mfra(MOVContext *c, AVIOContext *f);
77 static int64_t add_ctts_entry(MOVStts** ctts_data, unsigned int* ctts_count, unsigned int* allocated_size,
78  int count, int duration);
79 
81  unsigned len, const char *key)
82 {
83  char buf[16];
84 
85  short current, total = 0;
86  avio_rb16(pb); // unknown
87  current = avio_rb16(pb);
88  if (len >= 6)
89  total = avio_rb16(pb);
90  if (!total)
91  snprintf(buf, sizeof(buf), "%d", current);
92  else
93  snprintf(buf, sizeof(buf), "%d/%d", current, total);
94  c->fc->event_flags |= AVFMT_EVENT_FLAG_METADATA_UPDATED;
95  av_dict_set(&c->fc->metadata, key, buf, 0);
96 
97  return 0;
98 }
99 
101  unsigned len, const char *key)
102 {
103  /* bypass padding bytes */
104  avio_r8(pb);
105  avio_r8(pb);
106  avio_r8(pb);
107 
108  c->fc->event_flags |= AVFMT_EVENT_FLAG_METADATA_UPDATED;
109  av_dict_set_int(&c->fc->metadata, key, avio_r8(pb), 0);
110 
111  return 0;
112 }
113 
115  unsigned len, const char *key)
116 {
117  c->fc->event_flags |= AVFMT_EVENT_FLAG_METADATA_UPDATED;
118  av_dict_set_int(&c->fc->metadata, key, avio_r8(pb), 0);
119 
120  return 0;
121 }
122 
124  unsigned len, const char *key)
125 {
126  short genre;
127 
128  avio_r8(pb); // unknown
129 
130  genre = avio_r8(pb);
131  if (genre < 1 || genre > ID3v1_GENRE_MAX)
132  return 0;
133  c->fc->event_flags |= AVFMT_EVENT_FLAG_METADATA_UPDATED;
134  av_dict_set(&c->fc->metadata, key, ff_id3v1_genre_str[genre-1], 0);
135 
136  return 0;
137 }
138 
139 static const uint32_t mac_to_unicode[128] = {
140  0x00C4,0x00C5,0x00C7,0x00C9,0x00D1,0x00D6,0x00DC,0x00E1,
141  0x00E0,0x00E2,0x00E4,0x00E3,0x00E5,0x00E7,0x00E9,0x00E8,
142  0x00EA,0x00EB,0x00ED,0x00EC,0x00EE,0x00EF,0x00F1,0x00F3,
143  0x00F2,0x00F4,0x00F6,0x00F5,0x00FA,0x00F9,0x00FB,0x00FC,
144  0x2020,0x00B0,0x00A2,0x00A3,0x00A7,0x2022,0x00B6,0x00DF,
145  0x00AE,0x00A9,0x2122,0x00B4,0x00A8,0x2260,0x00C6,0x00D8,
146  0x221E,0x00B1,0x2264,0x2265,0x00A5,0x00B5,0x2202,0x2211,
147  0x220F,0x03C0,0x222B,0x00AA,0x00BA,0x03A9,0x00E6,0x00F8,
148  0x00BF,0x00A1,0x00AC,0x221A,0x0192,0x2248,0x2206,0x00AB,
149  0x00BB,0x2026,0x00A0,0x00C0,0x00C3,0x00D5,0x0152,0x0153,
150  0x2013,0x2014,0x201C,0x201D,0x2018,0x2019,0x00F7,0x25CA,
151  0x00FF,0x0178,0x2044,0x20AC,0x2039,0x203A,0xFB01,0xFB02,
152  0x2021,0x00B7,0x201A,0x201E,0x2030,0x00C2,0x00CA,0x00C1,
153  0x00CB,0x00C8,0x00CD,0x00CE,0x00CF,0x00CC,0x00D3,0x00D4,
154  0xF8FF,0x00D2,0x00DA,0x00DB,0x00D9,0x0131,0x02C6,0x02DC,
155  0x00AF,0x02D8,0x02D9,0x02DA,0x00B8,0x02DD,0x02DB,0x02C7,
156 };
157 
159  char *dst, int dstlen)
160 {
161  char *p = dst;
162  char *end = dst+dstlen-1;
163  int i;
164 
165  for (i = 0; i < len; i++) {
166  uint8_t t, c = avio_r8(pb);
167 
168  if (p >= end)
169  continue;
170 
171  if (c < 0x80)
172  *p++ = c;
173  else if (p < end)
174  PUT_UTF8(mac_to_unicode[c-0x80], t, if (p < end) *p++ = t;);
175  }
176  *p = 0;
177  return p - dst;
178 }
179 
180 static int mov_read_covr(MOVContext *c, AVIOContext *pb, int type, int len)
181 {
182  AVPacket pkt;
183  AVStream *st;
184  MOVStreamContext *sc;
185  enum AVCodecID id;
186  int ret;
187 
188  switch (type) {
189  case 0xd: id = AV_CODEC_ID_MJPEG; break;
190  case 0xe: id = AV_CODEC_ID_PNG; break;
191  case 0x1b: id = AV_CODEC_ID_BMP; break;
192  default:
193  av_log(c->fc, AV_LOG_WARNING, "Unknown cover type: 0x%x.\n", type);
194  avio_skip(pb, len);
195  return 0;
196  }
197 
198  st = avformat_new_stream(c->fc, NULL);
199  if (!st)
200  return AVERROR(ENOMEM);
201  sc = av_mallocz(sizeof(*sc));
202  if (!sc)
203  return AVERROR(ENOMEM);
204  st->priv_data = sc;
205 
206  ret = av_get_packet(pb, &pkt, len);
207  if (ret < 0)
208  return ret;
209 
210  if (pkt.size >= 8 && id != AV_CODEC_ID_BMP) {
211  if (AV_RB64(pkt.data) == 0x89504e470d0a1a0a) {
212  id = AV_CODEC_ID_PNG;
213  } else {
214  id = AV_CODEC_ID_MJPEG;
215  }
216  }
217 
219 
220  st->attached_pic = pkt;
221  st->attached_pic.stream_index = st->index;
223 
225  st->codecpar->codec_id = id;
226 
227  return 0;
228 }
229 
230 // 3GPP TS 26.244
231 static int mov_metadata_loci(MOVContext *c, AVIOContext *pb, unsigned len)
232 {
233  char language[4] = { 0 };
234  char buf[200], place[100];
235  uint16_t langcode = 0;
236  double longitude, latitude, altitude;
237  const char *key = "location";
238 
239  if (len < 4 + 2 + 1 + 1 + 4 + 4 + 4) {
240  av_log(c->fc, AV_LOG_ERROR, "loci too short\n");
241  return AVERROR_INVALIDDATA;
242  }
243 
244  avio_skip(pb, 4); // version+flags
245  langcode = avio_rb16(pb);
246  ff_mov_lang_to_iso639(langcode, language);
247  len -= 6;
248 
249  len -= avio_get_str(pb, len, place, sizeof(place));
250  if (len < 1) {
251  av_log(c->fc, AV_LOG_ERROR, "place name too long\n");
252  return AVERROR_INVALIDDATA;
253  }
254  avio_skip(pb, 1); // role
255  len -= 1;
256 
257  if (len < 12) {
258  av_log(c->fc, AV_LOG_ERROR,
259  "loci too short (%u bytes left, need at least %d)\n", len, 12);
260  return AVERROR_INVALIDDATA;
261  }
262  longitude = ((int32_t) avio_rb32(pb)) / (float) (1 << 16);
263  latitude = ((int32_t) avio_rb32(pb)) / (float) (1 << 16);
264  altitude = ((int32_t) avio_rb32(pb)) / (float) (1 << 16);
265 
266  // Try to output in the same format as the ?xyz field
267  snprintf(buf, sizeof(buf), "%+08.4f%+09.4f", latitude, longitude);
268  if (altitude)
269  av_strlcatf(buf, sizeof(buf), "%+f", altitude);
270  av_strlcatf(buf, sizeof(buf), "/%s", place);
271 
272  if (*language && strcmp(language, "und")) {
273  char key2[16];
274  snprintf(key2, sizeof(key2), "%s-%s", key, language);
275  av_dict_set(&c->fc->metadata, key2, buf, 0);
276  }
277  c->fc->event_flags |= AVFMT_EVENT_FLAG_METADATA_UPDATED;
278  return av_dict_set(&c->fc->metadata, key, buf, 0);
279 }
280 
281 static int mov_metadata_hmmt(MOVContext *c, AVIOContext *pb, unsigned len)
282 {
283  int i, n_hmmt;
284 
285  if (len < 2)
286  return 0;
287  if (c->ignore_chapters)
288  return 0;
289 
290  n_hmmt = avio_rb32(pb);
291  if (n_hmmt > len / 4)
292  return AVERROR_INVALIDDATA;
293  for (i = 0; i < n_hmmt && !pb->eof_reached; i++) {
294  int moment_time = avio_rb32(pb);
295  avpriv_new_chapter(c->fc, i, av_make_q(1, 1000), moment_time, AV_NOPTS_VALUE, NULL);
296  }
297  if (avio_feof(pb))
298  return AVERROR_INVALIDDATA;
299  return 0;
300 }
301 
303 {
304  char tmp_key[5];
305  char key2[32], language[4] = {0};
306  char *str = NULL;
307  const char *key = NULL;
308  uint16_t langcode = 0;
309  uint32_t data_type = 0, str_size, str_size_alloc;
310  int (*parse)(MOVContext*, AVIOContext*, unsigned, const char*) = NULL;
311  int raw = 0;
312  int num = 0;
313 
314  switch (atom.type) {
315  case MKTAG( '@','P','R','M'): key = "premiere_version"; raw = 1; break;
316  case MKTAG( '@','P','R','Q'): key = "quicktime_version"; raw = 1; break;
317  case MKTAG( 'X','M','P','_'):
318  if (c->export_xmp) { key = "xmp"; raw = 1; } break;
319  case MKTAG( 'a','A','R','T'): key = "album_artist"; break;
320  case MKTAG( 'a','k','I','D'): key = "account_type";
322  case MKTAG( 'a','p','I','D'): key = "account_id"; break;
323  case MKTAG( 'c','a','t','g'): key = "category"; break;
324  case MKTAG( 'c','p','i','l'): key = "compilation";
326  case MKTAG( 'c','p','r','t'): key = "copyright"; break;
327  case MKTAG( 'd','e','s','c'): key = "description"; break;
328  case MKTAG( 'd','i','s','k'): key = "disc";
330  case MKTAG( 'e','g','i','d'): key = "episode_uid";
332  case MKTAG( 'F','I','R','M'): key = "firmware"; raw = 1; break;
333  case MKTAG( 'g','n','r','e'): key = "genre";
334  parse = mov_metadata_gnre; break;
335  case MKTAG( 'h','d','v','d'): key = "hd_video";
337  case MKTAG( 'H','M','M','T'):
338  return mov_metadata_hmmt(c, pb, atom.size);
339  case MKTAG( 'k','e','y','w'): key = "keywords"; break;
340  case MKTAG( 'l','d','e','s'): key = "synopsis"; break;
341  case MKTAG( 'l','o','c','i'):
342  return mov_metadata_loci(c, pb, atom.size);
343  case MKTAG( 'm','a','n','u'): key = "make"; break;
344  case MKTAG( 'm','o','d','l'): key = "model"; break;
345  case MKTAG( 'p','c','s','t'): key = "podcast";
347  case MKTAG( 'p','g','a','p'): key = "gapless_playback";
349  case MKTAG( 'p','u','r','d'): key = "purchase_date"; break;
350  case MKTAG( 'r','t','n','g'): key = "rating";
352  case MKTAG( 's','o','a','a'): key = "sort_album_artist"; break;
353  case MKTAG( 's','o','a','l'): key = "sort_album"; break;
354  case MKTAG( 's','o','a','r'): key = "sort_artist"; break;
355  case MKTAG( 's','o','c','o'): key = "sort_composer"; break;
356  case MKTAG( 's','o','n','m'): key = "sort_name"; break;
357  case MKTAG( 's','o','s','n'): key = "sort_show"; break;
358  case MKTAG( 's','t','i','k'): key = "media_type";
360  case MKTAG( 't','r','k','n'): key = "track";
362  case MKTAG( 't','v','e','n'): key = "episode_id"; break;
363  case MKTAG( 't','v','e','s'): key = "episode_sort";
365  case MKTAG( 't','v','n','n'): key = "network"; break;
366  case MKTAG( 't','v','s','h'): key = "show"; break;
367  case MKTAG( 't','v','s','n'): key = "season_number";
369  case MKTAG(0xa9,'A','R','T'): key = "artist"; break;
370  case MKTAG(0xa9,'P','R','D'): key = "producer"; break;
371  case MKTAG(0xa9,'a','l','b'): key = "album"; break;
372  case MKTAG(0xa9,'a','u','t'): key = "artist"; break;
373  case MKTAG(0xa9,'c','h','p'): key = "chapter"; break;
374  case MKTAG(0xa9,'c','m','t'): key = "comment"; break;
375  case MKTAG(0xa9,'c','o','m'): key = "composer"; break;
376  case MKTAG(0xa9,'c','p','y'): key = "copyright"; break;
377  case MKTAG(0xa9,'d','a','y'): key = "date"; break;
378  case MKTAG(0xa9,'d','i','r'): key = "director"; break;
379  case MKTAG(0xa9,'d','i','s'): key = "disclaimer"; break;
380  case MKTAG(0xa9,'e','d','1'): key = "edit_date"; break;
381  case MKTAG(0xa9,'e','n','c'): key = "encoder"; break;
382  case MKTAG(0xa9,'f','m','t'): key = "original_format"; break;
383  case MKTAG(0xa9,'g','e','n'): key = "genre"; break;
384  case MKTAG(0xa9,'g','r','p'): key = "grouping"; break;
385  case MKTAG(0xa9,'h','s','t'): key = "host_computer"; break;
386  case MKTAG(0xa9,'i','n','f'): key = "comment"; break;
387  case MKTAG(0xa9,'l','y','r'): key = "lyrics"; break;
388  case MKTAG(0xa9,'m','a','k'): key = "make"; break;
389  case MKTAG(0xa9,'m','o','d'): key = "model"; break;
390  case MKTAG(0xa9,'n','a','m'): key = "title"; break;
391  case MKTAG(0xa9,'o','p','e'): key = "original_artist"; break;
392  case MKTAG(0xa9,'p','r','d'): key = "producer"; break;
393  case MKTAG(0xa9,'p','r','f'): key = "performers"; break;
394  case MKTAG(0xa9,'r','e','q'): key = "playback_requirements"; break;
395  case MKTAG(0xa9,'s','r','c'): key = "original_source"; break;
396  case MKTAG(0xa9,'s','t','3'): key = "subtitle"; break;
397  case MKTAG(0xa9,'s','w','r'): key = "encoder"; break;
398  case MKTAG(0xa9,'t','o','o'): key = "encoder"; break;
399  case MKTAG(0xa9,'t','r','k'): key = "track"; break;
400  case MKTAG(0xa9,'u','r','l'): key = "URL"; break;
401  case MKTAG(0xa9,'w','r','n'): key = "warning"; break;
402  case MKTAG(0xa9,'w','r','t'): key = "composer"; break;
403  case MKTAG(0xa9,'x','y','z'): key = "location"; break;
404  }
405 retry:
406  if (c->itunes_metadata && atom.size > 8) {
407  int data_size = avio_rb32(pb);
408  int tag = avio_rl32(pb);
409  if (tag == MKTAG('d','a','t','a') && data_size <= atom.size && data_size >= 16) {
410  data_type = avio_rb32(pb); // type
411  avio_rb32(pb); // unknown
412  str_size = data_size - 16;
413  atom.size -= 16;
414 
415  if (atom.type == MKTAG('c', 'o', 'v', 'r')) {
416  int ret = mov_read_covr(c, pb, data_type, str_size);
417  if (ret < 0) {
418  av_log(c->fc, AV_LOG_ERROR, "Error parsing cover art.\n");
419  return ret;
420  }
421  atom.size -= str_size;
422  if (atom.size > 8)
423  goto retry;
424  return ret;
425  } else if (!key && c->found_hdlr_mdta && c->meta_keys) {
426  uint32_t index = AV_RB32(&atom.type);
427  if (index < c->meta_keys_count && index > 0) {
428  key = c->meta_keys[index];
429  } else {
430  av_log(c->fc, AV_LOG_WARNING,
431  "The index of 'data' is out of range: %"PRId32" < 1 or >= %d.\n",
432  index, c->meta_keys_count);
433  }
434  }
435  } else return 0;
436  } else if (atom.size > 4 && key && !c->itunes_metadata && !raw) {
437  str_size = avio_rb16(pb); // string length
438  if (str_size > atom.size) {
439  raw = 1;
440  avio_seek(pb, -2, SEEK_CUR);
441  av_log(c->fc, AV_LOG_WARNING, "UDTA parsing failed retrying raw\n");
442  goto retry;
443  }
444  langcode = avio_rb16(pb);
445  ff_mov_lang_to_iso639(langcode, language);
446  atom.size -= 4;
447  } else
448  str_size = atom.size;
449 
450  if (c->export_all && !key) {
451  snprintf(tmp_key, 5, "%.4s", (char*)&atom.type);
452  key = tmp_key;
453  }
454 
455  if (!key)
456  return 0;
457  if (atom.size < 0 || str_size >= INT_MAX/2)
458  return AVERROR_INVALIDDATA;
459 
460  // Allocates enough space if data_type is a int32 or float32 number, otherwise
461  // worst-case requirement for output string in case of utf8 coded input
462  num = (data_type >= 21 && data_type <= 23);
463  str_size_alloc = (num ? 512 : (raw ? str_size : str_size * 2)) + 1;
464  str = av_mallocz(str_size_alloc);
465  if (!str)
466  return AVERROR(ENOMEM);
467 
468  if (parse)
469  parse(c, pb, str_size, key);
470  else {
471  if (!raw && (data_type == 3 || (data_type == 0 && (langcode < 0x400 || langcode == 0x7fff)))) { // MAC Encoded
472  mov_read_mac_string(c, pb, str_size, str, str_size_alloc);
473  } else if (data_type == 21) { // BE signed integer, variable size
474  int val = 0;
475  if (str_size == 1)
476  val = (int8_t)avio_r8(pb);
477  else if (str_size == 2)
478  val = (int16_t)avio_rb16(pb);
479  else if (str_size == 3)
480  val = ((int32_t)(avio_rb24(pb)<<8))>>8;
481  else if (str_size == 4)
482  val = (int32_t)avio_rb32(pb);
483  if (snprintf(str, str_size_alloc, "%d", val) >= str_size_alloc) {
484  av_log(c->fc, AV_LOG_ERROR,
485  "Failed to store the number (%d) in string.\n", val);
486  av_free(str);
487  return AVERROR_INVALIDDATA;
488  }
489  } else if (data_type == 22) { // BE unsigned integer, variable size
490  unsigned int val = 0;
491  if (str_size == 1)
492  val = avio_r8(pb);
493  else if (str_size == 2)
494  val = avio_rb16(pb);
495  else if (str_size == 3)
496  val = avio_rb24(pb);
497  else if (str_size == 4)
498  val = avio_rb32(pb);
499  if (snprintf(str, str_size_alloc, "%u", val) >= str_size_alloc) {
500  av_log(c->fc, AV_LOG_ERROR,
501  "Failed to store the number (%u) in string.\n", val);
502  av_free(str);
503  return AVERROR_INVALIDDATA;
504  }
505  } else if (data_type == 23 && str_size >= 4) { // BE float32
506  float val = av_int2float(avio_rb32(pb));
507  if (snprintf(str, str_size_alloc, "%f", val) >= str_size_alloc) {
508  av_log(c->fc, AV_LOG_ERROR,
509  "Failed to store the float32 number (%f) in string.\n", val);
510  av_free(str);
511  return AVERROR_INVALIDDATA;
512  }
513  } else {
514  int ret = ffio_read_size(pb, str, str_size);
515  if (ret < 0) {
516  av_free(str);
517  return ret;
518  }
519  str[str_size] = 0;
520  }
521  c->fc->event_flags |= AVFMT_EVENT_FLAG_METADATA_UPDATED;
522  av_dict_set(&c->fc->metadata, key, str, 0);
523  if (*language && strcmp(language, "und")) {
524  snprintf(key2, sizeof(key2), "%s-%s", key, language);
525  av_dict_set(&c->fc->metadata, key2, str, 0);
526  }
527  if (!strcmp(key, "encoder")) {
528  int major, minor, micro;
529  if (sscanf(str, "HandBrake %d.%d.%d", &major, &minor, &micro) == 3) {
530  c->handbrake_version = 1000000*major + 1000*minor + micro;
531  }
532  }
533  }
534 
535  av_freep(&str);
536  return 0;
537 }
538 
540 {
541  int64_t start;
542  int i, nb_chapters, str_len, version;
543  char str[256+1];
544  int ret;
545 
546  if (c->ignore_chapters)
547  return 0;
548 
549  if ((atom.size -= 5) < 0)
550  return 0;
551 
552  version = avio_r8(pb);
553  avio_rb24(pb);
554  if (version)
555  avio_rb32(pb); // ???
556  nb_chapters = avio_r8(pb);
557 
558  for (i = 0; i < nb_chapters; i++) {
559  if (atom.size < 9)
560  return 0;
561 
562  start = avio_rb64(pb);
563  str_len = avio_r8(pb);
564 
565  if ((atom.size -= 9+str_len) < 0)
566  return 0;
567 
568  ret = ffio_read_size(pb, str, str_len);
569  if (ret < 0)
570  return ret;
571  str[str_len] = 0;
572  avpriv_new_chapter(c->fc, i, (AVRational){1,10000000}, start, AV_NOPTS_VALUE, str);
573  }
574  return 0;
575 }
576 
577 #define MIN_DATA_ENTRY_BOX_SIZE 12
579 {
580  AVStream *st;
581  MOVStreamContext *sc;
582  int entries, i, j;
583 
584  if (c->fc->nb_streams < 1)
585  return 0;
586  st = c->fc->streams[c->fc->nb_streams-1];
587  sc = st->priv_data;
588 
589  avio_rb32(pb); // version + flags
590  entries = avio_rb32(pb);
591  if (!entries ||
592  entries > (atom.size - 1) / MIN_DATA_ENTRY_BOX_SIZE + 1 ||
593  entries >= UINT_MAX / sizeof(*sc->drefs))
594  return AVERROR_INVALIDDATA;
595  sc->drefs_count = 0;
596  av_free(sc->drefs);
597  sc->drefs_count = 0;
598  sc->drefs = av_mallocz(entries * sizeof(*sc->drefs));
599  if (!sc->drefs)
600  return AVERROR(ENOMEM);
601  sc->drefs_count = entries;
602 
603  for (i = 0; i < entries; i++) {
604  MOVDref *dref = &sc->drefs[i];
605  uint32_t size = avio_rb32(pb);
606  int64_t next = avio_tell(pb);
607 
608  if (size < 12 || next < 0 || next > INT64_MAX - size)
609  return AVERROR_INVALIDDATA;
610 
611  next += size - 4;
612 
613  dref->type = avio_rl32(pb);
614  avio_rb32(pb); // version + flags
615 
616  if (dref->type == MKTAG('a','l','i','s') && size > 150) {
617  /* macintosh alias record */
618  uint16_t volume_len, len;
619  int16_t type;
620  int ret;
621 
622  avio_skip(pb, 10);
623 
624  volume_len = avio_r8(pb);
625  volume_len = FFMIN(volume_len, 27);
626  ret = ffio_read_size(pb, dref->volume, 27);
627  if (ret < 0)
628  return ret;
629  dref->volume[volume_len] = 0;
630  av_log(c->fc, AV_LOG_DEBUG, "volume %s, len %d\n", dref->volume, volume_len);
631 
632  avio_skip(pb, 12);
633 
634  len = avio_r8(pb);
635  len = FFMIN(len, 63);
636  ret = ffio_read_size(pb, dref->filename, 63);
637  if (ret < 0)
638  return ret;
639  dref->filename[len] = 0;
640  av_log(c->fc, AV_LOG_DEBUG, "filename %s, len %d\n", dref->filename, len);
641 
642  avio_skip(pb, 16);
643 
644  /* read next level up_from_alias/down_to_target */
645  dref->nlvl_from = avio_rb16(pb);
646  dref->nlvl_to = avio_rb16(pb);
647  av_log(c->fc, AV_LOG_DEBUG, "nlvl from %d, nlvl to %d\n",
648  dref->nlvl_from, dref->nlvl_to);
649 
650  avio_skip(pb, 16);
651 
652  for (type = 0; type != -1 && avio_tell(pb) < next; ) {
653  if(avio_feof(pb))
654  return AVERROR_EOF;
655  type = avio_rb16(pb);
656  len = avio_rb16(pb);
657  av_log(c->fc, AV_LOG_DEBUG, "type %d, len %d\n", type, len);
658  if (len&1)
659  len += 1;
660  if (type == 2) { // absolute path
661  av_free(dref->path);
662  dref->path = av_mallocz(len+1);
663  if (!dref->path)
664  return AVERROR(ENOMEM);
665 
666  ret = ffio_read_size(pb, dref->path, len);
667  if (ret < 0) {
668  av_freep(&dref->path);
669  return ret;
670  }
671  if (len > volume_len && !strncmp(dref->path, dref->volume, volume_len)) {
672  len -= volume_len;
673  memmove(dref->path, dref->path+volume_len, len);
674  dref->path[len] = 0;
675  }
676  // trim string of any ending zeros
677  for (j = len - 1; j >= 0; j--) {
678  if (dref->path[j] == 0)
679  len--;
680  else
681  break;
682  }
683  for (j = 0; j < len; j++)
684  if (dref->path[j] == ':' || dref->path[j] == 0)
685  dref->path[j] = '/';
686  av_log(c->fc, AV_LOG_DEBUG, "path %s\n", dref->path);
687  } else if (type == 0) { // directory name
688  av_free(dref->dir);
689  dref->dir = av_malloc(len+1);
690  if (!dref->dir)
691  return AVERROR(ENOMEM);
692 
693  ret = ffio_read_size(pb, dref->dir, len);
694  if (ret < 0) {
695  av_freep(&dref->dir);
696  return ret;
697  }
698  dref->dir[len] = 0;
699  for (j = 0; j < len; j++)
700  if (dref->dir[j] == ':')
701  dref->dir[j] = '/';
702  av_log(c->fc, AV_LOG_DEBUG, "dir %s\n", dref->dir);
703  } else
704  avio_skip(pb, len);
705  }
706  } else {
707  av_log(c->fc, AV_LOG_DEBUG, "Unknown dref type 0x%08"PRIx32" size %"PRIu32"\n",
708  dref->type, size);
709  entries--;
710  i--;
711  }
712  avio_seek(pb, next, SEEK_SET);
713  }
714  return 0;
715 }
716 
718 {
719  AVStream *st;
720  uint32_t type;
721  uint32_t ctype;
722  int64_t title_size;
723  char *title_str;
724  int ret;
725 
726  avio_r8(pb); /* version */
727  avio_rb24(pb); /* flags */
728 
729  /* component type */
730  ctype = avio_rl32(pb);
731  type = avio_rl32(pb); /* component subtype */
732 
733  av_log(c->fc, AV_LOG_TRACE, "ctype=%s\n", av_fourcc2str(ctype));
734  av_log(c->fc, AV_LOG_TRACE, "stype=%s\n", av_fourcc2str(type));
735 
736  if (c->trak_index < 0) { // meta not inside a trak
737  if (type == MKTAG('m','d','t','a')) {
738  c->found_hdlr_mdta = 1;
739  }
740  return 0;
741  }
742 
743  st = c->fc->streams[c->fc->nb_streams-1];
744 
745  if (type == MKTAG('v','i','d','e'))
747  else if (type == MKTAG('s','o','u','n'))
749  else if (type == MKTAG('m','1','a',' '))
751  else if ((type == MKTAG('s','u','b','p')) || (type == MKTAG('c','l','c','p')))
753 
754  avio_rb32(pb); /* component manufacture */
755  avio_rb32(pb); /* component flags */
756  avio_rb32(pb); /* component flags mask */
757 
758  title_size = atom.size - 24;
759  if (title_size > 0) {
760  if (title_size > FFMIN(INT_MAX, SIZE_MAX-1))
761  return AVERROR_INVALIDDATA;
762  title_str = av_malloc(title_size + 1); /* Add null terminator */
763  if (!title_str)
764  return AVERROR(ENOMEM);
765 
766  ret = ffio_read_size(pb, title_str, title_size);
767  if (ret < 0) {
768  av_freep(&title_str);
769  return ret;
770  }
771  title_str[title_size] = 0;
772  if (title_str[0]) {
773  int off = (!c->isom && title_str[0] == title_size - 1);
774  // flag added so as to not set stream handler name if already set from mdia->hdlr
775  av_dict_set(&st->metadata, "handler_name", title_str + off, AV_DICT_DONT_OVERWRITE);
776  }
777  av_freep(&title_str);
778  }
779 
780  return 0;
781 }
782 
784 {
785  return ff_mov_read_esds(c->fc, pb);
786 }
787 
789 {
790  AVStream *st;
791  enum AVAudioServiceType *ast;
792  int ac3info, acmod, lfeon, bsmod;
793 
794  if (c->fc->nb_streams < 1)
795  return 0;
796  st = c->fc->streams[c->fc->nb_streams-1];
797 
799  sizeof(*ast));
800  if (!ast)
801  return AVERROR(ENOMEM);
802 
803  ac3info = avio_rb24(pb);
804  bsmod = (ac3info >> 14) & 0x7;
805  acmod = (ac3info >> 11) & 0x7;
806  lfeon = (ac3info >> 10) & 0x1;
807  st->codecpar->channels = ((int[]){2,1,2,3,3,4,4,5})[acmod] + lfeon;
809  if (lfeon)
811  *ast = bsmod;
812  if (st->codecpar->channels > 1 && bsmod == 0x7)
814 
815 #if FF_API_LAVF_AVCTX
817  st->codec->audio_service_type = *ast;
819 #endif
820 
821  return 0;
822 }
823 
825 {
826  AVStream *st;
827  enum AVAudioServiceType *ast;
828  int eac3info, acmod, lfeon, bsmod;
829 
830  if (c->fc->nb_streams < 1)
831  return 0;
832  st = c->fc->streams[c->fc->nb_streams-1];
833 
835  sizeof(*ast));
836  if (!ast)
837  return AVERROR(ENOMEM);
838 
839  /* No need to parse fields for additional independent substreams and its
840  * associated dependent substreams since libavcodec's E-AC-3 decoder
841  * does not support them yet. */
842  avio_rb16(pb); /* data_rate and num_ind_sub */
843  eac3info = avio_rb24(pb);
844  bsmod = (eac3info >> 12) & 0x1f;
845  acmod = (eac3info >> 9) & 0x7;
846  lfeon = (eac3info >> 8) & 0x1;
848  if (lfeon)
851  *ast = bsmod;
852  if (st->codecpar->channels > 1 && bsmod == 0x7)
854 
855 #if FF_API_LAVF_AVCTX
857  st->codec->audio_service_type = *ast;
859 #endif
860 
861  return 0;
862 }
863 
865 {
866  const uint32_t ddts_size = 20;
867  AVStream *st = NULL;
868  uint8_t *buf = NULL;
869  uint32_t frame_duration_code = 0;
870  uint32_t channel_layout_code = 0;
871  GetBitContext gb;
872 
874  if (!buf) {
875  return AVERROR(ENOMEM);
876  }
877  if (avio_read(pb, buf, ddts_size) < ddts_size) {
878  av_free(buf);
879  return AVERROR_INVALIDDATA;
880  }
881 
882  init_get_bits(&gb, buf, 8*ddts_size);
883 
884  if (c->fc->nb_streams < 1) {
885  av_free(buf);
886  return 0;
887  }
888  st = c->fc->streams[c->fc->nb_streams-1];
889 
890  st->codecpar->sample_rate = get_bits_long(&gb, 32);
891  if (st->codecpar->sample_rate <= 0) {
892  av_log(c->fc, AV_LOG_ERROR, "Invalid sample rate %d\n", st->codecpar->sample_rate);
893  av_free(buf);
894  return AVERROR_INVALIDDATA;
895  }
896  skip_bits_long(&gb, 32); /* max bitrate */
897  st->codecpar->bit_rate = get_bits_long(&gb, 32);
898  st->codecpar->bits_per_coded_sample = get_bits(&gb, 8);
899  frame_duration_code = get_bits(&gb, 2);
900  skip_bits(&gb, 30); /* various fields */
901  channel_layout_code = get_bits(&gb, 16);
902 
903  st->codecpar->frame_size =
904  (frame_duration_code == 0) ? 512 :
905  (frame_duration_code == 1) ? 1024 :
906  (frame_duration_code == 2) ? 2048 :
907  (frame_duration_code == 3) ? 4096 : 0;
908 
909  if (channel_layout_code > 0xff) {
910  av_log(c->fc, AV_LOG_WARNING, "Unsupported DTS audio channel layout");
911  }
912  st->codecpar->channel_layout =
913  ((channel_layout_code & 0x1) ? AV_CH_FRONT_CENTER : 0) |
914  ((channel_layout_code & 0x2) ? AV_CH_FRONT_LEFT : 0) |
915  ((channel_layout_code & 0x2) ? AV_CH_FRONT_RIGHT : 0) |
916  ((channel_layout_code & 0x4) ? AV_CH_SIDE_LEFT : 0) |
917  ((channel_layout_code & 0x4) ? AV_CH_SIDE_RIGHT : 0) |
918  ((channel_layout_code & 0x8) ? AV_CH_LOW_FREQUENCY : 0);
919 
921  av_free(buf);
922 
923  return 0;
924 }
925 
927 {
928  AVStream *st;
929 
930  if (c->fc->nb_streams < 1)
931  return 0;
932  st = c->fc->streams[c->fc->nb_streams-1];
933 
934  if (atom.size < 16)
935  return 0;
936 
937  /* skip version and flags */
938  avio_skip(pb, 4);
939 
940  ff_mov_read_chan(c->fc, pb, st, atom.size - 4);
941 
942  return 0;
943 }
944 
946 {
947  AVStream *st;
948  int ret;
949 
950  if (c->fc->nb_streams < 1)
951  return 0;
952  st = c->fc->streams[c->fc->nb_streams-1];
953 
954  if ((ret = ff_get_wav_header(c->fc, pb, st->codecpar, atom.size, 0)) < 0)
955  av_log(c->fc, AV_LOG_WARNING, "get_wav_header failed\n");
956 
957  return ret;
958 }
959 
961 {
962  const int num = avio_rb32(pb);
963  const int den = avio_rb32(pb);
964  AVStream *st;
965 
966  if (c->fc->nb_streams < 1)
967  return 0;
968  st = c->fc->streams[c->fc->nb_streams-1];
969 
970  if ((st->sample_aspect_ratio.den != 1 || st->sample_aspect_ratio.num) && // default
971  (den != st->sample_aspect_ratio.den || num != st->sample_aspect_ratio.num)) {
972  av_log(c->fc, AV_LOG_WARNING,
973  "sample aspect ratio already set to %d:%d, ignoring 'pasp' atom (%d:%d)\n",
975  num, den);
976  } else if (den != 0) {
978  num, den, 32767);
979  }
980  return 0;
981 }
982 
983 /* this atom contains actual media data */
985 {
986  if (atom.size == 0) /* wrong one (MP4) */
987  return 0;
988  c->found_mdat=1;
989  return 0; /* now go for moov */
990 }
991 
992 #define DRM_BLOB_SIZE 56
993 
995 {
996  uint8_t intermediate_key[20];
997  uint8_t intermediate_iv[20];
998  uint8_t input[64];
999  uint8_t output[64];
1000  uint8_t file_checksum[20];
1001  uint8_t calculated_checksum[20];
1002  struct AVSHA *sha;
1003  int i;
1004  int ret = 0;
1005  uint8_t *activation_bytes = c->activation_bytes;
1006  uint8_t *fixed_key = c->audible_fixed_key;
1007 
1008  c->aax_mode = 1;
1009 
1010  sha = av_sha_alloc();
1011  if (!sha)
1012  return AVERROR(ENOMEM);
1013  av_free(c->aes_decrypt);
1014  c->aes_decrypt = av_aes_alloc();
1015  if (!c->aes_decrypt) {
1016  ret = AVERROR(ENOMEM);
1017  goto fail;
1018  }
1019 
1020  /* drm blob processing */
1021  avio_read(pb, output, 8); // go to offset 8, absolute position 0x251
1023  avio_read(pb, output, 4); // go to offset 4, absolute position 0x28d
1024  avio_read(pb, file_checksum, 20);
1025 
1026  av_log(c->fc, AV_LOG_INFO, "[aax] file checksum == "); // required by external tools
1027  for (i = 0; i < 20; i++)
1028  av_log(c->fc, AV_LOG_INFO, "%02x", file_checksum[i]);
1029  av_log(c->fc, AV_LOG_INFO, "\n");
1030 
1031  /* verify activation data */
1032  if (!activation_bytes) {
1033  av_log(c->fc, AV_LOG_WARNING, "[aax] activation_bytes option is missing!\n");
1034  ret = 0; /* allow ffprobe to continue working on .aax files */
1035  goto fail;
1036  }
1037  if (c->activation_bytes_size != 4) {
1038  av_log(c->fc, AV_LOG_FATAL, "[aax] activation_bytes value needs to be 4 bytes!\n");
1039  ret = AVERROR(EINVAL);
1040  goto fail;
1041  }
1042 
1043  /* verify fixed key */
1044  if (c->audible_fixed_key_size != 16) {
1045  av_log(c->fc, AV_LOG_FATAL, "[aax] audible_fixed_key value needs to be 16 bytes!\n");
1046  ret = AVERROR(EINVAL);
1047  goto fail;
1048  }
1049 
1050  /* AAX (and AAX+) key derivation */
1051  av_sha_init(sha, 160);
1052  av_sha_update(sha, fixed_key, 16);
1053  av_sha_update(sha, activation_bytes, 4);
1054  av_sha_final(sha, intermediate_key);
1055  av_sha_init(sha, 160);
1056  av_sha_update(sha, fixed_key, 16);
1057  av_sha_update(sha, intermediate_key, 20);
1058  av_sha_update(sha, activation_bytes, 4);
1059  av_sha_final(sha, intermediate_iv);
1060  av_sha_init(sha, 160);
1061  av_sha_update(sha, intermediate_key, 16);
1062  av_sha_update(sha, intermediate_iv, 16);
1063  av_sha_final(sha, calculated_checksum);
1064  if (memcmp(calculated_checksum, file_checksum, 20)) { // critical error
1065  av_log(c->fc, AV_LOG_ERROR, "[aax] mismatch in checksums!\n");
1067  goto fail;
1068  }
1069  av_aes_init(c->aes_decrypt, intermediate_key, 128, 1);
1070  av_aes_crypt(c->aes_decrypt, output, input, DRM_BLOB_SIZE >> 4, intermediate_iv, 1);
1071  for (i = 0; i < 4; i++) {
1072  // file data (in output) is stored in big-endian mode
1073  if (activation_bytes[i] != output[3 - i]) { // critical error
1074  av_log(c->fc, AV_LOG_ERROR, "[aax] error in drm blob decryption!\n");
1076  goto fail;
1077  }
1078  }
1079  memcpy(c->file_key, output + 8, 16);
1080  memcpy(input, output + 26, 16);
1081  av_sha_init(sha, 160);
1082  av_sha_update(sha, input, 16);
1083  av_sha_update(sha, c->file_key, 16);
1084  av_sha_update(sha, fixed_key, 16);
1085  av_sha_final(sha, c->file_iv);
1086 
1087 fail:
1088  av_free(sha);
1089 
1090  return ret;
1091 }
1092 
1093 // Audible AAX (and AAX+) bytestream decryption
1095 {
1096  int blocks = 0;
1097  unsigned char iv[16];
1098 
1099  memcpy(iv, c->file_iv, 16); // iv is overwritten
1100  blocks = size >> 4; // trailing bytes are not encrypted!
1101  av_aes_init(c->aes_decrypt, c->file_key, 128, 1);
1102  av_aes_crypt(c->aes_decrypt, input, input, blocks, iv, 1);
1103 
1104  return 0;
1105 }
1106 
1107 /* read major brand, minor version and compatible brands and store them as metadata */
1109 {
1110  uint32_t minor_ver;
1111  int comp_brand_size;
1112  char* comp_brands_str;
1113  uint8_t type[5] = {0};
1114  int ret = ffio_read_size(pb, type, 4);
1115  if (ret < 0)
1116  return ret;
1117 
1118  if (strcmp(type, "qt "))
1119  c->isom = 1;
1120  av_log(c->fc, AV_LOG_DEBUG, "ISO: File Type Major Brand: %.4s\n",(char *)&type);
1121  av_dict_set(&c->fc->metadata, "major_brand", type, 0);
1122  minor_ver = avio_rb32(pb); /* minor version */
1123  av_dict_set_int(&c->fc->metadata, "minor_version", minor_ver, 0);
1124 
1125  comp_brand_size = atom.size - 8;
1126  if (comp_brand_size < 0 || comp_brand_size == INT_MAX)
1127  return AVERROR_INVALIDDATA;
1128  comp_brands_str = av_malloc(comp_brand_size + 1); /* Add null terminator */
1129  if (!comp_brands_str)
1130  return AVERROR(ENOMEM);
1131 
1132  ret = ffio_read_size(pb, comp_brands_str, comp_brand_size);
1133  if (ret < 0) {
1134  av_freep(&comp_brands_str);
1135  return ret;
1136  }
1137  comp_brands_str[comp_brand_size] = 0;
1138  av_dict_set(&c->fc->metadata, "compatible_brands", comp_brands_str, 0);
1139  av_freep(&comp_brands_str);
1140 
1141  return 0;
1142 }
1143 
1144 /* this atom should contain all header atoms */
1146 {
1147  int ret;
1148 
1149  if (c->found_moov) {
1150  av_log(c->fc, AV_LOG_WARNING, "Found duplicated MOOV Atom. Skipped it\n");
1151  avio_skip(pb, atom.size);
1152  return 0;
1153  }
1154 
1155  if ((ret = mov_read_default(c, pb, atom)) < 0)
1156  return ret;
1157  /* we parsed the 'moov' atom, we can terminate the parsing as soon as we find the 'mdat' */
1158  /* so we don't parse the whole file if over a network */
1159  c->found_moov=1;
1160  return 0; /* now go for mdat */
1161 }
1162 
1164  MOVFragmentIndex *frag_index,
1165  int index,
1166  int id)
1167 {
1168  int i;
1169  MOVFragmentIndexItem * item;
1170 
1171  if (index < 0 || index >= frag_index->nb_items)
1172  return NULL;
1173  item = &frag_index->item[index];
1174  for (i = 0; i < item->nb_stream_info; i++)
1175  if (item->stream_info[i].id == id)
1176  return &item->stream_info[i];
1177 
1178  // This shouldn't happen
1179  return NULL;
1180 }
1181 
1182 static void set_frag_stream(MOVFragmentIndex *frag_index, int id)
1183 {
1184  int i;
1185  MOVFragmentIndexItem * item;
1186 
1187  if (frag_index->current < 0 ||
1188  frag_index->current >= frag_index->nb_items)
1189  return;
1190 
1191  item = &frag_index->item[frag_index->current];
1192  for (i = 0; i < item->nb_stream_info; i++)
1193  if (item->stream_info[i].id == id) {
1194  item->current = i;
1195  return;
1196  }
1197 
1198  // id not found. This shouldn't happen.
1199  item->current = -1;
1200 }
1201 
1203  MOVFragmentIndex *frag_index)
1204 {
1205  MOVFragmentIndexItem *item;
1206  if (frag_index->current < 0 ||
1207  frag_index->current >= frag_index->nb_items)
1208  return NULL;
1209 
1210  item = &frag_index->item[frag_index->current];
1211  if (item->current >= 0 && item->current < item->nb_stream_info)
1212  return &item->stream_info[item->current];
1213 
1214  // This shouldn't happen
1215  return NULL;
1216 }
1217 
1218 static int search_frag_moof_offset(MOVFragmentIndex *frag_index, int64_t offset)
1219 {
1220  int a, b, m;
1221  int64_t moof_offset;
1222 
1223  // Optimize for appending new entries
1224  if (!frag_index->nb_items ||
1225  frag_index->item[frag_index->nb_items - 1].moof_offset < offset)
1226  return frag_index->nb_items;
1227 
1228  a = -1;
1229  b = frag_index->nb_items;
1230 
1231  while (b - a > 1) {
1232  m = (a + b) >> 1;
1233  moof_offset = frag_index->item[m].moof_offset;
1234  if (moof_offset >= offset)
1235  b = m;
1236  if (moof_offset <= offset)
1237  a = m;
1238  }
1239  return b;
1240 }
1241 
1242 static int64_t get_stream_info_time(MOVFragmentStreamInfo * frag_stream_info)
1243 {
1244  av_assert0(frag_stream_info);
1245  if (frag_stream_info->sidx_pts != AV_NOPTS_VALUE)
1246  return frag_stream_info->sidx_pts;
1247  if (frag_stream_info->first_tfra_pts != AV_NOPTS_VALUE)
1248  return frag_stream_info->first_tfra_pts;
1249  return frag_stream_info->tfdt_dts;
1250 }
1251 
1252 static int64_t get_frag_time(MOVFragmentIndex *frag_index,
1253  int index, int track_id)
1254 {
1255  MOVFragmentStreamInfo * frag_stream_info;
1256  int64_t timestamp;
1257  int i;
1258 
1259  if (track_id >= 0) {
1260  frag_stream_info = get_frag_stream_info(frag_index, index, track_id);
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].first_tfra_pts = AV_NOPTS_VALUE;
1345  frag_stream_info[i].index_entry = -1;
1346  frag_stream_info[i].encryption_index = NULL;
1347  }
1348 
1349  if (index < c->frag_index.nb_items)
1350  memmove(c->frag_index.item + index + 1, c->frag_index.item + index,
1351  (c->frag_index.nb_items - index) * sizeof(*c->frag_index.item));
1352 
1353  item = &c->frag_index.item[index];
1354  item->headers_read = 0;
1355  item->current = 0;
1356  item->nb_stream_info = c->fc->nb_streams;
1357  item->moof_offset = offset;
1358  item->stream_info = frag_stream_info;
1359  c->frag_index.nb_items++;
1360 
1361  return index;
1362 }
1363 
1364 static void fix_frag_index_entries(MOVFragmentIndex *frag_index, int index,
1365  int id, int entries)
1366 {
1367  int i;
1368  MOVFragmentStreamInfo * frag_stream_info;
1369 
1370  if (index < 0)
1371  return;
1372  for (i = index; i < frag_index->nb_items; i++) {
1373  frag_stream_info = get_frag_stream_info(frag_index, i, id);
1374  if (frag_stream_info && frag_stream_info->index_entry >= 0)
1375  frag_stream_info->index_entry += entries;
1376  }
1377 }
1378 
1380 {
1381  // Set by mov_read_tfhd(). mov_read_trun() will reject files missing tfhd.
1382  c->fragment.found_tfhd = 0;
1383 
1384  if (!c->has_looked_for_mfra && c->use_mfra_for > 0) {
1385  c->has_looked_for_mfra = 1;
1386  if (pb->seekable & AVIO_SEEKABLE_NORMAL) {
1387  int ret;
1388  av_log(c->fc, AV_LOG_VERBOSE, "stream has moof boxes, will look "
1389  "for a mfra\n");
1390  if ((ret = mov_read_mfra(c, pb)) < 0) {
1391  av_log(c->fc, AV_LOG_VERBOSE, "found a moof box but failed to "
1392  "read the mfra (may be a live ismv)\n");
1393  }
1394  } else {
1395  av_log(c->fc, AV_LOG_VERBOSE, "found a moof box but stream is not "
1396  "seekable, can not look for mfra\n");
1397  }
1398  }
1399  c->fragment.moof_offset = c->fragment.implicit_offset = avio_tell(pb) - 8;
1400  av_log(c->fc, AV_LOG_TRACE, "moof offset %"PRIx64"\n", c->fragment.moof_offset);
1401  c->frag_index.current = update_frag_index(c, c->fragment.moof_offset);
1402  return mov_read_default(c, pb, atom);
1403 }
1404 
1405 static void mov_metadata_creation_time(AVDictionary **metadata, int64_t time)
1406 {
1407  if (time) {
1408  if(time >= 2082844800)
1409  time -= 2082844800; /* seconds between 1904-01-01 and Epoch */
1410 
1411  if ((int64_t)(time * 1000000ULL) / 1000000 != time) {
1412  av_log(NULL, AV_LOG_DEBUG, "creation_time is not representable\n");
1413  return;
1414  }
1415 
1416  avpriv_dict_set_timestamp(metadata, "creation_time", time * 1000000);
1417  }
1418 }
1419 
1421 {
1422  AVStream *st;
1423  MOVStreamContext *sc;
1424  int version;
1425  char language[4] = {0};
1426  unsigned lang;
1427  int64_t creation_time;
1428 
1429  if (c->fc->nb_streams < 1)
1430  return 0;
1431  st = c->fc->streams[c->fc->nb_streams-1];
1432  sc = st->priv_data;
1433 
1434  if (sc->time_scale) {
1435  av_log(c->fc, AV_LOG_ERROR, "Multiple mdhd?\n");
1436  return AVERROR_INVALIDDATA;
1437  }
1438 
1439  version = avio_r8(pb);
1440  if (version > 1) {
1441  avpriv_request_sample(c->fc, "Version %d", version);
1442  return AVERROR_PATCHWELCOME;
1443  }
1444  avio_rb24(pb); /* flags */
1445  if (version == 1) {
1446  creation_time = avio_rb64(pb);
1447  avio_rb64(pb);
1448  } else {
1449  creation_time = avio_rb32(pb);
1450  avio_rb32(pb); /* modification time */
1451  }
1452  mov_metadata_creation_time(&st->metadata, creation_time);
1453 
1454  sc->time_scale = avio_rb32(pb);
1455  if (sc->time_scale <= 0) {
1456  av_log(c->fc, AV_LOG_ERROR, "Invalid mdhd time scale %d, defaulting to 1\n", sc->time_scale);
1457  sc->time_scale = 1;
1458  }
1459  st->duration = (version == 1) ? avio_rb64(pb) : avio_rb32(pb); /* duration */
1460 
1461  lang = avio_rb16(pb); /* language */
1462  if (ff_mov_lang_to_iso639(lang, language))
1463  av_dict_set(&st->metadata, "language", language, 0);
1464  avio_rb16(pb); /* quality */
1465 
1466  return 0;
1467 }
1468 
1470 {
1471  int i;
1472  int64_t creation_time;
1473  int version = avio_r8(pb); /* version */
1474  avio_rb24(pb); /* flags */
1475 
1476  if (version == 1) {
1477  creation_time = avio_rb64(pb);
1478  avio_rb64(pb);
1479  } else {
1480  creation_time = avio_rb32(pb);
1481  avio_rb32(pb); /* modification time */
1482  }
1483  mov_metadata_creation_time(&c->fc->metadata, creation_time);
1484  c->time_scale = avio_rb32(pb); /* time scale */
1485  if (c->time_scale <= 0) {
1486  av_log(c->fc, AV_LOG_ERROR, "Invalid mvhd time scale %d, defaulting to 1\n", c->time_scale);
1487  c->time_scale = 1;
1488  }
1489  av_log(c->fc, AV_LOG_TRACE, "time scale = %i\n", c->time_scale);
1490 
1491  c->duration = (version == 1) ? avio_rb64(pb) : avio_rb32(pb); /* duration */
1492  // set the AVCodecContext duration because the duration of individual tracks
1493  // may be inaccurate
1494  if (c->time_scale > 0 && !c->trex_data)
1495  c->fc->duration = av_rescale(c->duration, AV_TIME_BASE, c->time_scale);
1496  avio_rb32(pb); /* preferred scale */
1497 
1498  avio_rb16(pb); /* preferred volume */
1499 
1500  avio_skip(pb, 10); /* reserved */
1501 
1502  /* movie display matrix, store it in main context and use it later on */
1503  for (i = 0; i < 3; i++) {
1504  c->movie_display_matrix[i][0] = avio_rb32(pb); // 16.16 fixed point
1505  c->movie_display_matrix[i][1] = avio_rb32(pb); // 16.16 fixed point
1506  c->movie_display_matrix[i][2] = avio_rb32(pb); // 2.30 fixed point
1507  }
1508 
1509  avio_rb32(pb); /* preview time */
1510  avio_rb32(pb); /* preview duration */
1511  avio_rb32(pb); /* poster time */
1512  avio_rb32(pb); /* selection time */
1513  avio_rb32(pb); /* selection duration */
1514  avio_rb32(pb); /* current time */
1515  avio_rb32(pb); /* next track ID */
1516 
1517  return 0;
1518 }
1519 
1521 {
1522  AVStream *st;
1523  int little_endian;
1524 
1525  if (c->fc->nb_streams < 1)
1526  return 0;
1527  st = c->fc->streams[c->fc->nb_streams-1];
1528 
1529  little_endian = avio_rb16(pb) & 0xFF;
1530  av_log(c->fc, AV_LOG_TRACE, "enda %d\n", little_endian);
1531  if (little_endian == 1) {
1532  switch (st->codecpar->codec_id) {
1533  case AV_CODEC_ID_PCM_S24BE:
1535  break;
1536  case AV_CODEC_ID_PCM_S32BE:
1538  break;
1539  case AV_CODEC_ID_PCM_F32BE:
1541  break;
1542  case AV_CODEC_ID_PCM_F64BE:
1544  break;
1545  default:
1546  break;
1547  }
1548  }
1549  return 0;
1550 }
1551 
1553 {
1554  AVStream *st;
1555  char color_parameter_type[5] = { 0 };
1556  uint16_t color_primaries, color_trc, color_matrix;
1557  int ret;
1558 
1559  if (c->fc->nb_streams < 1)
1560  return 0;
1561  st = c->fc->streams[c->fc->nb_streams - 1];
1562 
1563  ret = ffio_read_size(pb, color_parameter_type, 4);
1564  if (ret < 0)
1565  return ret;
1566  if (strncmp(color_parameter_type, "nclx", 4) &&
1567  strncmp(color_parameter_type, "nclc", 4)) {
1568  av_log(c->fc, AV_LOG_WARNING, "unsupported color_parameter_type %s\n",
1569  color_parameter_type);
1570  return 0;
1571  }
1572 
1573  color_primaries = avio_rb16(pb);
1574  color_trc = avio_rb16(pb);
1575  color_matrix = avio_rb16(pb);
1576 
1577  av_log(c->fc, AV_LOG_TRACE,
1578  "%s: pri %d trc %d matrix %d",
1579  color_parameter_type, color_primaries, color_trc, color_matrix);
1580 
1581  if (!strncmp(color_parameter_type, "nclx", 4)) {
1582  uint8_t color_range = avio_r8(pb) >> 7;
1583  av_log(c->fc, AV_LOG_TRACE, " full %"PRIu8"", color_range);
1584  if (color_range)
1586  else
1588  }
1589 
1592  if (!av_color_transfer_name(color_trc))
1593  color_trc = AVCOL_TRC_UNSPECIFIED;
1594  if (!av_color_space_name(color_matrix))
1595  color_matrix = AVCOL_SPC_UNSPECIFIED;
1596 
1598  st->codecpar->color_trc = color_trc;
1599  st->codecpar->color_space = color_matrix;
1600  av_log(c->fc, AV_LOG_TRACE, "\n");
1601 
1602  return 0;
1603 }
1604 
1606 {
1607  AVStream *st;
1608  unsigned mov_field_order;
1609  enum AVFieldOrder decoded_field_order = AV_FIELD_UNKNOWN;
1610 
1611  if (c->fc->nb_streams < 1) // will happen with jp2 files
1612  return 0;
1613  st = c->fc->streams[c->fc->nb_streams-1];
1614  if (atom.size < 2)
1615  return AVERROR_INVALIDDATA;
1616  mov_field_order = avio_rb16(pb);
1617  if ((mov_field_order & 0xFF00) == 0x0100)
1618  decoded_field_order = AV_FIELD_PROGRESSIVE;
1619  else if ((mov_field_order & 0xFF00) == 0x0200) {
1620  switch (mov_field_order & 0xFF) {
1621  case 0x01: decoded_field_order = AV_FIELD_TT;
1622  break;
1623  case 0x06: decoded_field_order = AV_FIELD_BB;
1624  break;
1625  case 0x09: decoded_field_order = AV_FIELD_TB;
1626  break;
1627  case 0x0E: decoded_field_order = AV_FIELD_BT;
1628  break;
1629  }
1630  }
1631  if (decoded_field_order == AV_FIELD_UNKNOWN && mov_field_order) {
1632  av_log(NULL, AV_LOG_ERROR, "Unknown MOV field order 0x%04x\n", mov_field_order);
1633  }
1634  st->codecpar->field_order = decoded_field_order;
1635 
1636  return 0;
1637 }
1638 
1640 {
1641  int err = 0;
1642  uint64_t size = (uint64_t)par->extradata_size + atom.size + 8 + AV_INPUT_BUFFER_PADDING_SIZE;
1643  if (size > INT_MAX || (uint64_t)atom.size > INT_MAX)
1644  return AVERROR_INVALIDDATA;
1645  if ((err = av_reallocp(&par->extradata, size)) < 0) {
1646  par->extradata_size = 0;
1647  return err;
1648  }
1650  return 0;
1651 }
1652 
1653 /* Read a whole atom into the extradata return the size of the atom read, possibly truncated if != atom.size */
1655  AVCodecParameters *par, uint8_t *buf)
1656 {
1657  int64_t result = atom.size;
1658  int err;
1659 
1660  AV_WB32(buf , atom.size + 8);
1661  AV_WL32(buf + 4, atom.type);
1662  err = ffio_read_size(pb, buf + 8, atom.size);
1663  if (err < 0) {
1664  par->extradata_size -= atom.size;
1665  return err;
1666  } else if (err < atom.size) {
1667  av_log(c->fc, AV_LOG_WARNING, "truncated extradata\n");
1668  par->extradata_size -= atom.size - err;
1669  result = err;
1670  }
1671  memset(buf + 8 + err, 0, AV_INPUT_BUFFER_PADDING_SIZE);
1672  return result;
1673 }
1674 
1675 /* FIXME modify QDM2/SVQ3/H.264 decoders to take full atom as extradata */
1677  enum AVCodecID codec_id)
1678 {
1679  AVStream *st;
1680  uint64_t original_size;
1681  int err;
1682 
1683  if (c->fc->nb_streams < 1) // will happen with jp2 files
1684  return 0;
1685  st = c->fc->streams[c->fc->nb_streams-1];
1686 
1687  if (st->codecpar->codec_id != codec_id)
1688  return 0; /* unexpected codec_id - don't mess with extradata */
1689 
1690  original_size = st->codecpar->extradata_size;
1691  err = mov_realloc_extradata(st->codecpar, atom);
1692  if (err)
1693  return err;
1694 
1695  err = mov_read_atom_into_extradata(c, pb, atom, st->codecpar, st->codecpar->extradata + original_size);
1696  if (err < 0)
1697  return err;
1698  return 0; // Note: this is the original behavior to ignore truncation.
1699 }
1700 
1701 /* wrapper functions for reading ALAC/AVS/MJPEG/MJPEG2000 extradata atoms only for those codecs */
1703 {
1704  return mov_read_extradata(c, pb, atom, AV_CODEC_ID_ALAC);
1705 }
1706 
1708 {
1709  return mov_read_extradata(c, pb, atom, AV_CODEC_ID_AVS);
1710 }
1711 
1713 {
1714  return mov_read_extradata(c, pb, atom, AV_CODEC_ID_JPEG2000);
1715 }
1716 
1718 {
1719  return mov_read_extradata(c, pb, atom, AV_CODEC_ID_R10K);
1720 }
1721 
1723 {
1724  int ret = mov_read_extradata(c, pb, atom, AV_CODEC_ID_AVUI);
1725  if(ret == 0)
1726  ret = mov_read_extradata(c, pb, atom, AV_CODEC_ID_DNXHD);
1727  return ret;
1728 }
1729 
1731 {
1732  int ret = mov_read_extradata(c, pb, atom, AV_CODEC_ID_TARGA_Y216);
1733 
1734  if (!ret && c->fc->nb_streams >= 1) {
1735  AVCodecParameters *par = c->fc->streams[c->fc->nb_streams-1]->codecpar;
1736  if (par->extradata_size >= 40) {
1737  par->height = AV_RB16(&par->extradata[36]);
1738  par->width = AV_RB16(&par->extradata[38]);
1739  }
1740  }
1741  return ret;
1742 }
1743 
1745 {
1746  if (c->fc->nb_streams >= 1) {
1747  AVCodecParameters *par = c->fc->streams[c->fc->nb_streams-1]->codecpar;
1748  if (par->codec_tag == MKTAG('A', 'V', 'i', 'n') &&
1749  par->codec_id == AV_CODEC_ID_H264 &&
1750  atom.size > 11) {
1751  int cid;
1752  avio_skip(pb, 10);
1753  cid = avio_rb16(pb);
1754  /* For AVID AVCI50, force width of 1440 to be able to select the correct SPS and PPS */
1755  if (cid == 0xd4d || cid == 0xd4e)
1756  par->width = 1440;
1757  return 0;
1758  } else if ((par->codec_tag == MKTAG('A', 'V', 'd', '1') ||
1759  par->codec_tag == MKTAG('A', 'V', 'j', '2') ||
1760  par->codec_tag == MKTAG('A', 'V', 'd', 'n')) &&
1761  atom.size >= 24) {
1762  int num, den;
1763  avio_skip(pb, 12);
1764  num = avio_rb32(pb);
1765  den = avio_rb32(pb);
1766  if (num <= 0 || den <= 0)
1767  return 0;
1768  switch (avio_rb32(pb)) {
1769  case 2:
1770  if (den >= INT_MAX / 2)
1771  return 0;
1772  den *= 2;
1773  case 1:
1774  c->fc->streams[c->fc->nb_streams-1]->display_aspect_ratio.num = num;
1775  c->fc->streams[c->fc->nb_streams-1]->display_aspect_ratio.den = den;
1776  default:
1777  return 0;
1778  }
1779  }
1780  }
1781 
1782  return mov_read_avid(c, pb, atom);
1783 }
1784 
1786 {
1787  int ret = 0;
1788  int length = 0;
1789  uint64_t original_size;
1790  if (c->fc->nb_streams >= 1) {
1791  AVCodecParameters *par = c->fc->streams[c->fc->nb_streams-1]->codecpar;
1792  if (par->codec_id == AV_CODEC_ID_H264)
1793  return 0;
1794  if (atom.size == 16) {
1795  original_size = par->extradata_size;
1796  ret = mov_realloc_extradata(par, atom);
1797  if (!ret) {
1798  length = mov_read_atom_into_extradata(c, pb, atom, par, par->extradata + original_size);
1799  if (length == atom.size) {
1800  const uint8_t range_value = par->extradata[original_size + 19];
1801  switch (range_value) {
1802  case 1:
1804  break;
1805  case 2:
1807  break;
1808  default:
1809  av_log(c, AV_LOG_WARNING, "ignored unknown aclr value (%d)\n", range_value);
1810  break;
1811  }
1812  ff_dlog(c, "color_range: %d\n", par->color_range);
1813  } else {
1814  /* For some reason the whole atom was not added to the extradata */
1815  av_log(c, AV_LOG_ERROR, "aclr not decoded - incomplete atom\n");
1816  }
1817  } else {
1818  av_log(c, AV_LOG_ERROR, "aclr not decoded - unable to add atom to extradata\n");
1819  }
1820  } else {
1821  av_log(c, AV_LOG_WARNING, "aclr not decoded - unexpected size %"PRId64"\n", atom.size);
1822  }
1823  }
1824 
1825  return ret;
1826 }
1827 
1829 {
1830  return mov_read_extradata(c, pb, atom, AV_CODEC_ID_SVQ3);
1831 }
1832 
1834 {
1835  AVStream *st;
1836  int ret;
1837 
1838  if (c->fc->nb_streams < 1)
1839  return 0;
1840  st = c->fc->streams[c->fc->nb_streams-1];
1841 
1842  if ((uint64_t)atom.size > (1<<30))
1843  return AVERROR_INVALIDDATA;
1844 
1845  if (st->codecpar->codec_id == AV_CODEC_ID_QDM2 ||
1848  // pass all frma atom to codec, needed at least for QDMC and QDM2
1849  av_freep(&st->codecpar->extradata);
1850  ret = ff_get_extradata(c->fc, st->codecpar, pb, atom.size);
1851  if (ret < 0)
1852  return ret;
1853  } else if (atom.size > 8) { /* to read frma, esds atoms */
1854  if (st->codecpar->codec_id == AV_CODEC_ID_ALAC && atom.size >= 24) {
1855  uint64_t buffer;
1856  ret = ffio_ensure_seekback(pb, 8);
1857  if (ret < 0)
1858  return ret;
1859  buffer = avio_rb64(pb);
1860  atom.size -= 8;
1861  if ( (buffer & 0xFFFFFFFF) == MKBETAG('f','r','m','a')
1862  && buffer >> 32 <= atom.size
1863  && buffer >> 32 >= 8) {
1864  avio_skip(pb, -8);
1865  atom.size += 8;
1866  } else if (!st->codecpar->extradata_size) {
1867 #define ALAC_EXTRADATA_SIZE 36
1869  if (!st->codecpar->extradata)
1870  return AVERROR(ENOMEM);
1873  AV_WB32(st->codecpar->extradata + 4, MKTAG('a','l','a','c'));
1874  AV_WB64(st->codecpar->extradata + 12, buffer);
1875  avio_read(pb, st->codecpar->extradata + 20, 16);
1876  avio_skip(pb, atom.size - 24);
1877  return 0;
1878  }
1879  }
1880  if ((ret = mov_read_default(c, pb, atom)) < 0)
1881  return ret;
1882  } else
1883  avio_skip(pb, atom.size);
1884  return 0;
1885 }
1886 
1887 /**
1888  * This function reads atom content and puts data in extradata without tag
1889  * nor size unlike mov_read_extradata.
1890  */
1892 {
1893  AVStream *st;
1894  int ret;
1895 
1896  if (c->fc->nb_streams < 1)
1897  return 0;
1898  st = c->fc->streams[c->fc->nb_streams-1];
1899 
1900  if ((uint64_t)atom.size > (1<<30))
1901  return AVERROR_INVALIDDATA;
1902 
1903  if (atom.size >= 10) {
1904  // Broken files created by legacy versions of libavformat will
1905  // wrap a whole fiel atom inside of a glbl atom.
1906  unsigned size = avio_rb32(pb);
1907  unsigned type = avio_rl32(pb);
1908  if (avio_feof(pb))
1909  return AVERROR_INVALIDDATA;
1910  avio_seek(pb, -8, SEEK_CUR);
1911  if (type == MKTAG('f','i','e','l') && size == atom.size)
1912  return mov_read_default(c, pb, atom);
1913  }
1914  if (st->codecpar->extradata_size > 1 && st->codecpar->extradata) {
1915  av_log(c, AV_LOG_WARNING, "ignoring multiple glbl\n");
1916  return 0;
1917  }
1918  av_freep(&st->codecpar->extradata);
1919  ret = ff_get_extradata(c->fc, st->codecpar, pb, atom.size);
1920  if (ret < 0)
1921  return ret;
1922  if (atom.type == MKTAG('h','v','c','C') && st->codecpar->codec_tag == MKTAG('d','v','h','1'))
1923  /* HEVC-based Dolby Vision derived from hvc1.
1924  Happens to match with an identifier
1925  previously utilized for DV. Thus, if we have
1926  the hvcC extradata box available as specified,
1927  set codec to HEVC */
1929 
1930  return 0;
1931 }
1932 
1934 {
1935  AVStream *st;
1936  uint8_t profile_level;
1937  int ret;
1938 
1939  if (c->fc->nb_streams < 1)
1940  return 0;
1941  st = c->fc->streams[c->fc->nb_streams-1];
1942 
1943  if (atom.size >= (1<<28) || atom.size < 7)
1944  return AVERROR_INVALIDDATA;
1945 
1946  profile_level = avio_r8(pb);
1947  if ((profile_level & 0xf0) != 0xc0)
1948  return 0;
1949 
1950  avio_seek(pb, 6, SEEK_CUR);
1951  av_freep(&st->codecpar->extradata);
1952  ret = ff_get_extradata(c->fc, st->codecpar, pb, atom.size - 7);
1953  if (ret < 0)
1954  return ret;
1955 
1956  return 0;
1957 }
1958 
1959 /**
1960  * An strf atom is a BITMAPINFOHEADER struct. This struct is 40 bytes itself,
1961  * but can have extradata appended at the end after the 40 bytes belonging
1962  * to the struct.
1963  */
1965 {
1966  AVStream *st;
1967  int ret;
1968 
1969  if (c->fc->nb_streams < 1)
1970  return 0;
1971  if (atom.size <= 40)
1972  return 0;
1973  st = c->fc->streams[c->fc->nb_streams-1];
1974 
1975  if ((uint64_t)atom.size > (1<<30))
1976  return AVERROR_INVALIDDATA;
1977 
1978  avio_skip(pb, 40);
1979  av_freep(&st->codecpar->extradata);
1980  ret = ff_get_extradata(c->fc, st->codecpar, pb, atom.size - 40);
1981  if (ret < 0)
1982  return ret;
1983 
1984  return 0;
1985 }
1986 
1988 {
1989  AVStream *st;
1990  MOVStreamContext *sc;
1991  unsigned int i, entries;
1992 
1993  if (c->trak_index < 0) {
1994  av_log(c->fc, AV_LOG_WARNING, "STCO outside TRAK\n");
1995  return 0;
1996  }
1997  if (c->fc->nb_streams < 1)
1998  return 0;
1999  st = c->fc->streams[c->fc->nb_streams-1];
2000  sc = st->priv_data;
2001 
2002  avio_r8(pb); /* version */
2003  avio_rb24(pb); /* flags */
2004 
2005  entries = avio_rb32(pb);
2006 
2007  if (!entries)
2008  return 0;
2009 
2010  if (sc->chunk_offsets) {
2011  av_log(c->fc, AV_LOG_WARNING, "Ignoring duplicated STCO atom\n");
2012  return 0;
2013  }
2014  av_free(sc->chunk_offsets);
2015  sc->chunk_count = 0;
2016  sc->chunk_offsets = av_malloc_array(entries, sizeof(*sc->chunk_offsets));
2017  if (!sc->chunk_offsets)
2018  return AVERROR(ENOMEM);
2019  sc->chunk_count = entries;
2020 
2021  if (atom.type == MKTAG('s','t','c','o'))
2022  for (i = 0; i < entries && !pb->eof_reached; i++)
2023  sc->chunk_offsets[i] = avio_rb32(pb);
2024  else if (atom.type == MKTAG('c','o','6','4'))
2025  for (i = 0; i < entries && !pb->eof_reached; i++)
2026  sc->chunk_offsets[i] = avio_rb64(pb);
2027  else
2028  return AVERROR_INVALIDDATA;
2029 
2030  sc->chunk_count = i;
2031 
2032  if (pb->eof_reached) {
2033  av_log(c->fc, AV_LOG_WARNING, "reached eof, corrupted STCO atom\n");
2034  return AVERROR_EOF;
2035  }
2036 
2037  return 0;
2038 }
2039 
2040 static int mov_codec_id(AVStream *st, uint32_t format)
2041 {
2043 
2044  if (id <= 0 &&
2045  ((format & 0xFFFF) == 'm' + ('s' << 8) ||
2046  (format & 0xFFFF) == 'T' + ('S' << 8)))
2048 
2049  if (st->codecpar->codec_type != AVMEDIA_TYPE_VIDEO && id > 0) {
2051  } else if (st->codecpar->codec_type != AVMEDIA_TYPE_AUDIO &&
2052  /* skip old ASF MPEG-4 tag */
2053  format && format != MKTAG('m','p','4','s')) {
2055  if (id <= 0)
2057  if (id > 0)
2059  else if (st->codecpar->codec_type == AVMEDIA_TYPE_DATA ||
2061  st->codecpar->codec_id == AV_CODEC_ID_NONE)) {
2063  if (id > 0)
2065  else
2067  }
2068  }
2069 
2070  st->codecpar->codec_tag = format;
2071 
2072  return id;
2073 }
2074 
2076  AVStream *st, MOVStreamContext *sc)
2077 {
2078  uint8_t codec_name[32] = { 0 };
2079  int64_t stsd_start;
2080  unsigned int len;
2081 
2082  /* The first 16 bytes of the video sample description are already
2083  * read in ff_mov_read_stsd_entries() */
2084  stsd_start = avio_tell(pb) - 16;
2085 
2086  avio_rb16(pb); /* version */
2087  avio_rb16(pb); /* revision level */
2088  avio_rb32(pb); /* vendor */
2089  avio_rb32(pb); /* temporal quality */
2090  avio_rb32(pb); /* spatial quality */
2091 
2092  st->codecpar->width = avio_rb16(pb); /* width */
2093  st->codecpar->height = avio_rb16(pb); /* height */
2094 
2095  avio_rb32(pb); /* horiz resolution */
2096  avio_rb32(pb); /* vert resolution */
2097  avio_rb32(pb); /* data size, always 0 */
2098  avio_rb16(pb); /* frames per samples */
2099 
2100  len = avio_r8(pb); /* codec name, pascal string */
2101  if (len > 31)
2102  len = 31;
2103  mov_read_mac_string(c, pb, len, codec_name, sizeof(codec_name));
2104  if (len < 31)
2105  avio_skip(pb, 31 - len);
2106 
2107  if (codec_name[0])
2108  av_dict_set(&st->metadata, "encoder", codec_name, 0);
2109 
2110  /* codec_tag YV12 triggers an UV swap in rawdec.c */
2111  if (!strncmp(codec_name, "Planar Y'CbCr 8-bit 4:2:0", 25)) {
2112  st->codecpar->codec_tag = MKTAG('I', '4', '2', '0');
2113  st->codecpar->width &= ~1;
2114  st->codecpar->height &= ~1;
2115  }
2116  /* Flash Media Server uses tag H.263 with Sorenson Spark */
2117  if (st->codecpar->codec_tag == MKTAG('H','2','6','3') &&
2118  !strncmp(codec_name, "Sorenson H263", 13))
2120 
2121  st->codecpar->bits_per_coded_sample = avio_rb16(pb); /* depth */
2122 
2123  avio_seek(pb, stsd_start, SEEK_SET);
2124 
2125  if (ff_get_qtpalette(st->codecpar->codec_id, pb, sc->palette)) {
2126  st->codecpar->bits_per_coded_sample &= 0x1F;
2127  sc->has_palette = 1;
2128  }
2129 }
2130 
2132  AVStream *st, MOVStreamContext *sc)
2133 {
2134  int bits_per_sample, flags;
2135  uint16_t version = avio_rb16(pb);
2136  AVDictionaryEntry *compatible_brands = av_dict_get(c->fc->metadata, "compatible_brands", NULL, AV_DICT_MATCH_CASE);
2137 
2138  avio_rb16(pb); /* revision level */
2139  avio_rb32(pb); /* vendor */
2140 
2141  st->codecpar->channels = avio_rb16(pb); /* channel count */
2142  st->codecpar->bits_per_coded_sample = avio_rb16(pb); /* sample size */
2143  av_log(c->fc, AV_LOG_TRACE, "audio channels %d\n", st->codecpar->channels);
2144 
2145  sc->audio_cid = avio_rb16(pb);
2146  avio_rb16(pb); /* packet size = 0 */
2147 
2148  st->codecpar->sample_rate = ((avio_rb32(pb) >> 16));
2149 
2150  // Read QT version 1 fields. In version 0 these do not exist.
2151  av_log(c->fc, AV_LOG_TRACE, "version =%d, isom =%d\n", version, c->isom);
2152  if (!c->isom ||
2153  (compatible_brands && strstr(compatible_brands->value, "qt ")) ||
2154  (sc->stsd_version == 0 && version > 0)) {
2155  if (version == 1) {
2156  sc->samples_per_frame = avio_rb32(pb);
2157  avio_rb32(pb); /* bytes per packet */
2158  sc->bytes_per_frame = avio_rb32(pb);
2159  avio_rb32(pb); /* bytes per sample */
2160  } else if (version == 2) {
2161  avio_rb32(pb); /* sizeof struct only */
2163  st->codecpar->channels = avio_rb32(pb);
2164  avio_rb32(pb); /* always 0x7F000000 */
2166 
2167  flags = avio_rb32(pb); /* lpcm format specific flag */
2168  sc->bytes_per_frame = avio_rb32(pb);
2169  sc->samples_per_frame = avio_rb32(pb);
2170  if (st->codecpar->codec_tag == MKTAG('l','p','c','m'))
2171  st->codecpar->codec_id =
2173  flags);
2174  }
2175  if (version == 0 || (version == 1 && sc->audio_cid != -2)) {
2176  /* can't correctly handle variable sized packet as audio unit */
2177  switch (st->codecpar->codec_id) {
2178  case AV_CODEC_ID_MP2:
2179  case AV_CODEC_ID_MP3:
2181  break;
2182  }
2183  }
2184  }
2185 
2186  if (sc->format == 0) {
2187  if (st->codecpar->bits_per_coded_sample == 8)
2188  st->codecpar->codec_id = mov_codec_id(st, MKTAG('r','a','w',' '));
2189  else if (st->codecpar->bits_per_coded_sample == 16)
2190  st->codecpar->codec_id = mov_codec_id(st, MKTAG('t','w','o','s'));
2191  }
2192 
2193  switch (st->codecpar->codec_id) {
2194  case AV_CODEC_ID_PCM_S8:
2195  case AV_CODEC_ID_PCM_U8:
2196  if (st->codecpar->bits_per_coded_sample == 16)
2198  break;
2199  case AV_CODEC_ID_PCM_S16LE:
2200  case AV_CODEC_ID_PCM_S16BE:
2201  if (st->codecpar->bits_per_coded_sample == 8)
2203  else if (st->codecpar->bits_per_coded_sample == 24)
2204  st->codecpar->codec_id =
2207  else if (st->codecpar->bits_per_coded_sample == 32)
2208  st->codecpar->codec_id =
2211  break;
2212  /* set values for old format before stsd version 1 appeared */
2213  case AV_CODEC_ID_MACE3:
2214  sc->samples_per_frame = 6;
2215  sc->bytes_per_frame = 2 * st->codecpar->channels;
2216  break;
2217  case AV_CODEC_ID_MACE6:
2218  sc->samples_per_frame = 6;
2219  sc->bytes_per_frame = 1 * st->codecpar->channels;
2220  break;
2222  sc->samples_per_frame = 64;
2223  sc->bytes_per_frame = 34 * st->codecpar->channels;
2224  break;
2225  case AV_CODEC_ID_GSM:
2226  sc->samples_per_frame = 160;
2227  sc->bytes_per_frame = 33;
2228  break;
2229  default:
2230  break;
2231  }
2232 
2233  bits_per_sample = av_get_bits_per_sample(st->codecpar->codec_id);
2234  if (bits_per_sample && (bits_per_sample >> 3) * (uint64_t)st->codecpar->channels <= INT_MAX) {
2235  st->codecpar->bits_per_coded_sample = bits_per_sample;
2236  sc->sample_size = (bits_per_sample >> 3) * st->codecpar->channels;
2237  }
2238 }
2239 
2241  AVStream *st, MOVStreamContext *sc,
2242  int64_t size)
2243 {
2244  // ttxt stsd contains display flags, justification, background
2245  // color, fonts, and default styles, so fake an atom to read it
2246  MOVAtom fake_atom = { .size = size };
2247  // mp4s contains a regular esds atom
2248  if (st->codecpar->codec_tag != AV_RL32("mp4s"))
2249  mov_read_glbl(c, pb, fake_atom);
2250  st->codecpar->width = sc->width;
2251  st->codecpar->height = sc->height;
2252 }
2253 
2254 static uint32_t yuv_to_rgba(uint32_t ycbcr)
2255 {
2256  uint8_t r, g, b;
2257  int y, cb, cr;
2258 
2259  y = (ycbcr >> 16) & 0xFF;
2260  cr = (ycbcr >> 8) & 0xFF;
2261  cb = ycbcr & 0xFF;
2262 
2263  b = av_clip_uint8((1164 * (y - 16) + 2018 * (cb - 128)) / 1000);
2264  g = av_clip_uint8((1164 * (y - 16) - 813 * (cr - 128) - 391 * (cb - 128)) / 1000);
2265  r = av_clip_uint8((1164 * (y - 16) + 1596 * (cr - 128) ) / 1000);
2266 
2267  return (r << 16) | (g << 8) | b;
2268 }
2269 
2271 {
2272  char buf[256] = {0};
2273  uint8_t *src = st->codecpar->extradata;
2274  int i;
2275 
2276  if (st->codecpar->extradata_size != 64)
2277  return 0;
2278 
2279  if (st->codecpar->width > 0 && st->codecpar->height > 0)
2280  snprintf(buf, sizeof(buf), "size: %dx%d\n",
2281  st->codecpar->width, st->codecpar->height);
2282  av_strlcat(buf, "palette: ", sizeof(buf));
2283 
2284  for (i = 0; i < 16; i++) {
2285  uint32_t yuv = AV_RB32(src + i * 4);
2286  uint32_t rgba = yuv_to_rgba(yuv);
2287 
2288  av_strlcatf(buf, sizeof(buf), "%06"PRIx32"%s", rgba, i != 15 ? ", " : "");
2289  }
2290 
2291  if (av_strlcat(buf, "\n", sizeof(buf)) >= sizeof(buf))
2292  return 0;
2293 
2294  av_freep(&st->codecpar->extradata);
2295  st->codecpar->extradata_size = 0;
2297  if (!st->codecpar->extradata)
2298  return AVERROR(ENOMEM);
2299  st->codecpar->extradata_size = strlen(buf);
2300  memcpy(st->codecpar->extradata, buf, st->codecpar->extradata_size);
2301 
2302  return 0;
2303 }
2304 
2306  AVStream *st, MOVStreamContext *sc,
2307  int64_t size)
2308 {
2309  int ret;
2310 
2311  if (st->codecpar->codec_tag == MKTAG('t','m','c','d')) {
2312  if ((int)size != size)
2313  return AVERROR(ENOMEM);
2314 
2315  ret = ff_get_extradata(c->fc, st->codecpar, pb, size);
2316  if (ret < 0)
2317  return ret;
2318  if (size > 16) {
2319  MOVStreamContext *tmcd_ctx = st->priv_data;
2320  int val;
2321  val = AV_RB32(st->codecpar->extradata + 4);
2322  tmcd_ctx->tmcd_flags = val;
2323  st->avg_frame_rate.num = st->codecpar->extradata[16]; /* number of frame */
2324  st->avg_frame_rate.den = 1;
2325 #if FF_API_LAVF_AVCTX
2327  st->codec->time_base = av_inv_q(st->avg_frame_rate);
2329 #endif
2330  /* adjust for per frame dur in counter mode */
2331  if (tmcd_ctx->tmcd_flags & 0x0008) {
2332  int timescale = AV_RB32(st->codecpar->extradata + 8);
2333  int framedur = AV_RB32(st->codecpar->extradata + 12);
2334  st->avg_frame_rate = av_mul_q(st->avg_frame_rate, (AVRational){timescale, framedur});
2335 #if FF_API_LAVF_AVCTX
2337  st->codec->time_base = av_mul_q(st->codec->time_base , (AVRational){framedur, timescale});
2339 #endif
2340  }
2341  if (size > 30) {
2342  uint32_t len = AV_RB32(st->codecpar->extradata + 18); /* name atom length */
2343  uint32_t format = AV_RB32(st->codecpar->extradata + 22);
2344  if (format == AV_RB32("name") && (int64_t)size >= (int64_t)len + 18) {
2345  uint16_t str_size = AV_RB16(st->codecpar->extradata + 26); /* string length */
2346  if (str_size > 0 && size >= (int)str_size + 30) {
2347  char *reel_name = av_malloc(str_size + 1);
2348  if (!reel_name)
2349  return AVERROR(ENOMEM);
2350  memcpy(reel_name, st->codecpar->extradata + 30, str_size);
2351  reel_name[str_size] = 0; /* Add null terminator */
2352  /* don't add reel_name if emtpy string */
2353  if (*reel_name == 0) {
2354  av_free(reel_name);
2355  } else {
2356  av_dict_set(&st->metadata, "reel_name", reel_name, AV_DICT_DONT_STRDUP_VAL);
2357  }
2358  }
2359  }
2360  }
2361  }
2362  } else {
2363  /* other codec type, just skip (rtp, mp4s ...) */
2364  avio_skip(pb, size);
2365  }
2366  return 0;
2367 }
2368 
2370  AVStream *st, MOVStreamContext *sc)
2371 {
2372  if (st->codecpar->codec_type == AVMEDIA_TYPE_AUDIO &&
2373  !st->codecpar->sample_rate && sc->time_scale > 1)
2374  st->codecpar->sample_rate = sc->time_scale;
2375 
2376  /* special codec parameters handling */
2377  switch (st->codecpar->codec_id) {
2378 #if CONFIG_DV_DEMUXER
2379  case AV_CODEC_ID_DVAUDIO:
2380  c->dv_fctx = avformat_alloc_context();
2381  if (!c->dv_fctx) {
2382  av_log(c->fc, AV_LOG_ERROR, "dv demux context alloc error\n");
2383  return AVERROR(ENOMEM);
2384  }
2385  c->dv_demux = avpriv_dv_init_demux(c->dv_fctx);
2386  if (!c->dv_demux) {
2387  av_log(c->fc, AV_LOG_ERROR, "dv demux context init error\n");
2388  return AVERROR(ENOMEM);
2389  }
2390  sc->dv_audio_container = 1;
2392  break;
2393 #endif
2394  /* no ifdef since parameters are always those */
2395  case AV_CODEC_ID_QCELP:
2396  st->codecpar->channels = 1;
2397  // force sample rate for qcelp when not stored in mov
2398  if (st->codecpar->codec_tag != MKTAG('Q','c','l','p'))
2399  st->codecpar->sample_rate = 8000;
2400  // FIXME: Why is the following needed for some files?
2401  sc->samples_per_frame = 160;
2402  if (!sc->bytes_per_frame)
2403  sc->bytes_per_frame = 35;
2404  break;
2405  case AV_CODEC_ID_AMR_NB:
2406  st->codecpar->channels = 1;
2407  /* force sample rate for amr, stsd in 3gp does not store sample rate */
2408  st->codecpar->sample_rate = 8000;
2409  break;
2410  case AV_CODEC_ID_AMR_WB:
2411  st->codecpar->channels = 1;
2412  st->codecpar->sample_rate = 16000;
2413  break;
2414  case AV_CODEC_ID_MP2:
2415  case AV_CODEC_ID_MP3:
2416  /* force type after stsd for m1a hdlr */
2418  break;
2419  case AV_CODEC_ID_GSM:
2420  case AV_CODEC_ID_ADPCM_MS:
2422  case AV_CODEC_ID_ILBC:
2423  case AV_CODEC_ID_MACE3:
2424  case AV_CODEC_ID_MACE6:
2425  case AV_CODEC_ID_QDM2:
2427  break;
2428  case AV_CODEC_ID_ALAC:
2429  if (st->codecpar->extradata_size == 36) {
2430  st->codecpar->channels = AV_RB8 (st->codecpar->extradata + 21);
2431  st->codecpar->sample_rate = AV_RB32(st->codecpar->extradata + 32);
2432  }
2433  break;
2434  case AV_CODEC_ID_AC3:
2435  case AV_CODEC_ID_EAC3:
2437  case AV_CODEC_ID_VC1:
2438  case AV_CODEC_ID_VP8:
2439  case AV_CODEC_ID_VP9:
2441  break;
2442  default:
2443  break;
2444  }
2445  return 0;
2446 }
2447 
2449  int codec_tag, int format,
2450  int64_t size)
2451 {
2452  int video_codec_id = ff_codec_get_id(ff_codec_movvideo_tags, format);
2453 
2454  if (codec_tag &&
2455  (codec_tag != format &&
2456  // AVID 1:1 samples with differing data format and codec tag exist
2457  (codec_tag != AV_RL32("AV1x") || format != AV_RL32("AVup")) &&
2458  // prores is allowed to have differing data format and codec tag
2459  codec_tag != AV_RL32("apcn") && codec_tag != AV_RL32("apch") &&
2460  // so is dv (sigh)
2461  codec_tag != AV_RL32("dvpp") && codec_tag != AV_RL32("dvcp") &&
2462  (c->fc->video_codec_id ? video_codec_id != c->fc->video_codec_id
2463  : codec_tag != MKTAG('j','p','e','g')))) {
2464  /* Multiple fourcc, we skip JPEG. This is not correct, we should
2465  * export it as a separate AVStream but this needs a few changes
2466  * in the MOV demuxer, patch welcome. */
2467 
2468  av_log(c->fc, AV_LOG_WARNING, "multiple fourcc not supported\n");
2469  avio_skip(pb, size);
2470  return 1;
2471  }
2472 
2473  return 0;
2474 }
2475 
2477 {
2478  AVStream *st;
2479  MOVStreamContext *sc;
2480  int pseudo_stream_id;
2481 
2482  av_assert0 (c->fc->nb_streams >= 1);
2483  st = c->fc->streams[c->fc->nb_streams-1];
2484  sc = st->priv_data;
2485 
2486  for (pseudo_stream_id = 0;
2487  pseudo_stream_id < entries && !pb->eof_reached;
2488  pseudo_stream_id++) {
2489  //Parsing Sample description table
2490  enum AVCodecID id;
2491  int ret, dref_id = 1;
2492  MOVAtom a = { AV_RL32("stsd") };
2493  int64_t start_pos = avio_tell(pb);
2494  int64_t size = avio_rb32(pb); /* size */
2495  uint32_t format = avio_rl32(pb); /* data format */
2496 
2497  if (size >= 16) {
2498  avio_rb32(pb); /* reserved */
2499  avio_rb16(pb); /* reserved */
2500  dref_id = avio_rb16(pb);
2501  } else if (size <= 7) {
2502  av_log(c->fc, AV_LOG_ERROR,
2503  "invalid size %"PRId64" in stsd\n", size);
2504  return AVERROR_INVALIDDATA;
2505  }
2506 
2508  size - (avio_tell(pb) - start_pos))) {
2509  sc->stsd_count++;
2510  continue;
2511  }
2512 
2513  sc->pseudo_stream_id = st->codecpar->codec_tag ? -1 : pseudo_stream_id;
2514  sc->dref_id= dref_id;
2515  sc->format = format;
2516 
2517  id = mov_codec_id(st, format);
2518 
2519  av_log(c->fc, AV_LOG_TRACE,
2520  "size=%"PRId64" 4CC=%s codec_type=%d\n", size,
2522 
2523  st->codecpar->codec_id = id;
2525  mov_parse_stsd_video(c, pb, st, sc);
2526  } else if (st->codecpar->codec_type==AVMEDIA_TYPE_AUDIO) {
2527  mov_parse_stsd_audio(c, pb, st, sc);
2528  if (st->codecpar->sample_rate < 0) {
2529  av_log(c->fc, AV_LOG_ERROR, "Invalid sample rate %d\n", st->codecpar->sample_rate);
2530  return AVERROR_INVALIDDATA;
2531  }
2532  if (st->codecpar->channels < 0) {
2533  av_log(c->fc, AV_LOG_ERROR, "Invalid channels %d\n", st->codecpar->channels);
2534  return AVERROR_INVALIDDATA;
2535  }
2536  } else if (st->codecpar->codec_type==AVMEDIA_TYPE_SUBTITLE){
2537  mov_parse_stsd_subtitle(c, pb, st, sc,
2538  size - (avio_tell(pb) - start_pos));
2539  } else {
2540  ret = mov_parse_stsd_data(c, pb, st, sc,
2541  size - (avio_tell(pb) - start_pos));
2542  if (ret < 0)
2543  return ret;
2544  }
2545  /* this will read extra atoms at the end (wave, alac, damr, avcC, hvcC, SMI ...) */
2546  a.size = size - (avio_tell(pb) - start_pos);
2547  if (a.size > 8) {
2548  if ((ret = mov_read_default(c, pb, a)) < 0)
2549  return ret;
2550  } else if (a.size > 0)
2551  avio_skip(pb, a.size);
2552 
2553  if (sc->extradata && st->codecpar->extradata) {
2554  int extra_size = st->codecpar->extradata_size;
2555 
2556  /* Move the current stream extradata to the stream context one. */
2557  sc->extradata_size[pseudo_stream_id] = extra_size;
2558  sc->extradata[pseudo_stream_id] = av_malloc(extra_size + AV_INPUT_BUFFER_PADDING_SIZE);
2559  if (!sc->extradata[pseudo_stream_id])
2560  return AVERROR(ENOMEM);
2561  memcpy(sc->extradata[pseudo_stream_id], st->codecpar->extradata, extra_size);
2562  av_freep(&st->codecpar->extradata);
2563  st->codecpar->extradata_size = 0;
2564  }
2565  sc->stsd_count++;
2566  }
2567 
2568  if (pb->eof_reached) {
2569  av_log(c->fc, AV_LOG_WARNING, "reached eof, corrupted STSD atom\n");
2570  return AVERROR_EOF;
2571  }
2572 
2573  return 0;
2574 }
2575 
2577 {
2578  AVStream *st;
2579  MOVStreamContext *sc;
2580  int ret, entries;
2581 
2582  if (c->fc->nb_streams < 1)
2583  return 0;
2584  st = c->fc->streams[c->fc->nb_streams - 1];
2585  sc = st->priv_data;
2586 
2587  sc->stsd_version = avio_r8(pb);
2588  avio_rb24(pb); /* flags */
2589  entries = avio_rb32(pb);
2590 
2591  /* Each entry contains a size (4 bytes) and format (4 bytes). */
2592  if (entries <= 0 || entries > atom.size / 8) {
2593  av_log(c->fc, AV_LOG_ERROR, "invalid STSD entries %d\n", entries);
2594  return AVERROR_INVALIDDATA;
2595  }
2596 
2597  if (sc->extradata) {
2598  av_log(c->fc, AV_LOG_ERROR,
2599  "Duplicate stsd found in this track.\n");
2600  return AVERROR_INVALIDDATA;
2601  }
2602 
2603  /* Prepare space for hosting multiple extradata. */
2604  sc->extradata = av_mallocz_array(entries, sizeof(*sc->extradata));
2605  if (!sc->extradata)
2606  return AVERROR(ENOMEM);
2607 
2608  sc->extradata_size = av_mallocz_array(entries, sizeof(*sc->extradata_size));
2609  if (!sc->extradata_size) {
2610  ret = AVERROR(ENOMEM);
2611  goto fail;
2612  }
2613 
2614  ret = ff_mov_read_stsd_entries(c, pb, entries);
2615  if (ret < 0)
2616  goto fail;
2617 
2618  /* Restore back the primary extradata. */
2619  av_freep(&st->codecpar->extradata);
2620  st->codecpar->extradata_size = sc->extradata_size[0];
2621  if (sc->extradata_size[0]) {
2623  if (!st->codecpar->extradata)
2624  return AVERROR(ENOMEM);
2625  memcpy(st->codecpar->extradata, sc->extradata[0], sc->extradata_size[0]);
2626  }
2627 
2628  return mov_finalize_stsd_codec(c, pb, st, sc);
2629 fail:
2630  if (sc->extradata) {
2631  int j;
2632  for (j = 0; j < sc->stsd_count; j++)
2633  av_freep(&sc->extradata[j]);
2634  }
2635 
2636  av_freep(&sc->extradata);
2637  av_freep(&sc->extradata_size);
2638  return ret;
2639 }
2640 
2642 {
2643  AVStream *st;
2644  MOVStreamContext *sc;
2645  unsigned int i, entries;
2646 
2647  if (c->fc->nb_streams < 1)
2648  return 0;
2649  st = c->fc->streams[c->fc->nb_streams-1];
2650  sc = st->priv_data;
2651 
2652  avio_r8(pb); /* version */
2653  avio_rb24(pb); /* flags */
2654 
2655  entries = avio_rb32(pb);
2656  if ((uint64_t)entries * 12 + 4 > atom.size)
2657  return AVERROR_INVALIDDATA;
2658 
2659  av_log(c->fc, AV_LOG_TRACE, "track[%u].stsc.entries = %u\n", c->fc->nb_streams - 1, entries);
2660 
2661  if (!entries)
2662  return 0;
2663  if (sc->stsc_data) {
2664  av_log(c->fc, AV_LOG_WARNING, "Ignoring duplicated STSC atom\n");
2665  return 0;
2666  }
2667  av_free(sc->stsc_data);
2668  sc->stsc_count = 0;
2669  sc->stsc_data = av_malloc_array(entries, sizeof(*sc->stsc_data));
2670  if (!sc->stsc_data)
2671  return AVERROR(ENOMEM);
2672 
2673  for (i = 0; i < entries && !pb->eof_reached; i++) {
2674  sc->stsc_data[i].first = avio_rb32(pb);
2675  sc->stsc_data[i].count = avio_rb32(pb);
2676  sc->stsc_data[i].id = avio_rb32(pb);
2677  }
2678 
2679  sc->stsc_count = i;
2680  for (i = sc->stsc_count - 1; i < UINT_MAX; i--) {
2681  int64_t first_min = i + 1;
2682  if ((i+1 < sc->stsc_count && sc->stsc_data[i].first >= sc->stsc_data[i+1].first) ||
2683  (i > 0 && sc->stsc_data[i].first <= sc->stsc_data[i-1].first) ||
2684  sc->stsc_data[i].first < first_min ||
2685  sc->stsc_data[i].count < 1 ||
2686  sc->stsc_data[i].id < 1) {
2687  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);
2688  if (i+1 >= sc->stsc_count) {
2689  sc->stsc_data[i].first = FFMAX(sc->stsc_data[i].first, first_min);
2690  if (i > 0 && sc->stsc_data[i].first <= sc->stsc_data[i-1].first)
2691  sc->stsc_data[i].first = FFMIN(sc->stsc_data[i-1].first + 1LL, INT_MAX);
2692  sc->stsc_data[i].count = FFMAX(sc->stsc_data[i].count, 1);
2693  sc->stsc_data[i].id = FFMAX(sc->stsc_data[i].id, 1);
2694  continue;
2695  }
2696  av_assert0(sc->stsc_data[i+1].first >= 2);
2697  // We replace this entry by the next valid
2698  sc->stsc_data[i].first = sc->stsc_data[i+1].first - 1;
2699  sc->stsc_data[i].count = sc->stsc_data[i+1].count;
2700  sc->stsc_data[i].id = sc->stsc_data[i+1].id;
2701  }
2702  }
2703 
2704  if (pb->eof_reached) {
2705  av_log(c->fc, AV_LOG_WARNING, "reached eof, corrupted STSC atom\n");
2706  return AVERROR_EOF;
2707  }
2708 
2709  return 0;
2710 }
2711 
2712 static inline int mov_stsc_index_valid(unsigned int index, unsigned int count)
2713 {
2714  return index < count - 1;
2715 }
2716 
2717 /* Compute the samples value for the stsc entry at the given index. */
2718 static inline int64_t mov_get_stsc_samples(MOVStreamContext *sc, unsigned int index)
2719 {
2720  int chunk_count;
2721 
2723  chunk_count = sc->stsc_data[index + 1].first - sc->stsc_data[index].first;
2724  else {
2725  // Validation for stsc / stco happens earlier in mov_read_stsc + mov_read_trak.
2727  chunk_count = sc->chunk_count - (sc->stsc_data[index].first - 1);
2728  }
2729 
2730  return sc->stsc_data[index].count * (int64_t)chunk_count;
2731 }
2732 
2734 {
2735  AVStream *st;
2736  MOVStreamContext *sc;
2737  unsigned i, entries;
2738 
2739  if (c->fc->nb_streams < 1)
2740  return 0;
2741  st = c->fc->streams[c->fc->nb_streams-1];
2742  sc = st->priv_data;
2743 
2744  avio_rb32(pb); // version + flags
2745 
2746  entries = avio_rb32(pb);
2747  if (sc->stps_data)
2748  av_log(c->fc, AV_LOG_WARNING, "Duplicated STPS atom\n");
2749  av_free(sc->stps_data);
2750  sc->stps_count = 0;
2751  sc->stps_data = av_malloc_array(entries, sizeof(*sc->stps_data));
2752  if (!sc->stps_data)
2753  return AVERROR(ENOMEM);
2754 
2755  for (i = 0; i < entries && !pb->eof_reached; i++) {
2756  sc->stps_data[i] = avio_rb32(pb);
2757  }
2758 
2759  sc->stps_count = i;
2760 
2761  if (pb->eof_reached) {
2762  av_log(c->fc, AV_LOG_WARNING, "reached eof, corrupted STPS atom\n");
2763  return AVERROR_EOF;
2764  }
2765 
2766  return 0;
2767 }
2768 
2770 {
2771  AVStream *st;
2772  MOVStreamContext *sc;
2773  unsigned int i, entries;
2774 
2775  if (c->fc->nb_streams < 1)
2776  return 0;
2777  st = c->fc->streams[c->fc->nb_streams-1];
2778  sc = st->priv_data;
2779 
2780  avio_r8(pb); /* version */
2781  avio_rb24(pb); /* flags */
2782 
2783  entries = avio_rb32(pb);
2784 
2785  av_log(c->fc, AV_LOG_TRACE, "keyframe_count = %u\n", entries);
2786 
2787  if (!entries)
2788  {
2789  sc->keyframe_absent = 1;
2790  if (!st->need_parsing && st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO)
2792  return 0;
2793  }
2794  if (sc->keyframes)
2795  av_log(c->fc, AV_LOG_WARNING, "Duplicated STSS atom\n");
2796  if (entries >= UINT_MAX / sizeof(int))
2797  return AVERROR_INVALIDDATA;
2798  av_freep(&sc->keyframes);
2799  sc->keyframe_count = 0;
2800  sc->keyframes = av_malloc_array(entries, sizeof(*sc->keyframes));
2801  if (!sc->keyframes)
2802  return AVERROR(ENOMEM);
2803 
2804  for (i = 0; i < entries && !pb->eof_reached; i++) {
2805  sc->keyframes[i] = avio_rb32(pb);
2806  }
2807 
2808  sc->keyframe_count = i;
2809 
2810  if (pb->eof_reached) {
2811  av_log(c->fc, AV_LOG_WARNING, "reached eof, corrupted STSS atom\n");
2812  return AVERROR_EOF;
2813  }
2814 
2815  return 0;
2816 }
2817 
2819 {
2820  AVStream *st;
2821  MOVStreamContext *sc;
2822  unsigned int i, entries, sample_size, field_size, num_bytes;
2823  GetBitContext gb;
2824  unsigned char* buf;
2825  int ret;
2826 
2827  if (c->fc->nb_streams < 1)
2828  return 0;
2829  st = c->fc->streams[c->fc->nb_streams-1];
2830  sc = st->priv_data;
2831 
2832  avio_r8(pb); /* version */
2833  avio_rb24(pb); /* flags */
2834 
2835  if (atom.type == MKTAG('s','t','s','z')) {
2836  sample_size = avio_rb32(pb);
2837  if (!sc->sample_size) /* do not overwrite value computed in stsd */
2838  sc->sample_size = sample_size;
2839  sc->stsz_sample_size = sample_size;
2840  field_size = 32;
2841  } else {
2842  sample_size = 0;
2843  avio_rb24(pb); /* reserved */
2844  field_size = avio_r8(pb);
2845  }
2846  entries = avio_rb32(pb);
2847 
2848  av_log(c->fc, AV_LOG_TRACE, "sample_size = %u sample_count = %u\n", sc->sample_size, entries);
2849 
2850  sc->sample_count = entries;
2851  if (sample_size)
2852  return 0;
2853 
2854  if (field_size != 4 && field_size != 8 && field_size != 16 && field_size != 32) {
2855  av_log(c->fc, AV_LOG_ERROR, "Invalid sample field size %u\n", field_size);
2856  return AVERROR_INVALIDDATA;
2857  }
2858 
2859  if (!entries)
2860  return 0;
2861  if (entries >= (UINT_MAX - 4) / field_size)
2862  return AVERROR_INVALIDDATA;
2863  if (sc->sample_sizes)
2864  av_log(c->fc, AV_LOG_WARNING, "Duplicated STSZ atom\n");
2865  av_free(sc->sample_sizes);
2866  sc->sample_count = 0;
2867  sc->sample_sizes = av_malloc_array(entries, sizeof(*sc->sample_sizes));
2868  if (!sc->sample_sizes)
2869  return AVERROR(ENOMEM);
2870 
2871  num_bytes = (entries*field_size+4)>>3;
2872 
2874  if (!buf) {
2875  av_freep(&sc->sample_sizes);
2876  return AVERROR(ENOMEM);
2877  }
2878 
2879  ret = ffio_read_size(pb, buf, num_bytes);
2880  if (ret < 0) {
2881  av_freep(&sc->sample_sizes);
2882  av_free(buf);
2883  av_log(c->fc, AV_LOG_WARNING, "STSZ atom truncated\n");
2884  return 0;
2885  }
2886 
2887  init_get_bits(&gb, buf, 8*num_bytes);
2888 
2889  for (i = 0; i < entries && !pb->eof_reached; i++) {
2890  sc->sample_sizes[i] = get_bits_long(&gb, field_size);
2891  if (sc->sample_sizes[i] < 0) {
2892  av_free(buf);
2893  av_log(c->fc, AV_LOG_ERROR, "Invalid sample size %d\n", sc->sample_sizes[i]);
2894  return AVERROR_INVALIDDATA;
2895  }
2896  sc->data_size += sc->sample_sizes[i];
2897  }
2898 
2899  sc->sample_count = i;
2900 
2901  av_free(buf);
2902 
2903  if (pb->eof_reached) {
2904  av_log(c->fc, AV_LOG_WARNING, "reached eof, corrupted STSZ atom\n");
2905  return AVERROR_EOF;
2906  }
2907 
2908  return 0;
2909 }
2910 
2912 {
2913  AVStream *st;
2914  MOVStreamContext *sc;
2915  unsigned int i, entries, alloc_size = 0;
2916  int64_t duration=0;
2917  int64_t total_sample_count=0;
2918 
2919  if (c->fc->nb_streams < 1)
2920  return 0;
2921  st = c->fc->streams[c->fc->nb_streams-1];
2922  sc = st->priv_data;
2923 
2924  avio_r8(pb); /* version */
2925  avio_rb24(pb); /* flags */
2926  entries = avio_rb32(pb);
2927 
2928  av_log(c->fc, AV_LOG_TRACE, "track[%u].stts.entries = %u\n",
2929  c->fc->nb_streams-1, entries);
2930 
2931  if (sc->stts_data)
2932  av_log(c->fc, AV_LOG_WARNING, "Duplicated STTS atom\n");
2933  av_freep(&sc->stts_data);
2934  sc->stts_count = 0;
2935  if (entries >= INT_MAX / sizeof(*sc->stts_data))
2936  return AVERROR(ENOMEM);
2937 
2938  for (i = 0; i < entries && !pb->eof_reached; i++) {
2939  int sample_duration;
2940  unsigned int sample_count;
2941  unsigned int min_entries = FFMIN(FFMAX(i + 1, 1024 * 1024), entries);
2942  MOVStts *stts_data = av_fast_realloc(sc->stts_data, &alloc_size,
2943  min_entries * sizeof(*sc->stts_data));
2944  if (!stts_data) {
2945  av_freep(&sc->stts_data);
2946  sc->stts_count = 0;
2947  return AVERROR(ENOMEM);
2948  }
2949  sc->stts_count = min_entries;
2950  sc->stts_data = stts_data;
2951 
2952  sample_count=avio_rb32(pb);
2953  sample_duration = avio_rb32(pb);
2954 
2955  sc->stts_data[i].count= sample_count;
2956  sc->stts_data[i].duration= sample_duration;
2957 
2958  av_log(c->fc, AV_LOG_TRACE, "sample_count=%d, sample_duration=%d\n",
2959  sample_count, sample_duration);
2960 
2961  duration+=(int64_t)sample_duration*(uint64_t)sample_count;
2962  total_sample_count+=sample_count;
2963  }
2964 
2965  sc->stts_count = i;
2966 
2967  if (duration > 0 &&
2968  duration <= INT64_MAX - sc->duration_for_fps &&
2969  total_sample_count <= INT_MAX - sc->nb_frames_for_fps
2970  ) {
2971  sc->duration_for_fps += duration;
2972  sc->nb_frames_for_fps += total_sample_count;
2973  }
2974 
2975  if (pb->eof_reached) {
2976  av_log(c->fc, AV_LOG_WARNING, "reached eof, corrupted STTS atom\n");
2977  return AVERROR_EOF;
2978  }
2979 
2980  st->nb_frames= total_sample_count;
2981  if (duration)
2982  st->duration= FFMIN(st->duration, duration);
2983  sc->track_end = duration;
2984  return 0;
2985 }
2986 
2988 {
2989  if (duration < 0) {
2990  if (duration == INT_MIN) {
2991  av_log(NULL, AV_LOG_WARNING, "mov_update_dts_shift(): dts_shift set to %d\n", INT_MAX);
2992  duration++;
2993  }
2994  sc->dts_shift = FFMAX(sc->dts_shift, -duration);
2995  }
2996 }
2997 
2999 {
3000  AVStream *st;
3001  MOVStreamContext *sc;
3002  unsigned int i, entries, ctts_count = 0;
3003 
3004  if (c->fc->nb_streams < 1)
3005  return 0;
3006  st = c->fc->streams[c->fc->nb_streams-1];
3007  sc = st->priv_data;
3008 
3009  avio_r8(pb); /* version */
3010  avio_rb24(pb); /* flags */
3011  entries = avio_rb32(pb);
3012 
3013  av_log(c->fc, AV_LOG_TRACE, "track[%u].ctts.entries = %u\n", c->fc->nb_streams - 1, entries);
3014 
3015  if (!entries)
3016  return 0;
3017  if (entries >= UINT_MAX / sizeof(*sc->ctts_data))
3018  return AVERROR_INVALIDDATA;
3019  av_freep(&sc->ctts_data);
3020  sc->ctts_data = av_fast_realloc(NULL, &sc->ctts_allocated_size, entries * sizeof(*sc->ctts_data));
3021  if (!sc->ctts_data)
3022  return AVERROR(ENOMEM);
3023 
3024  for (i = 0; i < entries && !pb->eof_reached; i++) {
3025  int count =avio_rb32(pb);
3026  int duration =avio_rb32(pb);
3027 
3028  if (count <= 0) {
3029  av_log(c->fc, AV_LOG_TRACE,
3030  "ignoring CTTS entry with count=%d duration=%d\n",
3031  count, duration);
3032  continue;
3033  }
3034 
3035  add_ctts_entry(&sc->ctts_data, &ctts_count, &sc->ctts_allocated_size,
3036  count, duration);
3037 
3038  av_log(c->fc, AV_LOG_TRACE, "count=%d, duration=%d\n",
3039  count, duration);
3040 
3041  if (FFNABS(duration) < -(1<<28) && i+2<entries) {
3042  av_log(c->fc, AV_LOG_WARNING, "CTTS invalid\n");
3043  av_freep(&sc->ctts_data);
3044  sc->ctts_count = 0;
3045  return 0;
3046  }
3047 
3048  if (i+2<entries)
3050  }
3051 
3052  sc->ctts_count = ctts_count;
3053 
3054  if (pb->eof_reached) {
3055  av_log(c->fc, AV_LOG_WARNING, "reached eof, corrupted CTTS atom\n");
3056  return AVERROR_EOF;
3057  }
3058 
3059  av_log(c->fc, AV_LOG_TRACE, "dts shift %d\n", sc->dts_shift);
3060 
3061  return 0;
3062 }
3063 
3065 {
3066  AVStream *st;
3067  MOVStreamContext *sc;
3068  unsigned int i, entries;
3069  uint8_t version;
3070  uint32_t grouping_type;
3071 
3072  if (c->fc->nb_streams < 1)
3073  return 0;
3074  st = c->fc->streams[c->fc->nb_streams-1];
3075  sc = st->priv_data;
3076 
3077  version = avio_r8(pb); /* version */
3078  avio_rb24(pb); /* flags */
3079  grouping_type = avio_rl32(pb);
3080  if (grouping_type != MKTAG( 'r','a','p',' '))
3081  return 0; /* only support 'rap ' grouping */
3082  if (version == 1)
3083  avio_rb32(pb); /* grouping_type_parameter */
3084 
3085  entries = avio_rb32(pb);
3086  if (!entries)
3087  return 0;
3088  if (sc->rap_group)
3089  av_log(c->fc, AV_LOG_WARNING, "Duplicated SBGP atom\n");
3090  av_free(sc->rap_group);
3091  sc->rap_group_count = 0;
3092  sc->rap_group = av_malloc_array(entries, sizeof(*sc->rap_group));
3093  if (!sc->rap_group)
3094  return AVERROR(ENOMEM);
3095 
3096  for (i = 0; i < entries && !pb->eof_reached; i++) {
3097  sc->rap_group[i].count = avio_rb32(pb); /* sample_count */
3098  sc->rap_group[i].index = avio_rb32(pb); /* group_description_index */
3099  }
3100 
3101  sc->rap_group_count = i;
3102 
3103  if (pb->eof_reached) {
3104  av_log(c->fc, AV_LOG_WARNING, "reached eof, corrupted SBGP atom\n");
3105  return AVERROR_EOF;
3106  }
3107 
3108  return 0;
3109 }
3110 
3111 /**
3112  * Get ith edit list entry (media time, duration).
3113  */
3115  const MOVStreamContext *msc,
3116  unsigned int edit_list_index,
3117  int64_t *edit_list_media_time,
3118  int64_t *edit_list_duration,
3119  int64_t global_timescale)
3120 {
3121  if (edit_list_index == msc->elst_count) {
3122  return 0;
3123  }
3124  *edit_list_media_time = msc->elst_data[edit_list_index].time;
3125  *edit_list_duration = msc->elst_data[edit_list_index].duration;
3126 
3127  /* duration is in global timescale units;convert to msc timescale */
3128  if (global_timescale == 0) {
3129  avpriv_request_sample(mov->fc, "Support for mvhd.timescale = 0 with editlists");
3130  return 0;
3131  }
3132  *edit_list_duration = av_rescale(*edit_list_duration, msc->time_scale,
3133  global_timescale);
3134  return 1;
3135 }
3136 
3137 /**
3138  * Find the closest previous frame to the timestamp_pts, in e_old index
3139  * entries. Searching for just any frame / just key frames can be controlled by
3140  * last argument 'flag'.
3141  * Note that if ctts_data is not NULL, we will always search for a key frame
3142  * irrespective of the value of 'flag'. If we don't find any keyframe, we will
3143  * return the first frame of the video.
3144  *
3145  * Here the timestamp_pts is considered to be a presentation timestamp and
3146  * the timestamp of index entries are considered to be decoding timestamps.
3147  *
3148  * Returns 0 if successful in finding a frame, else returns -1.
3149  * Places the found index corresponding output arg.
3150  *
3151  * If ctts_old is not NULL, then refines the searched entry by searching
3152  * backwards from the found timestamp, to find the frame with correct PTS.
3153  *
3154  * Places the found ctts_index and ctts_sample in corresponding output args.
3155  */
3157  AVIndexEntry *e_old,
3158  int nb_old,
3159  MOVStts* ctts_data,
3160  int64_t ctts_count,
3161  int64_t timestamp_pts,
3162  int flag,
3163  int64_t* index,
3164  int64_t* ctts_index,
3165  int64_t* ctts_sample)
3166 {
3167  MOVStreamContext *msc = st->priv_data;
3168  AVIndexEntry *e_keep = st->index_entries;
3169  int nb_keep = st->nb_index_entries;
3170  int64_t i = 0;
3171  int64_t index_ctts_count;
3172 
3173  av_assert0(index);
3174 
3175  // If dts_shift > 0, then all the index timestamps will have to be offset by
3176  // at least dts_shift amount to obtain PTS.
3177  // Hence we decrement the searched timestamp_pts by dts_shift to find the closest index element.
3178  if (msc->dts_shift > 0) {
3179  timestamp_pts -= msc->dts_shift;
3180  }
3181 
3182  st->index_entries = e_old;
3183  st->nb_index_entries = nb_old;
3184  *index = av_index_search_timestamp(st, timestamp_pts, flag | AVSEEK_FLAG_BACKWARD);
3185 
3186  // Keep going backwards in the index entries until the timestamp is the same.
3187  if (*index >= 0) {
3188  for (i = *index; i > 0 && e_old[i].timestamp == e_old[i - 1].timestamp;
3189  i--) {
3190  if ((flag & AVSEEK_FLAG_ANY) ||
3191  (e_old[i - 1].flags & AVINDEX_KEYFRAME)) {
3192  *index = i - 1;
3193  }
3194  }
3195  }
3196 
3197  // If we have CTTS then refine the search, by searching backwards over PTS
3198  // computed by adding corresponding CTTS durations to index timestamps.
3199  if (ctts_data && *index >= 0) {
3200  av_assert0(ctts_index);
3201  av_assert0(ctts_sample);
3202  // Find out the ctts_index for the found frame.
3203  *ctts_index = 0;
3204  *ctts_sample = 0;
3205  for (index_ctts_count = 0; index_ctts_count < *index; index_ctts_count++) {
3206  if (*ctts_index < ctts_count) {
3207  (*ctts_sample)++;
3208  if (ctts_data[*ctts_index].count == *ctts_sample) {
3209  (*ctts_index)++;
3210  *ctts_sample = 0;
3211  }
3212  }
3213  }
3214 
3215  while (*index >= 0 && (*ctts_index) >= 0 && (*ctts_index) < ctts_count) {
3216  // Find a "key frame" with PTS <= timestamp_pts (So that we can decode B-frames correctly).
3217  // No need to add dts_shift to the timestamp here becase timestamp_pts has already been
3218  // compensated by dts_shift above.
3219  if ((e_old[*index].timestamp + ctts_data[*ctts_index].duration) <= timestamp_pts &&
3220  (e_old[*index].flags & AVINDEX_KEYFRAME)) {
3221  break;
3222  }
3223 
3224  (*index)--;
3225  if (*ctts_sample == 0) {
3226  (*ctts_index)--;
3227  if (*ctts_index >= 0)
3228  *ctts_sample = ctts_data[*ctts_index].count - 1;
3229  } else {
3230  (*ctts_sample)--;
3231  }
3232  }
3233  }
3234 
3235  /* restore AVStream state*/
3236  st->index_entries = e_keep;
3237  st->nb_index_entries = nb_keep;
3238  return *index >= 0 ? 0 : -1;
3239 }
3240 
3241 /**
3242  * Add index entry with the given values, to the end of st->index_entries.
3243  * Returns the new size st->index_entries if successful, else returns -1.
3244  *
3245  * This function is similar to ff_add_index_entry in libavformat/utils.c
3246  * except that here we are always unconditionally adding an index entry to
3247  * the end, instead of searching the entries list and skipping the add if
3248  * there is an existing entry with the same timestamp.
3249  * This is needed because the mov_fix_index calls this func with the same
3250  * unincremented timestamp for successive discarded frames.
3251  */
3252 static int64_t add_index_entry(AVStream *st, int64_t pos, int64_t timestamp,
3253  int size, int distance, int flags)
3254 {
3255  AVIndexEntry *entries, *ie;
3256  int64_t index = -1;
3257  const size_t min_size_needed = (st->nb_index_entries + 1) * sizeof(AVIndexEntry);
3258 
3259  // Double the allocation each time, to lower memory fragmentation.
3260  // Another difference from ff_add_index_entry function.
3261  const size_t requested_size =
3262  min_size_needed > st->index_entries_allocated_size ?
3263  FFMAX(min_size_needed, 2 * st->index_entries_allocated_size) :
3264  min_size_needed;
3265 
3266  if((unsigned)st->nb_index_entries + 1 >= UINT_MAX / sizeof(AVIndexEntry))
3267  return -1;
3268 
3269  entries = av_fast_realloc(st->index_entries,
3271  requested_size);
3272  if(!entries)
3273  return -1;
3274 
3275  st->index_entries= entries;
3276 
3277  index= st->nb_index_entries++;
3278  ie= &entries[index];
3279 
3280  ie->pos = pos;
3281  ie->timestamp = timestamp;
3282  ie->min_distance= distance;
3283  ie->size= size;
3284  ie->flags = flags;
3285  return index;
3286 }
3287 
3288 /**
3289  * Rewrite timestamps of index entries in the range [end_index - frame_duration_buffer_size, end_index)
3290  * by subtracting end_ts successively by the amounts given in frame_duration_buffer.
3291  */
3292 static void fix_index_entry_timestamps(AVStream* st, int end_index, int64_t end_ts,
3293  int64_t* frame_duration_buffer,
3294  int frame_duration_buffer_size) {
3295  int i = 0;
3296  av_assert0(end_index >= 0 && end_index <= st->nb_index_entries);
3297  for (i = 0; i < frame_duration_buffer_size; i++) {
3298  end_ts -= frame_duration_buffer[frame_duration_buffer_size - 1 - i];
3299  st->index_entries[end_index - 1 - i].timestamp = end_ts;
3300  }
3301 }
3302 
3303 /**
3304  * Append a new ctts entry to ctts_data.
3305  * Returns the new ctts_count if successful, else returns -1.
3306  */
3307 static int64_t add_ctts_entry(MOVStts** ctts_data, unsigned int* ctts_count, unsigned int* allocated_size,
3308  int count, int duration)
3309 {
3310  MOVStts *ctts_buf_new;
3311  const size_t min_size_needed = (*ctts_count + 1) * sizeof(MOVStts);
3312  const size_t requested_size =
3313  min_size_needed > *allocated_size ?
3314  FFMAX(min_size_needed, 2 * (*allocated_size)) :
3315  min_size_needed;
3316 
3317  if((unsigned)(*ctts_count) >= UINT_MAX / sizeof(MOVStts) - 1)
3318  return -1;
3319 
3320  ctts_buf_new = av_fast_realloc(*ctts_data, allocated_size, requested_size);
3321 
3322  if(!ctts_buf_new)
3323  return -1;
3324 
3325  *ctts_data = ctts_buf_new;
3326 
3327  ctts_buf_new[*ctts_count].count = count;
3328  ctts_buf_new[*ctts_count].duration = duration;
3329 
3330  *ctts_count = (*ctts_count) + 1;
3331  return *ctts_count;
3332 }
3333 
3334 #define MAX_REORDER_DELAY 16
3336  MOVStreamContext *msc = st->priv_data;
3337  int ind;
3338  int ctts_ind = 0;
3339  int ctts_sample = 0;
3340  int64_t pts_buf[MAX_REORDER_DELAY + 1]; // Circular buffer to sort pts.
3341  int buf_start = 0;
3342  int j, r, num_swaps;
3343 
3344  for (j = 0; j < MAX_REORDER_DELAY + 1; j++)
3345  pts_buf[j] = INT64_MIN;
3346 
3347  if (st->codecpar->video_delay <= 0 && msc->ctts_data &&
3349  st->codecpar->video_delay = 0;
3350  for(ind = 0; ind < st->nb_index_entries && ctts_ind < msc->ctts_count; ++ind) {
3351  // Point j to the last elem of the buffer and insert the current pts there.
3352  j = buf_start;
3353  buf_start = (buf_start + 1);
3354  if (buf_start == MAX_REORDER_DELAY + 1)
3355  buf_start = 0;
3356 
3357  pts_buf[j] = st->index_entries[ind].timestamp + msc->ctts_data[ctts_ind].duration;
3358 
3359  // The timestamps that are already in the sorted buffer, and are greater than the
3360  // current pts, are exactly the timestamps that need to be buffered to output PTS
3361  // in correct sorted order.
3362  // Hence the video delay (which is the buffer size used to sort DTS and output PTS),
3363  // can be computed as the maximum no. of swaps any particular timestamp needs to
3364  // go through, to keep this buffer in sorted order.
3365  num_swaps = 0;
3366  while (j != buf_start) {
3367  r = j - 1;
3368  if (r < 0) r = MAX_REORDER_DELAY;
3369  if (pts_buf[j] < pts_buf[r]) {
3370  FFSWAP(int64_t, pts_buf[j], pts_buf[r]);
3371  ++num_swaps;
3372  } else {
3373  break;
3374  }
3375  j = r;
3376  }
3377  st->codecpar->video_delay = FFMAX(st->codecpar->video_delay, num_swaps);
3378 
3379  ctts_sample++;
3380  if (ctts_sample == msc->ctts_data[ctts_ind].count) {
3381  ctts_ind++;
3382  ctts_sample = 0;
3383  }
3384  }
3385  av_log(c->fc, AV_LOG_DEBUG, "Setting codecpar->delay to %d for stream st: %d\n",
3386  st->codecpar->video_delay, st->index);
3387  }
3388 }
3389 
3391 {
3392  sc->current_sample++;
3393  sc->current_index++;
3394  if (sc->index_ranges &&
3395  sc->current_index >= sc->current_index_range->end &&
3396  sc->current_index_range->end) {
3397  sc->current_index_range++;
3399  }
3400 }
3401 
3403 {
3404  sc->current_sample--;
3405  sc->current_index--;
3406  if (sc->index_ranges &&
3408  sc->current_index_range > sc->index_ranges) {
3409  sc->current_index_range--;
3410  sc->current_index = sc->current_index_range->end - 1;
3411  }
3412 }
3413 
3414 static void mov_current_sample_set(MOVStreamContext *sc, int current_sample)
3415 {
3416  int64_t range_size;
3417 
3418  sc->current_sample = current_sample;
3419  sc->current_index = current_sample;
3420  if (!sc->index_ranges) {
3421  return;
3422  }
3423 
3424  for (sc->current_index_range = sc->index_ranges;
3425  sc->current_index_range->end;
3426  sc->current_index_range++) {
3427  range_size = sc->current_index_range->end - sc->current_index_range->start;
3428  if (range_size > current_sample) {
3429  sc->current_index = sc->current_index_range->start + current_sample;
3430  break;
3431  }
3432  current_sample -= range_size;
3433  }
3434 }
3435 
3436 /**
3437  * Fix st->index_entries, so that it contains only the entries (and the entries
3438  * which are needed to decode them) that fall in the edit list time ranges.
3439  * Also fixes the timestamps of the index entries to match the timeline
3440  * specified the edit lists.
3441  */
3442 static void mov_fix_index(MOVContext *mov, AVStream *st)
3443 {
3444  MOVStreamContext *msc = st->priv_data;
3445  AVIndexEntry *e_old = st->index_entries;
3446  int nb_old = st->nb_index_entries;
3447  const AVIndexEntry *e_old_end = e_old + nb_old;
3448  const AVIndexEntry *current = NULL;
3449  MOVStts *ctts_data_old = msc->ctts_data;
3450  int64_t ctts_index_old = 0;
3451  int64_t ctts_sample_old = 0;
3452  int64_t ctts_count_old = msc->ctts_count;
3453  int64_t edit_list_media_time = 0;
3454  int64_t edit_list_duration = 0;
3455  int64_t frame_duration = 0;
3456  int64_t edit_list_dts_counter = 0;
3457  int64_t edit_list_dts_entry_end = 0;
3458  int64_t edit_list_start_ctts_sample = 0;
3459  int64_t curr_cts;
3460  int64_t curr_ctts = 0;
3461  int64_t empty_edits_sum_duration = 0;
3462  int64_t edit_list_index = 0;
3463  int64_t index;
3464  int flags;
3465  int64_t start_dts = 0;
3466  int64_t edit_list_start_encountered = 0;
3467  int64_t search_timestamp = 0;
3468  int64_t* frame_duration_buffer = NULL;
3469  int num_discarded_begin = 0;
3470  int first_non_zero_audio_edit = -1;
3471  int packet_skip_samples = 0;
3472  MOVIndexRange *current_index_range;
3473  int i;
3474  int found_keyframe_after_edit = 0;
3475  int found_non_empty_edit = 0;
3476 
3477  if (!msc->elst_data || msc->elst_count <= 0 || nb_old <= 0) {
3478  return;
3479  }
3480 
3481  // allocate the index ranges array
3482  msc->index_ranges = av_malloc((msc->elst_count + 1) * sizeof(msc->index_ranges[0]));
3483  if (!msc->index_ranges) {
3484  av_log(mov->fc, AV_LOG_ERROR, "Cannot allocate index ranges buffer\n");
3485  return;
3486  }
3487  msc->current_index_range = msc->index_ranges;
3488  current_index_range = msc->index_ranges - 1;
3489 
3490  // Clean AVStream from traces of old index
3491  st->index_entries = NULL;
3493  st->nb_index_entries = 0;
3494 
3495  // Clean ctts fields of MOVStreamContext
3496  msc->ctts_data = NULL;
3497  msc->ctts_count = 0;
3498  msc->ctts_index = 0;
3499  msc->ctts_sample = 0;
3500  msc->ctts_allocated_size = 0;
3501 
3502  // Reinitialize min_corrected_pts so that it can be computed again.
3503  msc->min_corrected_pts = -1;
3504 
3505  // If the dts_shift is positive (in case of negative ctts values in mov),
3506  // then negate the DTS by dts_shift
3507  if (msc->dts_shift > 0) {
3508  edit_list_dts_entry_end -= msc->dts_shift;
3509  av_log(mov->fc, AV_LOG_DEBUG, "Shifting DTS by %d because of negative CTTS.\n", msc->dts_shift);
3510  }
3511 
3512  start_dts = edit_list_dts_entry_end;
3513 
3514  while (get_edit_list_entry(mov, msc, edit_list_index, &edit_list_media_time,
3515  &edit_list_duration, mov->time_scale)) {
3516  av_log(mov->fc, AV_LOG_DEBUG, "Processing st: %d, edit list %"PRId64" - media time: %"PRId64", duration: %"PRId64"\n",
3517  st->index, edit_list_index, edit_list_media_time, edit_list_duration);
3518  edit_list_index++;
3519  edit_list_dts_counter = edit_list_dts_entry_end;
3520  edit_list_dts_entry_end += edit_list_duration;
3521  num_discarded_begin = 0;
3522  if (!found_non_empty_edit && edit_list_media_time == -1) {
3523  empty_edits_sum_duration += edit_list_duration;
3524  continue;
3525  }
3526  found_non_empty_edit = 1;
3527 
3528  // If we encounter a non-negative edit list reset the skip_samples/start_pad fields and set them
3529  // according to the edit list below.
3530  if (st->codecpar->codec_type == AVMEDIA_TYPE_AUDIO) {
3531  if (first_non_zero_audio_edit < 0) {
3532  first_non_zero_audio_edit = 1;
3533  } else {
3534  first_non_zero_audio_edit = 0;
3535  }
3536 
3537  if (first_non_zero_audio_edit > 0)
3538  st->skip_samples = msc->start_pad = 0;
3539  }
3540 
3541  // While reordering frame index according to edit list we must handle properly
3542  // the scenario when edit list entry starts from none key frame.
3543  // We find closest previous key frame and preserve it and consequent frames in index.
3544  // All frames which are outside edit list entry time boundaries will be dropped after decoding.
3545  search_timestamp = edit_list_media_time;
3546  if (st->codecpar->codec_type == AVMEDIA_TYPE_AUDIO) {
3547  // Audio decoders like AAC need need a decoder delay samples previous to the current sample,
3548  // to correctly decode this frame. Hence for audio we seek to a frame 1 sec. before the
3549  // edit_list_media_time to cover the decoder delay.
3550  search_timestamp = FFMAX(search_timestamp - msc->time_scale, e_old[0].timestamp);
3551  }
3552 
3553  if (find_prev_closest_index(st, e_old, nb_old, ctts_data_old, ctts_count_old, search_timestamp, 0,
3554  &index, &ctts_index_old, &ctts_sample_old) < 0) {
3555  av_log(mov->fc, AV_LOG_WARNING,
3556  "st: %d edit list: %"PRId64" Missing key frame while searching for timestamp: %"PRId64"\n",
3557  st->index, edit_list_index, search_timestamp);
3558  if (find_prev_closest_index(st, e_old, nb_old, ctts_data_old, ctts_count_old, search_timestamp, AVSEEK_FLAG_ANY,
3559  &index, &ctts_index_old, &ctts_sample_old) < 0) {
3560  av_log(mov->fc, AV_LOG_WARNING,
3561  "st: %d edit list %"PRId64" Cannot find an index entry before timestamp: %"PRId64".\n",
3562  st->index, edit_list_index, search_timestamp);
3563  index = 0;
3564  ctts_index_old = 0;
3565  ctts_sample_old = 0;
3566  }
3567  }
3568  current = e_old + index;
3569  edit_list_start_ctts_sample = ctts_sample_old;
3570 
3571  // Iterate over index and arrange it according to edit list
3572  edit_list_start_encountered = 0;
3573  found_keyframe_after_edit = 0;
3574  for (; current < e_old_end; current++, index++) {
3575  // check if frame outside edit list mark it for discard
3576  frame_duration = (current + 1 < e_old_end) ?
3577  ((current + 1)->timestamp - current->timestamp) : edit_list_duration;
3578 
3579  flags = current->flags;
3580 
3581  // frames (pts) before or after edit list
3582  curr_cts = current->timestamp + msc->dts_shift;
3583  curr_ctts = 0;
3584 
3585  if (ctts_data_old && ctts_index_old < ctts_count_old) {
3586  curr_ctts = ctts_data_old[ctts_index_old].duration;
3587  av_log(mov->fc, AV_LOG_DEBUG, "stts: %"PRId64" ctts: %"PRId64", ctts_index: %"PRId64", ctts_count: %"PRId64"\n",
3588  curr_cts, curr_ctts, ctts_index_old, ctts_count_old);
3589  curr_cts += curr_ctts;
3590  ctts_sample_old++;
3591  if (ctts_sample_old == ctts_data_old[ctts_index_old].count) {
3592  if (add_ctts_entry(&msc->ctts_data, &msc->ctts_count,
3593  &msc->ctts_allocated_size,
3594  ctts_data_old[ctts_index_old].count - edit_list_start_ctts_sample,
3595  ctts_data_old[ctts_index_old].duration) == -1) {
3596  av_log(mov->fc, AV_LOG_ERROR, "Cannot add CTTS entry %"PRId64" - {%"PRId64", %d}\n",
3597  ctts_index_old,
3598  ctts_data_old[ctts_index_old].count - edit_list_start_ctts_sample,
3599  ctts_data_old[ctts_index_old].duration);
3600  break;
3601  }
3602  ctts_index_old++;
3603  ctts_sample_old = 0;
3604  edit_list_start_ctts_sample = 0;
3605  }
3606  }
3607 
3608  if (curr_cts < edit_list_media_time || curr_cts >= (edit_list_duration + edit_list_media_time)) {
3610  curr_cts < edit_list_media_time && curr_cts + frame_duration > edit_list_media_time &&
3611  first_non_zero_audio_edit > 0) {
3612  packet_skip_samples = edit_list_media_time - curr_cts;
3613  st->skip_samples += packet_skip_samples;
3614 
3615  // Shift the index entry timestamp by packet_skip_samples to be correct.
3616  edit_list_dts_counter -= packet_skip_samples;
3617  if (edit_list_start_encountered == 0) {
3618  edit_list_start_encountered = 1;
3619  // Make timestamps strictly monotonically increasing for audio, by rewriting timestamps for
3620  // discarded packets.
3621  if (frame_duration_buffer) {
3622  fix_index_entry_timestamps(st, st->nb_index_entries, edit_list_dts_counter,
3623  frame_duration_buffer, num_discarded_begin);
3624  av_freep(&frame_duration_buffer);
3625  }
3626  }
3627 
3628  av_log(mov->fc, AV_LOG_DEBUG, "skip %d audio samples from curr_cts: %"PRId64"\n", packet_skip_samples, curr_cts);
3629  } else {
3631  av_log(mov->fc, AV_LOG_DEBUG, "drop a frame at curr_cts: %"PRId64" @ %"PRId64"\n", curr_cts, index);
3632 
3633  if (edit_list_start_encountered == 0) {
3634  num_discarded_begin++;
3635  frame_duration_buffer = av_realloc(frame_duration_buffer,
3636  num_discarded_begin * sizeof(int64_t));
3637  if (!frame_duration_buffer) {
3638  av_log(mov->fc, AV_LOG_ERROR, "Cannot reallocate frame duration buffer\n");
3639  break;
3640  }
3641  frame_duration_buffer[num_discarded_begin - 1] = frame_duration;
3642 
3643  // Increment skip_samples for the first non-zero audio edit list
3644  if (st->codecpar->codec_type == AVMEDIA_TYPE_AUDIO &&
3645  first_non_zero_audio_edit > 0 && st->codecpar->codec_id != AV_CODEC_ID_VORBIS) {
3646  st->skip_samples += frame_duration;
3647  }
3648  }
3649  }
3650  } else {
3651  if (msc->min_corrected_pts < 0) {
3652  msc->min_corrected_pts = edit_list_dts_counter + curr_ctts + msc->dts_shift;
3653  } else {
3654  msc->min_corrected_pts = FFMIN(msc->min_corrected_pts, edit_list_dts_counter + curr_ctts + msc->dts_shift);
3655  }
3656  if (edit_list_start_encountered == 0) {
3657  edit_list_start_encountered = 1;
3658  // Make timestamps strictly monotonically increasing by rewriting timestamps for
3659  // discarded packets.
3660  if (frame_duration_buffer) {
3661  fix_index_entry_timestamps(st, st->nb_index_entries, edit_list_dts_counter,
3662  frame_duration_buffer, num_discarded_begin);
3663  av_freep(&frame_duration_buffer);
3664  }
3665  }
3666  }
3667 
3668  if (add_index_entry(st, current->pos, edit_list_dts_counter, current->size,
3669  current->min_distance, flags) == -1) {
3670  av_log(mov->fc, AV_LOG_ERROR, "Cannot add index entry\n");
3671  break;
3672  }
3673 
3674  // Update the index ranges array
3675  if (current_index_range < msc->index_ranges || index != current_index_range->end) {
3676  current_index_range++;
3677  current_index_range->start = index;
3678  }
3679  current_index_range->end = index + 1;
3680 
3681  // Only start incrementing DTS in frame_duration amounts, when we encounter a frame in edit list.
3682  if (edit_list_start_encountered > 0) {
3683  edit_list_dts_counter = edit_list_dts_counter + frame_duration;
3684  }
3685 
3686  // Break when found first key frame after edit entry completion
3687  if ((curr_cts + frame_duration >= (edit_list_duration + edit_list_media_time)) &&
3689  if (ctts_data_old) {
3690  // If we have CTTS and this is the first keyframe after edit elist,
3691  // wait for one more, because there might be trailing B-frames after this I-frame
3692  // that do belong to the edit.
3693  if (st->codecpar->codec_type != AVMEDIA_TYPE_AUDIO && found_keyframe_after_edit == 0) {
3694  found_keyframe_after_edit = 1;
3695  continue;
3696  }
3697  if (ctts_sample_old != 0) {
3698  if (add_ctts_entry(&msc->ctts_data, &msc->ctts_count,
3699  &msc->ctts_allocated_size,
3700  ctts_sample_old - edit_list_start_ctts_sample,
3701  ctts_data_old[ctts_index_old].duration) == -1) {
3702  av_log(mov->fc, AV_LOG_ERROR, "Cannot add CTTS entry %"PRId64" - {%"PRId64", %d}\n",
3703  ctts_index_old, ctts_sample_old - edit_list_start_ctts_sample,
3704  ctts_data_old[ctts_index_old].duration);
3705  break;
3706  }
3707  }
3708  }
3709  break;
3710  }
3711  }
3712  }
3713  // If there are empty edits, then msc->min_corrected_pts might be positive
3714  // intentionally. So we subtract the sum duration of emtpy edits here.
3715  msc->min_corrected_pts -= empty_edits_sum_duration;
3716 
3717  // If the minimum pts turns out to be greater than zero after fixing the index, then we subtract the
3718  // dts by that amount to make the first pts zero.
3719  if (st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO) {
3720  if (msc->min_corrected_pts > 0) {
3721  av_log(mov->fc, AV_LOG_DEBUG, "Offset DTS by %"PRId64" to make first pts zero.\n", msc->min_corrected_pts);
3722  for (i = 0; i < st->nb_index_entries; ++i) {
3724  }
3725  }
3726  }
3727  // Start time should be equal to zero or the duration of any empty edits.
3728  st->start_time = empty_edits_sum_duration;
3729 
3730  // Update av stream length, if it ends up shorter than the track's media duration
3731  st->duration = FFMIN(st->duration, edit_list_dts_entry_end - start_dts);
3732  msc->start_pad = st->skip_samples;
3733 
3734  // Free the old index and the old CTTS structures
3735  av_free(e_old);
3736  av_free(ctts_data_old);
3737  av_freep(&frame_duration_buffer);
3738 
3739  // Null terminate the index ranges array
3740  current_index_range++;
3741  current_index_range->start = 0;
3742  current_index_range->end = 0;
3743  msc->current_index = msc->index_ranges[0].start;
3744 }
3745 
3746 static void mov_build_index(MOVContext *mov, AVStream *st)
3747 {
3748  MOVStreamContext *sc = st->priv_data;
3749  int64_t current_offset;
3750  int64_t current_dts = 0;
3751  unsigned int stts_index = 0;
3752  unsigned int stsc_index = 0;
3753  unsigned int stss_index = 0;
3754  unsigned int stps_index = 0;
3755  unsigned int i, j;
3756  uint64_t stream_size = 0;
3757  MOVStts *ctts_data_old = sc->ctts_data;
3758  unsigned int ctts_count_old = sc->ctts_count;
3759 
3760  if (sc->elst_count) {
3761  int i, edit_start_index = 0, multiple_edits = 0;
3762  int64_t empty_duration = 0; // empty duration of the first edit list entry
3763  int64_t start_time = 0; // start time of the media
3764 
3765  for (i = 0; i < sc->elst_count; i++) {
3766  const MOVElst *e = &sc->elst_data[i];
3767  if (i == 0 && e->time == -1) {
3768  /* if empty, the first entry is the start time of the stream
3769  * relative to the presentation itself */
3770  empty_duration = e->duration;
3771  edit_start_index = 1;
3772  } else if (i == edit_start_index && e->time >= 0) {
3773  start_time = e->time;
3774  } else {
3775  multiple_edits = 1;
3776  }
3777  }
3778 
3779  if (multiple_edits && !mov->advanced_editlist)
3780  av_log(mov->fc, AV_LOG_WARNING, "multiple edit list entries, "
3781  "Use -advanced_editlist to correctly decode otherwise "
3782  "a/v desync might occur\n");
3783 
3784  /* adjust first dts according to edit list */
3785  if ((empty_duration || start_time) && mov->time_scale > 0) {
3786  if (empty_duration)
3787  empty_duration = av_rescale(empty_duration, sc->time_scale, mov->time_scale);
3788  sc->time_offset = start_time - empty_duration;
3790  if (!mov->advanced_editlist)
3791  current_dts = -sc->time_offset;
3792  }
3793 
3794  if (!multiple_edits && !mov->advanced_editlist &&
3796  sc->start_pad = start_time;
3797  }
3798 
3799  /* only use old uncompressed audio chunk demuxing when stts specifies it */
3800  if (!(st->codecpar->codec_type == AVMEDIA_TYPE_AUDIO &&
3801  sc->stts_count == 1 && sc->stts_data[0].duration == 1)) {
3802  unsigned int current_sample = 0;
3803  unsigned int stts_sample = 0;
3804  unsigned int sample_size;
3805  unsigned int distance = 0;
3806  unsigned int rap_group_index = 0;
3807  unsigned int rap_group_sample = 0;
3808  int64_t last_dts = 0;
3809  int64_t dts_correction = 0;
3810  int rap_group_present = sc->rap_group_count && sc->rap_group;
3811  int key_off = (sc->keyframe_count && sc->keyframes[0] > 0) || (sc->stps_count && sc->stps_data[0] > 0);
3812 
3813  current_dts -= sc->dts_shift;
3814  last_dts = current_dts;
3815 
3816  if (!sc->sample_count || st->nb_index_entries)
3817  return;
3818  if (sc->sample_count >= UINT_MAX / sizeof(*st->index_entries) - st->nb_index_entries)
3819  return;
3821  st->nb_index_entries + sc->sample_count,
3822  sizeof(*st->index_entries)) < 0) {
3823  st->nb_index_entries = 0;
3824  return;
3825  }
3827 
3828  if (ctts_data_old) {
3829  // Expand ctts entries such that we have a 1-1 mapping with samples
3830  if (sc->sample_count >= UINT_MAX / sizeof(*sc->ctts_data))
3831  return;
3832  sc->ctts_count = 0;
3833  sc->ctts_allocated_size = 0;
3835  sc->sample_count * sizeof(*sc->ctts_data));
3836  if (!sc->ctts_data) {
3837  av_free(ctts_data_old);
3838  return;
3839  }
3840 
3841  memset((uint8_t*)(sc->ctts_data), 0, sc->ctts_allocated_size);
3842 
3843  for (i = 0; i < ctts_count_old &&
3844  sc->ctts_count < sc->sample_count; i++)
3845  for (j = 0; j < ctts_data_old[i].count &&
3846  sc->ctts_count < sc->sample_count; j++)
3847  add_ctts_entry(&sc->ctts_data, &sc->ctts_count,
3848  &sc->ctts_allocated_size, 1,
3849  ctts_data_old[i].duration);
3850  av_free(ctts_data_old);
3851  }
3852 
3853  for (i = 0; i < sc->chunk_count; i++) {
3854  int64_t next_offset = i+1 < sc->chunk_count ? sc->chunk_offsets[i+1] : INT64_MAX;
3855  current_offset = sc->chunk_offsets[i];
3856  while (mov_stsc_index_valid(stsc_index, sc->stsc_count) &&
3857  i + 1 == sc->stsc_data[stsc_index + 1].first)
3858  stsc_index++;
3859 
3860  if (next_offset > current_offset && sc->sample_size>0 && sc->sample_size < sc->stsz_sample_size &&
3861  sc->stsc_data[stsc_index].count * (int64_t)sc->stsz_sample_size > next_offset - current_offset) {
3862  av_log(mov->fc, AV_LOG_WARNING, "STSZ sample size %d invalid (too large), ignoring\n", sc->stsz_sample_size);
3863  sc->stsz_sample_size = sc->sample_size;
3864  }
3865  if (sc->stsz_sample_size>0 && sc->stsz_sample_size < sc->sample_size) {
3866  av_log(mov->fc, AV_LOG_WARNING, "STSZ sample size %d invalid (too small), ignoring\n", sc->stsz_sample_size);
3867  sc->stsz_sample_size = sc->sample_size;
3868  }
3869 
3870  for (j = 0; j < sc->stsc_data[stsc_index].count; j++) {
3871  int keyframe = 0;
3872  if (current_sample >= sc->sample_count) {
3873  av_log(mov->fc, AV_LOG_ERROR, "wrong sample count\n");
3874  return;
3875  }
3876 
3877  if (!sc->keyframe_absent && (!sc->keyframe_count || current_sample+key_off == sc->keyframes[stss_index])) {
3878  keyframe = 1;
3879  if (stss_index + 1 < sc->keyframe_count)
3880  stss_index++;
3881  } else if (sc->stps_count && current_sample+key_off == sc->stps_data[stps_index]) {
3882  keyframe = 1;
3883  if (stps_index + 1 < sc->stps_count)
3884  stps_index++;
3885  }
3886  if (rap_group_present && rap_group_index < sc->rap_group_count) {
3887  if (sc->rap_group[rap_group_index].index > 0)
3888  keyframe = 1;
3889  if (++rap_group_sample == sc->rap_group[rap_group_index].count) {
3890  rap_group_sample = 0;
3891  rap_group_index++;
3892  }
3893  }
3894  if (sc->keyframe_absent
3895  && !sc->stps_count
3896  && !rap_group_present
3897  && (st->codecpar->codec_type == AVMEDIA_TYPE_AUDIO || (i==0 && j==0)))
3898  keyframe = 1;
3899  if (keyframe)
3900  distance = 0;
3901  sample_size = sc->stsz_sample_size > 0 ? sc->stsz_sample_size : sc->sample_sizes[current_sample];
3902  if (sc->pseudo_stream_id == -1 ||
3903  sc->stsc_data[stsc_index].id - 1 == sc->pseudo_stream_id) {
3904  AVIndexEntry *e;
3905  if (sample_size > 0x3FFFFFFF) {
3906  av_log(mov->fc, AV_LOG_ERROR, "Sample size %u is too large\n", sample_size);
3907  return;
3908  }
3909  e = &st->index_entries[st->nb_index_entries++];
3910  e->pos = current_offset;
3911  e->timestamp = current_dts;
3912  e->size = sample_size;
3913  e->min_distance = distance;
3914  e->flags = keyframe ? AVINDEX_KEYFRAME : 0;
3915  av_log(mov->fc, AV_LOG_TRACE, "AVIndex stream %d, sample %u, offset %"PRIx64", dts %"PRId64", "
3916  "size %u, distance %u, keyframe %d\n", st->index, current_sample,
3917  current_offset, current_dts, sample_size, distance, keyframe);
3918  if (st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO && st->nb_index_entries < 100)
3919  ff_rfps_add_frame(mov->fc, st, current_dts);
3920  }
3921 
3922  current_offset += sample_size;
3923  stream_size += sample_size;
3924 
3925  /* A negative sample duration is invalid based on the spec,
3926  * but some samples need it to correct the DTS. */
3927  if (sc->stts_data[stts_index].duration < 0) {
3928  av_log(mov->fc, AV_LOG_WARNING,
3929  "Invalid SampleDelta %d in STTS, at %d st:%d\n",
3930  sc->stts_data[stts_index].duration, stts_index,
3931  st->index);
3932  dts_correction += sc->stts_data[stts_index].duration - 1;
3933  sc->stts_data[stts_index].duration = 1;
3934  }
3935  current_dts += sc->stts_data[stts_index].duration;
3936  if (!dts_correction || current_dts + dts_correction > last_dts) {
3937  current_dts += dts_correction;
3938  dts_correction = 0;
3939  } else {
3940  /* Avoid creating non-monotonous DTS */
3941  dts_correction += current_dts - last_dts - 1;
3942  current_dts = last_dts + 1;
3943  }
3944  last_dts = current_dts;
3945  distance++;
3946  stts_sample++;
3947  current_sample++;
3948  if (stts_index + 1 < sc->stts_count && stts_sample == sc->stts_data[stts_index].count) {
3949  stts_sample = 0;
3950  stts_index++;
3951  }
3952  }
3953  }
3954  if (st->duration > 0)
3955  st->codecpar->bit_rate = stream_size*8*sc->time_scale/st->duration;
3956  } else {
3957  unsigned chunk_samples, total = 0;
3958 
3959  if (!sc->chunk_count)
3960  return;
3961 
3962  // compute total chunk count
3963  for (i = 0; i < sc->stsc_count; i++) {
3964  unsigned count, chunk_count;
3965 
3966  chunk_samples = sc->stsc_data[i].count;
3967  if (i != sc->stsc_count - 1 &&
3968  sc->samples_per_frame && chunk_samples % sc->samples_per_frame) {
3969  av_log(mov->fc, AV_LOG_ERROR, "error unaligned chunk\n");
3970  return;
3971  }
3972 
3973  if (sc->samples_per_frame >= 160) { // gsm
3974  count = chunk_samples / sc->samples_per_frame;
3975  } else if (sc->samples_per_frame > 1) {
3976  unsigned samples = (1024/sc->samples_per_frame)*sc->samples_per_frame;
3977  count = (chunk_samples+samples-1) / samples;
3978  } else {
3979  count = (chunk_samples+1023) / 1024;
3980  }
3981 
3982  if (mov_stsc_index_valid(i, sc->stsc_count))
3983  chunk_count = sc->stsc_data[i+1].first - sc->stsc_data[i].first;
3984  else
3985  chunk_count = sc->chunk_count - (sc->stsc_data[i].first - 1);
3986  total += chunk_count * count;
3987  }
3988 
3989  av_log(mov->fc, AV_LOG_TRACE, "chunk count %u\n", total);
3990  if (total >= UINT_MAX / sizeof(*st->index_entries) - st->nb_index_entries)
3991  return;
3993  st->nb_index_entries + total,
3994  sizeof(*st->index_entries)) < 0) {
3995  st->nb_index_entries = 0;
3996  return;
3997  }
3998  st->index_entries_allocated_size = (st->nb_index_entries + total) * sizeof(*st->index_entries);
3999 
4000  // populate index
4001  for (i = 0; i < sc->chunk_count; i++) {
4002  current_offset = sc->chunk_offsets[i];
4003  if (mov_stsc_index_valid(stsc_index, sc->stsc_count) &&
4004  i + 1 == sc->stsc_data[stsc_index + 1].first)
4005  stsc_index++;
4006  chunk_samples = sc->stsc_data[stsc_index].count;
4007 
4008  while (chunk_samples > 0) {
4009  AVIndexEntry *e;
4010  unsigned size, samples;
4011 
4012  if (sc->samples_per_frame > 1 && !sc->bytes_per_frame) {
4014  "Zero bytes per frame, but %d samples per frame",
4015  sc->samples_per_frame);
4016  return;
4017  }
4018 
4019  if (sc->samples_per_frame >= 160) { // gsm
4020  samples = sc->samples_per_frame;
4021  size = sc->bytes_per_frame;
4022  } else {
4023  if (sc->samples_per_frame > 1) {
4024  samples = FFMIN((1024 / sc->samples_per_frame)*
4025  sc->samples_per_frame, chunk_samples);
4027  } else {
4028  samples = FFMIN(1024, chunk_samples);
4029  size = samples * sc->sample_size;
4030  }
4031  }
4032 
4033  if (st->nb_index_entries >= total) {
4034  av_log(mov->fc, AV_LOG_ERROR, "wrong chunk count %u\n", total);
4035  return;
4036  }
4037  if (size > 0x3FFFFFFF) {
4038  av_log(mov->fc, AV_LOG_ERROR, "Sample size %u is too large\n", size);
4039  return;
4040  }
4041  e = &st->index_entries[st->nb_index_entries++];
4042  e->pos = current_offset;
4043  e->timestamp = current_dts;
4044  e->size = size;
4045  e->min_distance = 0;
4046  e->flags = AVINDEX_KEYFRAME;
4047  av_log(mov->fc, AV_LOG_TRACE, "AVIndex stream %d, chunk %u, offset %"PRIx64", dts %"PRId64", "
4048  "size %u, duration %u\n", st->index, i, current_offset, current_dts,
4049  size, samples);
4050 
4051  current_offset += size;
4052  current_dts += samples;
4053  chunk_samples -= samples;
4054  }
4055  }
4056  }
4057 
4058  if (!mov->ignore_editlist && mov->advanced_editlist) {
4059  // Fix index according to edit lists.
4060  mov_fix_index(mov, st);
4061  }
4062 
4063  // Update start time of the stream.
4065  st->start_time = st->index_entries[0].timestamp + sc->dts_shift;
4066  if (sc->ctts_data) {
4067  st->start_time += sc->ctts_data[0].duration;
4068  }
4069  }
4070 
4071  mov_estimate_video_delay(mov, st);
4072 }
4073 
4074 static int test_same_origin(const char *src, const char *ref) {
4075  char src_proto[64];
4076  char ref_proto[64];
4077  char src_auth[256];
4078  char ref_auth[256];
4079  char src_host[256];
4080  char ref_host[256];
4081  int src_port=-1;
4082  int ref_port=-1;
4083 
4084  av_url_split(src_proto, sizeof(src_proto), src_auth, sizeof(src_auth), src_host, sizeof(src_host), &src_port, NULL, 0, src);
4085  av_url_split(ref_proto, sizeof(ref_proto), ref_auth, sizeof(ref_auth), ref_host, sizeof(ref_host), &ref_port, NULL, 0, ref);
4086 
4087  if (strlen(src) == 0) {
4088  return -1;
4089  } else if (strlen(src_auth) + 1 >= sizeof(src_auth) ||
4090  strlen(ref_auth) + 1 >= sizeof(ref_auth) ||
4091  strlen(src_host) + 1 >= sizeof(src_host) ||
4092  strlen(ref_host) + 1 >= sizeof(ref_host)) {
4093  return 0;
4094  } else if (strcmp(src_proto, ref_proto) ||
4095  strcmp(src_auth, ref_auth) ||
4096  strcmp(src_host, ref_host) ||
4097  src_port != ref_port) {
4098  return 0;
4099  } else
4100  return 1;
4101 }
4102 
4103 static int mov_open_dref(MOVContext *c, AVIOContext **pb, const char *src, MOVDref *ref)
4104 {
4105  /* try relative path, we do not try the absolute because it can leak information about our
4106  system to an attacker */
4107  if (ref->nlvl_to > 0 && ref->nlvl_from > 0) {
4108  char filename[1025];
4109  const char *src_path;
4110  int i, l;
4111 
4112  /* find a source dir */
4113  src_path = strrchr(src, '/');
4114  if (src_path)
4115  src_path++;
4116  else
4117  src_path = src;
4118 
4119  /* find a next level down to target */
4120  for (i = 0, l = strlen(ref->path) - 1; l >= 0; l--)
4121  if (ref->path[l] == '/') {
4122  if (i == ref->nlvl_to - 1)
4123  break;
4124  else
4125  i++;
4126  }
4127 
4128  /* compose filename if next level down to target was found */
4129  if (i == ref->nlvl_to - 1 && src_path - src < sizeof(filename)) {
4130  memcpy(filename, src, src_path - src);
4131  filename[src_path - src] = 0;
4132 
4133  for (i = 1; i < ref->nlvl_from; i++)
4134  av_strlcat(filename, "../", sizeof(filename));
4135 
4136  av_strlcat(filename, ref->path + l + 1, sizeof(filename));
4137  if (!c->use_absolute_path) {
4138  int same_origin = test_same_origin(src, filename);
4139 
4140  if (!same_origin) {
4141  av_log(c->fc, AV_LOG_ERROR,
4142  "Reference with mismatching origin, %s not tried for security reasons, "
4143  "set demuxer option use_absolute_path to allow it anyway\n",
4144  ref->path);
4145  return AVERROR(ENOENT);
4146  }
4147 
4148  if(strstr(ref->path + l + 1, "..") ||
4149  strstr(ref->path + l + 1, ":") ||
4150  (ref->nlvl_from > 1 && same_origin < 0) ||
4151  (filename[0] == '/' && src_path == src))
4152  return AVERROR(ENOENT);
4153  }
4154 
4155  if (strlen(filename) + 1 == sizeof(filename))
4156  return AVERROR(ENOENT);
4157  if (!c->fc->io_open(c->fc, pb, filename, AVIO_FLAG_READ, NULL))
4158  return 0;
4159  }
4160  } else if (c->use_absolute_path) {
4161  av_log(c->fc, AV_LOG_WARNING, "Using absolute path on user request, "
4162  "this is a possible security issue\n");
4163  if (!c->fc->io_open(c->fc, pb, ref->path, AVIO_FLAG_READ, NULL))
4164  return 0;
4165  } else {
4166  av_log(c->fc, AV_LOG_ERROR,
4167  "Absolute path %s not tried for security reasons, "
4168  "set demuxer option use_absolute_path to allow absolute paths\n",
4169  ref->path);
4170  }
4171 
4172  return AVERROR(ENOENT);
4173 }
4174 
4176 {
4177  if (sc->time_scale <= 0) {
4178  av_log(c->fc, AV_LOG_WARNING, "stream %d, timescale not set\n", sc->ffindex);
4179  sc->time_scale = c->time_scale;
4180  if (sc->time_scale <= 0)
4181  sc->time_scale = 1;
4182  }
4183 }
4184 
4186 {
4187  AVStream *st;
4188  MOVStreamContext *sc;
4189  int ret;
4190 
4191  st = avformat_new_stream(c->fc, NULL);
4192  if (!st) return AVERROR(ENOMEM);
4193  st->id = -1;
4194  sc = av_mallocz(sizeof(MOVStreamContext));
4195  if (!sc) return AVERROR(ENOMEM);
4196 
4197  st->priv_data = sc;
4199  sc->ffindex = st->index;
4200  c->trak_index = st->index;
4201 
4202  if ((ret = mov_read_default(c, pb, atom)) < 0)
4203  return ret;
4204 
4205  c->trak_index = -1;
4206 
4207  // Here stsc refers to a chunk not described in stco. This is technically invalid,
4208  // but we can overlook it (clearing stsc) whenever stts_count == 0 (indicating no samples).
4209  if (!sc->chunk_count && !sc->stts_count && sc->stsc_count) {
4210  sc->stsc_count = 0;
4211  av_freep(&sc->stsc_data);
4212  }
4213 
4214  /* sanity checks */
4215  if ((sc->chunk_count && (!sc->stts_count || !sc->stsc_count ||
4216  (!sc->sample_size && !sc->sample_count))) ||
4217  (!sc->chunk_count && sc->sample_count)) {
4218  av_log(c->fc, AV_LOG_ERROR, "stream %d, missing mandatory atoms, broken header\n",
4219  st->index);
4220  return 0;
4221  }
4222  if (sc->stsc_count && sc->stsc_data[ sc->stsc_count - 1 ].first > sc->chunk_count) {
4223  av_log(c->fc, AV_LOG_ERROR, "stream %d, contradictionary STSC and STCO\n",
4224  st->index);
4225  return AVERROR_INVALIDDATA;
4226  }
4227 
4228  fix_timescale(c, sc);
4229 
4230  avpriv_set_pts_info(st, 64, 1, sc->time_scale);
4231 
4232  mov_build_index(c, st);
4233 
4234  if (sc->dref_id-1 < sc->drefs_count && sc->drefs[sc->dref_id-1].path) {
4235  MOVDref *dref = &sc->drefs[sc->dref_id - 1];
4236  if (c->enable_drefs) {
4237  if (mov_open_dref(c, &sc->pb, c->fc->url, dref) < 0)
4238  av_log(c->fc, AV_LOG_ERROR,
4239  "stream %d, error opening alias: path='%s', dir='%s', "
4240  "filename='%s', volume='%s', nlvl_from=%d, nlvl_to=%d\n",
4241  st->index, dref->path, dref->dir, dref->filename,
4242  dref->volume, dref->nlvl_from, dref->nlvl_to);
4243  } else {
4244  av_log(c->fc, AV_LOG_WARNING,
4245  "Skipped opening external track: "
4246  "stream %d, alias: path='%s', dir='%s', "
4247  "filename='%s', volume='%s', nlvl_from=%d, nlvl_to=%d."
4248  "Set enable_drefs to allow this.\n",
4249  st->index, dref->path, dref->dir, dref->filename,
4250  dref->volume, dref->nlvl_from, dref->nlvl_to);
4251  }
4252  } else {
4253  sc->pb = c->fc->pb;
4254  sc->pb_is_copied = 1;
4255  }
4256 
4257  if (st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO) {
4258  if (!st->sample_aspect_ratio.num && st->codecpar->width && st->codecpar->height &&
4259  sc->height && sc->width &&
4260  (st->codecpar->width != sc->width || st->codecpar->height != sc->height)) {
4261  st->sample_aspect_ratio = av_d2q(((double)st->codecpar->height * sc->width) /
4262  ((double)st->codecpar->width * sc->height), INT_MAX);
4263  }
4264 
4265 #if FF_API_R_FRAME_RATE
4266  if (sc->stts_count == 1 || (sc->stts_count == 2 && sc->stts_data[1].count == 1))
4268  sc->time_scale, sc->stts_data[0].duration, INT_MAX);
4269 #endif
4270  }
4271 
4272  // done for ai5q, ai52, ai55, ai1q, ai12 and ai15.
4273  if (!st->codecpar->extradata_size && st->codecpar->codec_id == AV_CODEC_ID_H264 &&
4274  TAG_IS_AVCI(st->codecpar->codec_tag)) {
4276  if (ret < 0)
4277  return ret;
4278  }
4279 
4280  switch (st->codecpar->codec_id) {
4281 #if CONFIG_H261_DECODER
4282  case AV_CODEC_ID_H261:
4283 #endif
4284 #if CONFIG_H263_DECODER
4285  case AV_CODEC_ID_H263:
4286 #endif
4287 #if CONFIG_MPEG4_DECODER
4288  case AV_CODEC_ID_MPEG4:
4289 #endif
4290  st->codecpar->width = 0; /* let decoder init width/height */
4291  st->codecpar->height= 0;
4292  break;
4293  }
4294 
4295  // If the duration of the mp3 packets is not constant, then they could need a parser
4296  if (st->codecpar->codec_id == AV_CODEC_ID_MP3
4297  && sc->stts_count > 3
4298  && sc->stts_count*10 > st->nb_frames
4299  && sc->time_scale == st->codecpar->sample_rate) {
4301  }
4302  /* Do not need those anymore. */
4303  av_freep(&sc->chunk_offsets);
4304  av_freep(&sc->sample_sizes);
4305  av_freep(&sc->keyframes);
4306  av_freep(&sc->stts_data);
4307  av_freep(&sc->stps_data);
4308  av_freep(&sc->elst_data);
4309  av_freep(&sc->rap_group);
4310 
4311  return 0;
4312 }
4313 
4315 {
4316  int ret;
4317  c->itunes_metadata = 1;
4318  ret = mov_read_default(c, pb, atom);
4319  c->itunes_metadata = 0;
4320  return ret;
4321 }
4322 
4324 {
4325  uint32_t count;
4326  uint32_t i;
4327 
4328  if (atom.size < 8)
4329  return 0;
4330 
4331  avio_skip(pb, 4);
4332  count = avio_rb32(pb);
4333  if (count > UINT_MAX / sizeof(*c->meta_keys) - 1) {
4334  av_log(c->fc, AV_LOG_ERROR,
4335  "The 'keys' atom with the invalid key count: %"PRIu32"\n", count);
4336  return AVERROR_INVALIDDATA;
4337  }
4338 
4339  c->meta_keys_count = count + 1;
4340  c->meta_keys = av_mallocz(c->meta_keys_count * sizeof(*c->meta_keys));
4341  if (!c->meta_keys)
4342  return AVERROR(ENOMEM);
4343 
4344  for (i = 1; i <= count; ++i) {
4345  uint32_t key_size = avio_rb32(pb);
4346  uint32_t type = avio_rl32(pb);
4347  if (key_size < 8) {
4348  av_log(c->fc, AV_LOG_ERROR,
4349  "The key# %"PRIu32" in meta has invalid size:"
4350  "%"PRIu32"\n", i, key_size);
4351  return AVERROR_INVALIDDATA;
4352  }
4353  key_size -= 8;
4354  if (type != MKTAG('m','d','t','a')) {
4355  avio_skip(pb, key_size);
4356  }
4357  c->meta_keys[i] = av_mallocz(key_size + 1);
4358  if (!c->meta_keys[i])
4359  return AVERROR(ENOMEM);
4360  avio_read(pb, c->meta_keys[i], key_size);
4361  }
4362 
4363  return 0;
4364 }
4365 
4367 {
4368  int64_t end = avio_tell(pb) + atom.size;
4369  uint8_t *key = NULL, *val = NULL, *mean = NULL;
4370  int i;
4371  int ret = 0;
4372  AVStream *st;
4373  MOVStreamContext *sc;
4374 
4375  if (c->fc->nb_streams < 1)
4376  return 0;
4377  st = c->fc->streams[c->fc->nb_streams-1];
4378  sc = st->priv_data;
4379 
4380  for (i = 0; i < 3; i++) {
4381  uint8_t **p;
4382  uint32_t len, tag;
4383 
4384  if (end - avio_tell(pb) <= 12)
4385  break;
4386 
4387  len = avio_rb32(pb);
4388  tag = avio_rl32(pb);
4389  avio_skip(pb, 4); // flags
4390 
4391  if (len < 12 || len - 12 > end - avio_tell(pb))
4392  break;
4393  len -= 12;
4394 
4395  if (tag == MKTAG('m', 'e', 'a', 'n'))
4396  p = &mean;
4397  else if (tag == MKTAG('n', 'a', 'm', 'e'))
4398  p = &key;
4399  else if (tag == MKTAG('d', 'a', 't', 'a') && len > 4) {
4400  avio_skip(pb, 4);
4401  len -= 4;
4402  p = &val;
4403  } else
4404  break;
4405 
4406  if (*p)
4407  break;
4408 
4409  *p = av_malloc(len + 1);
4410  if (!*p) {
4411  ret = AVERROR(ENOMEM);
4412  break;
4413  }
4414  ret = ffio_read_size(pb, *p, len);
4415  if (ret < 0) {
4416  av_freep(p);
4417  break;
4418  }
4419  (*p)[len] = 0;
4420  }
4421 
4422  if (mean && key && val) {
4423  if (strcmp(key, "iTunSMPB") == 0) {
4424  int priming, remainder, samples;
4425  if(sscanf(val, "%*X %X %X %X", &priming, &remainder, &samples) == 3){
4426  if(priming>0 && priming<16384)
4427  sc->start_pad = priming;
4428  }
4429  }
4430  if (strcmp(key, "cdec") != 0) {
4431  av_dict_set(&c->fc->metadata, key, val,
4433  key = val = NULL;
4434  }
4435  } else {
4436  av_log(c->fc, AV_LOG_VERBOSE,
4437  "Unhandled or malformed custom metadata of size %"PRId64"\n", atom.size);
4438  }
4439 
4440  avio_seek(pb, end, SEEK_SET);
4441  av_freep(&key);
4442  av_freep(&val);
4443  av_freep(&mean);
4444  return ret;
4445 }
4446 
4448 {
4449  while (atom.size > 8) {
4450  uint32_t tag;
4451  if (avio_feof(pb))
4452  return AVERROR_EOF;
4453  tag = avio_rl32(pb);
4454  atom.size -= 4;
4455  if (tag == MKTAG('h','d','l','r')) {
4456  avio_seek(pb, -8, SEEK_CUR);
4457  atom.size += 8;
4458  return mov_read_default(c, pb, atom);
4459  }
4460  }
4461  return 0;
4462 }
4463 
4464 // return 1 when matrix is identity, 0 otherwise
4465 #define IS_MATRIX_IDENT(matrix) \
4466  ( (matrix)[0][0] == (1 << 16) && \
4467  (matrix)[1][1] == (1 << 16) && \
4468  (matrix)[2][2] == (1 << 30) && \
4469  !(matrix)[0][1] && !(matrix)[0][2] && \
4470  !(matrix)[1][0] && !(matrix)[1][2] && \
4471  !(matrix)[2][0] && !(matrix)[2][1])
4472 
4474 {
4475  int i, j, e;
4476  int width;
4477  int height;
4478  int display_matrix[3][3];
4479  int res_display_matrix[3][3] = { { 0 } };
4480  AVStream *st;
4481  MOVStreamContext *sc;
4482  int version;
4483  int flags;
4484 
4485  if (c->fc->nb_streams < 1)
4486  return 0;
4487  st = c->fc->streams[c->fc->nb_streams-1];
4488  sc = st->priv_data;
4489 
4490  // Each stream (trak) should have exactly 1 tkhd. This catches bad files and
4491  // avoids corrupting AVStreams mapped to an earlier tkhd.
4492  if (st->id != -1)
4493  return AVERROR_INVALIDDATA;
4494 
4495  version = avio_r8(pb);
4496  flags = avio_rb24(pb);
4498 
4499  if (version == 1) {
4500  avio_rb64(pb);
4501  avio_rb64(pb);
4502  } else {
4503  avio_rb32(pb); /* creation time */
4504  avio_rb32(pb); /* modification time */
4505  }
4506  st->id = (int)avio_rb32(pb); /* track id (NOT 0 !)*/
4507  avio_rb32(pb); /* reserved */
4508 
4509  /* highlevel (considering edits) duration in movie timebase */
4510  (version == 1) ? avio_rb64(pb) : avio_rb32(pb);
4511  avio_rb32(pb); /* reserved */
4512  avio_rb32(pb); /* reserved */
4513 
4514  avio_rb16(pb); /* layer */
4515  avio_rb16(pb); /* alternate group */
4516  avio_rb16(pb); /* volume */
4517  avio_rb16(pb); /* reserved */
4518 
4519  //read in the display matrix (outlined in ISO 14496-12, Section 6.2.2)
4520  // they're kept in fixed point format through all calculations
4521  // save u,v,z to store the whole matrix in the AV_PKT_DATA_DISPLAYMATRIX
4522  // side data, but the scale factor is not needed to calculate aspect ratio
4523  for (i = 0; i < 3; i++) {
4524  display_matrix[i][0] = avio_rb32(pb); // 16.16 fixed point
4525  display_matrix[i][1] = avio_rb32(pb); // 16.16 fixed point
4526  display_matrix[i][2] = avio_rb32(pb); // 2.30 fixed point
4527  }
4528 
4529  width = avio_rb32(pb); // 16.16 fixed point track width
4530  height = avio_rb32(pb); // 16.16 fixed point track height
4531  sc->width = width >> 16;
4532  sc->height = height >> 16;
4533 
4534  // apply the moov display matrix (after the tkhd one)
4535  for (i = 0; i < 3; i++) {
4536  const int sh[3] = { 16, 16, 30 };
4537  for (j = 0; j < 3; j++) {
4538  for (e = 0; e < 3; e++) {
4539  res_display_matrix[i][j] +=
4540  ((int64_t) display_matrix[i][e] *
4541  c->movie_display_matrix[e][j]) >> sh[e];
4542  }
4543  }
4544  }
4545 
4546  // save the matrix when it is not the default identity
4547  if (!IS_MATRIX_IDENT(res_display_matrix)) {
4548  double rotate;
4549 
4550  av_freep(&sc->display_matrix);
4551  sc->display_matrix = av_malloc(sizeof(int32_t) * 9);
4552  if (!sc->display_matrix)
4553  return AVERROR(ENOMEM);
4554 
4555  for (i = 0; i < 3; i++)
4556  for (j = 0; j < 3; j++)
4557  sc->display_matrix[i * 3 + j] = res_display_matrix[i][j];
4558 
4561  if (!isnan(rotate)) {
4562  char rotate_buf[64];
4563  rotate = -rotate;
4564  if (rotate < 0) // for backward compatibility
4565  rotate += 360;
4566  snprintf(rotate_buf, sizeof(rotate_buf), "%g", rotate);
4567  av_dict_set(&st->metadata, "rotate", rotate_buf, 0);
4568  }
4569 #endif
4570  }
4571 
4572  // transform the display width/height according to the matrix
4573  // to keep the same scale, use [width height 1<<16]
4574  if (width && height && sc->display_matrix) {
4575  double disp_transform[2];
4576 
4577  for (i = 0; i < 2; i++)
4578  disp_transform[i] = hypot(sc->display_matrix[0 + i],
4579  sc->display_matrix[3 + i]);
4580 
4581  if (disp_transform[0] > 0 && disp_transform[1] > 0 &&
4582  disp_transform[0] < (1<<24) && disp_transform[1] < (1<<24) &&
4583  fabs((disp_transform[0] / disp_transform[1]) - 1.0) > 0.01)
4585  disp_transform[0] / disp_transform[1],
4586  INT_MAX);
4587  }
4588  return 0;
4589 }
4590 
4592 {
4593  MOVFragment *frag = &c->fragment;
4594  MOVTrackExt *trex = NULL;
4595  int flags, track_id, i;
4596 
4597  avio_r8(pb); /* version */
4598  flags = avio_rb24(pb);
4599 
4600  track_id = avio_rb32(pb);
4601  if (!track_id)
4602  return AVERROR_INVALIDDATA;
4603  for (i = 0; i < c->trex_count; i++)
4604  if (c->trex_data[i].track_id == track_id) {
4605  trex = &c->trex_data[i];
4606  break;
4607  }
4608  if (!trex) {
4609  av_log(c->fc, AV_LOG_WARNING, "could not find corresponding trex (id %u)\n", track_id);
4610  return 0;
4611  }
4612  c->fragment.found_tfhd = 1;
4613  frag->track_id = track_id;
4614  set_frag_stream(&c->frag_index, track_id);
4615 
4618  frag->moof_offset : frag->implicit_offset;
4619  frag->stsd_id = flags & MOV_TFHD_STSD_ID ? avio_rb32(pb) : trex->stsd_id;
4620 
4622  avio_rb32(pb) : trex->duration;
4623  frag->size = flags & MOV_TFHD_DEFAULT_SIZE ?
4624  avio_rb32(pb) : trex->size;
4625  frag->flags = flags & MOV_TFHD_DEFAULT_FLAGS ?
4626  avio_rb32(pb) : trex->flags;
4627  av_log(c->fc, AV_LOG_TRACE, "frag flags 0x%x\n", frag->flags);
4628 
4629  return 0;
4630 }
4631 
4633 {
4634  unsigned i, num;
4635  void *new_tracks;
4636 
4637  num = atom.size / 4;
4638  if (!(new_tracks = av_malloc_array(num, sizeof(int))))
4639  return AVERROR(ENOMEM);
4640 
4641  av_free(c->chapter_tracks);
4642  c->chapter_tracks = new_tracks;
4643  c->nb_chapter_tracks = num;
4644 
4645  for (i = 0; i < num && !pb->eof_reached; i++)
4646  c->chapter_tracks[i] = avio_rb32(pb);
4647 
4648  c->nb_chapter_tracks = i;
4649 
4650  return 0;
4651 }
4652 
4654 {
4655  MOVTrackExt *trex;
4656  int err;
4657 
4658  if ((uint64_t)c->trex_count+1 >= UINT_MAX / sizeof(*c->trex_data))
4659  return AVERROR_INVALIDDATA;
4660  if ((err = av_reallocp_array(&c->trex_data, c->trex_count + 1,
4661  sizeof(*c->trex_data))) < 0) {
4662  c->trex_count = 0;
4663  return err;
4664  }
4665 
4666  c->fc->duration = AV_NOPTS_VALUE; // the duration from mvhd is not representing the whole file when fragments are used.
4667 
4668  trex = &c->trex_data[c->trex_count++];
4669  avio_r8(pb); /* version */
4670  avio_rb24(pb); /* flags */
4671  trex->track_id = avio_rb32(pb);
4672  trex->stsd_id = avio_rb32(pb);
4673  trex->duration = avio_rb32(pb);
4674  trex->size = avio_rb32(pb);
4675  trex->flags = avio_rb32(pb);
4676  return 0;
4677 }
4678 
4680 {
4681  MOVFragment *frag = &c->fragment;
4682  AVStream *st = NULL;
4683  MOVStreamContext *sc;
4684  int version, i;
4685  MOVFragmentStreamInfo * frag_stream_info;
4686  int64_t base_media_decode_time;
4687 
4688  for (i = 0; i < c->fc->nb_streams; i++) {
4689  if (c->fc->streams[i]->id == frag->track_id) {
4690  st = c->fc->streams[i];
4691  break;
4692  }
4693  }
4694  if (!st) {
4695  av_log(c->fc, AV_LOG_WARNING, "could not find corresponding track id %u\n", frag->track_id);
4696  return 0;
4697  }
4698  sc = st->priv_data;
4699  if (sc->pseudo_stream_id + 1 != frag->stsd_id && sc->pseudo_stream_id != -1)
4700  return 0;
4701  version = avio_r8(pb);
4702  avio_rb24(pb); /* flags */
4703  if (version) {
4704  base_media_decode_time = avio_rb64(pb);
4705  } else {
4706  base_media_decode_time = avio_rb32(pb);
4707  }
4708 
4709  frag_stream_info = get_current_frag_stream_info(&c->frag_index);
4710  if (frag_stream_info)
4711  frag_stream_info->tfdt_dts = base_media_decode_time;
4712  sc->track_end = base_media_decode_time;
4713 
4714  return 0;
4715 }
4716 
4718 {
4719  MOVFragment *frag = &c->fragment;
4720  AVStream *st = NULL;
4721  MOVStreamContext *sc;
4722  MOVStts *ctts_data;
4723  uint64_t offset;
4724  int64_t dts, pts = AV_NOPTS_VALUE;
4725  int data_offset = 0;
4726  unsigned entries, first_sample_flags = frag->flags;
4727  int flags, distance, i;
4728  int64_t prev_dts = AV_NOPTS_VALUE;
4729  int next_frag_index = -1, index_entry_pos;
4730  size_t requested_size;
4731  size_t old_ctts_allocated_size;
4732  AVIndexEntry *new_entries;
4733  MOVFragmentStreamInfo * frag_stream_info;
4734 
4735  if (!frag->found_tfhd) {
4736  av_log(c->fc, AV_LOG_ERROR, "trun track id unknown, no tfhd was found\n");
4737  return AVERROR_INVALIDDATA;
4738  }
4739 
4740  for (i = 0; i < c->fc->nb_streams; i++) {
4741  if (c->fc->streams[i]->id == frag->track_id) {
4742  st = c->fc->streams[i];
4743  break;
4744  }
4745  }
4746  if (!st) {
4747  av_log(c->fc, AV_LOG_WARNING, "could not find corresponding track id %u\n", frag->track_id);
4748  return 0;
4749  }
4750  sc = st->priv_data;
4751  if (sc->pseudo_stream_id+1 != frag->stsd_id && sc->pseudo_stream_id != -1)
4752  return 0;
4753 
4754  // Find the next frag_index index that has a valid index_entry for
4755  // the current track_id.
4756  //
4757  // A valid index_entry means the trun for the fragment was read
4758  // and it's samples are in index_entries at the given position.
4759  // New index entries will be inserted before the index_entry found.
4760  index_entry_pos = st->nb_index_entries;
4761  for (i = c->frag_index.current + 1; i < c->frag_index.nb_items; i++) {
4762  frag_stream_info = get_frag_stream_info(&c->frag_index, i, frag->track_id);
4763  if (frag_stream_info && frag_stream_info->index_entry >= 0) {
4764  next_frag_index = i;
4765  index_entry_pos = frag_stream_info->index_entry;
4766  break;
4767  }
4768  }
4769  av_assert0(index_entry_pos <= st->nb_index_entries);
4770 
4771  avio_r8(pb); /* version */
4772  flags = avio_rb24(pb);
4773  entries = avio_rb32(pb);
4774  av_log(c->fc, AV_LOG_TRACE, "flags 0x%x entries %u\n", flags, entries);
4775 
4776  if ((uint64_t)entries+sc->ctts_count >= UINT_MAX/sizeof(*sc->ctts_data))
4777  return AVERROR_INVALIDDATA;
4778  if (flags & MOV_TRUN_DATA_OFFSET) data_offset = avio_rb32(pb);
4779  if (flags & MOV_TRUN_FIRST_SAMPLE_FLAGS) first_sample_flags = avio_rb32(pb);
4780 
4781  frag_stream_info = get_current_frag_stream_info(&c->frag_index);
4782  if (frag_stream_info)
4783  {
4784  if (frag_stream_info->first_tfra_pts != AV_NOPTS_VALUE &&
4785  c->use_mfra_for == FF_MOV_FLAG_MFRA_PTS) {
4786  pts = frag_stream_info->first_tfra_pts;
4787  av_log(c->fc, AV_LOG_DEBUG, "found mfra time %"PRId64
4788  ", using it for pts\n", pts);
4789  } else if (frag_stream_info->sidx_pts != AV_NOPTS_VALUE) {
4790  // FIXME: sidx earliest_presentation_time is *PTS*, s.b.
4791  // pts = frag_stream_info->sidx_pts;
4792  dts = frag_stream_info->sidx_pts - sc->time_offset;
4793  av_log(c->fc, AV_LOG_DEBUG, "found sidx time %"PRId64
4794  ", using it for pts\n", pts);
4795  } else if (frag_stream_info->tfdt_dts != AV_NOPTS_VALUE) {
4796  dts = frag_stream_info->tfdt_dts - sc->time_offset;
4797  av_log(c->fc, AV_LOG_DEBUG, "found tfdt time %"PRId64
4798  ", using it for dts\n", dts);
4799  } else {
4800  dts = sc->track_end - sc->time_offset;
4801  av_log(c->fc, AV_LOG_DEBUG, "found track end time %"PRId64
4802  ", using it for dts\n", dts);
4803  }
4804  } else {
4805  dts = sc->track_end - sc->time_offset;
4806  av_log(c->fc, AV_LOG_DEBUG, "found track end time %"PRId64
4807  ", using it for dts\n", dts);
4808  }
4809  offset = frag->base_data_offset + data_offset;
4810  distance = 0;
4811  av_log(c->fc, AV_LOG_TRACE, "first sample flags 0x%x\n", first_sample_flags);
4812 
4813  // realloc space for new index entries
4814  if((uint64_t)st->nb_index_entries + entries >= UINT_MAX / sizeof(AVIndexEntry)) {
4815  entries = UINT_MAX / sizeof(AVIndexEntry) - st->nb_index_entries;
4816  av_log(c->fc, AV_LOG_ERROR, "Failed to add index entry\n");
4817  }
4818  if (entries <= 0)
4819  return -1;
4820 
4821  requested_size = (st->nb_index_entries + entries) * sizeof(AVIndexEntry);
4822  new_entries = av_fast_realloc(st->index_entries,
4824  requested_size);
4825  if(!new_entries)
4826  return AVERROR(ENOMEM);
4827  st->index_entries= new_entries;
4828 
4829  requested_size = (st->nb_index_entries + entries) * sizeof(*sc->ctts_data);
4830  old_ctts_allocated_size = sc->ctts_allocated_size;
4831  ctts_data = av_fast_realloc(sc->ctts_data, &sc->ctts_allocated_size,
4832  requested_size);
4833  if (!ctts_data)
4834  return AVERROR(ENOMEM);
4835  sc->ctts_data = ctts_data;
4836 
4837  // In case there were samples without ctts entries, ensure they get
4838  // zero valued entries. This ensures clips which mix boxes with and
4839  // without ctts entries don't pickup uninitialized data.
4840  memset((uint8_t*)(sc->ctts_data) + old_ctts_allocated_size, 0,
4841  sc->ctts_allocated_size - old_ctts_allocated_size);
4842 
4843  if (index_entry_pos < st->nb_index_entries) {
4844  // Make hole in index_entries and ctts_data for new samples
4845  memmove(st->index_entries + index_entry_pos + entries,
4846  st->index_entries + index_entry_pos,
4847  sizeof(*st->index_entries) *
4848  (st->nb_index_entries - index_entry_pos));
4849  memmove(sc->ctts_data + index_entry_pos + entries,
4850  sc->ctts_data + index_entry_pos,
4851  sizeof(*sc->ctts_data) * (sc->ctts_count - index_entry_pos));
4852  if (index_entry_pos < sc->current_sample) {
4853  sc->current_sample += entries;
4854  }
4855  }
4856 
4857  st->nb_index_entries += entries;
4858  sc->ctts_count = st->nb_index_entries;
4859 
4860  // Record the index_entry position in frag_index of this fragment
4861  if (frag_stream_info)
4862  frag_stream_info->index_entry = index_entry_pos;
4863 
4864  if (index_entry_pos > 0)
4865  prev_dts = st->index_entries[index_entry_pos-1].timestamp;
4866 
4867  for (i = 0; i < entries && !pb->eof_reached; i++) {
4868  unsigned sample_size = frag->size;
4869  int sample_flags = i ? frag->flags : first_sample_flags;
4870  unsigned sample_duration = frag->duration;
4871  unsigned ctts_duration = 0;
4872  int keyframe = 0;
4873  int index_entry_flags = 0;
4874 
4875  if (flags & MOV_TRUN_SAMPLE_DURATION) sample_duration = avio_rb32(pb);
4876  if (flags & MOV_TRUN_SAMPLE_SIZE) sample_size = avio_rb32(pb);
4877  if (flags & MOV_TRUN_SAMPLE_FLAGS) sample_flags = avio_rb32(pb);
4878  if (flags & MOV_TRUN_SAMPLE_CTS) ctts_duration = avio_rb32(pb);
4879 
4880  mov_update_dts_shift(sc, ctts_duration);
4881  if (pts != AV_NOPTS_VALUE) {
4882  dts = pts - sc->dts_shift;
4883  if (flags & MOV_TRUN_SAMPLE_CTS) {
4884  dts -= ctts_duration;
4885  } else {
4886  dts -= sc->time_offset;
4887  }
4888  av_log(c->fc, AV_LOG_DEBUG,
4889  "pts %"PRId64" calculated dts %"PRId64
4890  " sc->dts_shift %d ctts.duration %d"
4891  " sc->time_offset %"PRId64
4892  " flags & MOV_TRUN_SAMPLE_CTS %d\n",
4893  pts, dts,
4894  sc->dts_shift, ctts_duration,
4896  pts = AV_NOPTS_VALUE;
4897  }
4898 
4900  keyframe = 1;
4901  else
4902  keyframe =
4903  !(sample_flags & (MOV_FRAG_SAMPLE_FLAG_IS_NON_SYNC |
4905  if (keyframe) {
4906  distance = 0;
4907  index_entry_flags |= AVINDEX_KEYFRAME;
4908  }
4909  // Fragments can overlap in time. Discard overlapping frames after
4910  // decoding.
4911  if (prev_dts >= dts)
4912  index_entry_flags |= AVINDEX_DISCARD_FRAME;
4913 
4914  st->index_entries[index_entry_pos].pos = offset;
4915  st->index_entries[index_entry_pos].timestamp = dts;
4916  st->index_entries[index_entry_pos].size= sample_size;
4917  st->index_entries[index_entry_pos].min_distance= distance;
4918  st->index_entries[index_entry_pos].flags = index_entry_flags;
4919 
4920  sc->ctts_data[index_entry_pos].count = 1;
4921  sc->ctts_data[index_entry_pos].duration = ctts_duration;
4922  index_entry_pos++;
4923 
4924  av_log(c->fc, AV_LOG_TRACE, "AVIndex stream %d, sample %d, offset %"PRIx64", dts %"PRId64", "
4925  "size %u, distance %d, keyframe %d\n", st->index,
4926  index_entry_pos, offset, dts, sample_size, distance, keyframe);
4927  distance++;
4928  dts += sample_duration;
4929  offset += sample_size;
4930  sc->data_size += sample_size;
4931 
4932  if (sample_duration <= INT64_MAX - sc->duration_for_fps &&
4933  1 <= INT_MAX - sc->nb_frames_for_fps
4934  ) {
4935  sc->duration_for_fps += sample_duration;
4936  sc->nb_frames_for_fps ++;
4937  }
4938  }
4939  if (i < entries) {
4940  // EOF found before reading all entries. Fix the hole this would
4941  // leave in index_entries and ctts_data
4942  int gap = entries - i;
4943  memmove(st->index_entries + index_entry_pos,
4944  st->index_entries + index_entry_pos + gap,
4945  sizeof(*st->index_entries) *
4946  (st->nb_index_entries - (index_entry_pos + gap)));
4947  memmove(sc->ctts_data + index_entry_pos,
4948  sc->ctts_data + index_entry_pos + gap,
4949  sizeof(*sc->ctts_data) *
4950  (sc->ctts_count - (index_entry_pos + gap)));
4951 
4952  st->nb_index_entries -= gap;
4953  sc->ctts_count -= gap;
4954  if (index_entry_pos < sc->current_sample) {
4955  sc->current_sample -= gap;
4956  }
4957  entries = i;
4958  }
4959 
4960  // The end of this new fragment may overlap in time with the start
4961  // of the next fragment in index_entries. Mark the samples in the next
4962  // fragment that overlap with AVINDEX_DISCARD_FRAME
4963  prev_dts = AV_NOPTS_VALUE;
4964  if (index_entry_pos > 0)
4965  prev_dts = st->index_entries[index_entry_pos-1].timestamp;
4966  for (i = index_entry_pos; i < st->nb_index_entries; i++) {
4967  if (prev_dts < st->index_entries[i].timestamp)
4968  break;
4970  }
4971 
4972  // If a hole was created to insert the new index_entries into,
4973  // the index_entry recorded for all subsequent moof must
4974  // be incremented by the number of entries inserted.
4975  fix_frag_index_entries(&c->frag_index, next_frag_index,
4976  frag->track_id, entries);
4977 
4978  if (pb->eof_reached) {
4979  av_log(c->fc, AV_LOG_WARNING, "reached eof, corrupted TRUN atom\n");
4980  return AVERROR_EOF;
4981  }
4982 
4983  frag->implicit_offset = offset;
4984 
4985  sc->track_end = dts + sc->time_offset;
4986  if (st->duration < sc->track_end)
4987  st->duration = sc->track_end;
4988 
4989  return 0;
4990 }
4991 
4993 {
4994  int64_t offset = avio_tell(pb) + atom.size, pts, timestamp;
4995  uint8_t version;
4996  unsigned i, j, track_id, item_count;
4997  AVStream *st = NULL;
4998  AVStream *ref_st = NULL;
4999  MOVStreamContext *sc, *ref_sc = NULL;
5000  AVRational timescale;
5001 
5002  version = avio_r8(pb);
5003  if (version > 1) {
5004  avpriv_request_sample(c->fc, "sidx version %u", version);
5005  return 0;
5006  }
5007 
5008  avio_rb24(pb); // flags
5009 
5010  track_id = avio_rb32(pb); // Reference ID
5011  for (i = 0; i < c->fc->nb_streams; i++) {
5012  if (c->fc->streams[i]->id == track_id) {
5013  st = c->fc->streams[i];
5014  break;
5015  }
5016  }
5017  if (!st) {
5018  av_log(c->fc, AV_LOG_WARNING, "could not find corresponding track id %d\n", track_id);
5019  return 0;
5020  }
5021 
5022  sc = st->priv_data;
5023 
5024  timescale = av_make_q(1, avio_rb32(pb));
5025 
5026  if (timescale.den <= 0) {
5027  av_log(c->fc, AV_LOG_ERROR, "Invalid sidx timescale 1/%d\n", timescale.den);
5028  return AVERROR_INVALIDDATA;
5029  }
5030 
5031  if (version == 0) {
5032  pts = avio_rb32(pb);
5033  offset += avio_rb32(pb);
5034  } else {
5035  pts = avio_rb64(pb);
5036  offset += avio_rb64(pb);
5037  }
5038 
5039  avio_rb16(pb); // reserved
5040 
5041  item_count = avio_rb16(pb);
5042  if (item_count == 0)
5043  return AVERROR_INVALIDDATA;
5044 
5045  for (i = 0; i < item_count; i++) {
5046  int index;
5047  MOVFragmentStreamInfo * frag_stream_info;
5048  uint32_t size = avio_rb32(pb);
5049  uint32_t duration = avio_rb32(pb);
5050  if (size & 0x80000000) {
5051  avpriv_request_sample(c->fc, "sidx reference_type 1");
5052  return AVERROR_PATCHWELCOME;
5053  }
5054  avio_rb32(pb); // sap_flags
5055  timestamp = av_rescale_q(pts, st->time_base, timescale);
5056 
5058  frag_stream_info = get_frag_stream_info(&c->frag_index, index, track_id);
5059  if (frag_stream_info)
5060  frag_stream_info->sidx_pts = timestamp;
5061 
5062  offset += size;
5063  pts += duration;
5064  }
5065 
5066  st->duration = sc->track_end = pts;
5067 
5068  sc->has_sidx = 1;
5069 
5070  if (offset == avio_size(pb)) {
5071  // Find first entry in fragment index that came from an sidx.
5072  // This will pretty much always be the first entry.
5073  for (i = 0; i < c->frag_index.nb_items; i++) {
5074  MOVFragmentIndexItem * item = &c->frag_index.item[i];
5075  for (j = 0; ref_st == NULL && j < item->nb_stream_info; j++) {
5076  MOVFragmentStreamInfo * si;
5077  si = &item->stream_info[j];
5078  if (si->sidx_pts != AV_NOPTS_VALUE) {
5079  ref_st = c->fc->streams[j];
5080  ref_sc = ref_st->priv_data;
5081  break;
5082  }
5083  }
5084  }
5085  if (ref_st) for (i = 0; i < c->fc->nb_streams; i++) {
5086  st = c->fc->streams[i];
5087  sc = st->priv_data;
5088  if (!sc->has_sidx) {
5089  st->duration = sc->track_end = av_rescale(ref_st->duration, sc->time_scale, ref_sc->time_scale);
5090  }
5091  }
5092 
5093  c->frag_index.complete = 1;
5094  }
5095 
5096  return 0;
5097 }
5098 
5099 /* this atom should be null (from specs), but some buggy files put the 'moov' atom inside it... */
5100 /* like the files created with Adobe Premiere 5.0, for samples see */
5101 /* http://graphics.tudelft.nl/~wouter/publications/soundtests/ */
5103 {
5104  int err;
5105 
5106  if (atom.size < 8)
5107  return 0; /* continue */
5108  if (avio_rb32(pb) != 0) { /* 0 sized mdat atom... use the 'wide' atom size */
5109  avio_skip(pb, atom.size - 4);
5110  return 0;
5111  }
5112  atom.type = avio_rl32(pb);
5113  atom.size -= 8;
5114  if (atom.type != MKTAG('m','d','a','t')) {
5115  avio_skip(pb, atom.size);
5116  return 0;
5117  }
5118  err = mov_read_mdat(c, pb, atom);
5119  return err;
5120 }
5121 
5123 {
5124 #if CONFIG_ZLIB
5125  AVIOContext ctx;
5126  uint8_t *cmov_data;
5127  uint8_t *moov_data; /* uncompressed data */
5128  long cmov_len, moov_len;
5129  int ret = -1;
5130 
5131  avio_rb32(pb); /* dcom atom */
5132  if (avio_rl32(pb) != MKTAG('d','c','o','m'))
5133  return AVERROR_INVALIDDATA;
5134  if (avio_rl32(pb) != MKTAG('z','l','i','b')) {
5135  av_log(c->fc, AV_LOG_ERROR, "unknown compression for cmov atom !\n");
5136  return AVERROR_INVALIDDATA;
5137  }
5138  avio_rb32(pb); /* cmvd atom */
5139  if (avio_rl32(pb) != MKTAG('c','m','v','d'))
5140  return AVERROR_INVALIDDATA;
5141  moov_len = avio_rb32(pb); /* uncompressed size */
5142  cmov_len = atom.size - 6 * 4;
5143 
5144  cmov_data = av_malloc(cmov_len);
5145  if (!cmov_data)
5146  return AVERROR(ENOMEM);
5147  moov_data = av_malloc(moov_len);
5148  if (!moov_data) {
5149  av_free(cmov_data);
5150  return AVERROR(ENOMEM);
5151  }
5152  ret = ffio_read_size(pb, cmov_data, cmov_len);
5153  if (ret < 0)
5154  goto free_and_return;
5155 
5157  if (uncompress (moov_data, (uLongf *) &moov_len, (const Bytef *)cmov_data, cmov_len) != Z_OK)
5158  goto free_and_return;
5159  if (ffio_init_context(&ctx, moov_data, moov_len, 0, NULL, NULL, NULL, NULL) != 0)
5160  goto free_and_return;
5161  ctx.seekable = AVIO_SEEKABLE_NORMAL;
5162  atom.type = MKTAG('m','o','o','v');
5163  atom.size = moov_len;
5164  ret = mov_read_default(c, &ctx, atom);
5165 free_and_return:
5166  av_free(moov_data);
5167  av_free(cmov_data);
5168  return ret;
5169 #else
5170  av_log(c->fc, AV_LOG_ERROR, "this file requires zlib support compiled in\n");
5171  return AVERROR(ENOSYS);
5172 #endif
5173 }
5174 
5175 /* edit list atom */
5177 {
5178  MOVStreamContext *sc;
5179  int i, edit_count, version;
5180  int64_t elst_entry_size;
5181 
5182  if (c->fc->nb_streams < 1 || c->ignore_editlist)
5183  return 0;
5184  sc = c->fc->streams[c->fc->nb_streams-1]->priv_data;
5185 
5186  version = avio_r8(pb); /* version */
5187  avio_rb24(pb); /* flags */
5188  edit_count = avio_rb32(pb); /* entries */
5189  atom.size -= 8;
5190 
5191  elst_entry_size = version == 1 ? 20 : 12;
5192  if (atom.size != edit_count * elst_entry_size) {
5193  if (c->fc->strict_std_compliance >= FF_COMPLIANCE_STRICT) {
5194  av_log(c->fc, AV_LOG_ERROR, "Invalid edit list entry_count: %d for elst atom of size: %"PRId64" bytes.\n",
5195  edit_count, atom.size + 8);
5196  return AVERROR_INVALIDDATA;
5197  } else {
5198  edit_count = atom.size / elst_entry_size;
5199  if (edit_count * elst_entry_size != atom.size) {
5200  av_log(c->fc, AV_LOG_WARNING, "ELST atom of %"PRId64" bytes, bigger than %d entries.", atom.size, edit_count);
5201  }
5202  }
5203  }
5204 
5205  if (!edit_count)
5206  return 0;
5207  if (sc->elst_data)
5208  av_log(c->fc, AV_LOG_WARNING, "Duplicated ELST atom\n");
5209  av_free(sc->elst_data);
5210  sc->elst_count = 0;
5211  sc->elst_data = av_malloc_array(edit_count, sizeof(*sc->elst_data));
5212  if (!sc->elst_data)
5213  return AVERROR(ENOMEM);
5214 
5215  av_log(c->fc, AV_LOG_TRACE, "track[%u].edit_count = %i\n", c->fc->nb_streams - 1, edit_count);
5216  for (i = 0; i < edit_count && atom.size > 0 && !pb->eof_reached; i++) {
5217  MOVElst *e = &sc->elst_data[i];
5218 
5219  if (version == 1) {
5220  e->duration = avio_rb64(pb);
5221  e->time = avio_rb64(pb);
5222  atom.size -= 16;
5223  } else {
5224  e->duration = avio_rb32(pb); /* segment duration */
5225  e->time = (int32_t)avio_rb32(pb); /* media time */
5226  atom.size -= 8;
5227  }
5228  e->rate = avio_rb32(pb) / 65536.0;
5229  atom.size -= 4;
5230  av_log(c->fc, AV_LOG_TRACE, "duration=%"PRId64" time=%"PRId64" rate=%f\n",
5231  e->duration, e->time, e->rate);
5232 
5233  if (e->time < 0 && e->time != -1 &&
5234  c->fc->strict_std_compliance >= FF_COMPLIANCE_STRICT) {
5235  av_log(c->fc, AV_LOG_ERROR, "Track %d, edit %d: Invalid edit list media time=%"PRId64"\n",
5236  c->fc->nb_streams-1, i, e->time);
5237  return AVERROR_INVALIDDATA;
5238  }
5239  }
5240  sc->elst_count = i;
5241 
5242  return 0;
5243 }
5244 
5246 {
5247  MOVStreamContext *sc;
5248 
5249  if (c->fc->nb_streams < 1)
5250  return AVERROR_INVALIDDATA;
5251  sc = c->fc->streams[c->fc->nb_streams - 1]->priv_data;
5252  sc->timecode_track = avio_rb32(pb);
5253  return 0;
5254 }
5255 
5257 {
5258  AVStream *st;
5259  int ret;
5260 
5261  if (c->fc->nb_streams < 1)
5262  return 0;
5263  st = c->fc->streams[c->fc->nb_streams - 1];
5264 
5265  if (atom.size < 4) {
5266  av_log(c->fc, AV_LOG_ERROR, "Empty AV1 Codec Configuration Box\n");
5267  return AVERROR_INVALIDDATA;
5268  }
5269 
5270  /* For now, propagate only the OBUs, if any. Once libavcodec is
5271  updated to handle isobmff style extradata this can be removed. */
5272  avio_skip(pb, 4);
5273 
5274  if (atom.size == 4)
5275  return 0;
5276 
5277  ret = ff_get_extradata(c->fc, st->codecpar, pb, atom.size - 4);
5278  if (ret < 0)
5279  return ret;
5280 
5281  return 0;
5282 }
5283 
5285 {
5286  AVStream *st;
5287  int version, color_range, color_primaries, color_trc, color_space;
5288 
5289  if (c->fc->nb_streams < 1)
5290  return 0;
5291  st = c->fc->streams[c->fc->nb_streams - 1];
5292 
5293  if (atom.size < 5) {
5294  av_log(c->fc, AV_LOG_ERROR, "Empty VP Codec Configuration box\n");
5295  return AVERROR_INVALIDDATA;
5296  }
5297 
5298  version = avio_r8(pb);
5299  if (version != 1) {
5300  av_log(c->fc, AV_LOG_WARNING, "Unsupported VP Codec Configuration box version %d\n", version);
5301  return 0;
5302  }
5303  avio_skip(pb, 3); /* flags */
5304 
5305  avio_skip(pb, 2); /* profile + level */
5306  color_range = avio_r8(pb); /* bitDepth, chromaSubsampling, videoFullRangeFlag */
5307  color_primaries = avio_r8(pb);
5308  color_trc = avio_r8(pb);
5309  color_space = avio_r8(pb);
5310  if (avio_rb16(pb)) /* codecIntializationDataSize */
5311  return AVERROR_INVALIDDATA;
5312 
5315  if (!av_color_transfer_name(color_trc))
5316  color_trc = AVCOL_TRC_UNSPECIFIED;
5317  if (!av_color_space_name(color_space))
5318  color_space = AVCOL_SPC_UNSPECIFIED;
5319 
5322  st->codecpar->color_trc = color_trc;
5323  st->codecpar->color_space = color_space;
5324 
5325  return 0;
5326 }
5327 
5329 {
5330  MOVStreamContext *sc;
5331  int i, version;
5332 
5333  if (c->fc->nb_streams < 1)
5334  return AVERROR_INVALIDDATA;
5335 
5336  sc = c->fc->streams[c->fc->nb_streams - 1]->priv_data;
5337 
5338  if (atom.size < 5) {
5339  av_log(c->fc, AV_LOG_ERROR, "Empty Mastering Display Metadata box\n");
5340  return AVERROR_INVALIDDATA;
5341  }
5342 
5343  version = avio_r8(pb);
5344  if (version) {
5345  av_log(c->fc, AV_LOG_WARNING, "Unsupported Mastering Display Metadata box version %d\n", version);
5346  return 0;
5347  }
5348  if (sc->mastering)
5349  return AVERROR_INVALIDDATA;
5350 
5351  avio_skip(pb, 3); /* flags */
5352 
5354  if (!sc->mastering)
5355  return AVERROR(ENOMEM);
5356 
5357  for (i = 0; i < 3; i++) {
5358  sc->mastering->display_primaries[i][0] = av_make_q(avio_rb16(pb), 1 << 16);
5359  sc->mastering->display_primaries[i][1] = av_make_q(avio_rb16(pb), 1 << 16);
5360  }
5361  sc->mastering->white_point[0] = av_make_q(avio_rb16(pb), 1 << 16);
5362  sc->mastering->white_point[1] = av_make_q(avio_rb16(pb), 1 << 16);
5363 
5364  sc->mastering->max_luminance = av_make_q(avio_rb32(pb), 1 << 8);
5365  sc->mastering->min_luminance = av_make_q(avio_rb32(pb), 1 << 14);
5366 
5367  sc->mastering->has_primaries = 1;
5368  sc->mastering->has_luminance = 1;
5369 
5370  return 0;
5371 }
5372 
5374 {
5375  MOVStreamContext *sc;
5376  const int mapping[3] = {1, 2, 0};
5377  const int chroma_den = 50000;
5378  const int luma_den = 10000;
5379  int i;
5380 
5381  if (c->fc->nb_streams < 1)
5382  return AVERROR_INVALIDDATA;
5383 
5384  sc = c->fc->streams[c->fc->nb_streams - 1]->priv_data;
5385 
5386  if (atom.size < 24 || sc->mastering) {
5387  av_log(c->fc, AV_LOG_ERROR, "Invalid Mastering Display Color Volume box\n");
5388  return AVERROR_INVALIDDATA;
5389  }
5390 
5392  if (!sc->mastering)
5393  return AVERROR(ENOMEM);
5394 
5395  for (i = 0; i < 3; i++) {
5396  const int j = mapping[i];
5397  sc->mastering->display_primaries[j][0] = av_make_q(avio_rb16(pb), chroma_den);
5398  sc->mastering->display_primaries[j][1] = av_make_q(avio_rb16(pb), chroma_den);
5399  }
5400  sc->mastering->white_point[0] = av_make_q(avio_rb16(pb), chroma_den);
5401  sc->mastering->white_point[1] = av_make_q(avio_rb16(pb), chroma_den);
5402 
5403  sc->mastering->max_luminance = av_make_q(avio_rb32(pb), luma_den);
5404  sc->mastering->min_luminance = av_make_q(avio_rb32(pb), luma_den);
5405 
5406  sc->mastering->has_luminance = 1;
5407  sc->mastering->has_primaries = 1;
5408 
5409  return 0;
5410 }
5411 
5413 {
5414  MOVStreamContext *sc;
5415  int version;
5416 
5417  if (c->fc->nb_streams < 1)
5418  return AVERROR_INVALIDDATA;
5419 
5420  sc = c->fc->streams[c->fc->nb_streams - 1]->priv_data;
5421 
5422  if (atom.size < 5) {
5423  av_log(c->fc, AV_LOG_ERROR, "Empty Content Light Level box\n");
5424  return AVERROR_INVALIDDATA;
5425  }
5426 
5427  version = avio_r8(pb);
5428  if (version) {
5429  av_log(c->fc, AV_LOG_WARNING, "Unsupported Content Light Level box version %d\n", version);
5430  return 0;
5431  }
5432  avio_skip(pb, 3); /* flags */
5433 
5434  if (sc->coll){
5435  av_log(c->fc, AV_LOG_WARNING, "Ignoring duplicate COLL\n");
5436  return 0;
5437  }
5438 
5440  if (!sc->coll)
5441  return AVERROR(ENOMEM);
5442 
5443  sc->coll->MaxCLL = avio_rb16(pb);
5444  sc->coll->MaxFALL = avio_rb16(pb);
5445 
5446  return 0;
5447 }
5448 
5450 {
5451  MOVStreamContext *sc;
5452 
5453  if (c->fc->nb_streams < 1)
5454  return AVERROR_INVALIDDATA;
5455 
5456  sc = c->fc->streams[c->fc->nb_streams - 1]->priv_data;
5457 
5458  if (atom.size < 4) {
5459  av_log(c->fc, AV_LOG_ERROR, "Empty Content Light Level Info box\n");
5460  return AVERROR_INVALIDDATA;
5461  }
5462 
5463  if (sc->coll){
5464  av_log(c->fc, AV_LOG_WARNING, "Ignoring duplicate CLLI/COLL\n");
5465  return 0;
5466  }
5467 
5469  if (!sc->coll)
5470  return AVERROR(ENOMEM);
5471 
5472  sc->coll->MaxCLL = avio_rb16(pb);
5473  sc->coll->MaxFALL = avio_rb16(pb);
5474 
5475  return 0;
5476 }
5477 
5479 {
5480  AVStream *st;
5481  MOVStreamContext *sc;
5482  enum AVStereo3DType type;
5483  int mode;
5484 
5485  if (c->fc->nb_streams < 1)
5486  return 0;
5487 
5488  st = c->fc->streams[c->fc->nb_streams - 1];
5489  sc = st->priv_data;
5490 
5491  if (atom.size < 5) {
5492  av_log(c->fc, AV_LOG_ERROR, "Empty stereoscopic video box\n");
5493  return AVERROR_INVALIDDATA;
5494  }
5495 
5496  if (sc->stereo3d)
5497  return AVERROR_INVALIDDATA;
5498 
5499  avio_skip(pb, 4); /* version + flags */
5500 
5501  mode = avio_r8(pb);
5502  switch (mode) {
5503  case 0:
5504  type = AV_STEREO3D_2D;
5505  break;
5506  case 1:
5508  break;
5509  case 2:
5511  break;
5512  default:
5513  av_log(c->fc, AV_LOG_WARNING, "Unknown st3d mode value %d\n", mode);
5514  return 0;
5515  }
5516 
5517  sc->stereo3d = av_stereo3d_alloc();
5518  if (!sc->stereo3d)
5519  return AVERROR(ENOMEM);
5520 
5521  sc->stereo3d->type = type;
5522  return 0;
5523 }
5524 
5526 {
5527  AVStream *st;
5528  MOVStreamContext *sc;
5529  int size, version, layout;
5530  int32_t yaw, pitch, roll;
5531  uint32_t l = 0, t = 0, r = 0, b = 0;
5532  uint32_t tag, padding = 0;
5533  enum AVSphericalProjection projection;
5534 
5535  if (c->fc->nb_streams < 1)
5536  return 0;
5537 
5538  st = c->fc->streams[c->fc->nb_streams - 1];
5539  sc = st->priv_data;
5540 
5541  if (atom.size < 8) {
5542  av_log(c->fc, AV_LOG_ERROR, "Empty spherical video box\n");
5543  return AVERROR_INVALIDDATA;
5544  }
5545 
5546  size = avio_rb32(pb);
5547  if (size <= 12 || size > atom.size)
5548  return AVERROR_INVALIDDATA;
5549 
5550  tag = avio_rl32(pb);
5551  if (tag != MKTAG('s','v','h','d')) {
5552  av_log(c->fc, AV_LOG_ERROR, "Missing spherical video header\n");
5553  return 0;
5554  }
5555  version = avio_r8(pb);
5556  if (version != 0) {
5557  av_log(c->fc, AV_LOG_WARNING, "Unknown spherical version %d\n",
5558  version);
5559  return 0;
5560  }
5561  avio_skip(pb, 3); /* flags */
5562  avio_skip(pb, size - 12); /* metadata_source */
5563 
5564  size = avio_rb32(pb);
5565  if (size > atom.size)
5566  return AVERROR_INVALIDDATA;
5567 
5568  tag = avio_rl32(pb);
5569  if (tag != MKTAG('p','r','o','j')) {
5570  av_log(c->fc, AV_LOG_ERROR, "Missing projection box\n");
5571  return 0;
5572  }
5573 
5574  size = avio_rb32(pb);
5575  if (size > atom.size)
5576  return AVERROR_INVALIDDATA;
5577 
5578  tag = avio_rl32(pb);
5579  if (tag != MKTAG('p','r','h','d')) {
5580  av_log(c->fc, AV_LOG_ERROR, "Missing projection header box\n");
5581  return 0;
5582  }
5583  version = avio_r8(pb);
5584  if (version != 0) {
5585  av_log(c->fc, AV_LOG_WARNING, "Unknown spherical version %d\n",
5586  version);
5587  return 0;
5588  }
5589  avio_skip(pb, 3); /* flags */
5590 
5591  /* 16.16 fixed point */
5592  yaw = avio_rb32(pb);
5593  pitch = avio_rb32(pb);
5594  roll = avio_rb32(pb);
5595 
5596  size = avio_rb32(pb);
5597  if (size > atom.size)
5598  return AVERROR_INVALIDDATA;
5599 
5600  tag = avio_rl32(pb);
5601  version = avio_r8(pb);
5602  if (version != 0) {
5603  av_log(c->fc, AV_LOG_WARNING, "Unknown spherical version %d\n",
5604  version);
5605  return 0;
5606  }
5607  avio_skip(pb, 3); /* flags */
5608  switch (tag) {
5609  case MKTAG('c','b','m','p'):
5610  layout = avio_rb32(pb);
5611  if (layout) {
5612  av_log(c->fc, AV_LOG_WARNING,
5613  "Unsupported cubemap layout %d\n", layout);
5614  return 0;
5615  }
5616  projection = AV_SPHERICAL_CUBEMAP;
5617  padding = avio_rb32(pb);
5618  break;
5619  case MKTAG('e','q','u','i'):
5620  t = avio_rb32(pb);
5621  b = avio_rb32(pb);
5622  l = avio_rb32(pb);
5623  r = avio_rb32(pb);
5624 
5625  if (b >= UINT_MAX - t || r >= UINT_MAX - l) {
5626  av_log(c->fc, AV_LOG_ERROR,
5627  "Invalid bounding rectangle coordinates "
5628  "%"PRIu32",%"PRIu32",%"PRIu32",%"PRIu32"\n", l, t, r, b);
5629  return AVERROR_INVALIDDATA;
5630  }
5631 
5632  if (l || t || r || b)
5633  projection = AV_SPHERICAL_EQUIRECTANGULAR_TILE;
5634  else
5635  projection = AV_SPHERICAL_EQUIRECTANGULAR;
5636  break;
5637  default:
5638  av_log(c->fc, AV_LOG_ERROR, "Unknown projection type: %s\n", av_fourcc2str(tag));
5639  return 0;
5640  }
5641 
5643  if (!sc->spherical)
5644  return AVERROR(ENOMEM);
5645 
5646  sc->spherical->projection = projection;
5647 
5648  sc->spherical->yaw = yaw;
5649  sc->spherical->pitch = pitch;
5650  sc->spherical->roll = roll;
5651 
5652  sc->spherical->padding = padding;
5653 
5654  sc->spherical->bound_left = l;
5655  sc->spherical->bound_top = t;
5656  sc->spherical->bound_right = r;
5657  sc->spherical->bound_bottom = b;
5658 
5659  return 0;
5660 }
5661 
5663 {
5664  int ret = 0;
5665  uint8_t *buffer = av_malloc(len + 1);
5666  const char *val;
5667 
5668  if (!buffer)
5669  return AVERROR(ENOMEM);
5670  buffer[len] = '\0';
5671 
5672  ret = ffio_read_size(pb, buffer, len);
5673  if (ret < 0)
5674  goto out;
5675 
5676  /* Check for mandatory keys and values, try to support XML as best-effort */
5677  if (!sc->spherical &&
5678  av_stristr(buffer, "<GSpherical:StitchingSoftware>") &&
5679  (val = av_stristr(buffer, "<GSpherical:Spherical>")) &&
5680  av_stristr(val, "true") &&
5681  (val = av_stristr(buffer, "<GSpherical:Stitched>")) &&
5682  av_stristr(val, "true") &&
5683  (val = av_stristr(buffer, "<GSpherical:ProjectionType>")) &&
5684  av_stristr(val, "equirectangular")) {
5686  if (!sc->spherical)
5687  goto out;
5688 
5690 
5691  if (av_stristr(buffer, "<GSpherical:StereoMode>") && !sc->stereo3d) {
5692  enum AVStereo3DType mode;
5693 
5694  if (av_stristr(buffer, "left-right"))
5696  else if (av_stristr(buffer, "top-bottom"))
5698  else
5699  mode = AV_STEREO3D_2D;
5700 
5701  sc->stereo3d = av_stereo3d_alloc();
5702  if (!sc->stereo3d)
5703  goto out;
5704 
5705  sc->stereo3d->type = mode;
5706  }
5707 
5708  /* orientation */
5709  val = av_stristr(buffer, "<GSpherical:InitialViewHeadingDegrees>");
5710  if (val)
5711  sc->spherical->yaw = strtol(val, NULL, 10) * (1 << 16);
5712  val = av_stristr(buffer, "<GSpherical:InitialViewPitchDegrees>");
5713  if (val)
5714  sc->spherical->pitch = strtol(val, NULL, 10) * (1 << 16);
5715  val = av_stristr(buffer, "<GSpherical:InitialViewRollDegrees>");
5716  if (val)
5717  sc->spherical->roll = strtol(val, NULL, 10) * (1 << 16);
5718  }
5719 
5720 out:
5721  av_free(buffer);
5722  return ret;
5723 }
5724 
5726 {
5727  AVStream *st;
5728  MOVStreamContext *sc;
5729  int64_t ret;
5730  uint8_t uuid[16];
5731  static const uint8_t uuid_isml_manifest[] = {
5732  0xa5, 0xd4, 0x0b, 0x30, 0xe8, 0x14, 0x11, 0xdd,
5733  0xba, 0x2f, 0x08, 0x00, 0x20, 0x0c, 0x9a, 0x66
5734  };
5735  static const uint8_t uuid_xmp[] = {
5736  0xbe, 0x7a, 0xcf, 0xcb, 0x97, 0xa9, 0x42, 0xe8,
5737  0x9c, 0x71, 0x99, 0x94, 0x91, 0xe3, 0xaf, 0xac
5738  };
5739  static const uint8_t uuid_spherical[] = {
5740  0xff, 0xcc, 0x82, 0x63, 0xf8, 0x55, 0x4a, 0x93,
5741  0x88, 0x14, 0x58, 0x7a, 0x02, 0x52, 0x1f, 0xdd,
5742  };
5743 
5744  if (atom.size < sizeof(uuid) || atom.size >= FFMIN(INT_MAX, SIZE_MAX))
5745  return AVERROR_INVALIDDATA;
5746 
5747  if (c->fc->nb_streams < 1)
5748  return 0;
5749  st = c->fc->streams[c->fc->nb_streams - 1];
5750  sc = st->priv_data;
5751 
5752  ret = avio_read(pb, uuid, sizeof(uuid));
5753  if (ret < 0) {
5754  return ret;
5755  } else if (ret != sizeof(uuid)) {
5756  return AVERROR_INVALIDDATA;
5757  }
5758  if (!memcmp(uuid, uuid_isml_manifest, sizeof(uuid))) {
5759  uint8_t *buffer, *ptr;
5760  char *endptr;
5761  size_t len = atom.size - sizeof(uuid);
5762 
5763  if (len < 4) {
5764  return AVERROR_INVALIDDATA;
5765  }
5766  ret = avio_skip(pb, 4); // zeroes
5767  len -= 4;
5768 
5769  buffer = av_mallocz(len + 1);
5770  if (!buffer) {
5771  return AVERROR(ENOMEM);
5772  }
5773  ret = avio_read(pb, buffer, len);
5774  if (ret < 0) {
5775  av_free(buffer);
5776  return ret;
5777  } else if (ret != len) {
5778  av_free(buffer);
5779  return AVERROR_INVALIDDATA;
5780  }
5781 
5782  ptr = buffer;
5783  while ((ptr = av_stristr(ptr, "systemBitrate=\""))) {
5784  ptr += sizeof("systemBitrate=\"") - 1;
5785  c->bitrates_count++;
5786  c->bitrates = av_realloc_f(c->bitrates, c->bitrates_count, sizeof(*c->bitrates));
5787  if (!c->bitrates) {
5788  c->bitrates_count = 0;
5789  av_free(buffer);
5790  return AVERROR(ENOMEM);
5791  }
5792  errno = 0;
5793  ret = strtol(ptr, &endptr, 10);
5794  if (ret < 0 || errno || *endptr != '"') {
5795  c->bitrates[c->bitrates_count - 1] = 0;
5796  } else {
5797  c->bitrates[c->bitrates_count - 1] = ret;
5798  }
5799  }
5800 
5801  av_free(buffer);
5802  } else if (!memcmp(uuid, uuid_xmp, sizeof(uuid))) {
5803  uint8_t *buffer;
5804  size_t len = atom.size - sizeof(uuid);
5805  if (c->export_xmp) {
5806  buffer = av_mallocz(len + 1);
5807  if (!buffer) {
5808  return AVERROR(ENOMEM);
5809  }
5810  ret = avio_read(pb, buffer, len);
5811  if (ret < 0) {
5812  av_free(buffer);
5813  return ret;
5814  } else if (ret != len) {
5815  av_free(buffer);
5816  return AVERROR_INVALIDDATA;
5817  }
5818  buffer[len] = '\0';
5819  av_dict_set(&c->fc->metadata, "xmp", buffer, 0);
5820  av_free(buffer);
5821  } else {
5822  // skip all uuid atom, which makes it fast for long uuid-xmp file
5823  ret = avio_skip(pb, len);
5824  if (ret < 0)
5825  return ret;
5826  }
5827  } else if (!memcmp(uuid, uuid_spherical, sizeof(uuid))) {
5828  size_t len = atom.size - sizeof(uuid);
5829  ret = mov_parse_uuid_spherical(sc, pb, len);
5830  if (ret < 0)
5831  return ret;
5832  if (!sc->spherical)
5833  av_log(c->fc, AV_LOG_WARNING, "Invalid spherical metadata found\n");
5834  }
5835 
5836  return 0;
5837 }
5838 
5840 {
5841  int ret;
5842  uint8_t content[16];
5843 
5844  if (atom.size < 8)
5845  return 0;
5846 
5847  ret = avio_read(pb, content, FFMIN(sizeof(content), atom.size));
5848  if (ret < 0)
5849  return ret;
5850 
5851  if ( !c->found_moov
5852  && !c->found_mdat
5853  && !memcmp(content, "Anevia\x1A\x1A", 8)
5854  && c->use_mfra_for == FF_MOV_FLAG_MFRA_AUTO) {
5855  c->use_mfra_for = FF_MOV_FLAG_MFRA_PTS;
5856  }
5857 
5858  return 0;
5859 }
5860 
5862 {
5863  uint32_t format = avio_rl32(pb);
5864  MOVStreamContext *sc;
5865  enum AVCodecID id;
5866  AVStream *st;
5867 
5868  if (c->fc->nb_streams < 1)
5869  return 0;
5870  st = c->fc->streams[c->fc->nb_streams - 1];
5871  sc = st->priv_data;
5872 
5873  switch (sc->format)
5874  {
5875  case MKTAG('e','n','c','v'): // encrypted video
5876  case MKTAG('e','n','c','a'): // encrypted audio
5877  id = mov_codec_id(st, format);
5878  if (st->codecpar->codec_id != AV_CODEC_ID_NONE &&
5879  st->codecpar->codec_id != id) {
5880  av_log(c->fc, AV_LOG_WARNING,
5881  "ignoring 'frma' atom of '%.4s', stream has codec id %d\n",
5882  (char*)&format, st->codecpar->codec_id);
5883  break;
5884  }
5885 
5886  st->codecpar->codec_id = id;
5887  sc->format = format;
5888  break;
5889 
5890  default:
5891  if (format != sc->format) {
5892  av_log(c->fc, AV_LOG_WARNING,
5893  "ignoring 'frma' atom of '%.4s', stream format is '%.4s'\n",
5894  (char*)&format, (char*)&sc->format);
5895  }
5896  break;
5897  }
5898 
5899  return 0;
5900 }
5901 
5902 /**
5903  * Gets the current encryption info and associated current stream context. If
5904  * we are parsing a track fragment, this will return the specific encryption
5905  * info for this fragment; otherwise this will return the global encryption
5906  * info for the current stream.
5907  */
5909 {
5910  MOVFragmentStreamInfo *frag_stream_info;
5911  AVStream *st;
5912  int i;
5913 
5914  frag_stream_info = get_current_frag_stream_info(&c->frag_index);
5915  if (frag_stream_info) {
5916  for (i = 0; i < c->fc->nb_streams; i++) {
5917  if (c->fc->streams[i]->id == frag_stream_info->id) {
5918  st = c->fc->streams[i];
5919  break;
5920  }
5921  }
5922  if (i == c->fc->nb_streams)
5923  return 0;
5924  *sc = st->priv_data;
5925 
5926  if (!frag_stream_info->encryption_index) {
5927  // If this stream isn't encrypted, don't create the index.
5928  if (!(*sc)->cenc.default_encrypted_sample)
5929  return 0;
5930  frag_stream_info->encryption_index = av_mallocz(sizeof(*frag_stream_info->encryption_index));
5931  if (!frag_stream_info->encryption_index)
5932  return AVERROR(ENOMEM);
5933  }
5934  *encryption_index = frag_stream_info->encryption_index;
5935  return 1;
5936  } else {
5937  // No current track fragment, using stream level encryption info.
5938 
5939  if (c->fc->nb_streams < 1)
5940  return 0;
5941  st = c->fc->streams[c->fc->nb_streams - 1];
5942  *sc = st->priv_data;
5943 
5944  if (!(*sc)->cenc.encryption_index) {
5945  // If this stream isn't encrypted, don't create the index.
5946  if (!(*sc)->cenc.default_encrypted_sample)
5947  return 0;
5948  (*sc)->cenc.encryption_index = av_mallocz(sizeof(*frag_stream_info->encryption_index));
5949  if (!(*sc)->cenc.encryption_index)
5950  return AVERROR(ENOMEM);
5951  }
5952 
5953  *encryption_index = (*sc)->cenc.encryption_index;
5954  return 1;
5955  }
5956 }
5957 
5959 {
5960  int i;
5961  unsigned int subsample_count;
5962  AVSubsampleEncryptionInfo *subsamples;
5963 
5964  if (!sc->cenc.default_encrypted_sample) {
5965  av_log(c->fc, AV_LOG_ERROR, "Missing schm or tenc\n");
5966  return AVERROR_INVALIDDATA;
5967  }
5968 
5970  if (!*sample)
5971  return AVERROR(ENOMEM);
5972 
5973  if (sc->cenc.per_sample_iv_size != 0) {
5974  if (avio_read(pb, (*sample)->iv, sc->cenc.per_sample_iv_size) != sc->cenc.per_sample_iv_size) {
5975  av_log(c->fc, AV_LOG_ERROR, "failed to read the initialization vector\n");
5977  *sample = NULL;
5978  return AVERROR_INVALIDDATA;
5979  }
5980  }
5981 
5982  if (use_subsamples) {
5983  subsample_count = avio_rb16(pb);
5984  av_free((*sample)->subsamples);
5985  (*sample)->subsamples = av_mallocz_array(subsample_count, sizeof(*subsamples));
5986  if (!(*sample)->subsamples) {
5988  *sample = NULL;
5989  return AVERROR(ENOMEM);
5990  }
5991 
5992  for (i = 0; i < subsample_count && !pb->eof_reached; i++) {
5993  (*sample)->subsamples[i].bytes_of_clear_data = avio_rb16(pb);
5994  (*sample)->subsamples[i].bytes_of_protected_data = avio_rb32(pb);
5995  }
5996 
5997  if (pb->eof_reached) {
5998  av_log(c->fc, AV_LOG_ERROR, "hit EOF while reading sub-sample encryption info\n");
6000  *sample = NULL;
6001  return AVERROR_INVALIDDATA;
6002  }
6003  (*sample)->subsample_count = subsample_count;
6004  }
6005 
6006  return 0;
6007 }
6008 
6010 {
6011  AVEncryptionInfo **encrypted_samples;
6012  MOVEncryptionIndex *encryption_index;
6013  MOVStreamContext *sc;
6014  int use_subsamples, ret;
6015  unsigned int sample_count, i, alloc_size = 0;
6016 
6017  ret = get_current_encryption_info(c, &encryption_index, &sc);
6018  if (ret != 1)
6019  return ret;
6020 
6021  if (encryption_index->nb_encrypted_samples) {
6022  // This can happen if we have both saio/saiz and senc atoms.
6023  av_log(c->fc, AV_LOG_DEBUG, "Ignoring duplicate encryption info in senc\n");
6024  return 0;
6025  }
6026 
6027  avio_r8(pb); /* version */
6028  use_subsamples = avio_rb24(pb) & 0x02; /* flags */
6029 
6030  sample_count = avio_rb32(pb);
6031  if (sample_count >= INT_MAX / sizeof(*encrypted_samples))
6032  return AVERROR(ENOMEM);
6033 
6034  for (i = 0; i < sample_count; i++) {
6035  unsigned int min_samples = FFMIN(FFMAX(i + 1, 1024 * 1024), sample_count);
6036  encrypted_samples = av_fast_realloc(encryption_index->encrypted_samples, &alloc_size,
6037  min_samples * sizeof(*encrypted_samples));
6038  if (encrypted_samples) {
6039  encryption_index->encrypted_samples = encrypted_samples;
6040 
6042  c, pb, sc, &encryption_index->encrypted_samples[i], use_subsamples);
6043  } else {
6044  ret = AVERROR(ENOMEM);
6045  }
6046  if (pb->eof_reached) {
6047  av_log(c->fc, AV_LOG_ERROR, "Hit EOF while reading senc\n");
6048  if (ret >= 0)
6049  av_encryption_info_free(encryption_index->encrypted_samples[i]);
6051  }
6052 
6053  if (ret < 0) {
6054  for (; i > 0; i--)
6055  av_encryption_info_free(encryption_index->encrypted_samples[i - 1]);
6056  av_freep(&encryption_index->encrypted_samples);
6057  return ret;
6058  }
6059  }
6060  encryption_index->nb_encrypted_samples = sample_count;
6061 
6062  return 0;
6063 }
6064 
6066 {
6067  AVEncryptionInfo **sample, **encrypted_samples;
6068  int64_t prev_pos;
6069  size_t sample_count, sample_info_size, i;
6070  int ret = 0;
6071  unsigned int alloc_size = 0;
6072 
6073  if (encryption_index->nb_encrypted_samples)
6074  return 0;
6075  sample_count = encryption_index->auxiliary_info_sample_count;
6076  if (encryption_index->auxiliary_offsets_count != 1) {
6077  av_log(c->fc, AV_LOG_ERROR, "Multiple auxiliary info chunks are not supported\n");
6078  return AVERROR_PATCHWELCOME;
6079  }
6080  if (sample_count >= INT_MAX / sizeof(*encrypted_samples))
6081  return AVERROR(ENOMEM);
6082 
6083  prev_pos = avio_tell(pb);
6084  if (!(pb->seekable & AVIO_SEEKABLE_NORMAL) ||
6085  avio_seek(pb, encryption_index->auxiliary_offsets[0], SEEK_SET) != encryption_index->auxiliary_offsets[0]) {
6086  av_log(c->fc, AV_LOG_INFO, "Failed to seek for auxiliary info, will only parse senc atoms for encryption info\n");
6087  goto finish;
6088  }
6089 
6090  for (i = 0; i < sample_count && !pb->eof_reached; i++) {
6091  unsigned int min_samples = FFMIN(FFMAX(i + 1, 1024 * 1024), sample_count);
6092  encrypted_samples = av_fast_realloc(encryption_index->encrypted_samples, &alloc_size,
6093  min_samples * sizeof(*encrypted_samples));
6094  if (!encrypted_samples) {
6095  ret = AVERROR(ENOMEM);
6096  goto finish;
6097  }
6098  encryption_index->encrypted_samples = encrypted_samples;
6099 
6100  sample = &encryption_index->encrypted_samples[i];
6101  sample_info_size = encryption_index->auxiliary_info_default_size
6102  ? encryption_index->auxiliary_info_default_size
6103  : encryption_index->auxiliary_info_sizes[i];
6104 
6105  ret = mov_read_sample_encryption_info(c, pb, sc, sample, sample_info_size > sc->cenc.per_sample_iv_size);
6106  if (ret < 0)
6107  goto finish;
6108  }
6109  if (pb->eof_reached) {
6110  av_log(c->fc, AV_LOG_ERROR, "Hit EOF while reading auxiliary info\n");
6112  } else {
6113  encryption_index->nb_encrypted_samples = sample_count;
6114  }
6115 
6116 finish:
6117  avio_seek(pb, prev_pos, SEEK_SET);
6118  if (ret < 0) {
6119  for (; i > 0; i--) {
6120  av_encryption_info_free(encryption_index->encrypted_samples[i - 1]);
6121  }
6122  av_freep(&encryption_index->encrypted_samples);
6123  }
6124  return ret;
6125 }
6126 
6127 /**
6128  * Tries to read the given number of bytes from the stream and puts it in a
6129  * newly allocated buffer. This reads in small chunks to avoid allocating large
6130  * memory if the file contains an invalid/malicious size value.
6131  */
6132 static int mov_try_read_block(AVIOContext *pb, size_t size, uint8_t **data)
6133 {
6134  const unsigned int block_size = 1024 * 1024;
6135  uint8_t *buffer = NULL;
6136  unsigned int alloc_size = 0, offset = 0;
6137  while (offset < size) {
6138  unsigned int new_size =
6139  alloc_size >= INT_MAX - block_size ? INT_MAX : alloc_size + block_size;
6140  uint8_t *new_buffer = av_fast_realloc(buffer, &alloc_size, new_size);
6141  unsigned int to_read = FFMIN(size, alloc_size) - offset;
6142  if (!new_buffer) {
6143  av_free(buffer);
6144  return AVERROR(ENOMEM);
6145  }
6146  buffer = new_buffer;
6147 
6148  if (avio_read(pb, buffer + offset, to_read) != to_read) {
6149  av_free(buffer);
6150  return AVERROR_INVALIDDATA;
6151  }
6152  offset += to_read;
6153  }
6154 
6155  *data = buffer;
6156  return 0;
6157 }
6158 
6160 {
6161  MOVEncryptionIndex *encryption_index;
6162  MOVStreamContext *sc;
6163  int ret;
6164  unsigned int sample_count, aux_info_type, aux_info_param;
6165 
6166  ret = get_current_encryption_info(c, &encryption_index, &sc);
6167  if (ret != 1)
6168  return ret;
6169 
6170  if (encryption_index->nb_encrypted_samples) {
6171  // This can happen if we have both saio/saiz and senc atoms.
6172  av_log(c->fc, AV_LOG_DEBUG, "Ignoring duplicate encryption info in saiz\n");
6173  return 0;
6174  }
6175 
6176  if (encryption_index->auxiliary_info_sample_count) {
6177  av_log(c->fc, AV_LOG_ERROR, "Duplicate saiz atom\n");
6178  return AVERROR_INVALIDDATA;
6179  }
6180 
6181  avio_r8(pb); /* version */
6182  if (avio_rb24(pb) & 0x01) { /* flags */
6183  aux_info_type = avio_rb32(pb);
6184  aux_info_param = avio_rb32(pb);
6185  if (sc->cenc.default_encrypted_sample) {
6186  if (aux_info_type != sc->cenc.default_encrypted_sample->scheme) {
6187  av_log(c->fc, AV_LOG_DEBUG, "Ignoring saiz box with non-zero aux_info_type\n");
6188  return 0;
6189  }
6190  if (aux_info_param != 0) {
6191  av_log(c->fc, AV_LOG_DEBUG, "Ignoring saiz box with non-zero aux_info_type_parameter\n");
6192  return 0;
6193  }
6194  } else {
6195  // Didn't see 'schm' or 'tenc', so this isn't encrypted.
6196  if ((aux_info_type == MKBETAG('c','e','n','c') ||
6197  aux_info_type == MKBETAG('c','e','n','s') ||
6198  aux_info_type == MKBETAG('c','b','c','1') ||
6199  aux_info_type == MKBETAG('c','b','c','s')) &&
6200  aux_info_param == 0) {
6201  av_log(c->fc, AV_LOG_ERROR, "Saw encrypted saiz without schm/tenc\n");
6202  return AVERROR_INVALIDDATA;
6203  } else {
6204  return 0;
6205  }
6206  }
6207  } else if (!sc->cenc.default_encrypted_sample) {
6208  // Didn't see 'schm' or 'tenc', so this isn't encrypted.
6209  return 0;
6210  }
6211 
6212  encryption_index->auxiliary_info_default_size = avio_r8(pb);
6213  sample_count = avio_rb32(pb);
6214  encryption_index->auxiliary_info_sample_count = sample_count;
6215 
6216  if (encryption_index->auxiliary_info_default_size == 0) {
6217  ret = mov_try_read_block(pb, sample_count, &encryption_index->auxiliary_info_sizes);
6218  if (ret < 0) {
6219  av_log(c->fc, AV_LOG_ERROR, "Failed to read the auxiliary info\n");
6220  return ret;
6221  }
6222  }
6223 
6224  if (encryption_index->auxiliary_offsets_count) {
6225  return mov_parse_auxiliary_info(c, sc, pb, encryption_index);
6226  }
6227 
6228  return 0;
6229 }
6230 
6232 {
6233  uint64_t *auxiliary_offsets;
6234  MOVEncryptionIndex *encryption_index;
6235  MOVStreamContext *sc;
6236  int i, ret;
6237  unsigned int version, entry_count, aux_info_type, aux_info_param;
6238  unsigned int alloc_size = 0;
6239 
6240  ret = get_current_encryption_info(c, &encryption_index, &sc);
6241  if (ret != 1)
6242  return ret;
6243 
6244  if (encryption_index->nb_encrypted_samples) {
6245  // This can happen if we have both saio/saiz and senc atoms.
6246  av_log(c->fc, AV_LOG_DEBUG, "Ignoring duplicate encryption info in saio\n");
6247  return 0;
6248  }
6249 
6250  if (encryption_index->auxiliary_offsets_count) {
6251  av_log(c->fc, AV_LOG_ERROR, "Duplicate saio atom\n");
6252  return AVERROR_INVALIDDATA;
6253  }
6254 
6255  version = avio_r8(pb); /* version */
6256  if (avio_rb24(pb) & 0x01) { /* flags */
6257  aux_info_type = avio_rb32(pb);
6258  aux_info_param = avio_rb32(pb);
6259  if (sc->cenc.default_encrypted_sample) {
6260  if (aux_info_type != sc->cenc.default_encrypted_sample->scheme) {
6261  av_log(c->fc, AV_LOG_DEBUG, "Ignoring saio box with non-zero aux_info_type\n");
6262  return 0;
6263  }
6264  if (aux_info_param != 0) {
6265  av_log(c->fc, AV_LOG_DEBUG, "Ignoring saio box with non-zero aux_info_type_parameter\n");
6266  return 0;
6267  }
6268  } else {
6269  // Didn't see 'schm' or 'tenc', so this isn't encrypted.
6270  if ((aux_info_type == MKBETAG('c','e','n','c') ||
6271  aux_info_type == MKBETAG('c','e','n','s') ||
6272  aux_info_type == MKBETAG('c','b','c','1') ||
6273  aux_info_type == MKBETAG('c','b','c','s')) &&
6274  aux_info_param == 0) {
6275  av_log(c->fc, AV_LOG_ERROR, "Saw encrypted saio without schm/tenc\n");
6276  return AVERROR_INVALIDDATA;
6277  } else {
6278  return 0;
6279  }
6280  }
6281  } else if (!sc->cenc.default_encrypted_sample) {
6282  // Didn't see 'schm' or 'tenc', so this isn't encrypted.
6283  return 0;
6284  }
6285 
6286  entry_count = avio_rb32(pb);
6287  if (entry_count >= INT_MAX / sizeof(*auxiliary_offsets))
6288  return AVERROR(ENOMEM);
6289 
6290  for (i = 0; i < entry_count && !pb->eof_reached; i++) {
6291  unsigned int min_offsets = FFMIN(FFMAX(i + 1, 1024), entry_count);
6292  auxiliary_offsets = av_fast_realloc(
6293  encryption_index->auxiliary_offsets, &alloc_size,
6294  min_offsets * sizeof(*auxiliary_offsets));
6295  if (!auxiliary_offsets) {
6296  av_freep(&encryption_index->auxiliary_offsets);
6297  return AVERROR(ENOMEM);
6298  }
6299  encryption_index->auxiliary_offsets = auxiliary_offsets;
6300 
6301  if (version == 0) {
6302  encryption_index->auxiliary_offsets[i] = avio_rb32(pb);
6303  } else {
6304  encryption_index->auxiliary_offsets[i] = avio_rb64(pb);
6305  }
6306  if (c->frag_index.current >= 0) {
6307  encryption_index->auxiliary_offsets[i] += c->fragment.base_data_offset;
6308  }
6309  }
6310 
6311  if (pb->eof_reached) {
6312  av_log(c->fc, AV_LOG_ERROR, "Hit EOF while reading saio\n");
6313  av_freep(&encryption_index->auxiliary_offsets);
6314  return AVERROR_INVALIDDATA;
6315  }
6316 
6317  encryption_index->auxiliary_offsets_count = entry_count;
6318 
6319  if (encryption_index->auxiliary_info_sample_count) {
6320  return mov_parse_auxiliary_info(c, sc, pb, encryption_index);
6321  }
6322 
6323  return 0;
6324 }
6325 
6327 {
6328  AVEncryptionInitInfo *info, *old_init_info;
6329  uint8_t **key_ids;
6330  AVStream *st;
6331  uint8_t *side_data, *extra_data, *old_side_data;
6332  size_t side_data_size;
6333  int ret = 0, old_side_data_size;
6334  unsigned int version, kid_count, extra_data_size, alloc_size = 0;
6335 
6336  if (c->fc->nb_streams < 1)
6337  return 0;
6338  st = c->fc->streams[c->fc->nb_streams-1];
6339 
6340  version = avio_r8(pb); /* version */
6341  avio_rb24(pb); /* flags */
6342 
6343  info = av_encryption_init_info_alloc(/* system_id_size */ 16, /* num_key_ids */ 0,
6344  /* key_id_size */ 16, /* data_size */ 0);
6345  if (!info)
6346  return AVERROR(ENOMEM);
6347 
6348  if (avio_read(pb, info->system_id, 16) != 16) {
6349  av_log(c->fc, AV_LOG_ERROR, "Failed to read the system id\n");
6351  goto finish;
6352  }
6353 
6354  if (version > 0) {
6355  kid_count = avio_rb32(pb);
6356  if (kid_count >= INT_MAX / sizeof(*key_ids)) {
6357  ret = AVERROR(ENOMEM);
6358  goto finish;
6359  }
6360 
6361  for (unsigned int i = 0; i < kid_count && !pb->eof_reached; i++) {
6362  unsigned int min_kid_count = FFMIN(FFMAX(i + 1, 1024), kid_count);
6363  key_ids = av_fast_realloc(info->key_ids, &alloc_size,
6364  min_kid_count * sizeof(*key_ids));
6365  if (!key_ids) {
6366  ret = AVERROR(ENOMEM);
6367  goto finish;
6368  }
6369  info->key_ids = key_ids;
6370 
6371  info->key_ids[i] = av_mallocz(16);
6372  if (!info->key_ids[i]) {
6373  ret = AVERROR(ENOMEM);
6374  goto finish;
6375  }
6376  info->num_key_ids = i + 1;
6377 
6378  if (avio_read(pb, info->key_ids[i], 16) != 16) {
6379  av_log(c->fc, AV_LOG_ERROR, "Failed to read the key id\n");
6381  goto finish;
6382  }
6383  }
6384 
6385  if (pb->eof_reached) {
6386  av_log(c->fc, AV_LOG_ERROR, "Hit EOF while reading pssh\n");
6388  goto finish;
6389  }
6390  }
6391 
6392  extra_data_size = avio_rb32(pb);
6393  ret = mov_try_read_block(pb, extra_data_size, &extra_data);
6394  if (ret < 0)
6395  goto finish;
6396 
6397  av_freep(&info->data); // malloc(0) may still allocate something.
6398  info->data = extra_data;
6399  info->data_size = extra_data_size;
6400 
6401  // If there is existing initialization data, append to the list.
6402  old_side_data = av_stream_get_side_data(st, AV_PKT_DATA_ENCRYPTION_INIT_INFO, &old_side_data_size);
6403  if (old_side_data) {
6404  old_init_info = av_encryption_init_info_get_side_data(old_side_data, old_side_data_size);
6405  if (old_init_info) {
6406  // Append to the end of the list.
6407  for (AVEncryptionInitInfo *cur = old_init_info;; cur = cur->next) {
6408  if (!cur->next) {
6409  cur->next = info;
6410  break;
6411  }
6412  }
6413  info = old_init_info;
6414  } else {
6415  // Assume existing side-data will be valid, so the only error we could get is OOM.
6416  ret = AVERROR(ENOMEM);
6417  goto finish;
6418  }
6419  }
6420 
6421  side_data = av_encryption_init_info_add_side_data(info, &side_data_size);
6422  if (!side_data) {
6423  ret = AVERROR(ENOMEM);
6424  goto finish;
6425  }
6427  side_data, side_data_size);
6428  if (ret < 0)
6429  av_free(side_data);
6430 
6431 finish:
6433  return ret;
6434 }
6435 
6437 {
6438  AVStream *st;
6439  MOVStreamContext *sc;
6440 
6441  if (c->fc->nb_streams < 1)
6442  return 0;
6443  st = c->fc->streams[c->fc->nb_streams-1];
6444  sc = st->priv_data;
6445 
6446  if (sc->pseudo_stream_id != 0) {
6447  av_log(c->fc, AV_LOG_ERROR, "schm boxes are only supported in first sample descriptor\n");
6448  return AVERROR_PATCHWELCOME;
6449  }
6450 
6451  if (atom.size < 8)
6452  return AVERROR_INVALIDDATA;
6453 
6454  avio_rb32(pb); /* version and flags */
6455 
6456  if (!sc->cenc.default_encrypted_sample) {
6458  if (!sc->cenc.default_encrypted_sample) {
6459  return AVERROR(ENOMEM);
6460  }
6461  }
6462 
6464  return 0;
6465 }
6466 
6468 {
6469  AVStream *st;
6470  MOVStreamContext *sc;
6471  unsigned int version, pattern, is_protected, iv_size;
6472 
6473  if (c->fc->nb_streams < 1)
6474  return 0;
6475  st = c->fc->streams[c->fc->nb_streams-1];
6476  sc = st->priv_data;
6477 
6478  if (sc->pseudo_stream_id != 0) {
6479  av_log(c->fc, AV_LOG_ERROR, "tenc atom are only supported in first sample descriptor\n");
6480  return AVERROR_PATCHWELCOME;
6481  }
6482 
6483  if (!sc->cenc.default_encrypted_sample) {
6485  if (!sc->cenc.default_encrypted_sample) {
6486  return AVERROR(ENOMEM);
6487  }
6488  }
6489 
6490  if (atom.size < 20)
6491  return AVERROR_INVALIDDATA;
6492 
6493  version = avio_r8(pb); /* version */
6494  avio_rb24(pb); /* flags */
6495 
6496  avio_r8(pb); /* reserved */
6497  pattern = avio_r8(pb);
6498 
6499  if (version > 0) {
6500  sc->cenc.default_encrypted_sample->crypt_byte_block = pattern >> 4;
6501  sc->cenc.default_encrypted_sample->skip_byte_block = pattern & 0xf;
6502  }
6503 
6504  is_protected = avio_r8(pb);
6505  if (is_protected && !sc->cenc.encryption_index) {
6506  // The whole stream should be by-default encrypted.
6508  if (!sc->cenc.encryption_index)
6509  return AVERROR(ENOMEM);
6510  }
6511  sc->cenc.per_sample_iv_size = avio_r8(pb);
6512  if (sc->cenc.per_sample_iv_size != 0 && sc->cenc.per_sample_iv_size != 8 &&
6513  sc->cenc.per_sample_iv_size != 16) {
6514  av_log(c->fc, AV_LOG_ERROR, "invalid per-sample IV size value\n");
6515  return AVERROR_INVALIDDATA;
6516  }
6517  if (avio_read(pb, sc->cenc.default_encrypted_sample->key_id, 16) != 16) {
6518  av_log(c->fc, AV_LOG_ERROR, "failed to read the default key ID\n");
6519  return AVERROR_INVALIDDATA;
6520  }
6521 
6522  if (is_protected && !sc->cenc.per_sample_iv_size) {
6523  iv_size = avio_r8(pb);
6524  if (iv_size != 8 && iv_size != 16) {
6525  av_log(c->fc, AV_LOG_ERROR, "invalid default_constant_IV_size in tenc atom\n");
6526  return AVERROR_INVALIDDATA;
6527  }
6528 
6529  if (avio_read(pb, sc->cenc.default_encrypted_sample->iv, iv_size) != iv_size) {
6530  av_log(c->fc, AV_LOG_ERROR, "failed to read the default IV\n");
6531  return AVERROR_INVALIDDATA;
6532  }
6533  }
6534 
6535  return 0;
6536 }
6537 
6539 {
6540  AVStream *st;
6541  int last, type, size, ret;
6542  uint8_t buf[4];
6543 
6544  if (c->fc->nb_streams < 1)
6545  return 0;
6546  st = c->fc->streams[c->fc->nb_streams-1];
6547 
6548  if ((uint64_t)atom.size > (1<<30) || atom.size < 42)
6549  return AVERROR_INVALIDDATA;
6550 
6551  /* Check FlacSpecificBox version. */
6552  if (avio_r8(pb) != 0)
6553  return AVERROR_INVALIDDATA;
6554 
6555  avio_rb24(pb); /* Flags */
6556 
6557  avio_read(pb, buf, sizeof(buf));
6558  flac_parse_block_header(buf, &last, &type, &size);
6559 
6561  av_log(c->fc, AV_LOG_ERROR, "STREAMINFO must be first FLACMetadataBlock\n");
6562  return AVERROR_INVALIDDATA;
6563  }
6564 
6565  ret = ff_get_extradata(c->fc, st->codecpar, pb, size);
6566  if (ret < 0)
6567  return ret;
6568 
6569  if (!last)
6570  av_log(c->fc, AV_LOG_WARNING, "non-STREAMINFO FLACMetadataBlock(s) ignored\n");
6571 
6572  return 0;
6573 }
6574 
6576 {
6577  int i, ret;
6578 
6579  if (sample->scheme != MKBETAG('c','e','n','c') || sample->crypt_byte_block != 0 || sample->skip_byte_block != 0) {
6580  av_log(c->fc, AV_LOG_ERROR, "Only the 'cenc' encryption scheme is supported\n");
6581  return AVERROR_PATCHWELCOME;
6582  }
6583 
6584  if (!sc->cenc.aes_ctr) {
6585  /* initialize the cipher */
6586  sc->cenc.aes_ctr = av_aes_ctr_alloc();
6587  if (!sc->cenc.aes_ctr) {
6588  return AVERROR(ENOMEM);
6589  }
6590 
6591  ret = av_aes_ctr_init(sc->cenc.aes_ctr, c->decryption_key);
6592  if (ret < 0) {
6593  return ret;
6594  }
6595  }
6596 
6598 
6599  if (!sample->subsample_count)
6600  {
6601  /* decrypt the whole packet */
6603  return 0;
6604  }
6605 
6606  for (i = 0; i < sample->subsample_count; i++)
6607  {
6608  if (sample->subsamples[i].bytes_of_clear_data + sample->subsamples[i].bytes_of_protected_data > size) {
6609  av_log(c->fc, AV_LOG_ERROR, "subsample size exceeds the packet size left\n");
6610  return AVERROR_INVALIDDATA;
6611  }
6612 
6613  /* skip the clear bytes */
6614  input += sample->subsamples[i].bytes_of_clear_data;
6615  size -= sample->subsamples[i].bytes_of_clear_data;
6616 
6617  /* decrypt the encrypted bytes */
6618  av_aes_ctr_crypt(sc->cenc.aes_ctr, input, input, sample->subsamples[i].bytes_of_protected_data);
6619  input += sample->subsamples[i].bytes_of_protected_data;
6620  size -= sample->subsamples[i].bytes_of_protected_data;
6621  }
6622 
6623  if (size > 0) {
6624  av_log(c->fc, AV_LOG_ERROR, "leftover packet bytes after subsample processing\n");
6625  return AVERROR_INVALIDDATA;
6626  }
6627 
6628  return 0;
6629 }
6630 
6631 static int cenc_filter(MOVContext *mov, AVStream* st, MOVStreamContext *sc, AVPacket *pkt, int current_index)
6632 {
6633  MOVFragmentStreamInfo *frag_stream_info;
6634  MOVEncryptionIndex *encryption_index;
6635  AVEncryptionInfo *encrypted_sample;
6636  int encrypted_index, ret;
6637 
6638  frag_stream_info = get_frag_stream_info(&mov->frag_index, mov->frag_index.current, st->id);
6639  encrypted_index = current_index;
6640  encryption_index = NULL;
6641  if (frag_stream_info) {
6642  // Note this only supports encryption info in the first sample descriptor.
6643  if (mov->fragment.stsd_id == 1) {
6644  if (frag_stream_info->encryption_index) {
6645  encrypted_index = current_index - frag_stream_info->index_entry;
6646  encryption_index = frag_stream_info->encryption_index;
6647  } else {
6648  encryption_index = sc->cenc.encryption_index;
6649  }
6650  }
6651  } else {
6652  encryption_index = sc->cenc.encryption_index;
6653  }
6654 
6655  if (encryption_index) {
6656  if (encryption_index->auxiliary_info_sample_count &&
6657  !encryption_index->nb_encrypted_samples) {
6658  av_log(mov->fc, AV_LOG_ERROR, "saiz atom found without saio\n");
6659  return AVERROR_INVALIDDATA;
6660  }
6661  if (encryption_index->auxiliary_offsets_count &&
6662  !encryption_index->nb_encrypted_samples) {
6663  av_log(mov->fc, AV_LOG_ERROR, "saio atom found without saiz\n");
6664  return AVERROR_INVALIDDATA;
6665  }
6666 
6667  if (!encryption_index->nb_encrypted_samples) {
6668  // Full-sample encryption with default settings.
6669  encrypted_sample = sc->cenc.default_encrypted_sample;
6670  } else if (encrypted_index >= 0 && encrypted_index < encryption_index->nb_encrypted_samples) {
6671  // Per-sample setting override.
6672  encrypted_sample = encryption_index->encrypted_samples[encrypted_index];
6673  } else {
6674  av_log(mov->fc, AV_LOG_ERROR, "Incorrect number of samples in encryption info\n");
6675  return AVERROR_INVALIDDATA;
6676  }
6677 
6678  if (mov->decryption_key) {
6679  return cenc_decrypt(mov, sc, encrypted_sample, pkt->data, pkt->size);
6680  } else {
6681  size_t size;
6682  uint8_t *side_data = av_encryption_info_add_side_data(encrypted_sample, &size);
6683  if (!side_data)
6684  return AVERROR(ENOMEM);
6686  if (ret < 0)
6687  av_free(side_data);
6688  return ret;
6689  }
6690  }
6691 
6692  return 0;
6693 }
6694 
6696 {
6697  const int OPUS_SEEK_PREROLL_MS = 80;
6698  AVStream *st;
6699  size_t size;
6700  uint16_t pre_skip;
6701 
6702  if (c->fc->nb_streams < 1)
6703  return 0;
6704  st = c->fc->streams[c->fc->nb_streams-1];
6705 
6706  if ((uint64_t)atom.size > (1<<30) || atom.size < 11)
6707  return AVERROR_INVALIDDATA;
6708 
6709  /* Check OpusSpecificBox version. */
6710  if (avio_r8(pb) != 0) {
6711  av_log(c->fc, AV_LOG_ERROR, "unsupported OpusSpecificBox version\n");
6712  return AVERROR_INVALIDDATA;
6713  }
6714 
6715  /* OpusSpecificBox size plus magic for Ogg OpusHead header. */
6716  size = atom.size + 8;
6717 
6718  if (ff_alloc_extradata(st->codecpar, size))
6719  return AVERROR(ENOMEM);
6720 
6721  AV_WL32(st->codecpar->extradata, MKTAG('O','p','u','s'));
6722  AV_WL32(st->codecpar->extradata + 4, MKTAG('H','e','a','d'));
6723  AV_WB8(st->codecpar->extradata + 8, 1); /* OpusHead version */
6724  avio_read(pb, st->codecpar->extradata + 9, size - 9);
6725 
6726  /* OpusSpecificBox is stored in big-endian, but OpusHead is
6727  little-endian; aside from the preceeding magic and version they're
6728  otherwise currently identical. Data after output gain at offset 16
6729  doesn't need to be bytewapped. */
6730  pre_skip = AV_RB16(st->codecpar->extradata + 10);
6731  AV_WL16(st->codecpar->extradata + 10, pre_skip);
6732  AV_WL32(st->codecpar->extradata + 12, AV_RB32(st->codecpar->extradata + 12));
6733  AV_WL16(st->codecpar->extradata + 16, AV_RB16(st->codecpar->extradata + 16));
6734 
6735  st->codecpar->initial_padding = pre_skip;
6737  (AVRational){1, 1000},
6738  (AVRational){1, 48000});
6739 
6740  return 0;
6741 }
6742 
6744 { MKTAG('A','C','L','R'), mov_read_aclr },
6745 { MKTAG('A','P','R','G'), mov_read_avid },
6746 { MKTAG('A','A','L','P'), mov_read_avid },
6747 { MKTAG('A','R','E','S'), mov_read_ares },
6748 { MKTAG('a','v','s','s'), mov_read_avss },
6749 { MKTAG('a','v','1','C'), mov_read_av1c },
6750 { MKTAG('c','h','p','l'), mov_read_chpl },
6751 { MKTAG('c','o','6','4'), mov_read_stco },
6752 { MKTAG('c','o','l','r'), mov_read_colr },
6753 { MKTAG('c','t','t','s'), mov_read_ctts }, /* composition time to sample */
6754 { MKTAG('d','i','n','f'), mov_read_default },
6755 { MKTAG('D','p','x','E'), mov_read_dpxe },
6756 { MKTAG('d','r','e','f'), mov_read_dref },
6757 { MKTAG('e','d','t','s'), mov_read_default },
6758 { MKTAG('e','l','s','t'), mov_read_elst },
6759 { MKTAG('e','n','d','a'), mov_read_enda },
6760 { MKTAG('f','i','e','l'), mov_read_fiel },
6761 { MKTAG('a','d','r','m'), mov_read_adrm },
6762 { MKTAG('f','t','y','p'), mov_read_ftyp },
6763 { MKTAG('g','l','b','l'), mov_read_glbl },
6764 { MKTAG('h','d','l','r'), mov_read_hdlr },
6765 { MKTAG('i','l','s','t'), mov_read_ilst },
6766 { MKTAG('j','p','2','h'), mov_read_jp2h },
6767 { MKTAG('m','d','a','t'), mov_read_mdat },
6768 { MKTAG('m','d','h','d'), mov_read_mdhd },
6769 { MKTAG('m','d','i','a'), mov_read_default },
6770 { MKTAG('m','e','t','a'), mov_read_meta },
6771 { MKTAG('m','i','n','f'), mov_read_default },
6772 { MKTAG('m','o','o','f'), mov_read_moof },
6773 { MKTAG('m','o','o','v'), mov_read_moov },
6774 { MKTAG('m','v','e','x'), mov_read_default },
6775 { MKTAG('m','v','h','d'), mov_read_mvhd },
6776 { MKTAG('S','M','I',' '), mov_read_svq3 },
6777 { MKTAG('a','l','a','c'), mov_read_alac }, /* alac specific atom */
6778 { MKTAG('a','v','c','C'), mov_read_glbl },
6779 { MKTAG('p','a','s','p'), mov_read_pasp },
6780 { MKTAG('s','i','d','x'), mov_read_sidx },
6781 { MKTAG('s','t','b','l'), mov_read_default },
6782 { MKTAG('s','t','c','o'), mov_read_stco },
6783 { MKTAG('s','t','p','s'), mov_read_stps },
6784 { MKTAG('s','t','r','f'), mov_read_strf },
6785 { MKTAG('s','t','s','c'), mov_read_stsc },
6786 { MKTAG('s','t','s','d'), mov_read_stsd }, /* sample description */
6787 { MKTAG('s','t','s','s'), mov_read_stss }, /* sync sample */
6788 { MKTAG('s','t','s','z'), mov_read_stsz }, /* sample size */
6789 { MKTAG('s','t','t','s'), mov_read_stts },
6790 { MKTAG('s','t','z','2'), mov_read_stsz }, /* compact sample size */
6791 { MKTAG('t','k','h','d'), mov_read_tkhd }, /* track header */
6792 { MKTAG('t','f','d','t'), mov_read_tfdt },
6793 { MKTAG('t','f','h','d'), mov_read_tfhd }, /* track fragment header */
6794 { MKTAG('t','r','a','k'), mov_read_trak },
6795 { MKTAG('t','r','a','f'), mov_read_default },
6796 { MKTAG('t','r','e','f'), mov_read_default },
6797 { MKTAG('t','m','c','d'), mov_read_tmcd },
6798 { MKTAG('c','h','a','p'), mov_read_chap },
6799 { MKTAG('t','r','e','x'), mov_read_trex },
6800 { MKTAG('t','r','u','n'), mov_read_trun },
6801 { MKTAG('u','d','t','a'), mov_read_default },
6802 { MKTAG('w','a','v','e'), mov_read_wave },
6803 { MKTAG('e','s','d','s'), mov_read_esds },
6804 { MKTAG('d','a','c','3'), mov_read_dac3 }, /* AC-3 info */
6805 { MKTAG('d','e','c','3'), mov_read_dec3 }, /* EAC-3 info */
6806 { MKTAG('d','d','t','s'), mov_read_ddts }, /* DTS audio descriptor */
6807 { MKTAG('w','i','d','e'), mov_read_wide }, /* place holder */
6808 { MKTAG('w','f','e','x'), mov_read_wfex },
6809 { MKTAG('c','m','o','v'), mov_read_cmov },
6810 { MKTAG('c','h','a','n'), mov_read_chan }, /* channel layout */
6811 { MKTAG('d','v','c','1'), mov_read_dvc1 },
6812 { MKTAG('s','b','g','p'), mov_read_sbgp },
6813 { MKTAG('h','v','c','C'), mov_read_glbl },
6814 { MKTAG('u','u','i','d'), mov_read_uuid },
6815 { MKTAG('C','i','n', 0x8e), mov_read_targa_y216 },
6816 { MKTAG('f','r','e','e'), mov_read_free },
6817 { MKTAG('-','-','-','-'), mov_read_custom },
6818 { MKTAG('s','i','n','f'), mov_read_default },
6819 { MKTAG('f','r','m','a'), mov_read_frma },
6820 { MKTAG('s','e','n','c'), mov_read_senc },
6821 { MKTAG('s','a','i','z'), mov_read_saiz },
6822 { MKTAG('s','a','i','o'), mov_read_saio },
6823 { MKTAG('p','s','s','h'), mov_read_pssh },
6824 { MKTAG('s','c','h','m'), mov_read_schm },
6825 { MKTAG('s','c','h','i'), mov_read_default },
6826 { MKTAG('t','e','n','c'), mov_read_tenc },
6827 { MKTAG('d','f','L','a'), mov_read_dfla },
6828 { MKTAG('s','t','3','d'), mov_read_st3d }, /* stereoscopic 3D video box */
6829 { MKTAG('s','v','3','d'), mov_read_sv3d }, /* spherical video box */
6830 { MKTAG('d','O','p','s'), mov_read_dops },
6831 { MKTAG('S','m','D','m'), mov_read_smdm },
6832 { MKTAG('C','o','L','L'), mov_read_coll },
6833 { MKTAG('v','p','c','C'), mov_read_vpcc },
6834 { MKTAG('m','d','c','v'), mov_read_mdcv },
6835 { MKTAG('c','l','l','i'), mov_read_clli },
6836 { 0, NULL }
6837 };
6838 
6840 {
6841  int64_t total_size = 0;
6842  MOVAtom a;
6843  int i;
6844 
6845  if (c->atom_depth > 10) {
6846  av_log(c->fc, AV_LOG_ERROR, "Atoms too deeply nested\n");
6847  return AVERROR_INVALIDDATA;
6848  }
6849  c->atom_depth ++;
6850 
6851  if (atom.size < 0)
6852  atom.size = INT64_MAX;
6853  while (total_size <= atom.size - 8 && !avio_feof(pb)) {
6855  a.size = atom.size;
6856  a.type=0;
6857  if (atom.size >= 8) {
6858  a.size = avio_rb32(pb);
6859  a.type = avio_rl32(pb);
6860  if (a.type == MKTAG('f','r','e','e') &&
6861  a.size >= 8 &&
6862  c->fc->strict_std_compliance < FF_COMPLIANCE_STRICT &&
6863  c->moov_retry) {
6864  uint32_t type;
6865  avio_skip(pb, 4);
6866  type = avio_rl32(pb);
6867  if (avio_feof(pb))
6868  break;
6869  avio_seek(pb, -8, SEEK_CUR);
6870  if (type == MKTAG('m','v','h','d') ||
6871  type == MKTAG('c','m','o','v')) {
6872  av_log(c->fc, AV_LOG_ERROR, "Detected moov in a free atom.\n");
6873  a.type = MKTAG('m','o','o','v');
6874  }
6875  }
6876  if (atom.type != MKTAG('r','o','o','t') &&
6877  atom.type != MKTAG('m','o','o','v'))
6878  {
6879  if (a.type == MKTAG('t','r','a','k') || a.type == MKTAG('m','d','a','t'))
6880  {
6881  av_log(c->fc, AV_LOG_ERROR, "Broken file, trak/mdat not at top-level\n");
6882  avio_skip(pb, -8);
6883  c->atom_depth --;
6884  return 0;
6885  }
6886  }
6887  total_size += 8;
6888  if (a.size == 1 && total_size + 8 <= atom.size) { /* 64 bit extended size */
6889  a.size = avio_rb64(pb) - 8;
6890  total_size += 8;
6891  }
6892  }
6893  av_log(c->fc, AV_LOG_TRACE, "type:'%s' parent:'%s' sz: %"PRId64" %"PRId64" %"PRId64"\n",
6894  av_fourcc2str(a.type), av_fourcc2str(atom.type), a.size, total_size, atom.size);
6895  if (a.size == 0) {
6896  a.size = atom.size - total_size + 8;
6897  }
6898  if (a.size < 0)
6899  break;
6900  a.size -= 8;
6901  if (a.size < 0)
6902  break;
6903  a.size = FFMIN(a.size, atom.size - total_size);
6904 
6905  for (i = 0; mov_default_parse_table[i].type; i++)
6906  if (mov_default_parse_table[i].type == a.type) {
6908  break;
6909  }
6910 
6911  // container is user data
6912  if (!parse && (atom.type == MKTAG('u','d','t','a') ||
6913  atom.type == MKTAG('i','l','s','t')))
6915 
6916  // Supports parsing the QuickTime Metadata Keys.
6917  // https://developer.apple.com/library/mac/documentation/QuickTime/QTFF/Metadata/Metadata.html
6918  if (!parse && c->found_hdlr_mdta &&
6919  atom.type == MKTAG('m','e','t','a') &&
6920  a.type == MKTAG('k','e','y','s')) {
6921  parse = mov_read_keys;
6922  }
6923 
6924  if (!parse) { /* skip leaf atoms data */
6925  avio_skip(pb, a.size);
6926  } else {
6927  int64_t start_pos = avio_tell(pb);
6928  int64_t left;
6929  int err = parse(c, pb, a);
6930  if (err < 0) {
6931  c->atom_depth --;
6932  return err;
6933  }
6934  if (c->found_moov && c->found_mdat && a.size <= INT64_MAX - start_pos &&
6935  ((!(pb->seekable & AVIO_SEEKABLE_NORMAL) || c->fc->flags & AVFMT_FLAG_IGNIDX || c->frag_index.complete) ||
6936  start_pos + a.size == avio_size(pb))) {
6937  if (!(pb->seekable & AVIO_SEEKABLE_NORMAL) || c->fc->flags & AVFMT_FLAG_IGNIDX || c->frag_index.complete)
6938  c->next_root_atom = start_pos + a.size;
6939  c->atom_depth --;
6940  return 0;
6941  }
6942  left = a.size - avio_tell(pb) + start_pos;
6943  if (left > 0) /* skip garbage at atom end */
6944  avio_skip(pb, left);
6945  else if (left < 0) {
6946  av_log(c->fc, AV_LOG_WARNING,
6947  "overread end of atom '%.4s' by %"PRId64" bytes\n",
6948  (char*)&a.type, -left);
6949  avio_seek(pb, left, SEEK_CUR);
6950  }
6951  }
6952 
6953  total_size += a.size;
6954  }
6955 
6956  if (total_size < atom.size && atom.size < 0x7ffff)
6957  avio_skip(pb, atom.size - total_size);
6958 
6959  c->atom_depth --;
6960  return 0;
6961 }
6962 
6963 static int mov_probe(const AVProbeData *p)
6964 {
6965  int64_t offset;
6966  uint32_t tag;
6967  int score = 0;
6968  int moov_offset = -1;
6969 
6970  /* check file header */
6971  offset = 0;
6972  for (;;) {
6973  /* ignore invalid offset */
6974  if ((offset + 8) > (unsigned int)p->buf_size)
6975  break;
6976  tag = AV_RL32(p->buf + offset + 4);
6977  switch(tag) {
6978  /* check for obvious tags */
6979  case MKTAG('m','o','o','v'):
6980  moov_offset = offset + 4;
6981  case MKTAG('m','d','a','t'):
6982  case MKTAG('p','n','o','t'): /* detect movs with preview pics like ew.mov and april.mov */
6983  case MKTAG('u','d','t','a'): /* Packet Video PVAuthor adds this and a lot of more junk */
6984  case MKTAG('f','t','y','p'):
6985  if (AV_RB32(p->buf+offset) < 8 &&
6986  (AV_RB32(p->buf+offset) != 1 ||
6987  offset + 12 > (unsigned int)p->buf_size ||
6988  AV_RB64(p->buf+offset + 8) == 0)) {
6989  score = FFMAX(score, AVPROBE_SCORE_EXTENSION);
6990  } else if (tag == MKTAG('f','t','y','p') &&
6991  ( AV_RL32(p->buf + offset + 8) == MKTAG('j','p','2',' ')
6992  || AV_RL32(p->buf + offset + 8) == MKTAG('j','p','x',' ')
6993  )) {
6994  score = FFMAX(score, 5);
6995  } else {
6996  score = AVPROBE_SCORE_MAX;
6997  }
6998  offset = FFMAX(4, AV_RB32(p->buf+offset)) + offset;
6999  break;
7000  /* those are more common words, so rate then a bit less */
7001  case MKTAG('e','d','i','w'): /* xdcam files have reverted first tags */
7002  case MKTAG('w','i','d','e'):
7003  case MKTAG('f','r','e','e'):
7004  case MKTAG('j','u','n','k'):
7005  case MKTAG('p','i','c','t'):
7006  score = FFMAX(score, AVPROBE_SCORE_MAX - 5);
7007  offset = FFMAX(4, AV_RB32(p->buf+offset)) + offset;
7008  break;
7009  case MKTAG(0x82,0x82,0x7f,0x7d):
7010  case MKTAG('s','k','i','p'):
7011  case MKTAG('u','u','i','d'):
7012  case MKTAG('p','r','f','l'):
7013  /* if we only find those cause probedata is too small at least rate them */
7014  score = FFMAX(score, AVPROBE_SCORE_EXTENSION);
7015  offset = FFMAX(4, AV_RB32(p->buf+offset)) + offset;
7016  break;
7017  default:
7018  offset = FFMAX(4, AV_RB32(p->buf+offset)) + offset;
7019  }
7020  }
7021  if(score > AVPROBE_SCORE_MAX - 50 && moov_offset != -1) {
7022  /* moov atom in the header - we should make sure that this is not a
7023  * MOV-packed MPEG-PS */
7024  offset = moov_offset;
7025 
7026  while(offset < (p->buf_size - 16)){ /* Sufficient space */
7027  /* We found an actual hdlr atom */
7028  if(AV_RL32(p->buf + offset ) == MKTAG('h','d','l','r') &&
7029  AV_RL32(p->buf + offset + 8) == MKTAG('m','h','l','r') &&
7030  AV_RL32(p->buf + offset + 12) == MKTAG('M','P','E','G')){
7031  av_log(NULL, AV_LOG_WARNING, "Found media data tag MPEG indicating this is a MOV-packed MPEG-PS.\n");
7032  /* We found a media handler reference atom describing an
7033  * MPEG-PS-in-MOV, return a
7034  * low score to force expanding the probe window until
7035  * mpegps_probe finds what it needs */
7036  return 5;
7037  }else
7038  /* Keep looking */
7039  offset+=2;
7040  }
7041  }
7042 
7043  return score;
7044 }
7045 
7046 // must be done after parsing all trak because there's no order requirement
7048 {
7049  MOVContext *mov = s->priv_data;
7050  AVStream *st;
7051  MOVStreamContext *sc;
7052  int64_t cur_pos;
7053  int i, j;
7054  int chapter_track;
7055 
7056  for (j = 0; j < mov->nb_chapter_tracks; j++) {
7057  chapter_track = mov->chapter_tracks[j];
7058  st = NULL;
7059  for (i = 0; i < s->nb_streams; i++)
7060  if (s->streams[i]->id == chapter_track) {
7061  st = s->streams[i];
7062  break;
7063  }
7064  if (!st) {
7065  av_log(s, AV_LOG_ERROR, "Referenced QT chapter track not found\n");
7066  continue;
7067  }
7068 
7069  sc = st->priv_data;
7070  cur_pos = avio_tell(sc->pb);
7071 
7072  if (st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO) {
7074  if (st->nb_index_entries) {
7075  // Retrieve the first frame, if possible
7076  AVPacket pkt;
7077  AVIndexEntry *sample = &st->index_entries[0];
7078  if (avio_seek(sc->pb, sample->pos, SEEK_SET) != sample->pos) {
7079  av_log(s, AV_LOG_ERROR, "Failed to retrieve first frame\n");
7080  goto finish;
7081  }
7082 
7083  if (av_get_packet(sc->pb, &pkt, sample->size) < 0)
7084  goto finish;
7085 
7086  st->attached_pic = pkt;
7087  st->attached_pic.stream_index = st->index;
7089  }
7090  } else {
7093  st->discard = AVDISCARD_ALL;
7094  for (i = 0; i < st->nb_index_entries; i++) {
7096  int64_t end = i+1 < st->nb_index_entries ? st->index_entries[i+1].timestamp : st->duration;
7097  uint8_t *title;
7098  uint16_t ch;
7099  int len, title_len;
7100 
7101  if (end < sample->timestamp) {
7102  av_log(s, AV_LOG_WARNING, "ignoring stream duration which is shorter than chapters\n");
7103  end = AV_NOPTS_VALUE;
7104  }
7105 
7106  if (avio_seek(sc->pb, sample->pos, SEEK_SET) != sample->pos) {
7107  av_log(s, AV_LOG_ERROR, "Chapter %d not found in file\n", i);
7108  goto finish;
7109  }
7110 
7111  // the first two bytes are the length of the title
7112  len = avio_rb16(sc->pb);
7113  if (len > sample->size-2)
7114  continue;
7115  title_len = 2*len + 1;
7116  if (!(title = av_mallocz(title_len)))
7117  goto finish;
7118 
7119  // The samples could theoretically be in any encoding if there's an encd
7120  // atom following, but in practice are only utf-8 or utf-16, distinguished
7121  // instead by the presence of a BOM
7122  if (!len) {
7123  title[0] = 0;
7124  } else {
7125  ch = avio_rb16(sc->pb);
7126  if (ch == 0xfeff)
7127  avio_get_str16be(sc->pb, len, title, title_len);
7128  else if (ch == 0xfffe)
7129  avio_get_str16le(sc->pb, len, title, title_len);
7130  else {
7131  AV_WB16(title, ch);
7132  if (len == 1 || len == 2)
7133  title[len] = 0;
7134  else
7135  avio_get_str(sc->pb, INT_MAX, title + 2, len - 1);
7136  }
7137  }
7138 
7139  avpriv_new_chapter(s, i, st->time_base, sample->timestamp, end, title);
7140  av_freep(&title);
7141  }
7142  }
7143 finish:
7144  avio_seek(sc->pb, cur_pos, SEEK_SET);
7145  }
7146 }
7147 
7149  uint32_t value, int flags)
7150 {
7151  AVTimecode tc;
7152  char buf[AV_TIMECODE_STR_SIZE];
7153  AVRational rate = st->avg_frame_rate;
7154  int ret = av_timecode_init(&tc, rate, flags, 0, s);
7155  if (ret < 0)
7156  return ret;
7157  av_dict_set(&st->metadata, "timecode",
7159  return 0;
7160 }
7161 
7163 {
7164  MOVStreamContext *sc = st->priv_data;
7165  char buf[AV_TIMECODE_STR_SIZE];
7166  int64_t cur_pos = avio_tell(sc->pb);
7167  int hh, mm, ss, ff, drop;
7168 
7169  if (!st->nb_index_entries)
7170  return -1;
7171 
7172  avio_seek(sc->pb, st->index_entries->pos, SEEK_SET);
7173  avio_skip(s->pb, 13);
7174  hh = avio_r8(s->pb);
7175  mm = avio_r8(s->pb);
7176  ss = avio_r8(s->pb);
7177  drop = avio_r8(s->pb);
7178  ff = avio_r8(s->pb);
7179  snprintf(buf, AV_TIMECODE_STR_SIZE, "%02d:%02d:%02d%c%02d",
7180  hh, mm, ss, drop ? ';' : ':', ff);
7181  av_dict_set(&st->metadata, "timecode", buf, 0);
7182 
7183  avio_seek(sc->pb, cur_pos, SEEK_SET);
7184  return 0;
7185 }
7186 
7188 {
7189  MOVStreamContext *sc = st->priv_data;
7190  int flags = 0;
7191  int64_t cur_pos = avio_tell(sc->pb);
7192  uint32_t value;
7193 
7194  if (!st->nb_index_entries)
7195  return -1;
7196 
7197  avio_seek(sc->pb, st->index_entries->pos, SEEK_SET);
7198  value = avio_rb32(s->pb);
7199 
7200  if (sc->tmcd_flags & 0x0001) flags |= AV_TIMECODE_FLAG_DROPFRAME;
7201  if (sc->tmcd_flags & 0x0002) flags |= AV_TIMECODE_FLAG_24HOURSMAX;
7202  if (sc->tmcd_flags & 0x0004) flags |= AV_TIMECODE_FLAG_ALLOWNEGATIVE;
7203 
7204  /* Assume Counter flag is set to 1 in tmcd track (even though it is likely
7205  * not the case) and thus assume "frame number format" instead of QT one.
7206  * No sample with tmcd track can be found with a QT timecode at the moment,
7207  * despite what the tmcd track "suggests" (Counter flag set to 0 means QT
7208  * format). */
7210 
7211  avio_seek(sc->pb, cur_pos, SEEK_SET);
7212  return 0;
7213 }
7214 
7216  int i;
7217  if (!index || !*index) return;
7218  for (i = 0; i < (*index)->nb_encrypted_samples; i++) {
7219  av_encryption_info_free((*index)->encrypted_samples[i]);
7220  }
7221  av_freep(&(*index)->encrypted_samples);
7222  av_freep(&(*index)->auxiliary_info_sizes);
7223  av_freep(&(*index)->auxiliary_offsets);
7224  av_freep(index);
7225 }
7226 
7228 {
7229  MOVContext *mov = s->priv_data;
7230  int i, j;
7231 
7232  for (i = 0; i < s->nb_streams; i++) {
7233  AVStream *st = s->streams[i];
7234  MOVStreamContext *sc = st->priv_data;
7235 
7236  if (!sc)
7237  continue;
7238 
7239  av_freep(&sc->ctts_data);
7240  for (j = 0; j < sc->drefs_count; j++) {
7241  av_freep(&sc->drefs[j].path);
7242  av_freep(&sc->drefs[j].dir);
7243  }
7244  av_freep(&sc->drefs);
7245 
7246  sc->drefs_count = 0;
7247 
7248  if (!sc->pb_is_copied)
7249  ff_format_io_close(s, &sc->pb);
7250 
7251  sc->pb = NULL;
7252  av_freep(&sc->chunk_offsets);
7253  av_freep(&sc->stsc_data);
7254  av_freep(&sc->sample_sizes);
7255  av_freep(&sc->keyframes);
7256  av_freep(&sc->stts_data);
7257  av_freep(&sc->stps_data);
7258  av_freep(&sc->elst_data);
7259  av_freep(&sc->rap_group);
7260  av_freep(&sc->display_matrix);
7261  av_freep(&sc->index_ranges);
7262 
7263  if (sc->extradata)
7264  for (j = 0; j < sc->stsd_count; j++)
7265  av_free(sc->extradata[j]);
7266  av_freep(&sc->extradata);
7267  av_freep(&sc->extradata_size);
7268 
7272 
7273  av_freep(&sc->stereo3d);
7274  av_freep(&sc->spherical);
7275  av_freep(&sc->mastering);
7276  av_freep(&sc->coll);
7277  }
7278 
7279  av_freep(&mov->dv_demux);
7281  mov->dv_fctx = NULL;
7282 
7283  if (mov->meta_keys) {
7284  for (i = 1; i < mov->meta_keys_count; i++) {
7285  av_freep(&mov->meta_keys[i]);
7286  }
7287  av_freep(&mov->meta_keys);
7288  }
7289 
7290  av_freep(&mov->trex_data);
7291  av_freep(&mov->bitrates);
7292 
7293  for (i = 0; i < mov->frag_index.nb_items; i++) {
7295  for (j = 0; j < mov->frag_index.item[i].nb_stream_info; j++) {
7296  mov_free_encryption_index(&frag[j].encryption_index);
7297  }
7299  }
7300  av_freep(&mov->frag_index.item);
7301 
7302  av_freep(&mov->aes_decrypt);
7303  av_freep(&mov->chapter_tracks);
7304 
7305  return 0;
7306 }
7307 
7308 static int tmcd_is_referenced(AVFormatContext *s, int tmcd_id)
7309 {
7310  int i;
7311 
7312  for (i = 0; i < s->nb_streams; i++) {
7313  AVStream *st = s->streams[i];
7314  MOVStreamContext *sc = st->priv_data;
7315 
7316  if (st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO &&
7317  sc->timecode_track == tmcd_id)
7318  return 1;
7319  }
7320  return 0;
7321 }
7322 
7323 /* look for a tmcd track not referenced by any video track, and export it globally */
7325 {
7326  int i;
7327 
7328  for (i = 0; i < s->nb_streams; i++) {
7329  AVStream *st = s->streams[i];
7330 
7331  if (st->codecpar->codec_tag == MKTAG('t','m','c','d') &&
7332  !tmcd_is_referenced(s, i + 1)) {
7333  AVDictionaryEntry *tcr = av_dict_get(st->metadata, "timecode", NULL, 0);
7334  if (tcr) {
7335  av_dict_set(&s->metadata, "timecode", tcr->value, 0);
7336  break;
7337  }
7338  }
7339  }
7340 }
7341 
7342 static int read_tfra(MOVContext *mov, AVIOContext *f)
7343 {
7344  int version, fieldlength, i, j;
7345  int64_t pos = avio_tell(f);
7346  uint32_t size = avio_rb32(f);
7347  unsigned track_id, item_count;
7348 
7349  if (avio_rb32(f) != MKBETAG('t', 'f', 'r', 'a')) {
7350  return 1;
7351  }
7352  av_log(mov->fc, AV_LOG_VERBOSE, "found tfra\n");
7353 
7354  version = avio_r8(f);
7355  avio_rb24(f);
7356  track_id = avio_rb32(f);
7357  fieldlength = avio_rb32(f);
7358  item_count = avio_rb32(f);
7359  for (i = 0; i < item_count; i++) {
7360  int64_t time, offset;
7361  int index;
7362  MOVFragmentStreamInfo * frag_stream_info;
7363 
7364  if (avio_feof(f)) {
7365  return AVERROR_INVALIDDATA;
7366  }
7367 
7368  if (version == 1) {
7369  time = avio_rb64(f);
7370  offset = avio_rb64(f);
7371  } else {
7372  time = avio_rb32(f);
7373  offset = avio_rb32(f);
7374  }
7375 
7376  // The first sample of each stream in a fragment is always a random
7377  // access sample. So it's entry in the tfra can be used as the
7378  // initial PTS of the fragment.
7379  index = update_frag_index(mov, offset);
7380  frag_stream_info = get_frag_stream_info(&mov->frag_index, index, track_id);
7381  if (frag_stream_info &&
7382  frag_stream_info->first_tfra_pts == AV_NOPTS_VALUE)
7383  frag_stream_info->first_tfra_pts = time;
7384 
7385  for (j = 0; j < ((fieldlength >> 4) & 3) + 1; j++)
7386  avio_r8(f);
7387  for (j = 0; j < ((fieldlength >> 2) & 3) + 1; j++)
7388  avio_r8(f);
7389  for (j = 0; j < ((fieldlength >> 0) & 3) + 1; j++)
7390  avio_r8(f);
7391  }
7392 
7393  avio_seek(f, pos + size, SEEK_SET);
7394  return 0;
7395 }
7396 
7398 {
7399  int64_t stream_size = avio_size(f);
7400  int64_t original_pos = avio_tell(f);
7401  int64_t seek_ret;
7402  int32_t mfra_size;
7403  int ret = -1;
7404  if ((seek_ret = avio_seek(f, stream_size - 4, SEEK_SET)) < 0) {
7405  ret = seek_ret;
7406  goto fail;
7407  }
7408  mfra_size = avio_rb32(f);
7409  if (mfra_size < 0 || mfra_size > stream_size) {
7410  av_log(c->fc, AV_LOG_DEBUG, "doesn't look like mfra (unreasonable size)\n");
7411  goto fail;
7412  }
7413  if ((seek_ret = avio_seek(f, -mfra_size, SEEK_CUR)) < 0) {
7414  ret = seek_ret;
7415  goto fail;
7416  }
7417  if (avio_rb32(f) != mfra_size) {
7418  av_log(c->fc, AV_LOG_DEBUG, "doesn't look like mfra (size mismatch)\n");
7419  goto fail;
7420  }
7421  if (avio_rb32(f) != MKBETAG('m', 'f', 'r', 'a')) {
7422  av_log(c->fc, AV_LOG_DEBUG, "doesn't look like mfra (tag mismatch)\n");
7423  goto fail;
7424  }
7425  av_log(c->fc, AV_LOG_VERBOSE, "stream has mfra\n");
7426  do {
7427  ret = read_tfra(c, f);
7428  if (ret < 0)
7429  goto fail;
7430  } while (!ret);
7431  ret = 0;
7432 fail:
7433  seek_ret = avio_seek(f, original_pos, SEEK_SET);
7434  if (seek_ret < 0) {
7435  av_log(c->fc, AV_LOG_ERROR,
7436  "failed to seek back after looking for mfra\n");
7437  ret = seek_ret;
7438  }
7439  return ret;
7440 }
7441 
7443 {
7444  MOVContext *mov = s->priv_data;
7445  AVIOContext *pb = s->pb;
7446  int j, err;
7447  MOVAtom atom = { AV_RL32("root") };
7448  int i;
7449 
7450  if (mov->decryption_key_len != 0 && mov->decryption_key_len != AES_CTR_KEY_SIZE) {
7451  av_log(s, AV_LOG_ERROR, "Invalid decryption key len %d expected %d\n",
7453  return AVERROR(EINVAL);
7454  }
7455 
7456  mov->fc = s;
7457  mov->trak_index = -1;
7458  /* .mov and .mp4 aren't streamable anyway (only progressive download if moov is before mdat) */
7459  if (pb->seekable & AVIO_SEEKABLE_NORMAL)
7460  atom.size = avio_size(pb);
7461  else
7462  atom.size = INT64_MAX;
7463 
7464  /* check MOV header */
7465  do {
7466  if (mov->moov_retry)
7467  avio_seek(pb, 0, SEEK_SET);
7468  if ((err = mov_read_default(mov, pb, atom)) < 0) {
7469  av_log(s, AV_LOG_ERROR, "error reading header\n");
7470  goto fail;
7471  }
7472  } while ((pb->seekable & AVIO_SEEKABLE_NORMAL) && !mov->found_moov && !mov->moov_retry++);
7473  if (!mov->found_moov) {
7474  av_log(s, AV_LOG_ERROR, "moov atom not found\n");
7475  err = AVERROR_INVALIDDATA;
7476  goto fail;
7477  }
7478  av_log(mov->fc, AV_LOG_TRACE, "on_parse_exit_offset=%"PRId64"\n", avio_tell(pb));
7479 
7480  if (pb->seekable & AVIO_SEEKABLE_NORMAL) {
7481  if (mov->nb_chapter_tracks > 0 && !mov->ignore_chapters)
7483  for (i = 0; i < s->nb_streams; i++)
7484  if (s->streams[i]->codecpar->codec_tag == AV_RL32("tmcd")) {
7485  mov_read_timecode_track(s, s->streams[i]);
7486  } else if (s->streams[i]->codecpar->codec_tag == AV_RL32("rtmd")) {
7487  mov_read_rtmd_track(s, s->streams[i]);
7488  }
7489  }
7490 
7491  /* copy timecode metadata from tmcd tracks to the related video streams */
7492  for (i = 0; i < s->nb_streams; i++) {
7493  AVStream *st = s->streams[i];
7494  MOVStreamContext *sc = st->priv_data;
7495  if (sc->timecode_track > 0) {
7496  AVDictionaryEntry *tcr;
7497  int tmcd_st_id = -1;
7498 
7499  for (j = 0; j < s->nb_streams; j++)
7500  if (s->streams[j]->id == sc->timecode_track)
7501  tmcd_st_id = j;
7502 
7503  if (tmcd_st_id < 0 || tmcd_st_id == i)
7504  continue;
7505  tcr = av_dict_get(s->streams[tmcd_st_id]->metadata, "timecode", NULL, 0);
7506  if (tcr)
7507  av_dict_set(&st->metadata, "timecode", tcr->value, 0);
7508  }
7509  }
7511 
7512  for (i = 0; i < s->nb_streams; i++) {
7513  AVStream *st = s->streams[i];
7514  MOVStreamContext *sc = st->priv_data;
7515  fix_timescale(mov, sc);
7517  st->skip_samples = sc->start_pad;
7518  }
7519  if (st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO && sc->nb_frames_for_fps > 0 && sc->duration_for_fps > 0)
7521  sc->time_scale*(int64_t)sc->nb_frames_for_fps, sc->duration_for_fps, INT_MAX);
7523  if (st->codecpar->width <= 0 || st->codecpar->height <= 0) {
7524  st->codecpar->width = sc->width;
7525  st->codecpar->height = sc->height;
7526  }
7528  if ((err = mov_rewrite_dvd_sub_extradata(st)) < 0)
7529  goto fail;
7530  }
7531  }
7532  if (mov->handbrake_version &&
7533  mov->handbrake_version <= 1000000*0 + 1000*10 + 2 && // 0.10.2
7535  ) {
7536  av_log(s, AV_LOG_VERBOSE, "Forcing full parsing for mp3 stream\n");
7538  }
7539  }
7540 
7541  if (mov->trex_data) {
7542  for (i = 0; i < s->nb_streams; i++) {
7543  AVStream *st = s->streams[i];
7544  MOVStreamContext *sc = st->priv_data;
7545  if (st->duration > 0) {
7546  if (sc->data_size > INT64_MAX / sc->time_scale / 8) {
7547  av_log(s, AV_LOG_ERROR, "Overflow during bit rate calculation %"PRId64" * 8 * %d\n",
7548  sc->data_size, sc->time_scale);
7549  err = AVERROR_INVALIDDATA;
7550  goto fail;
7551  }
7552  st->codecpar->bit_rate = sc->data_size * 8 * sc->time_scale / st->duration;
7553  }
7554  }
7555  }
7556 
7557  if (mov->use_mfra_for > 0) {
7558  for (i = 0; i < s->nb_streams; i++) {
7559  AVStream *st = s->streams[i];
7560  MOVStreamContext *sc = st->priv_data;
7561  if (sc->duration_for_fps > 0) {
7562  if (sc->data_size > INT64_MAX / sc->time_scale / 8) {
7563  av_log(s, AV_LOG_ERROR, "Overflow during bit rate calculation %"PRId64" * 8 * %d\n",
7564  sc->data_size, sc->time_scale);
7565  err = AVERROR_INVALIDDATA;
7566  goto fail;
7567  }
7568  st->codecpar->bit_rate = sc->data_size * 8 * sc->time_scale /
7569  sc->duration_for_fps;
7570  }
7571  }
7572  }
7573 
7574  for (i = 0; i < mov->bitrates_count && i < s->nb_streams; i++) {
7575  if (mov->bitrates[i]) {
7576  s->streams[i]->codecpar->bit_rate = mov->bitrates[i];
7577  }
7578  }
7579 
7581 
7582  for (i = 0; i < s->nb_streams; i++) {
7583  AVStream *st = s->streams[i];
7584  MOVStreamContext *sc = st->priv_data;
7585 
7586  switch (st->codecpar->codec_type) {
7587  case AVMEDIA_TYPE_AUDIO:
7588  err = ff_replaygain_export(st, s->metadata);
7589  if (err < 0) {
7590  goto fail;
7591  }
7592  break;
7593  case AVMEDIA_TYPE_VIDEO:
7594  if (sc->display_matrix) {
7596  sizeof(int32_t) * 9);
7597  if (err < 0)
7598  goto fail;
7599 
7600  sc->display_matrix = NULL;
7601  }
7602  if (sc->stereo3d) {
7604  (uint8_t *)sc->stereo3d,
7605  sizeof(*sc->stereo3d));
7606  if (err < 0)
7607  goto fail;
7608 
7609  sc->stereo3d = NULL;
7610  }
7611  if (sc->spherical) {
7613  (uint8_t *)sc->spherical,
7614  sc->spherical_size);
7615  if (err < 0)
7616  goto fail;
7617 
7618  sc->spherical = NULL;
7619  }
7620  if (sc->mastering) {
7622  (uint8_t *)sc->mastering,
7623  sizeof(*sc->mastering));
7624  if (err < 0)
7625  goto fail;
7626 
7627  sc->mastering = NULL;
7628  }
7629  if (sc->coll) {
7631  (uint8_t *)sc->coll,
7632  sc->coll_size);
7633  if (err < 0)
7634  goto fail;
7635 
7636  sc->coll = NULL;
7637  }
7638  break;
7639  }
7640  }
7642 
7643  for (i = 0; i < mov->frag_index.nb_items; i++)
7644  if (mov->frag_index.item[i].moof_offset <= mov->fragment.moof_offset)
7645  mov->frag_index.item[i].headers_read = 1;
7646 
7647  return 0;
7648 fail:
7649  mov_read_close(s);
7650  return err;
7651 }
7652 
7654 {
7656  int64_t best_dts = INT64_MAX;
7657  int i;
7658  for (i = 0; i < s->nb_streams; i++) {
7659  AVStream *avst = s->streams[i];
7660  MOVStreamContext *msc = avst->priv_data;
7661  if (msc->pb && msc->current_sample < avst->nb_index_entries) {
7662  AVIndexEntry *current_sample = &avst->index_entries[msc->current_sample];
7663  int64_t dts = av_rescale(current_sample->timestamp, AV_TIME_BASE, msc->time_scale);
7664  av_log(s, AV_LOG_TRACE, "stream %d, sample %d, dts %"PRId64"\n", i, msc->current_sample, dts);
7665  if (!sample || (!(s->pb->seekable & AVIO_SEEKABLE_NORMAL) && current_sample->pos < sample->pos) ||
7666  ((s->pb->seekable & AVIO_SEEKABLE_NORMAL) &&
7667  ((msc->pb != s->pb && dts < best_dts) || (msc->pb == s->pb && dts != AV_NOPTS_VALUE &&
7668  ((FFABS(best_dts - dts) <= AV_TIME_BASE && current_sample->pos < sample->pos) ||
7669  (FFABS(best_dts - dts) > AV_TIME_BASE && dts < best_dts)))))) {
7670  sample = current_sample;
7671  best_dts = dts;
7672  *st = avst;
7673  }
7674  }
7675  }
7676  return sample;
7677 }
7678 
7679 static int should_retry(AVIOContext *pb, int error_code) {
7680  if (error_code == AVERROR_EOF || avio_feof(pb))
7681  return 0;
7682 
7683  return 1;
7684 }
7685 
7686 static int mov_switch_root(AVFormatContext *s, int64_t target, int index)
7687 {
7688  int ret;
7689  MOVContext *mov = s->priv_data;
7690 
7691  if (index >= 0 && index < mov->frag_index.nb_items)
7692  target = mov->frag_index.item[index].moof_offset;
7693  if (avio_seek(s->pb, target, SEEK_SET) != target) {
7694  av_log(mov->fc, AV_LOG_ERROR, "root atom offset 0x%"PRIx64": partial file\n", target);
7695  return AVERROR_INVALIDDATA;
7696  }
7697 
7698  mov->next_root_atom = 0;
7699  if (index < 0 || index >= mov->frag_index.nb_items)
7700  index = search_frag_moof_offset(&mov->frag_index, target);
7701  if (index < mov->frag_index.nb_items) {
7702  if (index + 1 < mov->frag_index.nb_items)
7703  mov->next_root_atom = mov->frag_index.item[index + 1].moof_offset;
7704  if (mov->frag_index.item[index].headers_read)
7705  return 0;
7706  mov->frag_index.item[index].headers_read = 1;
7707  }
7708 
7709  mov->found_mdat = 0;
7710 
7711  ret = mov_read_default(mov, s->pb, (MOVAtom){ AV_RL32("root"), INT64_MAX });
7712  if (ret < 0)
7713  return ret;
7714  if (avio_feof(s->pb))
7715  return AVERROR_EOF;
7716  av_log(s, AV_LOG_TRACE, "read fragments, offset 0x%"PRIx64"\n", avio_tell(s->pb));
7717 
7718  return 1;
7719 }
7720 
7722 {
7723  uint8_t *side, *extradata;
7724  int extradata_size;
7725 
7726  /* Save the current index. */
7727  sc->last_stsd_index = sc->stsc_data[sc->stsc_index].id - 1;
7728 
7729  /* Notify the decoder that extradata changed. */
7730  extradata_size = sc->extradata_size[sc->last_stsd_index];
7731  extradata = sc->extradata[sc->last_stsd_index];
7732  if (extradata_size > 0 && extradata) {
7735  extradata_size);
7736  if (!side)
7737  return AVERROR(ENOMEM);
7738  memcpy(side, extradata, extradata_size);
7739  }
7740 
7741  return 0;
7742 }
7743 
7745 {
7746  MOVContext *mov = s->priv_data;
7747  MOVStreamContext *sc;
7749  AVStream *st = NULL;
7750  int64_t current_index;
7751  int ret;
7752  mov->fc = s;
7753  retry:
7754  sample = mov_find_next_sample(s, &st);
7755  if (!sample || (mov->next_root_atom && sample->pos > mov->next_root_atom)) {
7756  if (!mov->next_root_atom)
7757  return AVERROR_EOF;
7758  if ((ret = mov_switch_root(s, mov->next_root_atom, -1)) < 0)
7759  return ret;
7760  goto retry;
7761  }
7762  sc = st->priv_data;
7763  /* must be done just before reading, to avoid infinite loop on sample */
7764  current_index = sc->current_index;
7766 
7767  if (mov->next_root_atom) {
7768  sample->pos = FFMIN(sample->pos, mov->next_root_atom);
7769  sample->size = FFMIN(sample->size, (mov->next_root_atom - sample->pos));
7770  }
7771 
7772  if (st->discard != AVDISCARD_ALL) {
7773  int64_t ret64 = avio_seek(sc->pb, sample->pos, SEEK_SET);
7774  if (ret64 != sample->pos) {
7775  av_log(mov->fc, AV_LOG_ERROR, "stream %d, offset 0x%"PRIx64": partial file\n",
7776  sc->ffindex, sample->pos);
7777  if (should_retry(sc->pb, ret64)) {
7779  }
7780  return AVERROR_INVALIDDATA;
7781  }
7782 
7783  if( st->discard == AVDISCARD_NONKEY && 0==(sample->flags & AVINDEX_KEYFRAME) ) {
7784  av_log(mov->fc, AV_LOG_DEBUG, "Nonkey frame from stream %d discarded due to AVDISCARD_NONKEY\n", sc->ffindex);
7785  goto retry;
7786  }
7787 
7788  ret = av_get_packet(sc->pb, pkt, sample->size);
7789  if (ret < 0) {
7790  if (should_retry(sc->pb, ret)) {
7792  }
7793  return ret;
7794  }
7795 #if CONFIG_DV_DEMUXER
7796  if (mov->dv_demux && sc->dv_audio_container) {
7797  AVBufferRef *buf = pkt->buf;
7799  pkt->buf = buf;
7801  if (ret < 0)
7802  return ret;
7804  if (ret < 0)
7805  return ret;
7806  }
7807 #endif
7808  if (sc->has_palette) {
7809  uint8_t *pal;
7810 
7812  if (!pal) {
7813  av_log(mov->fc, AV_LOG_ERROR, "Cannot append palette to packet\n");
7814  } else {
7815  memcpy(pal, sc->palette, AVPALETTE_SIZE);
7816  sc->has_palette = 0;
7817  }
7818  }
7819  if (st->codecpar->codec_id == AV_CODEC_ID_MP3 && !st->need_parsing && pkt->size > 4) {
7820  if (ff_mpa_check_header(AV_RB32(pkt->data)) < 0)
7822  }
7823  }
7824 
7825  pkt->stream_index = sc->ffindex;
7826  pkt->dts = sample->timestamp;
7827  if (sample->flags & AVINDEX_DISCARD_FRAME) {
7829  }
7830  if (sc->ctts_data && sc->ctts_index < sc->ctts_count) {
7831  pkt->pts = pkt->dts + sc->dts_shift + sc->ctts_data[sc->ctts_index].duration;
7832  /* update ctts context */
7833  sc->ctts_sample++;
7834  if (sc->ctts_index < sc->ctts_count &&
7835  sc->ctts_data[sc->ctts_index].count == sc->ctts_sample) {
7836  sc->ctts_index++;
7837  sc->ctts_sample = 0;
7838  }
7839  } else {
7840  int64_t next_dts = (sc->current_sample < st->nb_index_entries) ?
7842 
7843  if (next_dts >= pkt->dts)
7844  pkt->duration = next_dts - pkt->dts;
7845  pkt->pts = pkt->dts;
7846  }
7847  if (st->discard == AVDISCARD_ALL)
7848  goto retry;
7849  pkt->flags |= sample->flags & AVINDEX_KEYFRAME ? AV_PKT_FLAG_KEY : 0;
7850  pkt->pos = sample->pos;
7851 
7852  /* Multiple stsd handling. */
7853  if (sc->stsc_data) {
7854  /* Keep track of the stsc index for the given sample, then check
7855  * if the stsd index is different from the last used one. */
7856  sc->stsc_sample++;
7857  if (mov_stsc_index_valid(sc->stsc_index, sc->stsc_count) &&
7858  mov_get_stsc_samples(sc, sc->stsc_index) == sc->stsc_sample) {
7859  sc->stsc_index++;
7860  sc->stsc_sample = 0;
7861  /* Do not check indexes after a switch. */
7862  } else if (sc->stsc_data[sc->stsc_index].id > 0 &&
7863  sc->stsc_data[sc->stsc_index].id - 1 < sc->stsd_count &&
7864  sc->stsc_data[sc->stsc_index].id - 1 != sc->last_stsd_index) {
7865  ret = mov_change_extradata(sc, pkt);
7866  if (ret < 0)
7867  return ret;
7868  }
7869  }
7870 
7871  if (mov->aax_mode)
7872  aax_filter(pkt->data, pkt->size, mov);
7873 
7874  ret = cenc_filter(mov, st, sc, pkt, current_index);
7875  if (ret < 0) {
7877  return ret;
7878  }
7879 
7880  return 0;
7881 }
7882 
7883 static int mov_seek_fragment(AVFormatContext *s, AVStream *st, int64_t timestamp)
7884 {
7885  MOVContext *mov = s->priv_data;
7886  int index;
7887 
7888  if (!mov->frag_index.complete)
7889  return 0;
7890 
7891  index = search_frag_timestamp(&mov->frag_index, st, timestamp);
7892  if (index < 0)
7893  index = 0;
7894  if (!mov->frag_index.item[index].headers_read)
7895  return mov_switch_root(s, -1, index);
7896  if (index + 1 < mov->frag_index.nb_items)
7897  mov->next_root_atom = mov->frag_index.item[index + 1].moof_offset;
7898 
7899  return 0;
7900 }
7901 
7902 static int mov_seek_stream(AVFormatContext *s, AVStream *st, int64_t timestamp, int flags)
7903 {
7904  MOVStreamContext *sc = st->priv_data;
7905  int sample, time_sample, ret;
7906  unsigned int i;
7907 
7908  // Here we consider timestamp to be PTS, hence try to offset it so that we
7909  // can search over the DTS timeline.
7910  timestamp -= (sc->min_corrected_pts + sc->dts_shift);
7911 
7912  ret = mov_seek_fragment(s, st, timestamp);
7913  if (ret < 0)
7914  return ret;
7915 
7916  sample = av_index_search_timestamp(st, timestamp, flags);
7917  av_log(s, AV_LOG_TRACE, "stream %d, timestamp %"PRId64", sample %d\n", st->index, timestamp, sample);
7918  if (sample < 0 && st->nb_index_entries && timestamp < st->index_entries[0].timestamp)
7919  sample = 0;
7920  if (sample < 0) /* not sure what to do */
7921  return AVERROR_INVALIDDATA;
7923  av_log(s, AV_LOG_TRACE, "stream %d, found sample %d\n", st->index, sc->current_sample);
7924  /* adjust ctts index */
7925  if (sc->ctts_data) {
7926  time_sample = 0;
7927  for (i = 0; i < sc->ctts_count; i++) {
7928  int next = time_sample + sc->ctts_data[i].count;
7929  if (next > sc->current_sample) {
7930  sc->ctts_index = i;
7931  sc->ctts_sample = sc->current_sample - time_sample;
7932  break;
7933  }
7934  time_sample = next;
7935  }
7936  }
7937 
7938  /* adjust stsd index */
7939  if (sc->chunk_count) {
7940  time_sample = 0;
7941  for (i = 0; i < sc->stsc_count; i++) {
7942  int64_t next = time_sample + mov_get_stsc_samples(sc, i);
7943  if (next > sc->current_sample) {
7944  sc->stsc_index = i;
7945  sc->stsc_sample = sc->current_sample - time_sample;
7946  break;
7947  }
7948  av_assert0(next == (int)next);
7949  time_sample = next;
7950  }
7951  }
7952 
7953  return sample;
7954 }
7955 
7956 static int mov_read_seek(AVFormatContext *s, int stream_index, int64_t sample_time, int flags)
7957 {
7958  MOVContext *mc = s->priv_data;
7959  AVStream *st;
7960  int sample;
7961  int i;
7962 
7963  if (stream_index >= s->nb_streams)
7964  return AVERROR_INVALIDDATA;
7965 
7966  st = s->streams[stream_index];
7967  sample = mov_seek_stream(s, st, sample_time, flags);
7968  if (sample < 0)
7969  return sample;
7970 
7971  if (mc->seek_individually) {
7972  /* adjust seek timestamp to found sample timestamp */
7973  int64_t seek_timestamp = st->index_entries[sample].timestamp;
7974 
7975  for (i = 0; i < s->nb_streams; i++) {
7976  int64_t timestamp;
7977  MOVStreamContext *sc = s->streams[i]->priv_data;
7978  st = s->streams[i];
7979  st->skip_samples = (sample_time <= 0) ? sc->start_pad : 0;
7980 
7981  if (stream_index == i)
7982  continue;
7983 
7984  timestamp = av_rescale_q(seek_timestamp, s->streams[stream_index]->time_base, st->time_base);
7985  mov_seek_stream(s, st, timestamp, flags);
7986  }
7987  } else {
7988  for (i = 0; i < s->nb_streams; i++) {
7989  MOVStreamContext *sc;
7990  st = s->streams[i];
7991  sc = st->priv_data;
7992  mov_current_sample_set(sc, 0);
7993  }
7994  while (1) {
7995  MOVStreamContext *sc;
7996  AVIndexEntry *entry = mov_find_next_sample(s, &st);
7997  if (!entry)
7998  return AVERROR_INVALIDDATA;
7999  sc = st->priv_data;
8000  if (sc->ffindex == stream_index && sc->current_sample == sample)
8001  break;
8003  }
8004  }
8005  return 0;
8006 }
8007 
8008 #define OFFSET(x) offsetof(MOVContext, x)
8009 #define FLAGS AV_OPT_FLAG_VIDEO_PARAM | AV_OPT_FLAG_DECODING_PARAM
8010 static const AVOption mov_options[] = {
8011  {"use_absolute_path",
8012  "allow using absolute path when opening alias, this is a possible security issue",
8013  OFFSET(use_absolute_path), AV_OPT_TYPE_BOOL, {.i64 = 0},
8014  0, 1, FLAGS},
8015  {"seek_streams_individually",
8016  "Seek each stream individually to the to the closest point",
8017  OFFSET(seek_individually), AV_OPT_TYPE_BOOL, { .i64 = 1 },
8018  0, 1, FLAGS},
8019  {"ignore_editlist", "Ignore the edit list atom.", OFFSET(ignore_editlist), AV_OPT_TYPE_BOOL, {.i64 = 0},
8020  0, 1, FLAGS},
8021  {"advanced_editlist",
8022  "Modify the AVIndex according to the editlists. Use this option to decode in the order specified by the edits.",
8023  OFFSET(advanced_editlist), AV_OPT_TYPE_BOOL, {.i64 = 1},
8024  0, 1, FLAGS},
8025  {"ignore_chapters", "", OFFSET(ignore_chapters), AV_OPT_TYPE_BOOL, {.i64 = 0},
8026  0, 1, FLAGS},
8027  {"use_mfra_for",
8028  "use mfra for fragment timestamps",
8029  OFFSET(use_mfra_for), AV_OPT_TYPE_INT, {.i64 = FF_MOV_FLAG_MFRA_AUTO},
8031  "use_mfra_for"},
8032  {"auto", "auto", 0, AV_OPT_TYPE_CONST, {.i64 = FF_MOV_FLAG_MFRA_AUTO}, 0, 0,
8033  FLAGS, "use_mfra_for" },
8034  {"dts", "dts", 0, AV_OPT_TYPE_CONST, {.i64 = FF_MOV_FLAG_MFRA_DTS}, 0, 0,
8035  FLAGS, "use_mfra_for" },
8036  {"pts", "pts", 0, AV_OPT_TYPE_CONST, {.i64 = FF_MOV_FLAG_MFRA_PTS}, 0, 0,
8037  FLAGS, "use_mfra_for" },
8038  { "export_all", "Export unrecognized metadata entries", OFFSET(export_all),
8039  AV_OPT_TYPE_BOOL, { .i64 = 0 }, 0, 1, .flags = FLAGS },
8040  { "export_xmp", "Export full XMP metadata", OFFSET(export_xmp),
8041  AV_OPT_TYPE_BOOL, { .i64 = 0 }, 0, 1, .flags = FLAGS },
8042  { "activation_bytes", "Secret bytes for Audible AAX files", OFFSET(activation_bytes),
8044  { "audible_fixed_key", // extracted from libAAX_SDK.so and AAXSDKWin.dll files!
8045  "Fixed key used for handling Audible AAX files", OFFSET(audible_fixed_key),
8046  AV_OPT_TYPE_BINARY, {.str="77214d4b196a87cd520045fd20a51d67"},
8047  .flags = AV_OPT_FLAG_DECODING_PARAM },
8048  { "decryption_key", "The media decryption key (hex)", OFFSET(decryption_key), AV_OPT_TYPE_BINARY, .flags = AV_OPT_FLAG_DECODING_PARAM },
8049  { "enable_drefs", "Enable external track support.", OFFSET(enable_drefs), AV_OPT_TYPE_BOOL,
8050  {.i64 = 0}, 0, 1, FLAGS },
8051 
8052  { NULL },
8053 };
8054 
8055 static const AVClass mov_class = {
8056  .class_name = "mov,mp4,m4a,3gp,3g2,mj2",
8057  .item_name = av_default_item_name,
8058  .option = mov_options,
8059  .version = LIBAVUTIL_VERSION_INT,
8060 };
8061 
8063  .name = "mov,mp4,m4a,3gp,3g2,mj2",
8064  .long_name = NULL_IF_CONFIG_SMALL("QuickTime / MOV"),
8065  .priv_class = &mov_class,
8066  .priv_data_size = sizeof(MOVContext),
8067  .extensions = "mov,mp4,m4a,3gp,3g2,mj2",
8068  .read_probe = mov_probe,
8074 };
AVStream::index_entries
AVIndexEntry * index_entries
Only used if the format does not support seeking natively.
Definition: avformat.h:1099
MOVStreamContext::ctts_allocated_size
unsigned int ctts_allocated_size
Definition: isom.h:167
AV_CODEC_ID_PCM_S16LE
@ AV_CODEC_ID_PCM_S16LE
Definition: avcodec.h:463
add_ctts_entry
static int64_t add_ctts_entry(MOVStts **ctts_data, unsigned int *ctts_count, unsigned int *allocated_size, int count, int duration)
Append a new ctts entry to ctts_data.
Definition: mov.c:3307
mov_read_chpl
static int mov_read_chpl(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:539
AVMasteringDisplayMetadata::has_primaries
int has_primaries
Flag indicating whether the display primaries (and white point) are set.
Definition: mastering_display_metadata.h:62
mov_read_frma
static int mov_read_frma(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:5861
mov_read_meta
static int mov_read_meta(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:4447
av_packet_unref
void av_packet_unref(AVPacket *pkt)
Wipe the packet.
Definition: avpacket.c:599
AV_CODEC_ID_MACE6
@ AV_CODEC_ID_MACE6
Definition: avcodec.h:574
MOVFragmentStreamInfo::first_tfra_pts
int64_t first_tfra_pts
Definition: isom.h:130
FF_ENABLE_DEPRECATION_WARNINGS
#define FF_ENABLE_DEPRECATION_WARNINGS
Definition: internal.h:85
AVMEDIA_TYPE_SUBTITLE
@ AVMEDIA_TYPE_SUBTITLE
Definition: avutil.h:204
skip_bits_long
static void skip_bits_long(GetBitContext *s, int n)
Skips the specified number of bits.
Definition: get_bits.h:291
AV_LOG_WARNING
#define AV_LOG_WARNING
Something somehow does not look correct.
Definition: log.h:182
MOV_TFHD_DEFAULT_FLAGS
#define MOV_TFHD_DEFAULT_FLAGS
Definition: isom.h:309
PUT_UTF8
#define PUT_UTF8(val, tmp, PUT_BYTE)
Definition: common.h:438
AV_TIMECODE_STR_SIZE
#define AV_TIMECODE_STR_SIZE
Definition: timecode.h:33
av_aes_init
int av_aes_init(AVAES *a, const uint8_t *key, int key_bits, int decrypt)
Initialize an AVAES context.
Definition: aes.c:195
AV_CODEC_ID_PCM_F32BE
@ AV_CODEC_ID_PCM_F32BE
Definition: avcodec.h:483
MOVStreamContext::audio_cid
int16_t audio_cid
stsd audio compression id
Definition: isom.h:197
AVMasteringDisplayMetadata::max_luminance
AVRational max_luminance
Max luminance of mastering display (cd/m^2).
Definition: mastering_display_metadata.h:57
AVSphericalProjection
AVSphericalProjection
Projection of the video surface(s) on a sphere.
Definition: spherical.h:51
AV_CODEC_ID_ADPCM_MS
@ AV_CODEC_ID_ADPCM_MS
Definition: avcodec.h:508
AVCodecParameters::extradata
uint8_t * extradata
Extra binary data needed for initializing the decoder, codec-dependent.
Definition: avcodec.h:3971
mov_read_dops
static int mov_read_dops(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:6695
AV_CODEC_ID_ADPCM_IMA_QT
@ AV_CODEC_ID_ADPCM_IMA_QT
Definition: avcodec.h:502
ff_rfps_add_frame
int ff_rfps_add_frame(AVFormatContext *ic, AVStream *st, int64_t dts)
add frame for rfps calculation.
Definition: utils.c:3343
AV_FIELD_PROGRESSIVE
@ AV_FIELD_PROGRESSIVE
Definition: avcodec.h:1545
AVFMT_NO_BYTE_SEEK
#define AVFMT_NO_BYTE_SEEK
Format does not allow seeking by bytes.
Definition: avformat.h:475
AV_CODEC_ID_AC3
@ AV_CODEC_ID_AC3
Definition: avcodec.h:567
MOVStreamContext::height
int height
tkhd height
Definition: isom.h:203
MOVContext::moov_retry
int moov_retry
Definition: isom.h:274
MOV_TRUN_SAMPLE_FLAGS
#define MOV_TRUN_SAMPLE_FLAGS
Definition: isom.h:317
MOVContext::nb_chapter_tracks
unsigned int nb_chapter_tracks
Definition: isom.h:263
MOVStreamContext::last_stsd_index
int last_stsd_index
Definition: isom.h:220
r
const char * r
Definition: vf_curves.c:114
AVERROR
Filter the word “frame” indicates either a video frame or a group of audio as stored in an AVFrame structure Format for each input and each output the list of supported formats For video that means pixel format For audio that means channel sample they are references to shared objects When the negotiation mechanism computes the intersection of the formats supported at each end of a all references to both lists are replaced with a reference to the intersection And when a single format is eventually chosen for a link amongst the remaining all references to the list are updated That means that if a filter requires that its input and output have the same format amongst a supported all it has to do is use a reference to the same list of formats query_formats can leave some formats unset and return AVERROR(EAGAIN) to cause the negotiation mechanism toagain later. That can be used by filters with complex requirements to use the format negotiated on one link to set the formats supported on another. Frame references ownership and permissions
opt.h
avformat_new_stream
AVStream * avformat_new_stream(AVFormatContext *s, const AVCodec *c)
Add a new stream to a media file.
Definition: utils.c:4480
MOV_TKHD_FLAG_ENABLED
#define MOV_TKHD_FLAG_ENABLED
Definition: isom.h:330
AVCodecParameters::codec_type
enum AVMediaType codec_type
General type of the encoded data.
Definition: avcodec.h:3953
AVSphericalMapping::projection
enum AVSphericalProjection projection
Projection type.
Definition: spherical.h:86
codec_id
enum AVCodecID codec_id
Definition: qsv.c:72
AV_WL32
#define AV_WL32(p, v)
Definition: intreadwrite.h:426
MOVStreamContext::extradata
uint8_t ** extradata
extradata array (and size) for multiple stsd
Definition: isom.h:218
mov_class
static const AVClass mov_class
Definition: mov.c:8055
AVSphericalMapping::bound_bottom
uint32_t bound_bottom
Distance from the bottom edge.
Definition: spherical.h:170
ff_get_extradata
int ff_get_extradata(AVFormatContext *s, AVCodecParameters *par, AVIOContext *pb, int size)
Allocate extradata with additional AV_INPUT_BUFFER_PADDING_SIZE at end which is always set to 0 and f...
Definition: utils.c:3327
out
FILE * out
Definition: movenc.c:54
MOVFragmentStreamInfo
Definition: isom.h:127
mov_read_targa_y216
static int mov_read_targa_y216(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:1730
FFSWAP
#define FFSWAP(type, a, b)
Definition: common.h:99
mov_read_moof
static int mov_read_moof(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:1379
cb
static double cb(void *priv, double x, double y)
Definition: vf_geq.c:112
AVCodecParameters
This struct describes the properties of an encoded stream.
Definition: avcodec.h:3949
AVFMT_FLAG_IGNIDX
#define AVFMT_FLAG_IGNIDX
Ignore index.
Definition: avformat.h:1475
av_stristr
char * av_stristr(const char *s1, const char *s2)
Locate the first case-independent occurrence in the string haystack of the string needle.
Definition: avstring.c:56
AVCodecParameters::color_space
enum AVColorSpace color_space
Definition: avcodec.h:4046
ff_replaygain_export
int ff_replaygain_export(AVStream *st, AVDictionary *metadata)
Parse replaygain tags and export them as per-stream side data.
Definition: replaygain.c:91
tmcd_is_referenced
static int tmcd_is_referenced(AVFormatContext *s, int tmcd_id)
Definition: mov.c:7308
AVStream::priv_data
void * priv_data
Definition: avformat.h:885
AVERROR_EOF
#define AVERROR_EOF
End of file.
Definition: error.h:55
MKTAG
#define MKTAG(a, b, c, d)
Definition: common.h:366
AV_DISPOSITION_ATTACHED_PIC
#define AV_DISPOSITION_ATTACHED_PIC
The stream is stored in the file as an attached picture/"cover art" (e.g.
Definition: avformat.h:838
AVStream::discard
enum AVDiscard discard
Selects which packets can be discarded at will and do not need to be demuxed.
Definition: avformat.h:925
mov_options
static const AVOption mov_options[]
Definition: mov.c:8010
mov_codec_id
static int mov_codec_id(AVStream *st, uint32_t format)
Definition: mov.c:2040
av_int2double
static av_always_inline double av_int2double(uint64_t i)
Reinterpret a 64-bit integer as a double.
Definition: intfloat.h:60
AVMasteringDisplayMetadata::display_primaries
AVRational display_primaries[3][2]
CIE 1931 xy chromaticity coords of color primaries (r, g, b order).
Definition: mastering_display_metadata.h:42
AV_PKT_FLAG_DISCARD
#define AV_PKT_FLAG_DISCARD
Flag is used to discard packets which are required to maintain valid decoder state but are not requir...
Definition: avcodec.h:1516
AVMasteringDisplayMetadata::has_luminance
int has_luminance
Flag indicating whether the luminance (min_ and max_) have been set.
Definition: mastering_display_metadata.h:67
get_bits_long
static unsigned int get_bits_long(GetBitContext *s, int n)
Read 0-32 bits.
Definition: get_bits.h:546
av_aes_ctr_init
int av_aes_ctr_init(struct AVAESCTR *a, const uint8_t *key)
Initialize an AVAESCTR context.
Definition: aes_ctr.c:69
ch
uint8_t pi<< 24) CONV_FUNC(AV_SAMPLE_FMT_S64, int64_t, AV_SAMPLE_FMT_U8,(uint64_t)((*(const uint8_t *) pi - 0x80U))<< 56) CONV_FUNC(AV_SAMPLE_FMT_FLT, float, AV_SAMPLE_FMT_U8,(*(const uint8_t *) pi - 0x80) *(1.0f/(1<< 7))) CONV_FUNC(AV_SAMPLE_FMT_DBL, double, AV_SAMPLE_FMT_U8,(*(const uint8_t *) pi - 0x80) *(1.0/(1<< 7))) CONV_FUNC(AV_SAMPLE_FMT_U8, uint8_t, AV_SAMPLE_FMT_S16,(*(const int16_t *) pi >>8)+0x80) CONV_FUNC(AV_SAMPLE_FMT_S64, int64_t, AV_SAMPLE_FMT_S16,(uint64_t)(*(const int16_t *) pi)<< 48) CONV_FUNC(AV_SAMPLE_FMT_FLT, float, AV_SAMPLE_FMT_S16, *(const int16_t *) pi *(1.0f/(1<< 15))) CONV_FUNC(AV_SAMPLE_FMT_DBL, double, AV_SAMPLE_FMT_S16, *(const int16_t *) pi *(1.0/(1<< 15))) CONV_FUNC(AV_SAMPLE_FMT_U8, uint8_t, AV_SAMPLE_FMT_S32,(*(const int32_t *) pi >>24)+0x80) CONV_FUNC(AV_SAMPLE_FMT_S64, int64_t, AV_SAMPLE_FMT_S32,(uint64_t)(*(const int32_t *) pi)<< 32) CONV_FUNC(AV_SAMPLE_FMT_FLT, float, AV_SAMPLE_FMT_S32, *(const int32_t *) pi *(1.0f/(1U<< 31))) CONV_FUNC(AV_SAMPLE_FMT_DBL, double, AV_SAMPLE_FMT_S32, *(const int32_t *) pi *(1.0/(1U<< 31))) CONV_FUNC(AV_SAMPLE_FMT_U8, uint8_t, AV_SAMPLE_FMT_S64,(*(const int64_t *) pi >>56)+0x80) CONV_FUNC(AV_SAMPLE_FMT_FLT, float, AV_SAMPLE_FMT_S64, *(const int64_t *) pi *(1.0f/(INT64_C(1)<< 63))) CONV_FUNC(AV_SAMPLE_FMT_DBL, double, AV_SAMPLE_FMT_S64, *(const int64_t *) pi *(1.0/(INT64_C(1)<< 63))) CONV_FUNC(AV_SAMPLE_FMT_U8, uint8_t, AV_SAMPLE_FMT_FLT, av_clip_uint8(lrintf(*(const float *) pi *(1<< 7))+0x80)) CONV_FUNC(AV_SAMPLE_FMT_S16, int16_t, AV_SAMPLE_FMT_FLT, av_clip_int16(lrintf(*(const float *) pi *(1<< 15)))) CONV_FUNC(AV_SAMPLE_FMT_S32, int32_t, AV_SAMPLE_FMT_FLT, av_clipl_int32(llrintf(*(const float *) pi *(1U<< 31)))) CONV_FUNC(AV_SAMPLE_FMT_S64, int64_t, AV_SAMPLE_FMT_FLT, llrintf(*(const float *) pi *(INT64_C(1)<< 63))) CONV_FUNC(AV_SAMPLE_FMT_U8, uint8_t, AV_SAMPLE_FMT_DBL, av_clip_uint8(lrint(*(const double *) pi *(1<< 7))+0x80)) CONV_FUNC(AV_SAMPLE_FMT_S16, int16_t, AV_SAMPLE_FMT_DBL, av_clip_int16(lrint(*(const double *) pi *(1<< 15)))) CONV_FUNC(AV_SAMPLE_FMT_S32, int32_t, AV_SAMPLE_FMT_DBL, av_clipl_int32(llrint(*(const double *) pi *(1U<< 31)))) CONV_FUNC(AV_SAMPLE_FMT_S64, int64_t, AV_SAMPLE_FMT_DBL, llrint(*(const double *) pi *(INT64_C(1)<< 63))) #define FMT_PAIR_FUNC(out, in) static conv_func_type *const fmt_pair_to_conv_functions[AV_SAMPLE_FMT_NB *AV_SAMPLE_FMT_NB]={ FMT_PAIR_FUNC(AV_SAMPLE_FMT_U8, AV_SAMPLE_FMT_U8), FMT_PAIR_FUNC(AV_SAMPLE_FMT_S16, AV_SAMPLE_FMT_U8), FMT_PAIR_FUNC(AV_SAMPLE_FMT_S32, AV_SAMPLE_FMT_U8), FMT_PAIR_FUNC(AV_SAMPLE_FMT_FLT, AV_SAMPLE_FMT_U8), FMT_PAIR_FUNC(AV_SAMPLE_FMT_DBL, AV_SAMPLE_FMT_U8), FMT_PAIR_FUNC(AV_SAMPLE_FMT_S64, AV_SAMPLE_FMT_U8), FMT_PAIR_FUNC(AV_SAMPLE_FMT_U8, AV_SAMPLE_FMT_S16), FMT_PAIR_FUNC(AV_SAMPLE_FMT_S16, AV_SAMPLE_FMT_S16), FMT_PAIR_FUNC(AV_SAMPLE_FMT_S32, AV_SAMPLE_FMT_S16), FMT_PAIR_FUNC(AV_SAMPLE_FMT_FLT, AV_SAMPLE_FMT_S16), FMT_PAIR_FUNC(AV_SAMPLE_FMT_DBL, AV_SAMPLE_FMT_S16), FMT_PAIR_FUNC(AV_SAMPLE_FMT_S64, AV_SAMPLE_FMT_S16), FMT_PAIR_FUNC(AV_SAMPLE_FMT_U8, AV_SAMPLE_FMT_S32), FMT_PAIR_FUNC(AV_SAMPLE_FMT_S16, AV_SAMPLE_FMT_S32), FMT_PAIR_FUNC(AV_SAMPLE_FMT_S32, AV_SAMPLE_FMT_S32), FMT_PAIR_FUNC(AV_SAMPLE_FMT_FLT, AV_SAMPLE_FMT_S32), FMT_PAIR_FUNC(AV_SAMPLE_FMT_DBL, AV_SAMPLE_FMT_S32), FMT_PAIR_FUNC(AV_SAMPLE_FMT_S64, AV_SAMPLE_FMT_S32), FMT_PAIR_FUNC(AV_SAMPLE_FMT_U8, AV_SAMPLE_FMT_FLT), FMT_PAIR_FUNC(AV_SAMPLE_FMT_S16, AV_SAMPLE_FMT_FLT), FMT_PAIR_FUNC(AV_SAMPLE_FMT_S32, AV_SAMPLE_FMT_FLT), FMT_PAIR_FUNC(AV_SAMPLE_FMT_FLT, AV_SAMPLE_FMT_FLT), FMT_PAIR_FUNC(AV_SAMPLE_FMT_DBL, AV_SAMPLE_FMT_FLT), FMT_PAIR_FUNC(AV_SAMPLE_FMT_S64, AV_SAMPLE_FMT_FLT), FMT_PAIR_FUNC(AV_SAMPLE_FMT_U8, AV_SAMPLE_FMT_DBL), FMT_PAIR_FUNC(AV_SAMPLE_FMT_S16, AV_SAMPLE_FMT_DBL), FMT_PAIR_FUNC(AV_SAMPLE_FMT_S32, AV_SAMPLE_FMT_DBL), FMT_PAIR_FUNC(AV_SAMPLE_FMT_FLT, AV_SAMPLE_FMT_DBL), FMT_PAIR_FUNC(AV_SAMPLE_FMT_DBL, AV_SAMPLE_FMT_DBL), FMT_PAIR_FUNC(AV_SAMPLE_FMT_S64, AV_SAMPLE_FMT_DBL), FMT_PAIR_FUNC(AV_SAMPLE_FMT_U8, AV_SAMPLE_FMT_S64), FMT_PAIR_FUNC(AV_SAMPLE_FMT_S16, AV_SAMPLE_FMT_S64), FMT_PAIR_FUNC(AV_SAMPLE_FMT_S32, AV_SAMPLE_FMT_S64), FMT_PAIR_FUNC(AV_SAMPLE_FMT_FLT, AV_SAMPLE_FMT_S64), FMT_PAIR_FUNC(AV_SAMPLE_FMT_DBL, AV_SAMPLE_FMT_S64), FMT_PAIR_FUNC(AV_SAMPLE_FMT_S64, AV_SAMPLE_FMT_S64), };static void cpy1(uint8_t **dst, const uint8_t **src, int len){ memcpy(*dst, *src, len);} static void cpy2(uint8_t **dst, const uint8_t **src, int len){ memcpy(*dst, *src, 2 *len);} static void cpy4(uint8_t **dst, const uint8_t **src, int len){ memcpy(*dst, *src, 4 *len);} static void cpy8(uint8_t **dst, const uint8_t **src, int len){ memcpy(*dst, *src, 8 *len);} AudioConvert *swri_audio_convert_alloc(enum AVSampleFormat out_fmt, enum AVSampleFormat in_fmt, int channels, const int *ch_map, int flags) { AudioConvert *ctx;conv_func_type *f=fmt_pair_to_conv_functions[av_get_packed_sample_fmt(out_fmt)+AV_SAMPLE_FMT_NB *av_get_packed_sample_fmt(in_fmt)];if(!f) return NULL;ctx=av_mallocz(sizeof(*ctx));if(!ctx) return NULL;if(channels==1){ in_fmt=av_get_planar_sample_fmt(in_fmt);out_fmt=av_get_planar_sample_fmt(out_fmt);} ctx->channels=channels;ctx->conv_f=f;ctx->ch_map=ch_map;if(in_fmt==AV_SAMPLE_FMT_U8||in_fmt==AV_SAMPLE_FMT_U8P) memset(ctx->silence, 0x80, sizeof(ctx->silence));if(out_fmt==in_fmt &&!ch_map) { switch(av_get_bytes_per_sample(in_fmt)){ case 1:ctx->simd_f=cpy1;break;case 2:ctx->simd_f=cpy2;break;case 4:ctx->simd_f=cpy4;break;case 8:ctx->simd_f=cpy8;break;} } if(HAVE_X86ASM &&1) swri_audio_convert_init_x86(ctx, out_fmt, in_fmt, channels);if(ARCH_ARM) swri_audio_convert_init_arm(ctx, out_fmt, in_fmt, channels);if(ARCH_AARCH64) swri_audio_convert_init_aarch64(ctx, out_fmt, in_fmt, channels);return ctx;} void swri_audio_convert_free(AudioConvert **ctx) { av_freep(ctx);} int swri_audio_convert(AudioConvert *ctx, AudioData *out, AudioData *in, int len) { int ch;int off=0;const int os=(out->planar ? 1 :out->ch_count) *out->bps;unsigned misaligned=0;av_assert0(ctx->channels==out->ch_count);if(ctx->in_simd_align_mask) { int planes=in->planar ? in->ch_count :1;unsigned m=0;for(ch=0;ch< planes;ch++) m|=(intptr_t) in->ch[ch];misaligned|=m &ctx->in_simd_align_mask;} if(ctx->out_simd_align_mask) { int planes=out->planar ? out->ch_count :1;unsigned m=0;for(ch=0;ch< planes;ch++) m|=(intptr_t) out->ch[ch];misaligned|=m &ctx->out_simd_align_mask;} if(ctx->simd_f &&!ctx->ch_map &&!misaligned){ off=len &~15;av_assert1(off >=0);av_assert1(off<=len);av_assert2(ctx->channels==SWR_CH_MAX||!in->ch[ctx->channels]);if(off >0){ if(out->planar==in->planar){ int planes=out->planar ? out->ch_count :1;for(ch=0;ch< planes;ch++){ ctx->simd_f(out-> ch ch
Definition: audioconvert.c:56
output
filter_frame For filters that do not use the this method is called when a frame is pushed to the filter s input It can be called at any time except in a reentrant way If the input frame is enough to produce output
Definition: filter_design.txt:225
mov_read_alac
static int mov_read_alac(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:1702
test_same_origin
static int test_same_origin(const char *src, const char *ref)
Definition: mov.c:4074
MOVFragment::base_data_offset
uint64_t base_data_offset
Definition: isom.h:92
MOVStreamContext
Definition: isom.h:157
MOVStreamContext::stsc_data
MOVStsc * stsc_data
Definition: isom.h:170
IS_MATRIX_IDENT
#define IS_MATRIX_IDENT(matrix)
Definition: mov.c:4465
count
void INT64 INT64 count
Definition: avisynth_c.h:767
AV_DISPOSITION_DEFAULT
#define AV_DISPOSITION_DEFAULT
Definition: avformat.h:815
MOVStreamContext::spherical
AVSphericalMapping * spherical
Definition: isom.h:226
AV_CODEC_ID_MPEG4
@ AV_CODEC_ID_MPEG4
Definition: avcodec.h:230
AVContentLightMetadata::MaxCLL
unsigned MaxCLL
Max content light level (cd/m^2).
Definition: mastering_display_metadata.h:102
end
static av_cold int end(AVCodecContext *avctx)
Definition: avrndec.c:90
avio_get_str16be
int avio_get_str16be(AVIOContext *pb, int maxlen, char *buf, int buflen)
MOVEncryptionIndex
Definition: isom.h:114
av_encryption_init_info_free
void av_encryption_init_info_free(AVEncryptionInitInfo *info)
Frees the given encryption init info object.
Definition: encryption_info.c:214
mov_read_avss
static int mov_read_avss(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:1707
AV_PKT_DATA_ENCRYPTION_INFO
@ AV_PKT_DATA_ENCRYPTION_INFO
This side data contains encryption info for how to decrypt the packet.
Definition: avcodec.h:1399
MOVContext::found_moov
int found_moov
'moov' atom has been found
Definition: isom.h:248
mov_read_custom
static int mov_read_custom(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:4366
pixdesc.h
ID3v1_GENRE_MAX
#define ID3v1_GENRE_MAX
Definition: id3v1.h:29
mov_metadata_creation_time
static void mov_metadata_creation_time(AVDictionary **metadata, int64_t time)
Definition: mov.c:1405
mov_read_extradata
static int mov_read_extradata(MOVContext *c, AVIOContext *pb, MOVAtom atom, enum AVCodecID codec_id)
Definition: mov.c:1676
AVCOL_RANGE_JPEG
@ AVCOL_RANGE_JPEG
the normal 2^n-1 "JPEG" YUV ranges
Definition: pixfmt.h:522
mpegaudiodecheader.h
MOVStreamContext::rap_group_count
unsigned int rap_group_count
Definition: isom.h:211
av_sha_init
av_cold int av_sha_init(AVSHA *ctx, int bits)
Initialize SHA-1 or SHA-2 hashing.
Definition: sha.c:273
mov_read_mvhd
static int mov_read_mvhd(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:1469
AVPacket::data
uint8_t * data
Definition: avcodec.h:1477
MOVContext::found_mdat
int found_mdat
'mdat' atom has been found
Definition: isom.h:249
MOVStreamContext::drefs_count
unsigned drefs_count
Definition: isom.h:198
AVEncryptionInfo::crypt_byte_block
uint32_t crypt_byte_block
Only used for pattern encryption.
Definition: encryption_info.h:51
mov_read_avid
static int mov_read_avid(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:1722
AVCodecParameters::seek_preroll
int seek_preroll
Audio only.
Definition: avcodec.h:4097
AVOption
AVOption.
Definition: opt.h:246
MOVContext::trex_data
MOVTrackExt * trex_data
Definition: isom.h:258
parse
static int parse(AVCodecParserContext *s, AVCodecContext *avctx, const uint8_t **poutbuf, int *poutbuf_size, const uint8_t *buf, int buf_size)
Definition: vp3_parser.c:23
mov_read_stps
static int mov_read_stps(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:2733
MOVContext::bitrates
int * bitrates
bitrates read before streams creation
Definition: isom.h:272
b
#define b
Definition: input.c:41
AVCOL_TRC_UNSPECIFIED
@ AVCOL_TRC_UNSPECIFIED
Definition: pixfmt.h:470
AV_PKT_DATA_PALETTE
@ AV_PKT_DATA_PALETTE
An AV_PKT_DATA_PALETTE side data packet contains exactly AVPALETTE_SIZE bytes worth of palette.
Definition: avcodec.h:1190
mov_read_tkhd
static int mov_read_tkhd(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:4473
MOVElst::rate
float rate
Definition: isom.h:70
AVStream::avg_frame_rate
AVRational avg_frame_rate
Average framerate.
Definition: avformat.h:943
spherical.h
mov_read_colr
static int mov_read_colr(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:1552
data
const char data[16]
Definition: mxf.c:91
mov_read_strf
static int mov_read_strf(MOVContext *c, AVIOContext *pb, MOVAtom atom)
An strf atom is a BITMAPINFOHEADER struct.
Definition: mov.c:1964
AV_CODEC_ID_ALAC
@ AV_CODEC_ID_ALAC
Definition: avcodec.h:580
yuv_to_rgba
static uint32_t yuv_to_rgba(uint32_t ycbcr)
Definition: mov.c:2254
AV_PKT_DATA_ENCRYPTION_INIT_INFO
@ AV_PKT_DATA_ENCRYPTION_INIT_INFO
This side data is encryption initialization data.
Definition: avcodec.h:1393
AV_CODEC_ID_AMR_NB
@ AV_CODEC_ID_AMR_NB
Definition: avcodec.h:547
mov_parse_auxiliary_info
static int mov_parse_auxiliary_info(MOVContext *c, MOVStreamContext *sc, AVIOContext *pb, MOVEncryptionIndex *encryption_index)
Definition: mov.c:6065
mov_seek_stream
static int mov_seek_stream(AVFormatContext *s, AVStream *st, int64_t timestamp, int flags)
Definition: mov.c:7902
mov_read_saio
static int mov_read_saio(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:6231
mov_get_stsc_samples
static int64_t mov_get_stsc_samples(MOVStreamContext *sc, unsigned int index)
Definition: mov.c:2718
av_mallocz_array
void * av_mallocz_array(size_t nmemb, size_t size)
Definition: mem.c:191
AV_LOG_VERBOSE
#define AV_LOG_VERBOSE
Detailed information.
Definition: log.h:192
ff_codec_wav_tags
const AVCodecTag ff_codec_wav_tags[]
Definition: riff.c:499
get_edit_list_entry
static int get_edit_list_entry(MOVContext *mov, const MOVStreamContext *msc, unsigned int edit_list_index, int64_t *edit_list_media_time, int64_t *edit_list_duration, int64_t global_timescale)
Get ith edit list entry (media time, duration).
Definition: mov.c:3114
MOVFragmentIndexItem::moof_offset
int64_t moof_offset
Definition: isom.h:137
MOVStreamContext::spherical_size
size_t spherical_size
Definition: isom.h:227
AVINDEX_DISCARD_FRAME
#define AVINDEX_DISCARD_FRAME
Definition: avformat.h:809
AVPacket::duration
int64_t duration
Duration of this packet in AVStream->time_base units, 0 if unknown.
Definition: avcodec.h:1495
AVCodecParameters::codec_tag
uint32_t codec_tag
Additional information about the codec (corresponds to the AVI FOURCC).
Definition: avcodec.h:3961
AV_SPHERICAL_EQUIRECTANGULAR_TILE
@ AV_SPHERICAL_EQUIRECTANGULAR_TILE
Video represents a portion of a sphere mapped on a flat surface using equirectangular projection.
Definition: spherical.h:72
MOVDref::dir
char * dir
Definition: isom.h:76
mov_current_sample_set
static void mov_current_sample_set(MOVStreamContext *sc, int current_sample)
Definition: mov.c:3414
mathematics.h
AVDictionary
Definition: dict.c:30
AVProbeData::buf_size
int buf_size
Size of buf except extra allocated bytes.
Definition: avformat.h:449
MOVAtom
Definition: isom.h:82
mov_read_moov
static int mov_read_moov(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:1145
FFNABS
#define FFNABS(a)
Negative Absolute value.
Definition: common.h:81
AV_PKT_DATA_SPHERICAL
@ AV_PKT_DATA_SPHERICAL
This side data should be associated with a video stream and corresponds to the AVSphericalMapping str...
Definition: avcodec.h:1372
mov_read_esds
static int mov_read_esds(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:783
MOVStreamContext::sample_count
unsigned int sample_count
Definition: isom.h:181
MOVTrackExt::flags
unsigned flags
Definition: isom.h:106
AV_SPHERICAL_EQUIRECTANGULAR
@ AV_SPHERICAL_EQUIRECTANGULAR
Video represents a sphere mapped on a flat surface using equirectangular projection.
Definition: spherical.h:56
intfloat.h
id3v1.h
AV_CODEC_ID_R10K
@ AV_CODEC_ID_R10K
Definition: avcodec.h:363
av_encryption_init_info_get_side_data
AVEncryptionInitInfo * av_encryption_init_info_get_side_data(const uint8_t *side_data, size_t side_data_size)
Creates a copy of the AVEncryptionInitInfo that is contained in the given side data.
Definition: encryption_info.c:229
avio_size
int64_t avio_size(AVIOContext *s)
Get the filesize.
Definition: aviobuf.c:336
av_strlcatf
size_t av_strlcatf(char *dst, size_t size, const char *fmt,...)
Definition: avstring.c:101
mov_read_stco
static int mov_read_stco(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:1987
AV_PKT_FLAG_KEY
#define AV_PKT_FLAG_KEY
The packet contains a keyframe.
Definition: avcodec.h:1509
init_get_bits
static int init_get_bits(GetBitContext *s, const uint8_t *buffer, int bit_size)
Initialize GetBitContext.
Definition: get_bits.h:659
MOVStreamContext::aes_ctr
struct AVAESCTR * aes_ctr
Definition: isom.h:236
cenc_filter
static int cenc_filter(MOVContext *mov, AVStream *st, MOVStreamContext *sc, AVPacket *pkt, int current_index)
Definition: mov.c:6631
mov_read_jp2h
static int mov_read_jp2h(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:1712
AVIndexEntry
Definition: avformat.h:800
AV_WB64
#define AV_WB64(p, v)
Definition: intreadwrite.h:433
MOVStreamContext::dv_audio_container
int dv_audio_container
Definition: isom.h:195
AV_CODEC_ID_AMR_WB
@ AV_CODEC_ID_AMR_WB
Definition: avcodec.h:548
mov_read_tfhd
static int mov_read_tfhd(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:4591
AV_CODEC_ID_BIN_DATA
@ AV_CODEC_ID_BIN_DATA
Definition: avcodec.h:698
av_malloc
#define av_malloc(s)
Definition: tableprint_vlc.h:31
OPUS_SEEK_PREROLL_MS
#define OPUS_SEEK_PREROLL_MS
Definition: oggparseopus.c:35
AV_CODEC_ID_H261
@ AV_CODEC_ID_H261
Definition: avcodec.h:221
mov_read_wide
static int mov_read_wide(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:5102
AVINDEX_KEYFRAME
#define AVINDEX_KEYFRAME
Definition: avformat.h:808
MOVStreamContext::stsd_count
int stsd_count
Definition: isom.h:221
ff_mov_lang_to_iso639
int ff_mov_lang_to_iso639(unsigned code, char to[4])
Definition: isom.c:441
ff_mov_demuxer
AVInputFormat ff_mov_demuxer
Definition: mov.c:8062
skip_bits
static void skip_bits(GetBitContext *s, int n)
Definition: get_bits.h:467
AVCodecParameters::color_primaries
enum AVColorPrimaries color_primaries
Definition: avcodec.h:4044
AVEncryptionInfo::scheme
uint32_t scheme
The fourcc encryption scheme, in big-endian byte order.
Definition: encryption_info.h:45
MOVStreamContext::stsc_count
unsigned int stsc_count
Definition: isom.h:169
MOVStreamContext::has_palette
int has_palette
Definition: isom.h:206
AVPROBE_SCORE_MAX
#define AVPROBE_SCORE_MAX
maximum score
Definition: avformat.h:458
AV_STEREO3D_SIDEBYSIDE
@ AV_STEREO3D_SIDEBYSIDE
Views are next to each other.
Definition: stereo3d.h:67
MOVIndexRange::start
int64_t start
Definition: isom.h:153
get_bits
static unsigned int get_bits(GetBitContext *s, int n)
Read 1-25 bits.
Definition: get_bits.h:379
OFFSET
#define OFFSET(x)
Definition: mov.c:8008
AVCodecParameters::channels
int channels
Audio only.
Definition: avcodec.h:4063
MOVStreamContext::nb_frames_for_fps
int nb_frames_for_fps
Definition: isom.h:214
avpriv_dv_produce_packet
int avpriv_dv_produce_packet(DVDemuxContext *c, AVPacket *pkt, uint8_t *buf, int buf_size, int64_t pos)
Definition: dv.c:364
AVEncryptionInfo::skip_byte_block
uint32_t skip_byte_block
Only used for pattern encryption.
Definition: encryption_info.h:57
finish
static void finish(void)
Definition: movenc.c:345
aax_filter
static int aax_filter(uint8_t *input, int size, MOVContext *c)
Definition: mov.c:1094
AV_OPT_TYPE_BINARY
@ AV_OPT_TYPE_BINARY
offset must point to a pointer immediately followed by an int for the length
Definition: opt.h:229
MOVStreamContext::cenc
struct MOVStreamContext::@262 cenc
av_color_space_name
const char * av_color_space_name(enum AVColorSpace space)
Definition: pixdesc.c:2915
av_packet_add_side_data
int av_packet_add_side_data(AVPacket *pkt, enum AVPacketSideDataType type, uint8_t *data, size_t size)
Wrap an existing array as a packet side data.
Definition: avpacket.c:295
MOVStreamContext::mastering
AVMasteringDisplayMetadata * mastering
Definition: isom.h:228
AV_CODEC_ID_SPEEX
@ AV_CODEC_ID_SPEEX
Definition: avcodec.h:599
MOVFragmentIndexItem::current
int current
Definition: isom.h:139
AVFMT_SEEK_TO_PTS
#define AVFMT_SEEK_TO_PTS
Seeking is based on PTS.
Definition: avformat.h:489
AV_CODEC_ID_PCM_S16BE
@ AV_CODEC_ID_PCM_S16BE
Definition: avcodec.h:464
mov_read_mdhd
static int mov_read_mdhd(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:1420
mov_read_ctts
static int mov_read_ctts(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:2998
MOVTrackExt
Definition: isom.h:101
MOV_FRAG_SAMPLE_FLAG_IS_NON_SYNC
#define MOV_FRAG_SAMPLE_FLAG_IS_NON_SYNC
Definition: isom.h:321
fail
#define fail()
Definition: checkasm.h:120
mov_read_aclr
static int mov_read_aclr(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:1785
AVSEEK_FLAG_ANY
#define AVSEEK_FLAG_ANY
seek to any frame, even non-keyframes
Definition: avformat.h:2497
av_int2float
static av_always_inline float av_int2float(uint32_t i)
Reinterpret a 32-bit integer as a float.
Definition: intfloat.h:40
start
void INT64 start
Definition: avisynth_c.h:767
MOVFragment::found_tfhd
int found_tfhd
Definition: isom.h:90
MOVContext::decryption_key
uint8_t * decryption_key
Definition: isom.h:287
AV_STEREO3D_2D
@ AV_STEREO3D_2D
Video is not stereoscopic (and metadata has to be there).
Definition: stereo3d.h:55
read_seek
static int read_seek(AVFormatContext *ctx, int stream_index, int64_t timestamp, int flags)
Definition: libcdio.c:153
timecode.h
get_current_frag_stream_info
static MOVFragmentStreamInfo * get_current_frag_stream_info(MOVFragmentIndex *frag_index)
Definition: mov.c:1202
MOVStreamContext::ctts_index
int ctts_index
Definition: isom.h:177
GetBitContext
Definition: get_bits.h:61
av_timecode_make_string
char * av_timecode_make_string(const AVTimecode *tc, char *buf, int framenum)
Load timecode string in buf.
Definition: timecode.c:84
av_aes_ctr_alloc
struct AVAESCTR * av_aes_ctr_alloc(void)
Allocate an AVAESCTR context.
Definition: aes_ctr.c:36
read_close
static av_cold int read_close(AVFormatContext *ctx)
Definition: libcdio.c:145
mov_read_enda
static int mov_read_enda(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:1520
mov_read_chap
static int mov_read_chap(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:4632
MOVParseTableEntry
Definition: mov.c:70
avio_tell
static av_always_inline int64_t avio_tell(AVIOContext *s)
ftell() equivalent for AVIOContext.
Definition: avio.h:557
MOV_TRUN_SAMPLE_DURATION
#define MOV_TRUN_SAMPLE_DURATION
Definition: isom.h:315
type
it s the only field you need to keep assuming you have a context There is some magic you don t need to care about around this just let it vf type
Definition: writing_filters.txt:86
MOVContext
Definition: isom.h:243
AV_FIELD_UNKNOWN
@ AV_FIELD_UNKNOWN
Definition: avcodec.h:1544
AV_DISPOSITION_TIMED_THUMBNAILS
#define AV_DISPOSITION_TIMED_THUMBNAILS
The stream is sparse, and contains thumbnail images, often corresponding to chapter markers.
Definition: avformat.h:843
pts
static int64_t pts
Definition: transcode_aac.c:647
AVEncryptionInfo::iv
uint8_t * iv
The initialization vector.
Definition: encryption_info.h:71
AV_PKT_DATA_DISPLAYMATRIX
@ AV_PKT_DATA_DISPLAYMATRIX
This side data contains a 3x3 transformation matrix describing an affine transformation that needs to...
Definition: avcodec.h:1252
AV_CODEC_ID_MP3
@ AV_CODEC_ID_MP3
preferred ID for decoding MPEG audio layer 1, 2 or 3
Definition: avcodec.h:565
AVStream::duration
int64_t duration
Decoding: duration of the stream, in stream time base.
Definition: avformat.h:919
ss
#define ss(width, name, subs,...)
Definition: cbs_vp9.c:261
MOVStreamContext::width
int width
tkhd width
Definition: isom.h:202
MOVContext::meta_keys
char ** meta_keys
Definition: isom.h:252
MOVStreamContext::extradata_size
int * extradata_size
Definition: isom.h:219
av_reduce
int av_reduce(int *dst_num, int *dst_den, int64_t num, int64_t den, int64_t max)
Reduce a fraction.
Definition: rational.c:35
update_frag_index
static int update_frag_index(MOVContext *c, int64_t offset)
Definition: mov.c:1307
AVRational::num
int num
Numerator.
Definition: rational.h:59
src
#define src
Definition: vp8dsp.c:254
MOVStreamContext::keyframes
int * keyframes
Definition: isom.h:185
MOVEncryptionIndex::auxiliary_info_sample_count
size_t auxiliary_info_sample_count
Definition: isom.h:121
AVStream::attached_pic
AVPacket attached_pic
For streams with AV_DISPOSITION_ATTACHED_PIC disposition, this packet will contain the attached pictu...
Definition: avformat.h:952
MOVStsc::id
int id
Definition: isom.h:64
mov_read_saiz
static int mov_read_saiz(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:6159
MOV_FRAG_SAMPLE_FLAG_DEPENDS_YES
#define MOV_FRAG_SAMPLE_FLAG_DEPENDS_YES
Definition: isom.h:328
MOV_TRUN_DATA_OFFSET
#define MOV_TRUN_DATA_OFFSET
Definition: isom.h:313
av_encryption_info_clone
AVEncryptionInfo * av_encryption_info_clone(const AVEncryptionInfo *info)
Allocates an AVEncryptionInfo structure with a copy of the given data.
Definition: encryption_info.c:63
AV_DICT_DONT_STRDUP_VAL
#define AV_DICT_DONT_STRDUP_VAL
Take ownership of a value that's been allocated with av_malloc() or another memory allocation functio...
Definition: dict.h:74
av_bswap32
#define av_bswap32
Definition: bswap.h:33
MOVStreamContext::elst_data
MOVElst * elst_data
Definition: isom.h:175
mov_read_ares
static int mov_read_ares(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:1744
mov_read_adrm
static int mov_read_adrm(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:994
AVCodecParameters::color_trc
enum AVColorTransferCharacteristic color_trc
Definition: avcodec.h:4045
MOVFragmentIndex::complete
int complete
Definition: isom.h:146
AV_CODEC_ID_PCM_S8
@ AV_CODEC_ID_PCM_S8
Definition: avcodec.h:467
avassert.h
avio_rb32
unsigned int avio_rb32(AVIOContext *s)
Definition: aviobuf.c:800
AV_LOG_TRACE
#define AV_LOG_TRACE
Extremely verbose debugging, useful for libav* development.
Definition: log.h:202
MOVStreamContext::stsc_sample
int stsc_sample
Definition: isom.h:172
AV_LOG_ERROR
#define AV_LOG_ERROR
Something went wrong and cannot losslessly be recovered.
Definition: log.h:176
AV_CODEC_ID_MACE3
@ AV_CODEC_ID_MACE3
Definition: avcodec.h:573
buf
void * buf
Definition: avisynth_c.h:766
AVInputFormat
Definition: avformat.h:640
MOVTrackExt::track_id
unsigned track_id
Definition: isom.h:102
mov_free_encryption_index
static void mov_free_encryption_index(MOVEncryptionIndex **index)
Definition: mov.c:7215
AV_CH_LOW_FREQUENCY
#define AV_CH_LOW_FREQUENCY
Definition: channel_layout.h:52
duration
int64_t duration
Definition: movenc.c:63
MOVEncryptionIndex::auxiliary_offsets
uint64_t * auxiliary_offsets
Absolute seek position.
Definition: isom.h:123
MOVStreamContext::dts_shift
int dts_shift
dts shift when ctts is negative
Definition: isom.h:204
AV_PKT_DATA_AUDIO_SERVICE_TYPE
@ AV_PKT_DATA_AUDIO_SERVICE_TYPE
This side data should be associated with an audio stream and corresponds to enum AVAudioServiceType.
Definition: avcodec.h:1264
av_timecode_init
int av_timecode_init(AVTimecode *tc, AVRational rate, int flags, int frame_start, void *log_ctx)
Init a timecode struct with the passed parameters.
Definition: timecode.c:184
av_stream_new_side_data
uint8_t * av_stream_new_side_data(AVStream *stream, enum AVPacketSideDataType type, int size)
Allocate new information from stream.
Definition: utils.c:5522
AVCodecParameters::frame_size
int frame_size
Audio only.
Definition: avcodec.h:4078
avio_get_str16le
int avio_get_str16le(AVIOContext *pb, int maxlen, char *buf, int buflen)
Read a UTF-16 string from pb and convert it to UTF-8.
mov_metadata_track_or_disc_number
static int mov_metadata_track_or_disc_number(MOVContext *c, AVIOContext *pb, unsigned len, const char *key)
Definition: mov.c:80
av_dict_get
AVDictionaryEntry * av_dict_get(const AVDictionary *m, const char *key, const AVDictionaryEntry *prev, int flags)
Get a dictionary entry with matching key.
Definition: dict.c:40
MOVStreamContext::stsd_version
int stsd_version
Definition: isom.h:222
av_fast_realloc
void * av_fast_realloc(void *ptr, unsigned int *size, size_t min_size)
Reallocate the given buffer if it is not large enough, otherwise do nothing.
Definition: mem.c:476
FF_MOV_FLAG_MFRA_PTS
#define FF_MOV_FLAG_MFRA_PTS
Definition: isom.h:364
width
#define width
ff_mov_read_esds
int ff_mov_read_esds(AVFormatContext *fc, AVIOContext *pb)
Definition: mov_esds.c:23
stereo3d.h
AVMasteringDisplayMetadata::white_point
AVRational white_point[2]
CIE 1931 xy chromaticity coords of white point.
Definition: mastering_display_metadata.h:47
intreadwrite.h
mov_read_coll
static int mov_read_coll(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:5412
s
#define s(width, name)
Definition: cbs_vp9.c:257
MOVFragmentStreamInfo::encryption_index
MOVEncryptionIndex * encryption_index
Definition: isom.h:133
mov_read_trak
static int mov_read_trak(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:4185
MOVContext::fc
AVFormatContext * fc
Definition: isom.h:245
MOV_TFHD_DEFAULT_BASE_IS_MOOF
#define MOV_TFHD_DEFAULT_BASE_IS_MOOF
Definition: isom.h:311
AV_PKT_DATA_STEREO3D
@ AV_PKT_DATA_STEREO3D
This side data should be associated with a video stream and contains Stereoscopic 3D information in f...
Definition: avcodec.h:1258
AV_CODEC_ID_BMP
@ AV_CODEC_ID_BMP
Definition: avcodec.h:296
MOV_TFHD_DEFAULT_DURATION
#define MOV_TFHD_DEFAULT_DURATION
Definition: isom.h:307
ALAC_EXTRADATA_SIZE
#define ALAC_EXTRADATA_SIZE
DRM_BLOB_SIZE
#define DRM_BLOB_SIZE
Definition: mov.c:992
AVFieldOrder
AVFieldOrder
Definition: avcodec.h:1543
MOVStreamContext::drefs
MOVDref * drefs
Definition: isom.h:199
av_realloc_array
void * av_realloc_array(void *ptr, size_t nmemb, size_t size)
Definition: mem.c:198
AV_PKT_DATA_MASTERING_DISPLAY_METADATA
@ AV_PKT_DATA_MASTERING_DISPLAY_METADATA
Mastering display metadata (based on SMPTE-2086:2014).
Definition: avcodec.h:1366
format
Filter the word “frame” indicates either a video frame or a group of audio as stored in an AVFrame structure Format for each input and each output the list of supported formats For video that means pixel format For audio that means channel sample format(the sample packing is implied by the sample format) and sample rate. The lists are not just lists
AVInputFormat::name
const char * name
A comma separated list of short names for the format.
Definition: avformat.h:645
MOVContext::aes_decrypt
struct AVAES * aes_decrypt
Definition: isom.h:286
g
const char * g
Definition: vf_curves.c:115
AVProbeData::buf
unsigned char * buf
Buffer must have AVPROBE_PADDING_SIZE of extra allocated bytes filled with zero.
Definition: avformat.h:448
AVSphericalMapping::bound_top
uint32_t bound_top
Distance from the top edge.
Definition: spherical.h:168
AVMEDIA_TYPE_AUDIO
@ AVMEDIA_TYPE_AUDIO
Definition: avutil.h:202
AV_CODEC_ID_VP9
@ AV_CODEC_ID_VP9
Definition: avcodec.h:386
MOVFragmentIndex::nb_items
int nb_items
Definition: isom.h:148
AVCodecParameters::width
int width
Video only.
Definition: avcodec.h:4023
AV_CODEC_ID_MP2
@ AV_CODEC_ID_MP2
Definition: avcodec.h:564
MOV_TRUN_FIRST_SAMPLE_FLAGS
#define MOV_TRUN_FIRST_SAMPLE_FLAGS
Definition: isom.h:314
AVIndexEntry::size
int size
Definition: avformat.h:811
MOVStreamContext::keyframe_absent
int keyframe_absent
Definition: isom.h:183
info
MIPS optimizations info
Definition: mips.txt:2
MOVStreamContext::coll_size
size_t coll_size
Definition: isom.h:230
av_mastering_display_metadata_alloc
AVMasteringDisplayMetadata * av_mastering_display_metadata_alloc(void)
Copyright (c) 2016 Neil Birkbeck neil.birkbeck@gmail.com
Definition: mastering_display_metadata.c:27
mov_estimate_video_delay
static void mov_estimate_video_delay(MOVContext *c, AVStream *st)
Definition: mov.c:3335
AVIndexEntry::timestamp
int64_t timestamp
Timestamp in AVStream.time_base units, preferably the time from which on correctly decoded frames are...
Definition: avformat.h:802
av_assert0
#define av_assert0(cond)
assert() equivalent, that is always enabled.
Definition: avassert.h:37
av_aes_ctr_crypt
void av_aes_ctr_crypt(struct AVAESCTR *a, uint8_t *dst, const uint8_t *src, int count)
Process a buffer using a previously initialized context.
Definition: aes_ctr.c:111
MOVStreamContext::min_corrected_pts
int64_t min_corrected_pts
minimum Composition time shown by the edits excluding empty edits.
Definition: isom.h:188
AV_LOG_DEBUG
#define AV_LOG_DEBUG
Stuff which is only useful for libav* developers.
Definition: log.h:197
AVStream::need_parsing
enum AVStreamParseType need_parsing
Definition: avformat.h:1088
ctx
AVFormatContext * ctx
Definition: movenc.c:48
get_bits.h
limits.h
mov_read_sidx
static int mov_read_sidx(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:4992
av_rescale_q
int64_t av_rescale_q(int64_t a, AVRational bq, AVRational cq)
Rescale a 64-bit integer by 2 rational numbers.
Definition: mathematics.c:142
AVAudioServiceType
AVAudioServiceType
Definition: avcodec.h:814
mov_find_next_sample
static AVIndexEntry * mov_find_next_sample(AVFormatContext *s, AVStream **st)
Definition: mov.c:7653
AV_CODEC_ID_TARGA_Y216
@ AV_CODEC_ID_TARGA_Y216
Definition: avcodec.h:419
AVIndexEntry::min_distance
int min_distance
Minimum distance between this and the previous keyframe, used to avoid unneeded searching.
Definition: avformat.h:812
MOVParseTableEntry::parse
int(* parse)(MOVContext *ctx, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:72
mov_try_read_block
static int mov_try_read_block(AVIOContext *pb, size_t size, uint8_t **data)
Tries to read the given number of bytes from the stream and puts it in a newly allocated buffer.
Definition: mov.c:6132
AV_CODEC_ID_SVQ3
@ AV_CODEC_ID_SVQ3
Definition: avcodec.h:241
key
const char * key
Definition: hwcontext_opencl.c:168
search_frag_timestamp
static int search_frag_timestamp(MOVFragmentIndex *frag_index, AVStream *st, int64_t timestamp)
Definition: mov.c:1273
color_range
color_range
Definition: vf_selectivecolor.c:44
AVMEDIA_TYPE_DATA
@ AVMEDIA_TYPE_DATA
Opaque data information usually continuous.
Definition: avutil.h:203
mov_read_udta_string
static int mov_read_udta_string(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:302
mov_read_stss
static int mov_read_stss(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:2769
mov_read_ddts
static int mov_read_ddts(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:864
mov_read_uuid
static int mov_read_uuid(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:5725
AVCOL_PRI_UNSPECIFIED
@ AVCOL_PRI_UNSPECIFIED
Definition: pixfmt.h:446
MOVTrackExt::duration
unsigned duration
Definition: isom.h:104
f
#define f(width, name)
Definition: cbs_vp9.c:255
AV_CODEC_ID_H264
@ AV_CODEC_ID_H264
Definition: avcodec.h:245
av_packet_new_side_data
uint8_t * av_packet_new_side_data(AVPacket *pkt, enum AVPacketSideDataType type, int size)
Allocate new information of a packet.
Definition: avpacket.c:329
av_content_light_metadata_alloc
AVContentLightMetadata * av_content_light_metadata_alloc(size_t *size)
Allocate an AVContentLightMetadata structure and set its fields to default values.
Definition: mastering_display_metadata.c:45
av_sha_final
void av_sha_final(AVSHA *ctx, uint8_t *digest)
Finish hashing and output digest value.
Definition: sha.c:345
MOVStreamContext::current_sample
int current_sample
Definition: isom.h:189
version
int version
Definition: avisynth_c.h:858
MOVFragmentStreamInfo::sidx_pts
int64_t sidx_pts
Definition: isom.h:129
MAX_REORDER_DELAY
#define MAX_REORDER_DELAY
Definition: mov.c:3334
MOVFragmentIndex::current
int current
Definition: isom.h:147
int32_t
int32_t
Definition: audio_convert.c:194
MOVEncryptionIndex::encrypted_samples
AVEncryptionInfo ** encrypted_samples
Definition: isom.h:118
mov_read_close
static int mov_read_close(AVFormatContext *s)
Definition: mov.c:7227
MOVAtom::size
int64_t size
Definition: isom.h:84
FFABS
#define FFABS(a)
Absolute value, Note, INT_MIN / INT64_MIN result in undefined behavior as they are not representable ...
Definition: common.h:72
ff_mov_get_lpcm_codec_id
static enum AVCodecID ff_mov_get_lpcm_codec_id(int bps, int flags)
Compute codec id for 'lpcm' tag.
Definition: isom.h:370
AV_CODEC_ID_PNG
@ AV_CODEC_ID_PNG
Definition: avcodec.h:279
AV_CODEC_ID_AVUI
@ AV_CODEC_ID_AVUI
Definition: avcodec.h:417
time_internal.h
FLAC_METADATA_TYPE_STREAMINFO
@ FLAC_METADATA_TYPE_STREAMINFO
Definition: flac.h:48
if
if(ret)
Definition: filter_design.txt:179
mov_read_cmov
static int mov_read_cmov(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:5122
mov_read_sample_encryption_info
static int mov_read_sample_encryption_info(MOVContext *c, AVIOContext *pb, MOVStreamContext *sc, AVEncryptionInfo **sample, int use_subsamples)
Definition: mov.c:5958
MOVStreamContext::keyframe_count
unsigned int keyframe_count
Definition: isom.h:184
MOVStreamContext::ctts_data
MOVStts * ctts_data
Definition: isom.h:168
AVDISCARD_ALL
@ AVDISCARD_ALL
discard all
Definition: avcodec.h:811
AVFormatContext
Format I/O context.
Definition: avformat.h:1342
av_realloc_f
#define av_realloc_f(p, o, n)
Definition: tableprint_vlc.h:33
mov_read_stts
static int mov_read_stts(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:2911
MOVStreamContext::index_ranges
MOVIndexRange * index_ranges
Definition: isom.h:191
internal.h
MOVTrackExt::stsd_id
unsigned stsd_id
Definition: isom.h:103
set_frag_stream
static void set_frag_stream(MOVFragmentIndex *frag_index, int id)
Definition: mov.c:1182
mov_read_free
static int mov_read_free(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:5839
mov_realloc_extradata
static int mov_realloc_extradata(AVCodecParameters *par, MOVAtom atom)
Definition: mov.c:1639
AVPacket::buf
AVBufferRef * buf
A reference to the reference-counted buffer where the packet data is stored.
Definition: avcodec.h:1460
AVStream::codecpar
AVCodecParameters * codecpar
Codec parameters associated with this stream.
Definition: avformat.h:1017
LIBAVUTIL_VERSION_INT
#define LIBAVUTIL_VERSION_INT
Definition: version.h:85
AVSEEK_FLAG_BACKWARD
#define AVSEEK_FLAG_BACKWARD
Definition: avformat.h:2495
read_header
static int read_header(FFV1Context *f)
Definition: ffv1dec.c:530
aes.h
AVClass
Describe the class of an AVClass context structure.
Definition: log.h:67
avpriv_dv_get_packet
int avpriv_dv_get_packet(DVDemuxContext *c, AVPacket *pkt)
Definition: dv.c:347
MOVContext::ignore_editlist
int ignore_editlist
Definition: isom.h:265
result
and forward the result(frame or status change) to the corresponding input. If nothing is possible
AVStream::time_base
AVRational time_base
This is the fundamental unit of time (in seconds) in terms of which frame timestamps are represented.
Definition: avformat.h:899
NULL
#define NULL
Definition: coverity.c:32
sha.h
MOVDref
Definition: isom.h:73
AVERROR_PATCHWELCOME
#define AVERROR_PATCHWELCOME
Not yet implemented in FFmpeg, patches welcome.
Definition: error.h:62
read_probe
static int read_probe(const AVProbeData *pd)
Definition: jvdec.c:55
MOVStreamContext::ctts_count
unsigned int ctts_count
Definition: isom.h:166
AVEncryptionInitInfo
This describes info used to initialize an encryption key system.
Definition: encryption_info.h:88
isom.h
mov_read_ftyp
static int mov_read_ftyp(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:1108
AV_WB16
#define AV_WB16(p, v)
Definition: intreadwrite.h:405
MOVElst
Definition: isom.h:67
flac_parse_block_header
static av_always_inline void flac_parse_block_header(const uint8_t *block_header, int *last, int *type, int *size)
Parse the metadata block parameters from the header.
Definition: flac.h:145
AVRational
Rational number (pair of numerator and denominator).
Definition: rational.h:58
isnan
#define isnan(x)
Definition: libm.h:340
mov_probe
static int mov_probe(const AVProbeData *p)
Definition: mov.c:6963
av_stream_add_side_data
int av_stream_add_side_data(AVStream *st, enum AVPacketSideDataType type, uint8_t *data, size_t size)
Wrap an existing array as stream side data.
Definition: utils.c:5486
AVPALETTE_SIZE
#define AVPALETTE_SIZE
Definition: pixfmt.h:32
MOVDref::nlvl_to
int16_t nlvl_to
Definition: isom.h:79
AV_CODEC_ID_DVD_SUBTITLE
@ AV_CODEC_ID_DVD_SUBTITLE
Definition: avcodec.h:658
AVIndexEntry::flags
int flags
Definition: avformat.h:810
MOVStreamContext::time_offset
int64_t time_offset
time offset of the edit list entries
Definition: isom.h:187
mov_read_smdm
static int mov_read_smdm(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:5328
av_default_item_name
const char * av_default_item_name(void *ptr)
Return the context name.
Definition: log.c:191
avio_rb64
uint64_t avio_rb64(AVIOContext *s)
Definition: aviobuf.c:921
av_aes_crypt
void av_aes_crypt(AVAES *a, uint8_t *dst, const uint8_t *src, int count, uint8_t *iv, int decrypt)
Encrypt or decrypt a buffer using a previously initialized context.
Definition: aes.c:163
MOVStreamContext::current_index_range
MOVIndexRange * current_index_range
Definition: isom.h:192
mov_open_dref
static int mov_open_dref(MOVContext *c, AVIOContext **pb, const char *src, MOVDref *ref)
Definition: mov.c:4103
AVProbeData
This structure contains the data a format has to probe a file.
Definition: avformat.h:446
av_aes_alloc
struct AVAES * av_aes_alloc(void)
Allocate an AVAES context.
Definition: aes.c:31
TAG_IS_AVCI
#define TAG_IS_AVCI(tag)
Definition: isom.h:340
MOVStreamContext::timecode_track
int timecode_track
Definition: isom.h:201
mov_read_schm
static int mov_read_schm(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:6436
AVStream::metadata
AVDictionary * metadata
Definition: avformat.h:934
FLAC_STREAMINFO_SIZE
#define FLAC_STREAMINFO_SIZE
Definition: flac.h:34
av_color_primaries_name
const char * av_color_primaries_name(enum AVColorPrimaries primaries)
Definition: pixdesc.c:2867
FF_MOV_FLAG_MFRA_DTS
#define FF_MOV_FLAG_MFRA_DTS
Definition: isom.h:363
AV_DICT_DONT_OVERWRITE
#define AV_DICT_DONT_OVERWRITE
Don't overwrite existing entries.
Definition: dict.h:76
MOVStreamContext::rap_group
MOVSbgp * rap_group
Definition: isom.h:212
AV_CODEC_ID_QDM2
@ AV_CODEC_ID_QDM2
Definition: avcodec.h:583
mov_read_ilst
static int mov_read_ilst(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:4314
AV_CH_FRONT_CENTER
#define AV_CH_FRONT_CENTER
Definition: channel_layout.h:51
mov_read_fiel
static int mov_read_fiel(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:1605
av_encryption_info_add_side_data
uint8_t * av_encryption_info_add_side_data(const AVEncryptionInfo *info, size_t *size)
Allocates and initializes side data that holds a copy of the given encryption info.
Definition: encryption_info.c:125
MOV_TFHD_BASE_DATA_OFFSET
#define MOV_TFHD_BASE_DATA_OFFSET
Definition: isom.h:305
ff_codec_movdata_tags
const AVCodecTag ff_codec_movdata_tags[]
Definition: isom.c:383
mov_read_wfex
static int mov_read_wfex(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:945
av_sha_update
void av_sha_update(struct AVSHA *ctx, const uint8_t *data, unsigned int len)
Update hash value.
Definition: sha.c:315
index
int index
Definition: gxfenc.c:89
c
Undefined Behavior In the C some operations are like signed integer dereferencing freed accessing outside allocated Undefined Behavior must not occur in a C it is not safe even if the output of undefined operations is unused The unsafety may seem nit picking but Optimizing compilers have in fact optimized code on the assumption that no undefined Behavior occurs Optimizing code based on wrong assumptions can and has in some cases lead to effects beyond the output of computations The signed integer overflow problem in speed critical code Code which is highly optimized and works with signed integers sometimes has the problem that often the output of the computation does not c
Definition: undefined.txt:32
AVPROBE_SCORE_EXTENSION
#define AVPROBE_SCORE_EXTENSION
score for file extension
Definition: avformat.h:456
MOVSbgp::count
unsigned int count
Definition: isom.h:110
AVCodecParameters::sample_rate
int sample_rate
Audio only.
Definition: avcodec.h:4067
av_get_channel_layout_nb_channels
int av_get_channel_layout_nb_channels(uint64_t channel_layout)
Return the number of channels in the channel layout.
Definition: channel_layout.c:220
mov_parse_stsd_subtitle
static void mov_parse_stsd_subtitle(MOVContext *c, AVIOContext *pb, AVStream *st, MOVStreamContext *sc, int64_t size)
Definition: mov.c:2240
mov_skip_multiple_stsd
static int mov_skip_multiple_stsd(MOVContext *c, AVIOContext *pb, int codec_tag, int format, int64_t size)
Definition: mov.c:2448
MOVStts
Definition: isom.h:56
AV_CODEC_ID_MPEG1VIDEO
@ AV_CODEC_ID_MPEG1VIDEO
Definition: avcodec.h:219
AV_CODEC_ID_GSM
@ AV_CODEC_ID_GSM
as in Berlin toast format
Definition: avcodec.h:582
AVStream::nb_frames
int64_t nb_frames
number of frames in this stream if known or 0
Definition: avformat.h:921
AVCodecID
AVCodecID
Identify the syntax and semantics of the bitstream.
Definition: avcodec.h:215
AV_CODEC_ID_EAC3
@ AV_CODEC_ID_EAC3
Definition: avcodec.h:604
should_retry
static int should_retry(AVIOContext *pb, int error_code)
Definition: mov.c:7679
AVCodecParameters::extradata_size
int extradata_size
Size of the extradata content in bytes.
Definition: avcodec.h:3975
AV_WB32
#define AV_WB32(p, v)
Definition: intreadwrite.h:419
AV_AUDIO_SERVICE_TYPE_KARAOKE
@ AV_AUDIO_SERVICE_TYPE_KARAOKE
Definition: avcodec.h:823
mov_read_pasp
static int mov_read_pasp(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:960
MOVContext::dv_demux
DVDemuxContext * dv_demux
Definition: isom.h:254
AV_CODEC_ID_AAC
@ AV_CODEC_ID_AAC
Definition: avcodec.h:566
ff_dlog
#define ff_dlog(a,...)
Definition: tableprint_vlc.h:29
av_aes_ctr_free
void av_aes_ctr_free(struct AVAESCTR *a)
Release an AVAESCTR context.
Definition: aes_ctr.c:84
mov_read_elst
static int mov_read_elst(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:5176
MOVEncryptionIndex::auxiliary_info_default_size
uint8_t auxiliary_info_default_size
Definition: isom.h:122
cid
int cid
Definition: mxfenc.c:2072
mov_read_header
static int mov_read_header(AVFormatContext *s)
Definition: mov.c:7442
ff_codec_movvideo_tags
const AVCodecTag ff_codec_movvideo_tags[]
Definition: isom.c:75
AV_CODEC_ID_QCELP
@ AV_CODEC_ID_QCELP
Definition: avcodec.h:588
av_get_bits_per_sample
int av_get_bits_per_sample(enum AVCodecID codec_id)
Return codec bits per sample.
Definition: utils.c:1550
avio_rl32
unsigned int avio_rl32(AVIOContext *s)
Definition: aviobuf.c:769
AVDISCARD_NONKEY
@ AVDISCARD_NONKEY
discard all frames except keyframes
Definition: avcodec.h:810
MOVFragment::flags
unsigned flags
Definition: isom.h:98
AVIOContext
Bytestream IO Context.
Definition: avio.h:161
AV_CODEC_ID_PCM_S24LE
@ AV_CODEC_ID_PCM_S24LE
Definition: avcodec.h:475
mov_read_wave
static int mov_read_wave(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:1833
ffio_init_context
int ffio_init_context(AVIOContext *s, unsigned char *buffer, int buffer_size, int write_flag, void *opaque, int(*read_packet)(void *opaque, uint8_t *buf, int buf_size), int(*write_packet)(void *opaque, uint8_t *buf, int buf_size), int64_t(*seek)(void *opaque, int64_t offset, int whence))
Definition: aviobuf.c:81
AV_SPHERICAL_CUBEMAP
@ AV_SPHERICAL_CUBEMAP
Video frame is split into 6 faces of a cube, and arranged on a 3x2 layout.
Definition: spherical.h:65
avio_rb24
unsigned int avio_rb24(AVIOContext *s)
Definition: aviobuf.c:793
ff_mpa_check_header
static int ff_mpa_check_header(uint32_t header)
Definition: mpegaudiodecheader.h:61
MOVContext::handbrake_version
int handbrake_version
Definition: isom.h:261
AVPacket::size
int size
Definition: avcodec.h:1478
MOVStreamContext::ctts_sample
int ctts_sample
Definition: isom.h:178
NULL_IF_CONFIG_SMALL
#define NULL_IF_CONFIG_SMALL(x)
Return NULL if CONFIG_SMALL is true, otherwise the argument without modification.
Definition: internal.h:188
id
enum AVCodecID id
Definition: extract_extradata_bsf.c:329
ff_codec_get_id
enum AVCodecID ff_codec_get_id(const AVCodecTag *tags, unsigned int tag)
Definition: utils.c:3146
avformat_alloc_context
AVFormatContext * avformat_alloc_context(void)
Allocate an AVFormatContext.
Definition: options.c:144
MOVFragmentIndexItem
Definition: isom.h:136
get_current_encryption_info
static int get_current_encryption_info(MOVContext *c, MOVEncryptionIndex **encryption_index, MOVStreamContext **sc)
Gets the current encryption info and associated current stream context.
Definition: mov.c:5908
AVIOContext::seekable
int seekable
A combination of AVIO_SEEKABLE_ flags or 0 when the stream is not seekable.
Definition: avio.h:260
AVStream::nb_index_entries
int nb_index_entries
Definition: avformat.h:1101
qtpalette.h
mov_read_dref
static int mov_read_dref(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:578
mov_current_sample_dec
static void mov_current_sample_dec(MOVStreamContext *sc)
Definition: mov.c:3402
av_stream_get_side_data
uint8_t * av_stream_get_side_data(const AVStream *stream, enum AVPacketSideDataType type, int *size)
Get side information from stream.
Definition: utils.c:5471
AVSphericalMapping::bound_right
uint32_t bound_right
Distance from the right edge.
Definition: spherical.h:169
MOVStsc::first
int first
Definition: isom.h:62
MOVStreamContext::stsz_sample_size
unsigned int stsz_sample_size
always contains sample size from stsz atom
Definition: isom.h:180
FF_MOV_FLAG_MFRA_AUTO
#define FF_MOV_FLAG_MFRA_AUTO
Definition: isom.h:362
FF_COMPLIANCE_STRICT
#define FF_COMPLIANCE_STRICT
Strictly conform to all the things in the spec no matter what consequences.
Definition: avcodec.h:2630
start_time
static int64_t start_time
Definition: ffplay.c:331
FFMAX
#define FFMAX(a, b)
Definition: common.h:94
avpriv_set_pts_info
void avpriv_set_pts_info(AVStream *s, int pts_wrap_bits, unsigned int pts_num, unsigned int pts_den)
Set the time base and wrapping info for a given stream.
Definition: utils.c:4910
mov_read_trun
static int mov_read_trun(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:4717
avio_get_str
int avio_get_str(AVIOContext *pb, int maxlen, char *buf, int buflen)
Read a string from pb into buf.
Definition: aviobuf.c:879
sample
#define sample
Definition: flacdsp_template.c:44
hypot
static av_const double hypot(double x, double y)
Definition: libm.h:366
AV_CODEC_ID_H263
@ AV_CODEC_ID_H263
Definition: avcodec.h:222
MOV_TFHD_STSD_ID
#define MOV_TFHD_STSD_ID
Definition: isom.h:306
size
int size
Definition: twinvq_data.h:11134
mov_read_chan
static int mov_read_chan(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:926
av_make_q
static AVRational av_make_q(int num, int den)
Create an AVRational.
Definition: rational.h:71
mov_read_stsc
static int mov_read_stsc(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:2641
av_reallocp
int av_reallocp(void *ptr, size_t size)
Allocate, reallocate, or free a block of memory through a pointer to a pointer.
Definition: mem.c:163
ff_get_qtpalette
int ff_get_qtpalette(int codec_id, AVIOContext *pb, uint32_t *palette)
Retrieve the palette (or "color table" in QuickTime terms), either from the video sample description,...
Definition: qtpalette.c:31
AV_NOPTS_VALUE
#define AV_NOPTS_VALUE
Undefined timestamp value.
Definition: avutil.h:248
AV_CODEC_ID_QDMC
@ AV_CODEC_ID_QDMC
Definition: avcodec.h:614
AV_RB32
uint64_t_TMPL AV_WL64 unsigned int_TMPL AV_WL32 unsigned int_TMPL AV_WL24 unsigned int_TMPL AV_WL16 uint64_t_TMPL AV_WB64 unsigned int_TMPL AV_RB32
Definition: bytestream.h:92
AES_CTR_KEY_SIZE
#define AES_CTR_KEY_SIZE
Definition: aes_ctr.h:30
MKBETAG
#define MKBETAG(a, b, c, d)
Definition: common.h:367
MOVStreamContext::coll
AVContentLightMetadata * coll
Definition: isom.h:229
aes_ctr.h
add_index_entry
static int64_t add_index_entry(AVStream *st, int64_t pos, int64_t timestamp, int size, int distance, int flags)
Add index entry with the given values, to the end of st->index_entries.
Definition: mov.c:3252
MOVDref::path
char * path
Definition: isom.h:75
mov_current_sample_inc
static void mov_current_sample_inc(MOVStreamContext *sc)
Definition: mov.c:3390
AVStream::sample_aspect_ratio
AVRational sample_aspect_ratio
sample aspect ratio (0 if unknown)
Definition: avformat.h:932
val
const char const char void * val
Definition: avisynth_c.h:863
get_frag_time
static int64_t get_frag_time(MOVFragmentIndex *frag_index, int index, int track_id)
Definition: mov.c:1252
AVPacket::dts
int64_t dts
Decompression timestamp in AVStream->time_base units; the time at which the packet is decompressed.
Definition: avcodec.h:1476
AV_WL16
#define AV_WL16(p, v)
Definition: intreadwrite.h:412
fix_timescale
static void fix_timescale(MOVContext *c, MOVStreamContext *sc)
Definition: mov.c:4175
avio_r8
int avio_r8(AVIOContext *s)
Definition: aviobuf.c:638
height
#define height
AVSphericalMapping::padding
uint32_t padding
Number of pixels to pad from the edge of each cube face.
Definition: spherical.h:182
a
The reader does not expect b to be semantically here and if the code is changed by maybe adding a a division or other the signedness will almost certainly be mistaken To avoid this confusion a new type was SUINT is the C unsigned type but it holds a signed int to use the same example SUINT a
Definition: undefined.txt:41
FFMIN
#define FFMIN(a, b)
Definition: common.h:96
av_reallocp_array
int av_reallocp_array(void *ptr, size_t nmemb, size_t size)
Allocate, reallocate, or free an array through a pointer to a pointer.
Definition: mem.c:205
mov_read_default
static int mov_read_default(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:6839
AV_TIMECODE_FLAG_24HOURSMAX
@ AV_TIMECODE_FLAG_24HOURSMAX
timecode wraps after 24 hours
Definition: timecode.h:37
ffio_ensure_seekback
int ffio_ensure_seekback(AVIOContext *s, int64_t buf_size)
Ensures that the requested seekback buffer size will be available.
Definition: aviobuf.c:1051
AV_FIELD_TT
@ AV_FIELD_TT
Definition: avcodec.h:1546
mov_read_packet
static int mov_read_packet(AVFormatContext *s, AVPacket *pkt)
Definition: mov.c:7744
offset
it s the only field you need to keep assuming you have a context There is some magic you don t need to care about around this just let it vf offset
Definition: writing_filters.txt:86
attributes.h
AV_PKT_DATA_CONTENT_LIGHT_LEVEL
@ AV_PKT_DATA_CONTENT_LIGHT_LEVEL
Content light level (based on CTA-861.3).
Definition: avcodec.h:1379
MOVEncryptionIndex::auxiliary_offsets_count
size_t auxiliary_offsets_count
Definition: isom.h:124
AVPacket::flags
int flags
A combination of AV_PKT_FLAG values.
Definition: avcodec.h:1483
av_encryption_info_free
void av_encryption_info_free(AVEncryptionInfo *info)
Frees the given encryption info object.
Definition: encryption_info.c:80
AVSubsampleEncryptionInfo
This file is part of FFmpeg.
Definition: encryption_info.h:25
MOVFragmentIndexItem::stream_info
MOVFragmentStreamInfo * stream_info
Definition: isom.h:141
AVEncryptionInitInfo::next
struct AVEncryptionInitInfo * next
An optional pointer to the next initialization info in the list.
Definition: encryption_info.h:122
input
and forward the test the status of outputs and forward it to the corresponding return FFERROR_NOT_READY If the filters stores internally one or a few frame for some input
Definition: filter_design.txt:172
mov_read_clli
static int mov_read_clli(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:5449
MOVStreamContext::chunk_offsets
int64_t * chunk_offsets
Definition: isom.h:163
MOVFragmentIndex::item
MOVFragmentIndexItem * item
Definition: isom.h:149
AV_LOG_INFO
#define AV_LOG_INFO
Standard information.
Definition: log.h:187
av_encryption_init_info_alloc
AVEncryptionInitInfo * av_encryption_init_info_alloc(uint32_t system_id_size, uint32_t num_key_ids, uint32_t key_id_size, uint32_t data_size)
Allocates an AVEncryptionInitInfo structure and sub-pointers to hold the given sizes.
Definition: encryption_info.c:176
MOVContext::decryption_key_len
int decryption_key_len
Definition: isom.h:288
mov_read_dfla
static int mov_read_dfla(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:6538
mov_default_parse_table
static const MOVParseTableEntry mov_default_parse_table[]
Definition: mov.c:6743
av_realloc
void * av_realloc(void *ptr, size_t size)
Allocate, reallocate, or free a block of memory.
Definition: mem.c:135
layout
Filter the word “frame” indicates either a video frame or a group of audio as stored in an AVFrame structure Format for each input and each output the list of supported formats For video that means pixel format For audio that means channel layout
Definition: filter_design.txt:18
MOVDref::nlvl_from
int16_t nlvl_from
Definition: isom.h:79
flag
#define flag(name)
Definition: cbs_av1.c:557
parse_timecode_in_framenum_format
static int parse_timecode_in_framenum_format(AVFormatContext *s, AVStream *st, uint32_t value, int flags)
Definition: mov.c:7148
mov_metadata_hmmt
static int mov_metadata_hmmt(MOVContext *c, AVIOContext *pb, unsigned len)
Definition: mov.c:281
AV_CODEC_ID_MJPEG
@ AV_CODEC_ID_MJPEG
Definition: avcodec.h:225
MOVStreamContext::stsc_index
unsigned int stsc_index
Definition: isom.h:171
av_sha_alloc
struct AVSHA * av_sha_alloc(void)
Allocate an AVSHA context.
Definition: sha.c:45
mov_read_tenc
static int mov_read_tenc(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:6467
mov_stsc_index_valid
static int mov_stsc_index_valid(unsigned int index, unsigned int count)
Definition: mov.c:2712
MOVIndexRange
Definition: isom.h:152
mov_read_seek
static int mov_read_seek(AVFormatContext *s, int stream_index, int64_t sample_time, int flags)
Definition: mov.c:7956
MOVContext::advanced_editlist
int advanced_editlist
Definition: isom.h:266
MOVStreamContext::time_scale
int time_scale
Definition: isom.h:186
mac_to_unicode
static const uint32_t mac_to_unicode[128]
Definition: mov.c:139
MOVStreamContext::bytes_per_frame
unsigned int bytes_per_frame
Definition: isom.h:193
AVSphericalMapping::roll
int32_t roll
Rotation around the forward vector [-180, 180].
Definition: spherical.h:128
MOVIndexRange::end
int64_t end
Definition: isom.h:154
AV_CODEC_ID_NONE
@ AV_CODEC_ID_NONE
Definition: avcodec.h:216
i
#define i(width, name, range_min, range_max)
Definition: cbs_h2645.c:259
AVPacket::pts
int64_t pts
Presentation timestamp in AVStream->time_base units; the time at which the decompressed packet will b...
Definition: avcodec.h:1470
avio_internal.h
mov_read_trex
static int mov_read_trex(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:4653
FLAGS
#define FLAGS
Definition: mov.c:8009
AV_CODEC_ID_AVS
@ AV_CODEC_ID_AVS
Definition: avcodec.h:300
MOVStreamContext::stereo3d
AVStereo3D * stereo3d
Definition: isom.h:225
mov_fix_index
static void mov_fix_index(MOVContext *mov, AVStream *st)
Fix st->index_entries, so that it contains only the entries (and the entries which are needed to deco...
Definition: mov.c:3442
mov_read_pssh
static int mov_read_pssh(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:6326
MOVDref::volume
char volume[28]
Definition: isom.h:77
mov_read_stsd
static int mov_read_stsd(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:2576
internal.h
AVCodecParameters::height
int height
Definition: avcodec.h:4024
mov_rewrite_dvd_sub_extradata
static int mov_rewrite_dvd_sub_extradata(AVStream *st)
Definition: mov.c:2270
MOVStts::duration
int duration
Definition: isom.h:58
AV_TIME_BASE
#define AV_TIME_BASE
Internal time base represented as integer.
Definition: avutil.h:254
MOVStreamContext::stps_count
unsigned int stps_count
Definition: isom.h:173
AVCodecParameters::block_align
int block_align
Audio only.
Definition: avcodec.h:4074
av_malloc_array
#define av_malloc_array(a, b)
Definition: tableprint_vlc.h:32
display.h
ff_mov_read_stsd_entries
int ff_mov_read_stsd_entries(MOVContext *c, AVIOContext *pb, int entries)
Definition: mov.c:2476
avpriv_new_chapter
AVChapter * avpriv_new_chapter(AVFormatContext *s, int id, AVRational time_base, int64_t start, int64_t end, const char *title)
Add a new chapter.
Definition: utils.c:4608
avpriv_ac3_channel_layout_tab
const uint16_t avpriv_ac3_channel_layout_tab[8]
Map audio coding mode (acmod) to channel layout mask.
Definition: ac3tab.c:89
AV_STEREO3D_TOPBOTTOM
@ AV_STEREO3D_TOPBOTTOM
Views are on top of each other.
Definition: stereo3d.h:79
MOVFragment::duration
unsigned duration
Definition: isom.h:96
ff_id3v1_genre_str
const char *const ff_id3v1_genre_str[ID3v1_GENRE_MAX+1]
ID3v1 genres.
Definition: id3v1.c:27
MOVContext::frag_index
MOVFragmentIndex frag_index
Definition: isom.h:277
mov_read_vpcc
static int mov_read_vpcc(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:5284
AV_CODEC_ID_PCM_F64BE
@ AV_CODEC_ID_PCM_F64BE
Definition: avcodec.h:485
mov_update_dts_shift
static void mov_update_dts_shift(MOVStreamContext *sc, int duration)
Definition: mov.c:2987
AV_CODEC_ID_HEVC
@ AV_CODEC_ID_HEVC
Definition: avcodec.h:392
value
it s the only field you need to keep assuming you have a context There is some magic you don t need to care about around this just let it vf default value
Definition: writing_filters.txt:86
AV_OPT_FLAG_DECODING_PARAM
#define AV_OPT_FLAG_DECODING_PARAM
a generic parameter which can be set by the user for demuxing or decoding
Definition: opt.h:277
av_url_split
void av_url_split(char *proto, int proto_size, char *authorization, int authorization_size, char *hostname, int hostname_size, int *port_ptr, char *path, int path_size, const char *url)
Split a URL string into components.
Definition: utils.c:4756
MOVStreamContext::dref_id
int dref_id
Definition: isom.h:200
av_d2q
AVRational av_d2q(double d, int max)
Convert a double precision floating point number to a rational.
Definition: rational.c:106
fix_frag_index_entries
static void fix_frag_index_entries(MOVFragmentIndex *frag_index, int index, int id, int entries)
Definition: mov.c:1364
mov_finalize_stsd_codec
static int mov_finalize_stsd_codec(MOVContext *c, AVIOContext *pb, AVStream *st, MOVStreamContext *sc)
Definition: mov.c:2369
AV_CH_FRONT_LEFT
#define AV_CH_FRONT_LEFT
Definition: channel_layout.h:49
AV_CODEC_ID_PCM_S32BE
@ AV_CODEC_ID_PCM_S32BE
Definition: avcodec.h:472
uint8_t
uint8_t
Definition: audio_convert.c:194
mov_read_mdcv
static int mov_read_mdcv(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:5373
av_mallocz
void * av_mallocz(size_t size)
Allocate a memory block with alignment suitable for all memory accesses (including vectors if availab...
Definition: mem.c:236
AV_TIMECODE_FLAG_ALLOWNEGATIVE
@ AV_TIMECODE_FLAG_ALLOWNEGATIVE
negative time values are allowed
Definition: timecode.h:38
av_inv_q
static av_always_inline AVRational av_inv_q(AVRational q)
Invert a rational.
Definition: rational.h:159
mov_read_mdat
static int mov_read_mdat(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:984
AV_CODEC_ID_VC1
@ AV_CODEC_ID_VC1
Definition: avcodec.h:288
MOVStreamContext::pb
AVIOContext * pb
Definition: isom.h:158
mov_read_keys
static int mov_read_keys(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:4323
AVCodecParameters::color_range
enum AVColorRange color_range
Video only.
Definition: avcodec.h:4043
AV_CH_SIDE_RIGHT
#define AV_CH_SIDE_RIGHT
Definition: channel_layout.h:59
len
int len
Definition: vorbis_enc_data.h:452
AV_CODEC_ID_JPEG2000
@ AV_CODEC_ID_JPEG2000
Definition: avcodec.h:306
MOVFragment::size
unsigned size
Definition: isom.h:97
MOV_TFHD_DEFAULT_SIZE
#define MOV_TFHD_DEFAULT_SIZE
Definition: isom.h:308
ff_get_wav_header
int ff_get_wav_header(AVFormatContext *s, AVIOContext *pb, AVCodecParameters *par, int size, int big_endian)
Definition: riffdec.c:91
AVCOL_SPC_UNSPECIFIED
@ AVCOL_SPC_UNSPECIFIED
Definition: pixfmt.h:499
av_rescale
int64_t av_rescale(int64_t a, int64_t b, int64_t c)
Rescale a 64-bit integer with rounding to nearest.
Definition: mathematics.c:129
mov_build_index
static void mov_build_index(MOVContext *mov, AVStream *st)
Definition: mov.c:3746
mov_read_svq3
static int mov_read_svq3(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:1828
AVSHA
hash context
Definition: sha.c:34
AVCOL_RANGE_MPEG
@ AVCOL_RANGE_MPEG
the normal 219*2^(n-8) "MPEG" YUV ranges
Definition: pixfmt.h:521
MOVFragmentStreamInfo::tfdt_dts
int64_t tfdt_dts
Definition: isom.h:131
AVCodecParameters::field_order
enum AVFieldOrder field_order
Video only.
Definition: avcodec.h:4038
MOVStreamContext::sample_sizes
int * sample_sizes
Definition: isom.h:182
av_get_packet
int av_get_packet(AVIOContext *s, AVPacket *pkt, int size)
Allocate and read the payload of a packet and initialize its fields with default values.
Definition: utils.c:313
get_stream_info_time
static int64_t get_stream_info_time(MOVFragmentStreamInfo *frag_stream_info)
Definition: mov.c:1242
fix_index_entry_timestamps
static void fix_index_entry_timestamps(AVStream *st, int end_index, int64_t end_ts, int64_t *frame_duration_buffer, int frame_duration_buffer_size)
Rewrite timestamps of index entries in the range [end_index - frame_duration_buffer_size,...
Definition: mov.c:3292
AV_WB8
#define AV_WB8(p, d)
Definition: intreadwrite.h:396
MOVStreamContext::chunk_count
unsigned int chunk_count
Definition: isom.h:162
AVStream::skip_samples
int skip_samples
Number of samples to skip at the start of the frame decoded from the next packet.
Definition: avformat.h:1138
MOVStreamContext::data_size
int64_t data_size
Definition: isom.h:207
AV_TIMECODE_FLAG_DROPFRAME
@ AV_TIMECODE_FLAG_DROPFRAME
timecode is drop frame
Definition: timecode.h:36
language
Undefined Behavior In the C language
Definition: undefined.txt:3
ff_rfps_calculate
void ff_rfps_calculate(AVFormatContext *ic)
Definition: utils.c:3403
mov_read_tmcd
static int mov_read_tmcd(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:5245
mov_chan.h
AVStream::disposition
int disposition
AV_DISPOSITION_* bit field.
Definition: avformat.h:923
tag
uint32_t tag
Definition: movenc.c:1496
AVStream::id
int id
Format-specific stream ID.
Definition: avformat.h:877
ret
ret
Definition: filter_design.txt:187
read_packet
static int read_packet(void *opaque, uint8_t *buf, int buf_size)
Definition: avio_reading.c:42
AVStream
Stream structure.
Definition: avformat.h:870
AV_LOG_FATAL
#define AV_LOG_FATAL
Something went wrong and recovery is not possible.
Definition: log.h:170
MOVEncryptionIndex::nb_encrypted_samples
unsigned int nb_encrypted_samples
Definition: isom.h:117
av_stereo3d_alloc
AVStereo3D * av_stereo3d_alloc(void)
Allocate an AVStereo3D structure and set its fields to default values.
Definition: stereo3d.c:28
mov_read_senc
static int mov_read_senc(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:6009
avio_seek
int64_t avio_seek(AVIOContext *s, int64_t offset, int whence)
fseek() equivalent for AVIOContext.
Definition: aviobuf.c:246
AVClass::class_name
const char * class_name
The name of the class; usually it is the same name as the context structure type to which the AVClass...
Definition: log.h:72
AVEncryptionInfo::key_id
uint8_t * key_id
The ID of the key used to encrypt the packet.
Definition: encryption_info.h:63
av_strlcat
size_t av_strlcat(char *dst, const char *src, size_t size)
Append the string src to the string dst, but to a total length of no more than size - 1 bytes,...
Definition: avstring.c:93
MOVStreamContext::stts_data
MOVStts * stts_data
Definition: isom.h:165
AVSphericalMapping::pitch
int32_t pitch
Rotation around the right vector [-90, 90].
Definition: spherical.h:127
avio_rb16
unsigned int avio_rb16(AVIOContext *s)
Definition: aviobuf.c:785
AVStereo3D::type
enum AVStereo3DType type
How views are packed within the video.
Definition: stereo3d.h:180
MOVSbgp::index
unsigned int index
Definition: isom.h:111
MOVContext::chapter_tracks
int * chapter_tracks
Definition: isom.h:262
AVSTREAM_PARSE_HEADERS
@ AVSTREAM_PARSE_HEADERS
Only parse headers, do not repack.
Definition: avformat.h:792
avformat.h
MOVFragment::implicit_offset
uint64_t implicit_offset
Definition: isom.h:94
dict.h
av_aes_ctr_set_full_iv
void av_aes_ctr_set_full_iv(struct AVAESCTR *a, const uint8_t *iv)
Forcefully change the "full" 16-byte iv, including the counter.
Definition: aes_ctr.c:48
AV_INPUT_BUFFER_PADDING_SIZE
#define AV_INPUT_BUFFER_PADDING_SIZE
Definition: avcodec.h:790
MOVStreamContext::pseudo_stream_id
int pseudo_stream_id
-1 means demux all ids
Definition: isom.h:196
MOVContext::time_scale
int time_scale
Definition: isom.h:246
mov_read_tfdt
static int mov_read_tfdt(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:4679
left
Tag MUST be and< 10hcoeff half pel interpolation filter coefficients, hcoeff[0] are the 2 middle coefficients[1] are the next outer ones and so on, resulting in a filter like:...eff[2], hcoeff[1], hcoeff[0], hcoeff[0], hcoeff[1], hcoeff[2] ... the sign of the coefficients is not explicitly stored but alternates after each coeff and coeff[0] is positive, so ...,+,-,+,-,+,+,-,+,-,+,... hcoeff[0] is not explicitly stored but found by subtracting the sum of all stored coefficients with signs from 32 hcoeff[0]=32 - hcoeff[1] - hcoeff[2] - ... a good choice for hcoeff and htaps is htaps=6 hcoeff={40,-10, 2} an alternative which requires more computations at both encoder and decoder side and may or may not be better is htaps=8 hcoeff={42,-14, 6,-2}ref_frames minimum of the number of available reference frames and max_ref_frames for example the first frame after a key frame always has ref_frames=1spatial_decomposition_type wavelet type 0 is a 9/7 symmetric compact integer wavelet 1 is a 5/3 symmetric compact integer wavelet others are reserved stored as delta from last, last is reset to 0 if always_reset||keyframeqlog quality(logarithmic quantizer scale) stored as delta from last, last is reset to 0 if always_reset||keyframemv_scale stored as delta from last, last is reset to 0 if always_reset||keyframe FIXME check that everything works fine if this changes between framesqbias dequantization bias stored as delta from last, last is reset to 0 if always_reset||keyframeblock_max_depth maximum depth of the block tree stored as delta from last, last is reset to 0 if always_reset||keyframequant_table quantization tableHighlevel bitstream structure:==============================--------------------------------------------|Header|--------------------------------------------|------------------------------------|||Block0||||split?||||yes no||||......... intra?||||:Block01 :yes no||||:Block02 :....... ..........||||:Block03 ::y DC ::ref index:||||:Block04 ::cb DC ::motion x :||||......... :cr DC ::motion y :||||....... ..........|||------------------------------------||------------------------------------|||Block1|||...|--------------------------------------------|------------ ------------ ------------|||Y subbands||Cb subbands||Cr subbands||||--- ---||--- ---||--- ---|||||LL0||HL0||||LL0||HL0||||LL0||HL0|||||--- ---||--- ---||--- ---||||--- ---||--- ---||--- ---|||||LH0||HH0||||LH0||HH0||||LH0||HH0|||||--- ---||--- ---||--- ---||||--- ---||--- ---||--- ---|||||HL1||LH1||||HL1||LH1||||HL1||LH1|||||--- ---||--- ---||--- ---||||--- ---||--- ---||--- ---|||||HH1||HL2||||HH1||HL2||||HH1||HL2|||||...||...||...|||------------ ------------ ------------|--------------------------------------------Decoding process:=================------------|||Subbands|------------||||------------|Intra DC||||LL0 subband prediction ------------|\ Dequantization ------------------- \||Reference frames|\ IDWT|------- -------|Motion \|||Frame 0||Frame 1||Compensation . OBMC v -------|------- -------|--------------. \------> Frame n output Frame Frame<----------------------------------/|...|------------------- Range Coder:============Binary Range Coder:------------------- The implemented range coder is an adapted version based upon "Range encoding: an algorithm for removing redundancy from a digitised message." by G. N. N. Martin. The symbols encoded by the Snow range coder are bits(0|1). The associated probabilities are not fix but change depending on the symbol mix seen so far. bit seen|new state ---------+----------------------------------------------- 0|256 - state_transition_table[256 - old_state];1|state_transition_table[old_state];state_transition_table={ 0, 0, 0, 0, 0, 0, 0, 0, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, 128, 129, 130, 131, 132, 133, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, 145, 146, 147, 148, 149, 150, 151, 152, 152, 153, 154, 155, 156, 157, 158, 159, 160, 161, 162, 163, 164, 165, 166, 167, 168, 169, 170, 171, 171, 172, 173, 174, 175, 176, 177, 178, 179, 180, 181, 182, 183, 184, 185, 186, 187, 188, 189, 190, 190, 191, 192, 194, 194, 195, 196, 197, 198, 199, 200, 201, 202, 202, 204, 205, 206, 207, 208, 209, 209, 210, 211, 212, 213, 215, 215, 216, 217, 218, 219, 220, 220, 222, 223, 224, 225, 226, 227, 227, 229, 229, 230, 231, 232, 234, 234, 235, 236, 237, 238, 239, 240, 241, 242, 243, 244, 245, 246, 247, 248, 248, 0, 0, 0, 0, 0, 0, 0};FIXME Range Coding of integers:------------------------- FIXME Neighboring Blocks:===================left and top are set to the respective blocks unless they are outside of the image in which case they are set to the Null block top-left is set to the top left block unless it is outside of the image in which case it is set to the left block if this block has no larger parent block or it is at the left side of its parent block and the top right block is not outside of the image then the top right block is used for top-right else the top-left block is used Null block y, cb, cr are 128 level, ref, mx and my are 0 Motion Vector Prediction:=========================1. the motion vectors of all the neighboring blocks are scaled to compensate for the difference of reference frames scaled_mv=(mv *(256 *(current_reference+1)/(mv.reference+1))+128)> the median of the scaled left
Definition: snow.txt:386
search_frag_moof_offset
static int search_frag_moof_offset(MOVFragmentIndex *frag_index, int64_t offset)
Definition: mov.c:1218
MOVFragment
Definition: isom.h:89
AV_DICT_MATCH_CASE
#define AV_DICT_MATCH_CASE
Only get an entry with exact-case key match.
Definition: dict.h:69
AV_RL32
uint64_t_TMPL AV_WL64 unsigned int_TMPL AV_RL32
Definition: bytestream.h:88
mov_switch_root
static int mov_switch_root(AVFormatContext *s, int64_t target, int index)
Definition: mov.c:7686
MOVContext::use_mfra_for
int use_mfra_for
Definition: isom.h:275
AVEncryptionInfo
This describes encryption info for a packet.
Definition: encryption_info.h:43
MOVStreamContext::encryption_index
MOVEncryptionIndex * encryption_index
Definition: isom.h:239
MIN_DATA_ENTRY_BOX_SIZE
#define MIN_DATA_ENTRY_BOX_SIZE
Definition: mov.c:577
avpriv_dv_init_demux
DVDemuxContext * avpriv_dv_init_demux(AVFormatContext *s)
Definition: dv.c:324
AVStream::index
int index
stream index in AVFormatContext
Definition: avformat.h:871
mov_seek_fragment
static int mov_seek_fragment(AVFormatContext *s, AVStream *st, int64_t timestamp)
Definition: mov.c:7883
mov_parse_stsd_video
static void mov_parse_stsd_video(MOVContext *c, AVIOContext *pb, AVStream *st, MOVStreamContext *sc)
Definition: mov.c:2075
ff_codec_bmp_tags
const AVCodecTag ff_codec_bmp_tags[]
Definition: riff.c:32
mov_read_dec3
static int mov_read_dec3(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:824
MOVStreamContext::sample_size
unsigned int sample_size
may contain value calculated from stsd or value from stsz atom
Definition: isom.h:179
channel_layout.h
MOVStreamContext::duration_for_fps
int64_t duration_for_fps
Definition: isom.h:215
pkt
static AVPacket pkt
Definition: demuxing_decoding.c:54
mov_read_sbgp
static int mov_read_sbgp(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:3064
MOVFragment::moof_offset
uint64_t moof_offset
Definition: isom.h:93
AVIO_SEEKABLE_NORMAL
#define AVIO_SEEKABLE_NORMAL
Seeking works like for a local file.
Definition: avio.h:40
buffer
the frame and frame reference mechanism is intended to as much as expensive copies of that data while still allowing the filters to produce correct results The data is stored in buffers represented by AVFrame structures Several references can point to the same frame buffer
Definition: filter_design.txt:49
mov_read_glbl
static int mov_read_glbl(MOVContext *c, AVIOContext *pb, MOVAtom atom)
This function reads atom content and puts data in extradata without tag nor size unlike mov_read_extr...
Definition: mov.c:1891
mov_change_extradata
static int mov_change_extradata(MOVStreamContext *sc, AVPacket *pkt)
Definition: mov.c:7721
AV_PKT_DATA_NEW_EXTRADATA
@ AV_PKT_DATA_NEW_EXTRADATA
The AV_PKT_DATA_NEW_EXTRADATA is used to notify the codec or the format that the extradata buffer was...
Definition: avcodec.h:1199
AVRational::den
int den
Denominator.
Definition: rational.h:60
mode
mode
Definition: ebur128.h:83
mov_parse_uuid_spherical
static int mov_parse_uuid_spherical(MOVStreamContext *sc, AVIOContext *pb, size_t len)
Definition: mov.c:5662
MOVTrackExt::size
unsigned size
Definition: isom.h:105
AV_OPT_TYPE_INT
@ AV_OPT_TYPE_INT
Definition: opt.h:223
MOVContext::dv_fctx
AVFormatContext * dv_fctx
Definition: isom.h:255
AV_CODEC_ID_DVAUDIO
@ AV_CODEC_ID_DVAUDIO
Definition: avcodec.h:570
avformat_free_context
void avformat_free_context(AVFormatContext *s)
Free an AVFormatContext and all its streams.
Definition: utils.c:4414
MOVContext::aax_mode
unsigned int aax_mode
'aax' file has been detected
Definition: isom.h:279
mov_read_sv3d
static int mov_read_sv3d(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:5525
avio_read
int avio_read(AVIOContext *s, unsigned char *buf, int size)
Read size bytes from AVIOContext into buf.
Definition: aviobuf.c:647
MOVFragmentIndex
Definition: isom.h:144
AV_RB8
uint64_t_TMPL AV_WL64 unsigned int_TMPL AV_WL32 unsigned int_TMPL AV_WL24 unsigned int_TMPL AV_WL16 uint64_t_TMPL AV_WB64 unsigned int_TMPL AV_WB32 unsigned int_TMPL AV_WB24 unsigned int_TMPL AV_WB16 unsigned int_TMPL AV_RB8
Definition: bytestream.h:95
mov_read_av1c
static int mov_read_av1c(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:5256
ref
static int ref[MAX_W *MAX_W]
Definition: jpeg2000dwt.c:107
AVStream::r_frame_rate
AVRational r_frame_rate
Real base framerate of the stream.
Definition: avformat.h:994
MOVStreamContext::track_end
int64_t track_end
used for dts generation in fragmented movie files
Definition: isom.h:209
MOVContext::fragment
MOVFragment fragment
current fragment in moof atom
Definition: isom.h:257
AVIndexEntry::pos
int64_t pos
Definition: avformat.h:801
AVIOContext::eof_reached
int eof_reached
true if was unable to read due to error or eof
Definition: avio.h:239
mov_metadata_int8_bypass_padding
static int mov_metadata_int8_bypass_padding(MOVContext *c, AVIOContext *pb, unsigned len, const char *key)
Definition: mov.c:100
MOVDref::type
uint32_t type
Definition: isom.h:74
samples
Filter the word “frame” indicates either a video frame or a group of audio samples
Definition: filter_design.txt:8
mov_read_covr
static int mov_read_covr(MOVContext *c, AVIOContext *pb, int type, int len)
Definition: mov.c:180
MOVParseTableEntry::type
uint32_t type
Definition: mov.c:71
AVMasteringDisplayMetadata::min_luminance
AVRational min_luminance
Min luminance of mastering display (cd/m^2).
Definition: mastering_display_metadata.h:52
MOVStreamContext::per_sample_iv_size
unsigned int per_sample_iv_size
Definition: isom.h:237
av_mul_q
AVRational av_mul_q(AVRational b, AVRational c)
Multiply two rationals.
Definition: rational.c:80
ff_codec_movsubtitle_tags
const AVCodecTag ff_codec_movsubtitle_tags[]
Definition: isom.c:376
AVPacket::stream_index
int stream_index
Definition: avcodec.h:1479
MOVFragmentIndexItem::nb_stream_info
int nb_stream_info
Definition: isom.h:140
avio_skip
int64_t avio_skip(AVIOContext *s, int64_t offset)
Skip given number of bytes forward.
Definition: aviobuf.c:331
export_orphan_timecode
static void export_orphan_timecode(AVFormatContext *s)
Definition: mov.c:7324
MOVStreamContext::has_sidx
int has_sidx
Definition: isom.h:234
AV_CH_FRONT_RIGHT
#define AV_CH_FRONT_RIGHT
Definition: channel_layout.h:50
mov_metadata_gnre
static int mov_metadata_gnre(MOVContext *c, AVIOContext *pb, unsigned len, const char *key)
Definition: mov.c:123
FF_DISABLE_DEPRECATION_WARNINGS
#define FF_DISABLE_DEPRECATION_WARNINGS
Definition: internal.h:84
av_dict_set_int
int av_dict_set_int(AVDictionary **pm, const char *key, int64_t value, int flags)
Convenience wrapper for av_dict_set that converts the value to a string and stores it.
Definition: dict.c:147
mov_read_dpxe
static int mov_read_dpxe(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:1717
ff_format_io_close
void ff_format_io_close(AVFormatContext *s, AVIOContext **pb)
Definition: utils.c:5665
MOVFragmentStreamInfo::id
int id
Definition: isom.h:128
AVIO_FLAG_READ
#define AVIO_FLAG_READ
read-only
Definition: avio.h:654
tc
#define tc
Definition: regdef.h:69
av_spherical_alloc
AVSphericalMapping * av_spherical_alloc(size_t *size)
Allocate a AVSphericalVideo structure and initialize its fields to default values.
Definition: spherical.c:24
mov_read_rtmd_track
static int mov_read_rtmd_track(AVFormatContext *s, AVStream *st)
Definition: mov.c:7162
AVMEDIA_TYPE_VIDEO
@ AVMEDIA_TYPE_VIDEO
Definition: avutil.h:201
MOVStreamContext::pb_is_copied
int pb_is_copied
Definition: isom.h:159
AV_CODEC_ID_PCM_S32LE
@ AV_CODEC_ID_PCM_S32LE
Definition: avcodec.h:471
AVCodecParameters::bits_per_coded_sample
int bits_per_coded_sample
The number of bits per sample in the codedwords.
Definition: avcodec.h:3999
MOVElst::time
int64_t time
Definition: isom.h:69
AVBufferRef
A reference to a data buffer.
Definition: buffer.h:81
mov_parse_stsd_audio
static void mov_parse_stsd_audio(MOVContext *c, AVIOContext *pb, AVStream *st, MOVStreamContext *sc)
Definition: mov.c:2131
AV_CODEC_ID_PCM_U8
@ AV_CODEC_ID_PCM_U8
Definition: avcodec.h:468
MOVContext::trak_index
int trak_index
Index of the current 'trak'.
Definition: isom.h:251
mov_read_timecode_track
static int mov_read_timecode_track(AVFormatContext *s, AVStream *st)
Definition: mov.c:7187
AVSphericalMapping::bound_left
uint32_t bound_left
Distance from the left edge.
Definition: spherical.h:167
mov_read_mac_string
static int mov_read_mac_string(MOVContext *c, AVIOContext *pb, int len, char *dst, int dstlen)
Definition: mov.c:158
MOVEncryptionIndex::auxiliary_info_sizes
uint8_t * auxiliary_info_sizes
Definition: isom.h:120
MOVFragment::stsd_id
unsigned stsd_id
Definition: isom.h:95
AVCodecParameters::video_delay
int video_delay
Video only.
Definition: avcodec.h:4052
avpriv_request_sample
#define avpriv_request_sample(...)
Definition: tableprint_vlc.h:39
ff_generate_avci_extradata
int ff_generate_avci_extradata(AVStream *st)
Generate standard extradata for AVC-Intra based on width/height and field order.
Definition: utils.c:5335
AV_CODEC_ID_PCM_F64LE
@ AV_CODEC_ID_PCM_F64LE
Definition: avcodec.h:486
read_tfra
static int read_tfra(MOVContext *mov, AVIOContext *f)
Definition: mov.c:7342
av_free
#define av_free(p)
Definition: tableprint_vlc.h:34
AVDictionaryEntry
Definition: dict.h:81
AVCodecParameters::codec_id
enum AVCodecID codec_id
Specific type of the encoded data (the codec used).
Definition: avcodec.h:3957
AVContentLightMetadata::MaxFALL
unsigned MaxFALL
Max average light level per frame (cd/m^2).
Definition: mastering_display_metadata.h:107
AVPacket
This structure stores compressed data.
Definition: avcodec.h:1454
AV_OPT_TYPE_BOOL
@ AV_OPT_TYPE_BOOL
Definition: opt.h:240
cr
static double cr(void *priv, double x, double y)
Definition: vf_geq.c:113
MOVStreamContext::stps_data
unsigned * stps_data
partial sync sample for mpeg-2 open gop
Definition: isom.h:174
AV_CODEC_ID_ADPCM_IMA_WAV
@ AV_CODEC_ID_ADPCM_IMA_WAV
Definition: avcodec.h:503
av_freep
#define av_freep(p)
Definition: tableprint_vlc.h:35
av_dict_set
int av_dict_set(AVDictionary **pm, const char *key, const char *value, int flags)
Set the given entry in *pm, overwriting an existing entry.
Definition: dict.c:70
riff.h
av_encryption_info_alloc
AVEncryptionInfo * av_encryption_info_alloc(uint32_t subsample_count, uint32_t key_id_size, uint32_t iv_size)
Allocates an AVEncryptionInfo structure and sub-pointers to hold the given number of subsamples.
Definition: encryption_info.c:39
AVPacket::pos
int64_t pos
byte position in stream, -1 if unknown
Definition: avcodec.h:1497
AV_FIELD_TB
@ AV_FIELD_TB
Definition: avcodec.h:1548
AVCodecParameters::channel_layout
uint64_t channel_layout
Audio only.
Definition: avcodec.h:4059
mov_metadata_loci
static int mov_metadata_loci(MOVContext *c, AVIOContext *pb, unsigned len)
Definition: mov.c:231
AV_CODEC_ID_ILBC
@ AV_CODEC_ID_ILBC
Definition: avcodec.h:623
AV_FIELD_BB
@ AV_FIELD_BB
Definition: avcodec.h:1547
MOV_TRUN_SAMPLE_SIZE
#define MOV_TRUN_SAMPLE_SIZE
Definition: isom.h:316
MOVStreamContext::tmcd_flags
uint32_t tmcd_flags
tmcd track flags
Definition: isom.h:208
MOVAtom::type
uint32_t type
Definition: isom.h:83
distance
static float distance(float x, float y, int band)
Definition: nellymoserenc.c:234
AVSTREAM_PARSE_FULL
@ AVSTREAM_PARSE_FULL
full parsing and repack
Definition: avformat.h:791
replaygain.h
MOVFragmentIndexItem::headers_read
int headers_read
Definition: isom.h:138
AV_CODEC_ID_VP8
@ AV_CODEC_ID_VP8
Definition: avcodec.h:358
flags
#define flags(name, subs,...)
Definition: cbs_av1.c:565
MOVStreamContext::start_pad
int start_pad
amount of samples to skip due to enc-dec delay
Definition: isom.h:210
AVStereo3DType
AVStereo3DType
List of possible 3D Types.
Definition: stereo3d.h:51
MOVDref::filename
char filename[64]
Definition: isom.h:78
MOVStsc::count
int count
Definition: isom.h:63
AV_CODEC_ID_PCM_F32LE
@ AV_CODEC_ID_PCM_F32LE
Definition: avcodec.h:484
AVCodecParameters::bit_rate
int64_t bit_rate
The average bitrate of the encoded data (in bits per second).
Definition: avcodec.h:3986
MOVStts::count
unsigned int count
Definition: isom.h:57
av_log
#define av_log(a,...)
Definition: tableprint_vlc.h:28
MOVStreamContext::display_matrix
int32_t * display_matrix
Definition: isom.h:224
MOVStreamContext::current_index
int64_t current_index
Definition: isom.h:190
AVERROR_INVALIDDATA
#define AVERROR_INVALIDDATA
Invalid data found when processing input.
Definition: error.h:59
length
const char int length
Definition: avisynth_c.h:860
find_prev_closest_index
static int find_prev_closest_index(AVStream *st, AVIndexEntry *e_old, int nb_old, MOVStts *ctts_data, int64_t ctts_count, int64_t timestamp_pts, int flag, int64_t *index, int64_t *ctts_index, int64_t *ctts_sample)
Find the closest previous frame to the timestamp_pts, in e_old index entries.
Definition: mov.c:3156
ff_codec_movaudio_tags
const AVCodecTag ff_codec_movaudio_tags[]
Definition: isom.c:318
MOVFragmentStreamInfo::index_entry
int index_entry
Definition: isom.h:132
cenc_decrypt
static int cenc_decrypt(MOVContext *c, MOVStreamContext *sc, AVEncryptionInfo *sample, uint8_t *input, int size)
Definition: mov.c:6575
MOVStreamContext::format
uint32_t format
Definition: isom.h:232
ffio_read_size
int ffio_read_size(AVIOContext *s, unsigned char *buf, int size)
Read size bytes from AVIOContext into buf.
Definition: aviobuf.c:696
MOVContext::bitrates_count
int bitrates_count
Definition: isom.h:273
AV_CODEC_ID_VORBIS
@ AV_CODEC_ID_VORBIS
Definition: avcodec.h:569
AVDictionaryEntry::value
char * value
Definition: dict.h:83
AVStream::start_time
int64_t start_time
Decoding: pts of the first frame of the stream in presentation order, in stream time base.
Definition: avformat.h:909
MOVStreamContext::samples_per_frame
unsigned int samples_per_frame
Definition: isom.h:194
MOVElst::duration
int64_t duration
Definition: isom.h:68
ac3tab.h
avstring.h
mov_read_mfra
static int mov_read_mfra(MOVContext *c, AVIOContext *f)
Definition: mov.c:7397
AV_CODEC_ID_FLV1
@ AV_CODEC_ID_FLV1
Definition: avcodec.h:239
mov_metadata_int8_no_padding
static int mov_metadata_int8_no_padding(MOVContext *c, AVIOContext *pb, unsigned len, const char *key)
Definition: mov.c:114
flac.h
AVTimecode
Definition: timecode.h:41
get_frag_stream_info
static MOVFragmentStreamInfo * get_frag_stream_info(MOVFragmentIndex *frag_index, int index, int id)
Definition: mov.c:1163
int
int
Definition: ffmpeg_filter.c:191
AV_FIELD_BT
@ AV_FIELD_BT
Definition: avcodec.h:1549
MOVStreamContext::stts_count
unsigned int stts_count
Definition: isom.h:164
MOV_TRUN_SAMPLE_CTS
#define MOV_TRUN_SAMPLE_CTS
Definition: isom.h:318
AV_OPT_TYPE_CONST
@ AV_OPT_TYPE_CONST
Definition: opt.h:232
snprintf
#define snprintf
Definition: snprintf.h:34
AVCodecParameters::initial_padding
int initial_padding
Audio only.
Definition: avcodec.h:4086
AV_CODEC_ID_PCM_S24BE
@ AV_CODEC_ID_PCM_S24BE
Definition: avcodec.h:476
color_primaries
static const struct ColorPrimaries color_primaries[AVCOL_PRI_NB]
Definition: vf_colorspace.c:209
mov_read_st3d
static int mov_read_st3d(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:5478
mov_read_dvc1
static int mov_read_dvc1(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:1933
MOVStreamContext::elst_count
unsigned int elst_count
Definition: isom.h:176
av_color_transfer_name
const char * av_color_transfer_name(enum AVColorTransferCharacteristic transfer)
Definition: pixdesc.c:2891
avpriv_dict_set_timestamp
int avpriv_dict_set_timestamp(AVDictionary **dict, const char *key, int64_t timestamp)
Set a dictionary value to an ISO-8601 compliant timestamp string.
Definition: dict.c:258
FF_API_OLD_ROTATE_API
#define FF_API_OLD_ROTATE_API
Definition: version.h:80
mov_read_atom_into_extradata
static int64_t mov_read_atom_into_extradata(MOVContext *c, AVIOContext *pb, MOVAtom atom, AVCodecParameters *par, uint8_t *buf)
Definition: mov.c:1654
AV_RB64
uint64_t_TMPL AV_WL64 unsigned int_TMPL AV_WL32 unsigned int_TMPL AV_WL24 unsigned int_TMPL AV_WL16 uint64_t_TMPL AV_RB64
Definition: bytestream.h:91
AVSphericalMapping::yaw
int32_t yaw
Rotation around the up vector [-180, 180].
Definition: spherical.h:126
mov_read_chapters
static void mov_read_chapters(AVFormatContext *s)
Definition: mov.c:7047
AV_CODEC_ID_DNXHD
@ AV_CODEC_ID_DNXHD
Definition: avcodec.h:317
MOVStreamContext::default_encrypted_sample
AVEncryptionInfo * default_encrypted_sample
Definition: isom.h:238
AVStream::index_entries_allocated_size
unsigned int index_entries_allocated_size
Definition: avformat.h:1102
AVFMT_EVENT_FLAG_METADATA_UPDATED
#define AVFMT_EVENT_FLAG_METADATA_UPDATED
The call resulted in updated metadata.
Definition: avformat.h:1658
AV_DICT_DONT_STRDUP_KEY
#define AV_DICT_DONT_STRDUP_KEY
Take ownership of a key that's been allocated with av_malloc() or another memory allocation function.
Definition: dict.h:72
MOVContext::next_root_atom
int64_t next_root_atom
offset of the next root atom
Definition: isom.h:269
MOVContext::meta_keys_count
unsigned meta_keys_count
Definition: isom.h:253
MOVStreamContext::palette
uint32_t palette[256]
Definition: isom.h:205
ff_configure_buffers_for_index
void ff_configure_buffers_for_index(AVFormatContext *s, int64_t time_tolerance)
Definition: utils.c:2108
MOVFragment::track_id
unsigned track_id
Definition: isom.h:91
mov_read_hdlr
static int mov_read_hdlr(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:717
mov_parse_stsd_data
static int mov_parse_stsd_data(MOVContext *c, AVIOContext *pb, AVStream *st, MOVStreamContext *sc, int64_t size)
Definition: mov.c:2305
AV_CH_SIDE_LEFT
#define AV_CH_SIDE_LEFT
Definition: channel_layout.h:58
av_display_rotation_get
double av_display_rotation_get(const int32_t matrix[9])
Extract the rotation component of the transformation matrix.
Definition: display.c:34
AV_RB16
uint64_t_TMPL AV_WL64 unsigned int_TMPL AV_WL32 unsigned int_TMPL AV_WL24 unsigned int_TMPL AV_WL16 uint64_t_TMPL AV_WB64 unsigned int_TMPL AV_WB32 unsigned int_TMPL AV_WB24 unsigned int_TMPL AV_RB16
Definition: bytestream.h:94
av_encryption_init_info_add_side_data
uint8_t * av_encryption_init_info_add_side_data(const AVEncryptionInitInfo *info, size_t *side_data_size)
Allocates and initializes side data that holds a copy of the given encryption init info.
Definition: encryption_info.c:290
av_fourcc2str
#define av_fourcc2str(fourcc)
Definition: avutil.h:348
ff_mov_read_chan
int ff_mov_read_chan(AVFormatContext *s, AVIOContext *pb, AVStream *st, int64_t size)
Read 'chan' tag from the input stream.
Definition: mov_chan.c:547
av_index_search_timestamp
int av_index_search_timestamp(AVStream *st, int64_t timestamp, int flags)
Get the index for a specific timestamp.
Definition: utils.c:2167
MOVContext::ignore_chapters
int ignore_chapters
Definition: isom.h:267
mov_read_dac3
static int mov_read_dac3(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:788
ff_alloc_extradata
int ff_alloc_extradata(AVCodecParameters *par, int size)
Allocate extradata with additional AV_INPUT_BUFFER_PADDING_SIZE at end which is always set to 0.
Definition: utils.c:3309
avio_feof
int avio_feof(AVIOContext *s)
Similar to feof() but also returns nonzero on read errors.
Definition: aviobuf.c:358
mc
#define mc
Definition: vf_colormatrix.c:102
MOVStreamContext::ffindex
int ffindex
AVStream index.
Definition: isom.h:160
mov_read_stsz
static int mov_read_stsz(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:2818