FFmpeg
Loading...
Searching...
No Matches
mov.c
Go to the documentation of this file.
1/*
2 * MOV demuxer
3 * Copyright (c) 2001 Fabrice Bellard
4 * Copyright (c) 2009 Baptiste Coudurier <baptiste dot coudurier at gmail dot com>
5 *
6 * first version by Francois Revol <revol@free.fr>
7 * seek function by Gael Chardon <gael.dev@4now.net>
8 *
9 * This file is part of FFmpeg.
10 *
11 * FFmpeg is free software; you can redistribute it and/or
12 * modify it under the terms of the GNU Lesser General Public
13 * License as published by the Free Software Foundation; either
14 * version 2.1 of the License, or (at your option) any later version.
15 *
16 * FFmpeg is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
19 * Lesser General Public License for more details.
20 *
21 * You should have received a copy of the GNU Lesser General Public
22 * License along with FFmpeg; if not, write to the Free Software
23 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
24 */
25
26#include "config_components.h"
27
28#include <inttypes.h>
29#include <limits.h>
30#include <stdint.h>
31#include <stdlib.h>
32
34#include "libavutil/bprint.h"
36#include "libavutil/dovi_meta.h"
37#include "libavutil/internal.h"
39#include "libavutil/intfloat.h"
41#include "libavutil/avassert.h"
42#include "libavutil/avstring.h"
43#include "libavutil/dict.h"
44#include "libavutil/display.h"
45#include "libavutil/mem.h"
46#include "libavutil/opt.h"
47#include "libavutil/aes.h"
48#include "libavutil/aes_ctr.h"
49#include "libavutil/pixdesc.h"
50#include "libavutil/sha.h"
51#include "libavutil/spherical.h"
52#include "libavutil/stereo3d.h"
53#include "libavutil/timecode.h"
54#include "libavutil/uuid.h"
55#include "libavcodec/ac3tab.h"
56#include "libavcodec/exif.h"
57#include "libavcodec/flac.h"
61#include "avformat.h"
62#include "internal.h"
63#include "avio_internal.h"
64#include "demux.h"
65#include "dvdclut.h"
66#include "iamf_parse.h"
67#include "iamf_reader.h"
68#include "dovi_isom.h"
69#include "riff.h"
70#include "isom.h"
71#include "libavcodec/get_bits.h"
72#include "id3v1.h"
73#include "mov_chan.h"
74#include "replaygain.h"
75
76#if CONFIG_ZLIB
77#include <zlib.h>
78#endif
79
80#include "qtpalette.h"
81
82/* those functions parse an atom */
83/* links atom IDs to parse functions */
84typedef struct MOVParseTableEntry {
85 uint32_t type;
86 int (*parse)(MOVContext *ctx, AVIOContext *pb, MOVAtom atom);
88
89static int mov_read_default(MOVContext *c, AVIOContext *pb, MOVAtom atom);
92
94 unsigned len, const char *key)
95{
96 char buf[16];
97
98 short current, total = 0;
99 avio_rb16(pb); // unknown
100 current = avio_rb16(pb);
101 if (len >= 6)
102 total = avio_rb16(pb);
103 if (!total)
104 snprintf(buf, sizeof(buf), "%d", current);
105 else
106 snprintf(buf, sizeof(buf), "%d/%d", current, total);
107 c->fc->event_flags |= AVFMT_EVENT_FLAG_METADATA_UPDATED;
108 av_dict_set(&c->fc->metadata, key, buf, 0);
109
110 return 0;
111}
112
114 unsigned len, const char *key)
115{
116 /* bypass padding bytes */
117 avio_r8(pb);
118 avio_r8(pb);
119 avio_r8(pb);
120
121 c->fc->event_flags |= AVFMT_EVENT_FLAG_METADATA_UPDATED;
122 av_dict_set_int(&c->fc->metadata, key, avio_r8(pb), 0);
123
124 return 0;
125}
126
128 unsigned len, const char *key)
129{
130 c->fc->event_flags |= AVFMT_EVENT_FLAG_METADATA_UPDATED;
131 av_dict_set_int(&c->fc->metadata, key, avio_r8(pb), 0);
132
133 return 0;
134}
135
137 unsigned len, const char *key)
138{
139 short genre;
140
141 avio_r8(pb); // unknown
142
143 genre = avio_r8(pb);
144 if (genre < 1 || genre > ID3v1_GENRE_MAX)
145 return 0;
146 c->fc->event_flags |= AVFMT_EVENT_FLAG_METADATA_UPDATED;
147 av_dict_set(&c->fc->metadata, key, ff_id3v1_genre_str[genre-1], 0);
148
149 return 0;
150}
151
152static const uint32_t mac_to_unicode[128] = {
153 0x00C4,0x00C5,0x00C7,0x00C9,0x00D1,0x00D6,0x00DC,0x00E1,
154 0x00E0,0x00E2,0x00E4,0x00E3,0x00E5,0x00E7,0x00E9,0x00E8,
155 0x00EA,0x00EB,0x00ED,0x00EC,0x00EE,0x00EF,0x00F1,0x00F3,
156 0x00F2,0x00F4,0x00F6,0x00F5,0x00FA,0x00F9,0x00FB,0x00FC,
157 0x2020,0x00B0,0x00A2,0x00A3,0x00A7,0x2022,0x00B6,0x00DF,
158 0x00AE,0x00A9,0x2122,0x00B4,0x00A8,0x2260,0x00C6,0x00D8,
159 0x221E,0x00B1,0x2264,0x2265,0x00A5,0x00B5,0x2202,0x2211,
160 0x220F,0x03C0,0x222B,0x00AA,0x00BA,0x03A9,0x00E6,0x00F8,
161 0x00BF,0x00A1,0x00AC,0x221A,0x0192,0x2248,0x2206,0x00AB,
162 0x00BB,0x2026,0x00A0,0x00C0,0x00C3,0x00D5,0x0152,0x0153,
163 0x2013,0x2014,0x201C,0x201D,0x2018,0x2019,0x00F7,0x25CA,
164 0x00FF,0x0178,0x2044,0x20AC,0x2039,0x203A,0xFB01,0xFB02,
165 0x2021,0x00B7,0x201A,0x201E,0x2030,0x00C2,0x00CA,0x00C1,
166 0x00CB,0x00C8,0x00CD,0x00CE,0x00CF,0x00CC,0x00D3,0x00D4,
167 0xF8FF,0x00D2,0x00DA,0x00DB,0x00D9,0x0131,0x02C6,0x02DC,
168 0x00AF,0x02D8,0x02D9,0x02DA,0x00B8,0x02DD,0x02DB,0x02C7,
169};
170
172 char *dst, int dstlen)
173{
174 char *p = dst;
175 char *end = dst+dstlen-1;
176 int i;
177
178 for (i = 0; i < len; i++) {
179 uint8_t t, c = avio_r8(pb);
180
181 if (p >= end)
182 continue;
183
184 if (c < 0x80)
185 *p++ = c;
186 else if (p < end)
187 PUT_UTF8(mac_to_unicode[c-0x80], t, if (p < end) *p++ = t;);
188 }
189 *p = 0;
190 return p - dst;
191}
192
193/**
194 * Get the requested item.
195 */
196static HEIFItem *get_heif_item(MOVContext *c, unsigned id)
197{
198 HEIFItem *item = NULL;
199
200 for (int i = 0; i < c->nb_heif_item; i++) {
201 if (!c->heif_item[i] || c->heif_item[i]->item_id != id)
202 continue;
203
204 item = c->heif_item[i];
205 break;
206 }
207
208 return item;
209}
210
211/**
212 * Get the current stream in the parsing process. This can either be the
213 * latest stream added to the context, or the stream referenced by an item.
214 */
216{
217 AVStream *st = NULL;
218 HEIFItem *item;
219
220 if (c->fc->nb_streams < 1)
221 return NULL;
222
223 if (c->cur_item_id == -1)
224 return c->fc->streams[c->fc->nb_streams-1];
225
226 item = get_heif_item(c, c->cur_item_id);
227 if (item)
228 st = item->st;
229
230 return st;
231}
232
233static int mov_read_covr(MOVContext *c, AVIOContext *pb, int type, int len)
234{
235 AVStream *st;
237 enum AVCodecID id;
238 int ret;
239
240 switch (type) {
241 case 0xd: id = AV_CODEC_ID_MJPEG; break;
242 case 0xe: id = AV_CODEC_ID_PNG; break;
243 case 0x1b: id = AV_CODEC_ID_BMP; break;
244 default:
245 av_log(c->fc, AV_LOG_WARNING, "Unknown cover type: 0x%x.\n", type);
246 avio_skip(pb, len);
247 return 0;
248 }
249
250 sc = av_mallocz(sizeof(*sc));
251 if (!sc)
252 return AVERROR(ENOMEM);
253 ret = ff_add_attached_pic(c->fc, NULL, pb, NULL, len);
254 if (ret < 0) {
255 av_free(sc);
256 return ret;
257 }
258 st = c->fc->streams[c->fc->nb_streams - 1];
259 st->priv_data = sc;
260 sc->id = st->id;
261 sc->refcount = 1;
262
263 if (st->attached_pic.size >= 8 && id != AV_CODEC_ID_BMP) {
264 if (AV_RB64(st->attached_pic.data) == 0x89504e470d0a1a0a) {
265 id = AV_CODEC_ID_PNG;
266 } else {
268 }
269 }
270 st->codecpar->codec_id = id;
271
272 return 0;
273}
274
275// 3GPP TS 26.244
276static int mov_metadata_loci(MOVContext *c, AVIOContext *pb, unsigned len)
277{
278 char language[4] = { 0 };
279 char buf[200], place[100];
280 uint16_t langcode = 0;
281 double longitude, latitude, altitude;
282 const char *key = "location";
283
284 if (len < 4 + 2 + 1 + 1 + 4 + 4 + 4) {
285 av_log(c->fc, AV_LOG_ERROR, "loci too short\n");
286 return AVERROR_INVALIDDATA;
287 }
288
289 avio_skip(pb, 4); // version+flags
290 langcode = avio_rb16(pb);
291 ff_mov_lang_to_iso639(langcode, language);
292 len -= 6;
293
294 len -= avio_get_str(pb, len, place, sizeof(place));
295 if (len < 1) {
296 av_log(c->fc, AV_LOG_ERROR, "place name too long\n");
297 return AVERROR_INVALIDDATA;
298 }
299 avio_skip(pb, 1); // role
300 len -= 1;
301
302 if (len < 12) {
303 av_log(c->fc, AV_LOG_ERROR,
304 "loci too short (%u bytes left, need at least %d)\n", len, 12);
305 return AVERROR_INVALIDDATA;
306 }
307 longitude = ((int32_t) avio_rb32(pb)) / (float) (1 << 16);
308 latitude = ((int32_t) avio_rb32(pb)) / (float) (1 << 16);
309 altitude = ((int32_t) avio_rb32(pb)) / (float) (1 << 16);
310
311 // Try to output in the same format as the ?xyz field
312 snprintf(buf, sizeof(buf), "%+08.4f%+09.4f", latitude, longitude);
313 if (altitude)
314 av_strlcatf(buf, sizeof(buf), "%+f", altitude);
315 av_strlcatf(buf, sizeof(buf), "/%s", place);
316
317 if (*language && strcmp(language, "und")) {
318 char key2[16];
319 snprintf(key2, sizeof(key2), "%s-%s", key, language);
320 av_dict_set(&c->fc->metadata, key2, buf, 0);
321 }
322 c->fc->event_flags |= AVFMT_EVENT_FLAG_METADATA_UPDATED;
323 return av_dict_set(&c->fc->metadata, key, buf, 0);
324}
325
326static int mov_metadata_hmmt(MOVContext *c, AVIOContext *pb, unsigned len)
327{
328 int i, n_hmmt;
329
330 if (len < 2)
331 return 0;
332 if (c->ignore_chapters)
333 return 0;
334
335 n_hmmt = avio_rb32(pb);
336 if (n_hmmt > len / 4)
337 return AVERROR_INVALIDDATA;
338 for (i = 0; i < n_hmmt && !pb->eof_reached; i++) {
339 int moment_time = avio_rb32(pb);
340 avpriv_new_chapter(c->fc, i, av_make_q(1, 1000), moment_time, AV_NOPTS_VALUE, NULL);
341 }
342 if (avio_feof(pb))
343 return AVERROR_INVALIDDATA;
344 return 0;
345}
346
348{
349 char tmp_key[AV_FOURCC_MAX_STRING_SIZE] = {0};
350 char key2[32], language[4] = {0};
351 char *str = NULL;
352 const char *key = NULL;
353 uint16_t langcode = 0;
354 uint32_t data_type = 0, str_size_alloc;
355 uint64_t str_size;
356 int (*parse)(MOVContext*, AVIOContext*, unsigned, const char*) = NULL;
357 int raw = 0;
358 int num = 0;
360
361 if (c->trak_index >= 0 && c->trak_index < c->fc->nb_streams)
362 metadata = &c->fc->streams[c->trak_index]->metadata;
363 else
364 metadata = &c->fc->metadata;
365
366 switch (atom.type) {
367 case MKTAG( '@','P','R','M'): key = "premiere_version"; raw = 1; break;
368 case MKTAG( '@','P','R','Q'): key = "quicktime_version"; raw = 1; break;
369 case MKTAG( 'X','M','P','_'):
370 if (c->export_xmp) { key = "xmp"; raw = 1; } break;
371 case MKTAG( 'a','A','R','T'): key = "album_artist"; break;
372 case MKTAG( 'a','k','I','D'): key = "account_type";
374 case MKTAG( 'a','p','I','D'): key = "account_id"; break;
375 case MKTAG( 'c','a','t','g'): key = "category"; break;
376 case MKTAG( 'c','p','i','l'): key = "compilation";
378 case MKTAG( 'c','p','r','t'): key = "copyright"; break;
379 case MKTAG( 'd','e','s','c'): key = "description"; break;
380 case MKTAG( 'd','i','s','k'): key = "disc";
382 case MKTAG( 'e','g','i','d'): key = "episode_uid";
384 case MKTAG( 'F','I','R','M'): key = "firmware"; raw = 1; break;
385 case MKTAG( 'g','n','r','e'): key = "genre";
386 parse = mov_metadata_gnre; break;
387 case MKTAG( 'h','d','v','d'): key = "hd_video";
389 case MKTAG( 'H','M','M','T'):
390 return mov_metadata_hmmt(c, pb, atom.size);
391 case MKTAG( 'k','e','y','w'): key = "keywords"; break;
392 case MKTAG( 'l','d','e','s'): key = "synopsis"; break;
393 case MKTAG( 'l','o','c','i'):
394 return mov_metadata_loci(c, pb, atom.size);
395 case MKTAG( 'm','a','n','u'): key = "make"; break;
396 case MKTAG( 'm','o','d','l'): key = "model"; break;
397 case MKTAG( 'n','a','m','e'): key = "name"; break;
398 case MKTAG( 'p','c','s','t'): key = "podcast";
400 case MKTAG( 'p','g','a','p'): key = "gapless_playback";
402 case MKTAG( 'p','u','r','d'): key = "purchase_date"; break;
403 case MKTAG( 'r','t','n','g'): key = "rating";
405 case MKTAG( 's','o','a','a'): key = "sort_album_artist"; break;
406 case MKTAG( 's','o','a','l'): key = "sort_album"; break;
407 case MKTAG( 's','o','a','r'): key = "sort_artist"; break;
408 case MKTAG( 's','o','c','o'): key = "sort_composer"; break;
409 case MKTAG( 's','o','n','m'): key = "sort_name"; break;
410 case MKTAG( 's','o','s','n'): key = "sort_show"; break;
411 case MKTAG( 's','t','i','k'): key = "media_type";
413 case MKTAG( 't','r','k','n'): key = "track";
415 case MKTAG( 't','v','e','n'): key = "episode_id"; break;
416 case MKTAG( 't','v','e','s'): key = "episode_sort";
418 case MKTAG( 't','v','n','n'): key = "network"; break;
419 case MKTAG( 't','v','s','h'): key = "show"; break;
420 case MKTAG( 't','v','s','n'): key = "season_number";
422 case MKTAG(0xa9,'A','R','T'): key = "artist"; break;
423 case MKTAG(0xa9,'P','R','D'): key = "producer"; break;
424 case MKTAG(0xa9,'a','l','b'): key = "album"; break;
425 case MKTAG(0xa9,'a','u','t'): key = "artist"; break;
426 case MKTAG(0xa9,'c','h','p'): key = "chapter"; break;
427 case MKTAG(0xa9,'c','m','t'): key = "comment"; break;
428 case MKTAG(0xa9,'c','o','m'): key = "composer"; break;
429 case MKTAG(0xa9,'c','p','y'): key = "copyright"; break;
430 case MKTAG(0xa9,'d','a','y'): key = "date"; break;
431 case MKTAG(0xa9,'d','i','r'): key = "director"; break;
432 case MKTAG(0xa9,'d','i','s'): key = "disclaimer"; break;
433 case MKTAG(0xa9,'e','d','1'): key = "edit_date"; break;
434 case MKTAG(0xa9,'e','n','c'): key = "encoder"; break;
435 case MKTAG(0xa9,'f','m','t'): key = "original_format"; break;
436 case MKTAG(0xa9,'g','e','n'): key = "genre"; break;
437 case MKTAG(0xa9,'g','r','p'): key = "grouping"; break;
438 case MKTAG(0xa9,'h','s','t'): key = "host_computer"; break;
439 case MKTAG(0xa9,'i','n','f'): key = "comment"; break;
440 case MKTAG(0xa9,'l','y','r'): key = "lyrics"; break;
441 case MKTAG(0xa9,'m','a','k'): key = "make"; break;
442 case MKTAG(0xa9,'m','o','d'): key = "model"; break;
443 case MKTAG(0xa9,'n','a','m'): key = "title"; break;
444 case MKTAG(0xa9,'o','p','e'): key = "original_artist"; break;
445 case MKTAG(0xa9,'p','r','d'): key = "producer"; break;
446 case MKTAG(0xa9,'p','r','f'): key = "performers"; break;
447 case MKTAG(0xa9,'r','e','q'): key = "playback_requirements"; break;
448 case MKTAG(0xa9,'s','r','c'): key = "original_source"; break;
449 case MKTAG(0xa9,'s','t','3'): key = "subtitle"; break;
450 case MKTAG(0xa9,'s','w','r'): key = "encoder"; break;
451 case MKTAG(0xa9,'t','o','o'): key = "encoder"; break;
452 case MKTAG(0xa9,'t','r','k'): key = "track"; break;
453 case MKTAG(0xa9,'u','r','l'): key = "URL"; break;
454 case MKTAG(0xa9,'w','r','n'): key = "warning"; break;
455 case MKTAG(0xa9,'w','r','t'): key = "composer"; break;
456 case MKTAG(0xa9,'x','y','z'): key = "location"; break;
457 }
458retry:
459 if (c->itunes_metadata && atom.size > 8) {
460 int data_size = avio_rb32(pb);
461 int tag = avio_rl32(pb);
462 if (tag == MKTAG('d','a','t','a') && data_size <= atom.size && data_size >= 16) {
463 data_type = avio_rb32(pb); // type
464 avio_rb32(pb); // unknown
465 str_size = data_size - 16;
466 atom.size -= 16;
467
468 if (!key && c->found_hdlr_mdta && c->meta_keys) {
469 uint32_t index = av_bswap32(atom.type); // BE number has been read as LE
470 if (index < c->meta_keys_count && index > 0) {
471 key = c->meta_keys[index];
472 } else if (atom.type != MKTAG('c', 'o', 'v', 'r')) {
474 "The index of 'data' is out of range: %"PRId32" < 1 or >= %d.\n",
475 index, c->meta_keys_count);
476 }
477 }
478 if (atom.type == MKTAG('c', 'o', 'v', 'r') ||
479 (key && !strcmp(key, "com.apple.quicktime.artwork"))) {
480 int ret = mov_read_covr(c, pb, data_type, str_size);
481 if (ret < 0) {
482 av_log(c->fc, AV_LOG_ERROR, "Error parsing cover art.\n");
483 return ret;
484 }
485 atom.size -= str_size;
486 if (atom.size > 8)
487 goto retry;
488 return ret;
489 }
490 } else return 0;
491 } else if (atom.size > 4 && (key || c->export_all) && !c->itunes_metadata && !raw) {
492 str_size = avio_rb16(pb); // string length
493 if (str_size > atom.size) {
494 raw = 1;
495 avio_seek(pb, -2, SEEK_CUR);
496 av_log(c->fc, AV_LOG_WARNING, "UDTA parsing failed retrying raw\n");
497 goto retry;
498 }
499 langcode = avio_rb16(pb);
500 ff_mov_lang_to_iso639(langcode, language);
501 atom.size -= 4;
502 } else
503 str_size = atom.size;
504
505 if (c->export_all && !key) {
506 key = av_fourcc_make_string(tmp_key, atom.type);
507 }
508
509 if (!key)
510 return 0;
511 if (atom.size < 0 || str_size >= INT_MAX/2)
512 return AVERROR_INVALIDDATA;
513
514 // Allocates enough space if data_type is a int32 or float32 number, otherwise
515 // worst-case requirement for output string in case of utf8 coded input
516 num = (data_type >= 21 && data_type <= 23);
517 str_size_alloc = (num ? 512 : (raw ? str_size : str_size * 2)) + 1;
518 str = av_mallocz(str_size_alloc);
519 if (!str)
520 return AVERROR(ENOMEM);
521
522 if (parse)
523 parse(c, pb, str_size, key);
524 else {
525 if (!raw && (data_type == 3 || (data_type == 0 && (langcode < 0x400 || langcode == 0x7fff)))) { // MAC Encoded
526 mov_read_mac_string(c, pb, str_size, str, str_size_alloc);
527 } else if (data_type == 21) { // BE signed integer, variable size
528 int val = 0;
529 if (str_size == 1)
530 val = (int8_t)avio_r8(pb);
531 else if (str_size == 2)
532 val = (int16_t)avio_rb16(pb);
533 else if (str_size == 3)
534 val = ((int32_t)(avio_rb24(pb)<<8))>>8;
535 else if (str_size == 4)
536 val = (int32_t)avio_rb32(pb);
537 if (snprintf(str, str_size_alloc, "%d", val) >= str_size_alloc) {
538 av_log(c->fc, AV_LOG_ERROR,
539 "Failed to store the number (%d) in string.\n", val);
540 av_free(str);
541 return AVERROR_INVALIDDATA;
542 }
543 } else if (data_type == 22) { // BE unsigned integer, variable size
544 unsigned int val = 0;
545 if (str_size == 1)
546 val = avio_r8(pb);
547 else if (str_size == 2)
548 val = avio_rb16(pb);
549 else if (str_size == 3)
550 val = avio_rb24(pb);
551 else if (str_size == 4)
552 val = avio_rb32(pb);
553 if (snprintf(str, str_size_alloc, "%u", val) >= str_size_alloc) {
554 av_log(c->fc, AV_LOG_ERROR,
555 "Failed to store the number (%u) in string.\n", val);
556 av_free(str);
557 return AVERROR_INVALIDDATA;
558 }
559 } else if (data_type == 23 && str_size >= 4) { // BE float32
560 float val = av_int2float(avio_rb32(pb));
561 if (snprintf(str, str_size_alloc, "%f", val) >= str_size_alloc) {
562 av_log(c->fc, AV_LOG_ERROR,
563 "Failed to store the float32 number (%f) in string.\n", val);
564 av_free(str);
565 return AVERROR_INVALIDDATA;
566 }
567 } else if (data_type > 1 && data_type != 4) {
568 // data_type can be 0 if not set at all above. data_type 1 means
569 // UTF8 and 4 means "UTF8 sort". For any other type (UTF16 or e.g.
570 // a picture), don't return it blindly in a string that is supposed
571 // to be UTF8 text.
572 av_log(c->fc, AV_LOG_WARNING, "Skipping unhandled metadata %s of type %"PRIu32"\n", key, data_type);
573 av_free(str);
574 return 0;
575 } else {
576 int ret = ffio_read_size(pb, str, str_size);
577 if (ret < 0) {
578 av_free(str);
579 return ret;
580 }
581 str[str_size] = 0;
582 }
583 c->fc->event_flags |= AVFMT_EVENT_FLAG_METADATA_UPDATED;
584 if (c->itunes_metadata && av_dict_get(*metadata, key, NULL, 0))
586 av_dict_set(metadata, key, str, c->itunes_metadata ? AV_DICT_APPEND : 0);
587 if (*language && strcmp(language, "und")) {
588 snprintf(key2, sizeof(key2), "%s-%s", key, language);
589 av_dict_set(metadata, key2, str, 0);
590 }
591 if (!strcmp(key, "encoder")) {
592 int major, minor, micro;
593 if (sscanf(str, "HandBrake %d.%d.%d", &major, &minor, &micro) == 3) {
594 c->handbrake_version = 1000000*major + 1000*minor + micro;
595 }
596 }
597
598 atom.size -= str_size;
599 av_freep(&str);
600
601 // Read remaining data atoms for multi-valued iTunes tags (e.g. multiple
602 // artists stored as multiple data atoms within one tag atom), consistent
603 // with the existing covr path.
604 // Note: multiple sibling tag atoms with the same key (e.g. three separate
605 // ©ART atoms under ilst) are handled by the AV_DICT_APPEND logic above,
606 // since mov_read_udta_string() is called once per tag atom.
607 if (c->itunes_metadata && atom.size > 8)
608 goto retry;
609 }
610
611 av_freep(&str);
612 return 0;
613}
614
616{
617 int64_t start;
618 int i, nb_chapters, str_len, version;
619 char str[256+1];
620 int ret;
621
622 if (c->ignore_chapters)
623 return 0;
624
625 if ((atom.size -= 5) < 0)
626 return 0;
627
628 version = avio_r8(pb);
629 avio_rb24(pb);
630 if (version)
631 avio_rb32(pb); // ???
632 nb_chapters = avio_r8(pb);
633
634 for (i = 0; i < nb_chapters; i++) {
635 if (atom.size < 9)
636 return 0;
637
638 start = avio_rb64(pb);
639 str_len = avio_r8(pb);
640
641 if ((atom.size -= 9+str_len) < 0)
642 return 0;
643
644 ret = ffio_read_size(pb, str, str_len);
645 if (ret < 0)
646 return ret;
647 str[str_len] = 0;
648 avpriv_new_chapter(c->fc, i, (AVRational){1,10000000}, start, AV_NOPTS_VALUE, str);
649 }
650 return 0;
651}
652
653#define MIN_DATA_ENTRY_BOX_SIZE 12
655{
656 AVStream *st;
658 int entries, i, j;
659
660 if (c->fc->nb_streams < 1)
661 return 0;
662 st = c->fc->streams[c->fc->nb_streams-1];
663 sc = st->priv_data;
664
665 avio_rb32(pb); // version + flags
666 entries = avio_rb32(pb);
667 if (!entries ||
668 entries > (atom.size - 1) / MIN_DATA_ENTRY_BOX_SIZE + 1 ||
669 entries >= UINT_MAX / sizeof(*sc->drefs))
670 return AVERROR_INVALIDDATA;
671
672 for (i = 0; i < sc->drefs_count; i++) {
673 MOVDref *dref = &sc->drefs[i];
674 av_freep(&dref->path);
675 av_freep(&dref->dir);
676 }
677 av_free(sc->drefs);
678 sc->drefs_count = 0;
679 sc->drefs = av_mallocz(entries * sizeof(*sc->drefs));
680 if (!sc->drefs)
681 return AVERROR(ENOMEM);
682 sc->drefs_count = entries;
683
684 for (i = 0; i < entries; i++) {
685 MOVDref *dref = &sc->drefs[i];
686 uint32_t size = avio_rb32(pb);
687 int64_t next = avio_tell(pb);
688
689 if (size < 12 || next < 0 || next > INT64_MAX - size)
690 return AVERROR_INVALIDDATA;
691
692 next += size - 4;
693
694 dref->type = avio_rl32(pb);
695 avio_rb32(pb); // version + flags
696
697 if (dref->type == MKTAG('a','l','i','s') && size > 150) {
698 /* macintosh alias record */
699 uint16_t volume_len, len;
700 int16_t type;
701 int ret;
702
703 avio_skip(pb, 10);
704
705 volume_len = avio_r8(pb);
706 volume_len = FFMIN(volume_len, 27);
707 ret = ffio_read_size(pb, dref->volume, 27);
708 if (ret < 0)
709 return ret;
710 dref->volume[volume_len] = 0;
711 av_log(c->fc, AV_LOG_DEBUG, "volume %s, len %d\n", dref->volume, volume_len);
712
713 avio_skip(pb, 12);
714
715 len = avio_r8(pb);
716 len = FFMIN(len, 63);
717 ret = ffio_read_size(pb, dref->filename, 63);
718 if (ret < 0)
719 return ret;
720 dref->filename[len] = 0;
721 av_log(c->fc, AV_LOG_DEBUG, "filename %s, len %d\n", dref->filename, len);
722
723 avio_skip(pb, 16);
724
725 /* read next level up_from_alias/down_to_target */
726 dref->nlvl_from = avio_rb16(pb);
727 dref->nlvl_to = avio_rb16(pb);
728 av_log(c->fc, AV_LOG_DEBUG, "nlvl from %d, nlvl to %d\n",
729 dref->nlvl_from, dref->nlvl_to);
730
731 avio_skip(pb, 16);
732
733 for (type = 0; type != -1 && avio_tell(pb) < next; ) {
734 if (avio_feof(pb))
735 return AVERROR_EOF;
736 type = avio_rb16(pb);
737 len = avio_rb16(pb);
738 av_log(c->fc, AV_LOG_DEBUG, "type %d, len %d\n", type, len);
739 if (len&1)
740 len += 1;
741 if (type == 2) { // absolute path
742 av_free(dref->path);
743 dref->path = av_mallocz(len+1);
744 if (!dref->path)
745 return AVERROR(ENOMEM);
746
747 ret = ffio_read_size(pb, dref->path, len);
748 if (ret < 0) {
749 av_freep(&dref->path);
750 return ret;
751 }
752 if (len > volume_len && !strncmp(dref->path, dref->volume, volume_len)) {
753 len -= volume_len;
754 memmove(dref->path, dref->path+volume_len, len);
755 dref->path[len] = 0;
756 }
757 // trim string of any ending zeros
758 for (j = len - 1; j >= 0; j--) {
759 if (dref->path[j] == 0)
760 len--;
761 else
762 break;
763 }
764 for (j = 0; j < len; j++)
765 if (dref->path[j] == ':' || dref->path[j] == 0)
766 dref->path[j] = '/';
767 av_log(c->fc, AV_LOG_DEBUG, "path %s\n", dref->path);
768 } else if (type == 0) { // directory name
769 av_free(dref->dir);
770 dref->dir = av_malloc(len+1);
771 if (!dref->dir)
772 return AVERROR(ENOMEM);
773
774 ret = ffio_read_size(pb, dref->dir, len);
775 if (ret < 0) {
776 av_freep(&dref->dir);
777 return ret;
778 }
779 dref->dir[len] = 0;
780 for (j = 0; j < len; j++)
781 if (dref->dir[j] == ':')
782 dref->dir[j] = '/';
783 av_log(c->fc, AV_LOG_DEBUG, "dir %s\n", dref->dir);
784 } else
785 avio_skip(pb, len);
786 }
787 } else {
788 av_log(c->fc, AV_LOG_DEBUG, "Unknown dref type 0x%08"PRIx32" size %"PRIu32"\n",
789 dref->type, size);
790 entries--;
791 i--;
792 }
793 avio_seek(pb, next, SEEK_SET);
794 }
795 return 0;
796}
797
799{
800 AVStream *st;
801 uint32_t type;
802 uint32_t ctype;
803 int64_t title_size;
804 char *title_str;
805 int ret;
806
807 avio_r8(pb); /* version */
808 avio_rb24(pb); /* flags */
809
810 /* component type */
811 ctype = avio_rl32(pb);
812 type = avio_rl32(pb); /* component subtype */
813
814 av_log(c->fc, AV_LOG_TRACE, "ctype=%s\n", av_fourcc2str(ctype));
815 av_log(c->fc, AV_LOG_TRACE, "stype=%s\n", av_fourcc2str(type));
816
817 if (c->trak_index < 0) { // meta not inside a trak
818 if (type == MKTAG('m','d','t','a')) {
819 c->found_hdlr_mdta = 1;
820 }
821 return 0;
822 }
823
824 st = c->fc->streams[c->fc->nb_streams-1];
825
826 if (type == MKTAG('v','i','d','e'))
828 else if (type == MKTAG('s','o','u','n'))
830 else if (type == MKTAG('m','1','a',' '))
832 else if ((type == MKTAG('s','u','b','p')) || (type == MKTAG('c','l','c','p')))
834
835 avio_rb32(pb); /* component manufacture */
836 avio_rb32(pb); /* component flags */
837 avio_rb32(pb); /* component flags mask */
838
839 title_size = atom.size - 24;
840 if (title_size > 0) {
841 if (title_size > FFMIN(INT_MAX, SIZE_MAX-1))
842 return AVERROR_INVALIDDATA;
843 title_str = av_malloc(title_size + 1); /* Add null terminator */
844 if (!title_str)
845 return AVERROR(ENOMEM);
846
847 ret = ffio_read_size(pb, title_str, title_size);
848 if (ret < 0) {
849 av_freep(&title_str);
850 return ret;
851 }
852 title_str[title_size] = 0;
853 if (title_str[0]) {
854 int off = (!c->isom && title_str[0] == title_size - 1);
855 // flag added so as to not set stream handler name if already set from mdia->hdlr
856 av_dict_set(&st->metadata, "handler_name", title_str + off, AV_DICT_DONT_OVERWRITE);
857 }
858 av_freep(&title_str);
859 }
860
861 return 0;
862}
863
865{
866 return ff_mov_read_esds(c->fc, pb);
867}
868
870{
871 AVStream *st;
873 enum AVAudioServiceType *ast;
874 int ac3info, acmod, lfeon, bsmod;
875 uint64_t mask;
876
877 if (c->fc->nb_streams < 1)
878 return 0;
879 st = c->fc->streams[c->fc->nb_streams-1];
880
884 sizeof(*ast), 0);
885 if (!sd)
886 return AVERROR(ENOMEM);
887
888 ast = (enum AVAudioServiceType*)sd->data;
889 ac3info = avio_rb24(pb);
890 bsmod = (ac3info >> 14) & 0x7;
891 acmod = (ac3info >> 11) & 0x7;
892 lfeon = (ac3info >> 10) & 0x1;
893
895 if (lfeon)
899
900 *ast = bsmod;
901 if (st->codecpar->ch_layout.nb_channels > 1 && bsmod == 0x7)
903
904 return 0;
905}
906
907#if CONFIG_IAMFDEC
908static int mov_read_iacb(MOVContext *c, AVIOContext *pb, MOVAtom atom)
909{
910 AVStream *st;
913 AVIOContext *descriptor_pb;
915 IAMFContext *iamf;
917 unsigned descriptors_size;
918 int nb_frames, disposition;
919 int version, ret;
920
921 if (atom.size < 5)
922 return AVERROR_INVALIDDATA;
923
924 if (c->fc->nb_streams < 1)
925 return 0;
926
927 version = avio_r8(pb);
928 if (version != 1) {
929 av_log(c->fc, AV_LOG_ERROR, "%s configurationVersion %d",
930 version < 1 ? "invalid" : "unsupported", version);
931 return AVERROR_INVALIDDATA;
932 }
933
934 descriptors_size = ffio_read_leb(pb);
935 if (!descriptors_size || descriptors_size > INT_MAX)
936 return AVERROR_INVALIDDATA;
937
938 st = c->fc->streams[c->fc->nb_streams - 1];
939 sc = st->priv_data;
940
941 if (st->codecpar->extradata) {
942 av_log(c->fc, AV_LOG_WARNING, "ignoring iacb\n");
943 return 0;
944 }
945
946 sc->iamf = av_mallocz(sizeof(*sc->iamf));
947 if (!sc->iamf)
948 return AVERROR(ENOMEM);
949 iamf = &sc->iamf->iamf;
950
951 ret = ff_alloc_extradata(st->codecpar, descriptors_size);
952 if (ret < 0)
953 return ret;
954
955 ret = avio_read(pb, st->codecpar->extradata, descriptors_size);
956 if (ret != descriptors_size)
957 return ret < 0 ? ret : AVERROR_INVALIDDATA;
958
959 ffio_init_read_context(&b, st->codecpar->extradata, descriptors_size);
960 descriptor_pb = &b.pub;
961
962 ret = ff_iamfdec_read_descriptors(iamf, descriptor_pb, descriptors_size, c->fc);
963 if (ret < 0)
964 return ret;
965
966 metadata = st->metadata;
967 st->metadata = NULL;
969 nb_frames = st->nb_frames;
970 duration = st->duration;
971 disposition = st->disposition;
972
973 for (int i = 0; i < iamf->nb_audio_elements; i++) {
974 IAMFAudioElement *audio_element = iamf->audio_elements[i];
975 const AVIAMFAudioElement *element;
976 AVStreamGroup *stg =
978
979 if (!stg) {
980 ret = AVERROR(ENOMEM);
981 goto fail;
982 }
983
985 stg->id = audio_element->audio_element_id;
986 /* Transfer ownership */
987 element = stg->params.iamf_audio_element = audio_element->element;
988 audio_element->element = NULL;
989
990 for (int j = 0; j < audio_element->nb_substreams; j++) {
991 IAMFSubStream *substream = &audio_element->substreams[j];
992 AVStream *stream;
993
994 if (!i && !j) {
995 if (audio_element->layers[0].substream_count != 1)
996 disposition &= ~AV_DISPOSITION_DEFAULT;
997 stream = st;
998 } else
999 stream = avformat_new_stream(c->fc, NULL);
1000 if (!stream) {
1001 ret = AVERROR(ENOMEM);
1002 goto fail;
1003 }
1004
1005 stream->start_time = start_time;
1006 stream->nb_frames = nb_frames;
1007 stream->duration = duration;
1008 stream->disposition = disposition;
1009 if (stream != st) {
1010 stream->priv_data = sc;
1011 sc->refcount++;
1012 }
1013
1016 if (i || j) {
1018 if (audio_element->layers[0].substream_count == 1)
1020 }
1021
1022 ret = avcodec_parameters_copy(stream->codecpar, substream->codecpar);
1023 if (ret < 0)
1024 goto fail;
1025
1026 stream->id = substream->audio_substream_id;
1027
1028 avpriv_set_pts_info(st, 64, 1, sc->time_scale);
1029
1030 ret = avformat_stream_group_add_stream(stg, stream);
1031 if (ret < 0)
1032 goto fail;
1033 }
1034
1035 ret = av_dict_copy(&stg->metadata, metadata, 0);
1036 if (ret < 0)
1037 goto fail;
1038 }
1039
1040 for (int i = 0; i < iamf->nb_mix_presentations; i++) {
1041 IAMFMixPresentation *mix_presentation = iamf->mix_presentations[i];
1042 const AVIAMFMixPresentation *mix = mix_presentation->cmix;
1043 AVStreamGroup *stg =
1045
1046 if (!stg) {
1047 ret = AVERROR(ENOMEM);
1048 goto fail;
1049 }
1050
1052 stg->id = mix_presentation->mix_presentation_id;
1053 /* Transfer ownership */
1054 stg->params.iamf_mix_presentation = mix_presentation->mix;
1055 mix_presentation->mix = NULL;
1056
1057 for (int j = 0; j < mix->nb_submixes; j++) {
1058 const AVIAMFSubmix *submix = mix->submixes[j];
1059
1060 for (int k = 0; k < submix->nb_elements; k++) {
1061 const AVIAMFSubmixElement *submix_element = submix->elements[k];
1062 const AVStreamGroup *audio_element = NULL;
1063
1064 for (int l = 0; l < c->fc->nb_stream_groups; l++)
1065 if (c->fc->stream_groups[l]->type == AV_STREAM_GROUP_PARAMS_IAMF_AUDIO_ELEMENT &&
1066 c->fc->stream_groups[l]->id == submix_element->audio_element_id) {
1067 audio_element = c->fc->stream_groups[l];
1068 break;
1069 }
1070 av_assert0(audio_element);
1071
1072 for (int l = 0; l < audio_element->nb_streams; l++) {
1073 ret = avformat_stream_group_add_stream(stg, audio_element->streams[l]);
1074 if (ret < 0 && ret != AVERROR(EEXIST))
1075 goto fail;
1076 }
1077 }
1078 }
1079
1080 ret = av_dict_copy(&stg->metadata, metadata, 0);
1081 if (ret < 0)
1082 goto fail;
1083 }
1084
1085 ret = 0;
1086fail:
1088
1089 return ret;
1090}
1091#endif
1092
1094{
1095 AVStream *st;
1096 int32_t sample_rate;
1097
1098 if (atom.size < 8 || c->fc->nb_streams < 1)
1099 return 0;
1100
1101 st = c->fc->streams[c->fc->nb_streams-1];
1103 av_log(c->fc, AV_LOG_WARNING, "'srat' within non-audio sample entry, skip\n");
1104 return 0;
1105 }
1106
1107 if (!c->isom) {
1108 av_log(c->fc, AV_LOG_WARNING, "'srat' within non-isom, skip\n");
1109 return 0;
1110 }
1111
1112 avio_skip(pb, 4); // version+flags
1113 sample_rate = avio_rb32(pb);
1114 if (sample_rate > 0) {
1115 av_log(c->fc, AV_LOG_DEBUG,
1116 "overwrite sample rate from %d to %d by 'srat'\n",
1117 st->codecpar->sample_rate, sample_rate);
1118 st->codecpar->sample_rate = sample_rate;
1119 } else {
1120 av_log(c->fc, AV_LOG_WARNING,
1121 "ignore invalid sample rate %d in 'srat'\n", sample_rate);
1122 }
1123
1124 return 0;
1125}
1126
1128{
1129 AVStream *st;
1130 AVPacketSideData *sd;
1131 enum AVAudioServiceType *ast;
1132 int eac3info, acmod, lfeon, bsmod;
1133 uint64_t mask;
1134
1135 if (c->fc->nb_streams < 1)
1136 return 0;
1137 st = c->fc->streams[c->fc->nb_streams-1];
1138
1142 sizeof(*ast), 0);
1143 if (!sd)
1144 return AVERROR(ENOMEM);
1145
1146 ast = (enum AVAudioServiceType*)sd->data;
1147
1148 /* No need to parse fields for additional independent substreams and its
1149 * associated dependent substreams since libavcodec's E-AC-3 decoder
1150 * does not support them yet. */
1151 avio_rb16(pb); /* data_rate and num_ind_sub */
1152 eac3info = avio_rb24(pb);
1153 bsmod = (eac3info >> 12) & 0x1f;
1154 acmod = (eac3info >> 9) & 0x7;
1155 lfeon = (eac3info >> 8) & 0x1;
1156
1158 if (lfeon)
1162
1163 *ast = bsmod;
1164 if (st->codecpar->ch_layout.nb_channels > 1 && bsmod == 0x7)
1166
1167 return 0;
1168}
1169
1170/* Maps the DTS `StreamConstruction` field (ETSI TS 102 114 Table E-2) to the
1171 * coarse FFmpeg DTS profile enum. Extension-substream XLL maps to HD_MA;
1172 * extension-substream XXCH, X96, or XBR maps to HD_HRA; core-substream XCH or
1173 * XXCH maps to ES; core-substream X96 maps to 96/24; a core component alone
1174 * maps to DTS; and extension-substream LBR maps to Express. Value 0 (undefined)
1175 * and values outside 1..21 map to AV_PROFILE_UNKNOWN. */
1177{
1178 static const int profile[22] = {
1179 [ 1] = AV_PROFILE_DTS, /* core Core */
1180 [ 2] = AV_PROFILE_DTS_ES, /* core Core + core XCH */
1181 [ 3] = AV_PROFILE_DTS_ES, /* core Core + core XXCH */
1182 [ 4] = AV_PROFILE_DTS_96_24, /* core Core + core X96 */
1183 [ 5] = AV_PROFILE_DTS_HD_HRA, /* core Core + ext XXCH */
1184 [ 6] = AV_PROFILE_DTS_HD_HRA, /* core Core + ext XBR */
1185 [ 7] = AV_PROFILE_DTS_HD_HRA, /* core Core + core XCH + ext XBR */
1186 [ 8] = AV_PROFILE_DTS_HD_HRA, /* core Core + core XXCH + ext XBR */
1187 [ 9] = AV_PROFILE_DTS_HD_HRA, /* core Core + ext XXCH + ext XBR */
1188 [10] = AV_PROFILE_DTS_HD_HRA, /* core Core + ext X96 */
1189 [11] = AV_PROFILE_DTS_HD_HRA, /* core Core + core XCH + ext X96 */
1190 [12] = AV_PROFILE_DTS_HD_HRA, /* core Core + core XXCH + ext X96 */
1191 [13] = AV_PROFILE_DTS_HD_HRA, /* core Core + ext XXCH + ext X96 */
1192 [14] = AV_PROFILE_DTS_HD_MA, /* core Core + ext XLL */
1193 [15] = AV_PROFILE_DTS_HD_MA, /* core Core + core XCH + ext XLL */
1194 [16] = AV_PROFILE_DTS_HD_MA, /* core Core + core X96 + ext XLL */
1195 [17] = AV_PROFILE_DTS_HD_MA, /* ext XLL */
1196 [18] = AV_PROFILE_DTS_EXPRESS, /* ext LBR */
1197 [19] = AV_PROFILE_DTS, /* ext Core */
1198 [20] = AV_PROFILE_DTS_HD_HRA, /* ext Core + ext XXCH */
1199 [21] = AV_PROFILE_DTS_HD_MA, /* ext Core + ext XLL */
1200 };
1201 if (!sc || sc > 21)
1202 return AV_PROFILE_UNKNOWN;
1203 return profile[sc];
1204}
1205
1206/* Maps the 16-bit DTS `ChannelLayout` bitmask (ETSI TS 102 114 Table E-5) to an
1207 * ffmpeg channel mask. Pair bits follow Table 7-10 / DCA_SPEAKER_PAIR_*;
1208 * LwRw (0x0400) and LssRss (0x0800) must not collapse onto SIDE like LsRs. */
1209static uint64_t mov_dts_channel_layout_to_mask(unsigned int code)
1210{
1211 static const struct { unsigned int dts; uint64_t av; } map[] = {
1212 { 0x0001, AV_CH_FRONT_CENTER },
1213 { 0x0002, AV_CH_FRONT_LEFT | AV_CH_FRONT_RIGHT },
1214 { 0x0004, AV_CH_SIDE_LEFT | AV_CH_SIDE_RIGHT },
1215 { 0x0008, AV_CH_LOW_FREQUENCY },
1216 { 0x0010, AV_CH_BACK_CENTER },
1218 { 0x0040, AV_CH_BACK_LEFT | AV_CH_BACK_RIGHT },
1219 { 0x0080, AV_CH_TOP_FRONT_CENTER },
1220 { 0x0100, AV_CH_TOP_CENTER },
1222 { 0x0400, AV_CH_WIDE_LEFT | AV_CH_WIDE_RIGHT },
1224 { 0x1000, AV_CH_LOW_FREQUENCY_2 },
1226 { 0x4000, AV_CH_TOP_BACK_CENTER },
1228 };
1229 uint64_t mask = 0;
1230 int i;
1231 for (i = 0; i < FF_ARRAY_ELEMS(map); i++)
1232 if (code & map[i].dts)
1233 mask |= map[i].av;
1234 return mask;
1235}
1236
1238{
1239#define DDTS_SIZE 20
1241 AVStream *st = NULL;
1242 uint32_t frame_duration_code = 0;
1243 uint32_t channel_layout_code = 0;
1244 uint64_t channel_layout_mask;
1245 unsigned int stream_construction;
1246 unsigned int representation_type;
1247 GetBitContext gb;
1248 int ret;
1249
1250 if ((ret = ffio_read_size(pb, buf, DDTS_SIZE)) < 0)
1251 return ret;
1252
1253 init_get_bits(&gb, buf, 8 * DDTS_SIZE);
1254
1255 if (c->fc->nb_streams < 1) {
1256 return 0;
1257 }
1258 st = c->fc->streams[c->fc->nb_streams-1];
1259
1260 st->codecpar->sample_rate = get_bits_long(&gb, 32);
1261 if (st->codecpar->sample_rate <= 0) {
1262 av_log(c->fc, AV_LOG_ERROR, "Invalid sample rate %d\n", st->codecpar->sample_rate);
1263 return AVERROR_INVALIDDATA;
1264 }
1265 skip_bits_long(&gb, 32); /* max bitrate */
1266 st->codecpar->bit_rate = get_bits_long(&gb, 32);
1268 frame_duration_code = get_bits(&gb, 2);
1269 stream_construction = get_bits(&gb, 5); /* Table E-2 - profile source */
1270 skip_bits(&gb, 1); /* CoreLFEPresent */
1271 skip_bits(&gb, 6); /* CoreLayout */
1272 skip_bits(&gb, 14); /* CoreSize */
1273 skip_bits(&gb, 1); /* StereoDownmix */
1274 representation_type = get_bits(&gb, 3);
1275 channel_layout_code = get_bits(&gb, 16);
1276
1277 st->codecpar->frame_size =
1278 (frame_duration_code == 0) ? 512 :
1279 (frame_duration_code == 1) ? 1024 :
1280 (frame_duration_code == 2) ? 2048 :
1281 (frame_duration_code == 3) ? 4096 : 0;
1282
1283 /* Publish StreamConstruction as codecpar->profile, including for encrypted
1284 * tracks where frame headers cannot be inspected. */
1285 st->codecpar->profile = mov_dts_stream_construction_to_profile(stream_construction);
1286
1287 channel_layout_mask = mov_dts_channel_layout_to_mask(channel_layout_code);
1288 if (channel_layout_mask) {
1290 av_channel_layout_from_mask(&st->codecpar->ch_layout, channel_layout_mask);
1291 } else if (representation_type == 2 || representation_type == 3) {
1294 }
1295
1296 return 0;
1297}
1298
1300{
1301 AVStream *st;
1302
1303 if (c->fc->nb_streams < 1)
1304 return 0;
1305 st = c->fc->streams[c->fc->nb_streams-1];
1306
1307 if (atom.size < 16)
1308 return 0;
1309
1310 /* skip version and flags */
1311 avio_skip(pb, 4);
1312
1313 ff_mov_read_chan(c->fc, pb, st, atom.size - 4);
1314
1315 return 0;
1316}
1317
1319{
1320 int64_t end = av_sat_add64(avio_tell(pb), atom.size);
1321 int version, flags;
1322 int ret;
1323 AVStream *st;
1324
1325 if (c->fc->nb_streams < 1)
1326 return 0;
1327 st = c->fc->streams[c->fc->nb_streams-1];
1328
1329 version = avio_r8(pb);
1330 flags = avio_rb24(pb);
1331 if (version > 1 || flags != 0) {
1332 av_log(c->fc, AV_LOG_WARNING,
1333 "Unsupported 'chnl' box with version %d, flags: %#x\n",
1334 version, flags);
1335 return 0;
1336 }
1337
1338 ret = ff_mov_read_chnl(c->fc, pb, st, version);
1339 if (ret < 0) {
1340 avio_seek(pb, end, SEEK_SET);
1341 return 0;
1342 }
1343
1344 if (avio_tell(pb) != end) {
1345 av_log(c->fc, AV_LOG_WARNING, "skip %" PRId64 " bytes of unknown data inside chnl\n",
1346 end - avio_tell(pb));
1347 avio_seek(pb, end, SEEK_SET);
1348 }
1349 return ret;
1350}
1351
1353{
1354 AVStream *st;
1355 int ret;
1356
1357 if (c->fc->nb_streams < 1)
1358 return 0;
1359 st = c->fc->streams[c->fc->nb_streams-1];
1360
1361 if ((ret = ff_get_wav_header(c->fc, pb, st->codecpar, atom.size, 0)) < 0)
1362 av_log(c->fc, AV_LOG_WARNING, "get_wav_header failed\n");
1363
1364 return ret;
1365}
1366
1368{
1369 AVStream *st;
1370 HEIFItem *item;
1371 AVPacketSideData *sd;
1372 int width, height, err = 0;
1373 AVRational aperture_width, aperture_height, horiz_off, vert_off;
1374 AVRational pc_x, pc_y;
1375 uint64_t top, bottom, left, right;
1376
1377 item = get_heif_item(c, c->cur_item_id);
1378 st = get_curr_st(c);
1379 if (!st)
1380 return 0;
1381
1382 width = st->codecpar->width;
1383 height = st->codecpar->height;
1384 if ((!width || !height) && item) {
1385 width = item->width;
1386 height = item->height;
1387 }
1388 if (!width || !height) {
1389 err = AVERROR_INVALIDDATA;
1390 goto fail;
1391 }
1392
1393 aperture_width.num = avio_rb32(pb);
1394 aperture_width.den = avio_rb32(pb);
1395 aperture_height.num = avio_rb32(pb);
1396 aperture_height.den = avio_rb32(pb);
1397
1398 horiz_off.num = avio_rb32(pb);
1399 horiz_off.den = avio_rb32(pb);
1400 vert_off.num = avio_rb32(pb);
1401 vert_off.den = avio_rb32(pb);
1402
1403 if (aperture_width.num < 0 || aperture_width.den < 0 ||
1404 aperture_height.num < 0 || aperture_height.den < 0 ||
1405 horiz_off.den < 0 || vert_off.den < 0) {
1406 err = AVERROR_INVALIDDATA;
1407 goto fail;
1408 }
1409 if ((av_cmp_q((AVRational) { width, 1 }, aperture_width) < 0) ||
1410 (av_cmp_q((AVRational) { height, 1 }, aperture_height) < 0)) {
1411 err = AVERROR_INVALIDDATA;
1412 goto fail;
1413 }
1414 av_log(c->fc, AV_LOG_TRACE, "clap: apertureWidth %d/%d, apertureHeight %d/%d "
1415 "horizOff %d/%d vertOff %d/%d\n",
1416 aperture_width.num, aperture_width.den, aperture_height.num, aperture_height.den,
1417 horiz_off.num, horiz_off.den, vert_off.num, vert_off.den);
1418
1419 pc_x = av_mul_q((AVRational) { width - 1, 1 }, (AVRational) { 1, 2 });
1420 pc_x = av_add_q(pc_x, horiz_off);
1421 pc_y = av_mul_q((AVRational) { height - 1, 1 }, (AVRational) { 1, 2 });
1422 pc_y = av_add_q(pc_y, vert_off);
1423
1424 aperture_width = av_sub_q(aperture_width, (AVRational) { 1, 1 });
1425 aperture_width = av_mul_q(aperture_width, (AVRational) { 1, 2 });
1426 aperture_height = av_sub_q(aperture_height, (AVRational) { 1, 1 });
1427 aperture_height = av_mul_q(aperture_height, (AVRational) { 1, 2 });
1428
1429 left = av_q2d(av_sub_q(pc_x, aperture_width));
1430 right = av_q2d(av_add_q(pc_x, aperture_width));
1431 top = av_q2d(av_sub_q(pc_y, aperture_height));
1432 bottom = av_q2d(av_add_q(pc_y, aperture_height));
1433
1434 if (bottom > (height - 1) ||
1435 right > (width - 1)) {
1436 err = AVERROR_INVALIDDATA;
1437 goto fail;
1438 }
1439
1440 bottom = height - 1 - bottom;
1441 right = width - 1 - right;
1442
1443 if (!(left | right | top | bottom))
1444 return 0;
1445
1446 if ((left + right) >= width ||
1447 (top + bottom) >= height) {
1448 err = AVERROR_INVALIDDATA;
1449 goto fail;
1450 }
1451
1455 sizeof(uint32_t) * 4, 0);
1456 if (!sd)
1457 return AVERROR(ENOMEM);
1458
1459 AV_WL32A(sd->data, top);
1460 AV_WL32A(sd->data + 4, bottom);
1461 AV_WL32A(sd->data + 8, left);
1462 AV_WL32A(sd->data + 12, right);
1463
1464fail:
1465 if (err < 0) {
1466 int explode = !!(c->fc->error_recognition & AV_EF_EXPLODE);
1467 av_log(c->fc, explode ? AV_LOG_ERROR : AV_LOG_WARNING, "Invalid clap box\n");
1468 if (!explode)
1469 err = 0;
1470 }
1471
1472 return err;
1473}
1474
1475/* This atom overrides any previously set aspect ratio */
1477{
1478 const int num = avio_rb32(pb);
1479 const int den = avio_rb32(pb);
1480 AVStream *st;
1481 MOVStreamContext *sc;
1482
1483 if (c->fc->nb_streams < 1)
1484 return 0;
1485 st = c->fc->streams[c->fc->nb_streams-1];
1486 sc = st->priv_data;
1487
1488 av_log(c->fc, AV_LOG_TRACE, "pasp: hSpacing %d, vSpacing %d\n", num, den);
1489
1490 if (den != 0) {
1491 sc->h_spacing = num;
1492 sc->v_spacing = den;
1493 }
1494 return 0;
1495}
1496
1497/* this atom contains actual media data */
1499{
1500 if (atom.size == 0) /* wrong one (MP4) */
1501 return 0;
1502 c->found_mdat=1;
1503 return 0; /* now go for moov */
1504}
1505
1506#define DRM_BLOB_SIZE 56
1507
1509{
1510 uint8_t intermediate_key[20];
1511 uint8_t intermediate_iv[20];
1512 uint8_t input[64];
1513 uint8_t output[64];
1514 uint8_t file_checksum[20];
1515 uint8_t calculated_checksum[20];
1516 char checksum_string[2 * sizeof(file_checksum) + 1];
1517 struct AVSHA *sha;
1518 int i;
1519 int ret = 0;
1520 uint8_t *activation_bytes = c->activation_bytes;
1521 uint8_t *fixed_key = c->audible_fixed_key;
1522
1523 c->aax_mode = 1;
1524
1525 sha = av_sha_alloc();
1526 if (!sha)
1527 return AVERROR(ENOMEM);
1528 av_free(c->aes_decrypt);
1529 c->aes_decrypt = av_aes_alloc();
1530 if (!c->aes_decrypt) {
1531 ret = AVERROR(ENOMEM);
1532 goto fail;
1533 }
1534
1535 /* drm blob processing */
1536 avio_read(pb, output, 8); // go to offset 8, absolute position 0x251
1537 avio_read(pb, input, DRM_BLOB_SIZE);
1538 avio_read(pb, output, 4); // go to offset 4, absolute position 0x28d
1539 ret = ffio_read_size(pb, file_checksum, 20);
1540 if (ret < 0)
1541 goto fail;
1542
1543 // required by external tools
1544 ff_data_to_hex(checksum_string, file_checksum, sizeof(file_checksum), 1);
1545 av_log(c->fc, AV_LOG_INFO, "[aax] file checksum == %s\n", checksum_string);
1546
1547 /* verify activation data */
1548 if (!activation_bytes) {
1549 av_log(c->fc, AV_LOG_WARNING, "[aax] activation_bytes option is missing!\n");
1550 ret = 0; /* allow ffprobe to continue working on .aax files */
1551 goto fail;
1552 }
1553 if (c->activation_bytes_size != 4) {
1554 av_log(c->fc, AV_LOG_FATAL, "[aax] activation_bytes value needs to be 4 bytes!\n");
1555 ret = AVERROR(EINVAL);
1556 goto fail;
1557 }
1558
1559 /* verify fixed key */
1560 if (c->audible_fixed_key_size != 16) {
1561 av_log(c->fc, AV_LOG_FATAL, "[aax] audible_fixed_key value needs to be 16 bytes!\n");
1562 ret = AVERROR(EINVAL);
1563 goto fail;
1564 }
1565
1566 /* AAX (and AAX+) key derivation */
1567 av_sha_init(sha, 160);
1568 av_sha_update(sha, fixed_key, 16);
1569 av_sha_update(sha, activation_bytes, 4);
1570 av_sha_final(sha, intermediate_key);
1571 av_sha_init(sha, 160);
1572 av_sha_update(sha, fixed_key, 16);
1573 av_sha_update(sha, intermediate_key, 20);
1574 av_sha_update(sha, activation_bytes, 4);
1575 av_sha_final(sha, intermediate_iv);
1576 av_sha_init(sha, 160);
1577 av_sha_update(sha, intermediate_key, 16);
1578 av_sha_update(sha, intermediate_iv, 16);
1579 av_sha_final(sha, calculated_checksum);
1580 if (memcmp(calculated_checksum, file_checksum, 20)) { // critical error
1581 av_log(c->fc, AV_LOG_ERROR, "[aax] mismatch in checksums!\n");
1582 ret = AVERROR_INVALIDDATA;
1583 goto fail;
1584 }
1585 av_aes_init(c->aes_decrypt, intermediate_key, 128, 1);
1586 av_aes_crypt(c->aes_decrypt, output, input, DRM_BLOB_SIZE >> 4, intermediate_iv, 1);
1587 for (i = 0; i < 4; i++) {
1588 // file data (in output) is stored in big-endian mode
1589 if (activation_bytes[i] != output[3 - i]) { // critical error
1590 av_log(c->fc, AV_LOG_ERROR, "[aax] error in drm blob decryption!\n");
1591 ret = AVERROR_INVALIDDATA;
1592 goto fail;
1593 }
1594 }
1595 memcpy(c->file_key, output + 8, 16);
1596 memcpy(input, output + 26, 16);
1597 av_sha_init(sha, 160);
1598 av_sha_update(sha, input, 16);
1599 av_sha_update(sha, c->file_key, 16);
1600 av_sha_update(sha, fixed_key, 16);
1601 av_sha_final(sha, c->file_iv);
1602
1603fail:
1604 av_free(sha);
1605
1606 return ret;
1607}
1608
1610{
1611 if (c->audible_key_size != 16) {
1612 av_log(c->fc, AV_LOG_FATAL, "[aaxc] audible_key value needs to be 16 bytes!\n");
1613 return AVERROR(EINVAL);
1614 }
1615
1616 if (c->audible_iv_size != 16) {
1617 av_log(c->fc, AV_LOG_FATAL, "[aaxc] audible_iv value needs to be 16 bytes!\n");
1618 return AVERROR(EINVAL);
1619 }
1620
1621 c->aes_decrypt = av_aes_alloc();
1622 if (!c->aes_decrypt) {
1623 return AVERROR(ENOMEM);
1624 }
1625
1626 memcpy(c->file_key, c->audible_key, 16);
1627 memcpy(c->file_iv, c->audible_iv, 16);
1628 c->aax_mode = 1;
1629
1630 return 0;
1631}
1632
1633// Audible AAX (and AAX+) bytestream decryption
1634static int aax_filter(uint8_t *input, int size, MOVContext *c)
1635{
1636 int blocks = 0;
1637 unsigned char iv[16];
1638
1639 memcpy(iv, c->file_iv, 16); // iv is overwritten
1640 blocks = size >> 4; // trailing bytes are not encrypted!
1641 av_aes_init(c->aes_decrypt, c->file_key, 128, 1);
1642 av_aes_crypt(c->aes_decrypt, input, input, blocks, iv, 1);
1643
1644 return 0;
1645}
1646
1647/* read major brand, minor version and compatible brands and store them as metadata */
1649{
1650 uint32_t minor_ver;
1651 int comp_brand_size;
1652 char* comp_brands_str;
1653 uint8_t type[5] = {0};
1654 int ret = ffio_read_size(pb, type, 4);
1655 if (ret < 0)
1656 return ret;
1657 if (c->fc->nb_streams) {
1658 if (c->fc->strict_std_compliance >= FF_COMPLIANCE_STRICT)
1659 return AVERROR_INVALIDDATA;
1660 av_log(c->fc, AV_LOG_DEBUG, "Ignoring duplicate FTYP\n");
1661 return 0;
1662 }
1663
1664 if (strcmp(type, "qt "))
1665 c->isom = 1;
1666 av_log(c->fc, AV_LOG_DEBUG, "ISO: File Type Major Brand: %.4s\n",(char *)&type);
1667 av_dict_set(&c->fc->metadata, "major_brand", type, 0);
1668 minor_ver = avio_rb32(pb); /* minor version */
1669 av_dict_set_int(&c->fc->metadata, "minor_version", minor_ver, 0);
1670
1671 comp_brand_size = atom.size - 8;
1672 if (comp_brand_size < 0 || comp_brand_size == INT_MAX)
1673 return AVERROR_INVALIDDATA;
1674 comp_brands_str = av_malloc(comp_brand_size + 1); /* Add null terminator */
1675 if (!comp_brands_str)
1676 return AVERROR(ENOMEM);
1677
1678 ret = ffio_read_size(pb, comp_brands_str, comp_brand_size);
1679 if (ret < 0) {
1680 av_freep(&comp_brands_str);
1681 return ret;
1682 }
1683 comp_brands_str[comp_brand_size] = 0;
1684 av_dict_set(&c->fc->metadata, "compatible_brands",
1685 comp_brands_str, AV_DICT_DONT_STRDUP_VAL);
1686
1687 // Logic for handling Audible's .aaxc files
1688 if (!strcmp(type, "aaxc")) {
1690 }
1691
1692 return 0;
1693}
1694
1695/* this atom should contain all header atoms */
1697{
1698 int ret;
1699
1700 if (c->found_moov) {
1701 av_log(c->fc, AV_LOG_WARNING, "Found duplicated MOOV Atom. Skipped it\n");
1702 avio_skip(pb, atom.size);
1703 return 0;
1704 }
1705
1706 if ((ret = mov_read_default(c, pb, atom)) < 0)
1707 return ret;
1708 /* we parsed the 'moov' atom, we can terminate the parsing as soon as we find the 'mdat' */
1709 /* so we don't parse the whole file if over a network */
1710 c->found_moov=1;
1711 return 0; /* now go for mdat */
1712}
1713
1715 MOVFragmentIndex *frag_index,
1716 int index,
1717 int id)
1718{
1719 int i;
1720 MOVFragmentIndexItem * item;
1721
1722 if (index < 0 || index >= frag_index->nb_items)
1723 return NULL;
1724 item = &frag_index->item[index];
1725 for (i = 0; i < item->nb_stream_info; i++)
1726 if (item->stream_info[i].id == id)
1727 return &item->stream_info[i];
1728
1729 // This shouldn't happen
1730 return NULL;
1731}
1732
1733static void set_frag_stream(MOVFragmentIndex *frag_index, int id)
1734{
1735 int i;
1736 MOVFragmentIndexItem * item;
1737
1738 if (frag_index->current < 0 ||
1739 frag_index->current >= frag_index->nb_items)
1740 return;
1741
1742 item = &frag_index->item[frag_index->current];
1743 for (i = 0; i < item->nb_stream_info; i++)
1744 if (item->stream_info[i].id == id) {
1745 item->current = i;
1746 return;
1747 }
1748
1749 // id not found. This shouldn't happen.
1750 item->current = -1;
1751}
1752
1754 MOVFragmentIndex *frag_index)
1755{
1757 if (frag_index->current < 0 ||
1758 frag_index->current >= frag_index->nb_items)
1759 return NULL;
1760
1761 item = &frag_index->item[frag_index->current];
1762 if (item->current >= 0 && item->current < item->nb_stream_info)
1763 return &item->stream_info[item->current];
1764
1765 // This shouldn't happen
1766 return NULL;
1767}
1768
1770{
1771 int a, b, m;
1772 int64_t moof_offset;
1773
1774 // Optimize for appending new entries
1775 if (!frag_index->nb_items ||
1776 frag_index->item[frag_index->nb_items - 1].moof_offset < offset)
1777 return frag_index->nb_items;
1778
1779 a = -1;
1780 b = frag_index->nb_items;
1781
1782 while (b - a > 1) {
1783 m = (a + b) >> 1;
1784 moof_offset = frag_index->item[m].moof_offset;
1785 if (moof_offset >= offset)
1786 b = m;
1787 if (moof_offset <= offset)
1788 a = m;
1789 }
1790 return b;
1791}
1792
1794{
1795 av_assert0(frag_stream_info);
1796 if (frag_stream_info->sidx_pts != AV_NOPTS_VALUE)
1797 return frag_stream_info->sidx_pts;
1798 if (frag_stream_info->first_tfra_pts != AV_NOPTS_VALUE)
1799 return frag_stream_info->first_tfra_pts;
1800 return frag_stream_info->tfdt_dts;
1801}
1802
1804 MOVFragmentIndex *frag_index, int index)
1805{
1806 MOVFragmentStreamInfo * frag_stream_info;
1807 MOVStreamContext *sc = dst_st->priv_data;
1808 int64_t timestamp;
1809 int i, j;
1810
1811 // If the stream is referenced by any sidx, limit the search
1812 // to fragments that referenced this stream in the sidx
1813 if (sc->has_sidx) {
1814 frag_stream_info = get_frag_stream_info(frag_index, index, sc->id);
1815 if (!frag_stream_info)
1816 return AV_NOPTS_VALUE;
1817 if (frag_stream_info->sidx_pts != AV_NOPTS_VALUE)
1818 return frag_stream_info->sidx_pts;
1819 if (frag_stream_info->first_tfra_pts != AV_NOPTS_VALUE)
1820 return frag_stream_info->first_tfra_pts;
1821 return frag_stream_info->sidx_pts;
1822 }
1823
1824 for (i = 0; i < frag_index->item[index].nb_stream_info; i++) {
1825 if (dst_st->id != frag_index->item[index].stream_info[i].id)
1826 continue;
1827 AVStream *frag_stream = NULL;
1828 frag_stream_info = &frag_index->item[index].stream_info[i];
1829 for (j = 0; j < s->nb_streams; j++) {
1830 MOVStreamContext *sc2 = s->streams[j]->priv_data;
1831 if (sc2->id == frag_stream_info->id)
1832 frag_stream = s->streams[j];
1833 }
1834 if (!frag_stream) {
1835 av_log(s, AV_LOG_WARNING, "No stream matching sidx ID found.\n");
1836 continue;
1837 }
1838 timestamp = get_stream_info_time(frag_stream_info);
1839 if (timestamp != AV_NOPTS_VALUE)
1840 return av_rescale_q(timestamp, frag_stream->time_base, dst_st->time_base);
1841 }
1842 return AV_NOPTS_VALUE;
1843}
1844
1846 AVStream *st, int64_t timestamp)
1847{
1848 int a, b, m, m0;
1849 int64_t frag_time;
1850
1851 a = -1;
1852 b = frag_index->nb_items;
1853
1854 while (b - a > 1) {
1855 m0 = m = (a + b) >> 1;
1856
1857 while (m < b &&
1858 (frag_time = get_frag_time(s, st, frag_index, m)) == AV_NOPTS_VALUE)
1859 m++;
1860
1861 if (m < b && frag_time <= timestamp)
1862 a = m;
1863 else
1864 b = m0;
1865 }
1866
1867 return a;
1868}
1869
1871{
1872 int index, i;
1873 MOVFragmentIndexItem * item;
1874 MOVFragmentStreamInfo * frag_stream_info;
1875
1876 // If moof_offset already exists in frag_index, return index to it
1877 index = search_frag_moof_offset(&c->frag_index, offset);
1878 if (index < c->frag_index.nb_items &&
1879 c->frag_index.item[index].moof_offset == offset)
1880 return index;
1881
1882 // offset is not yet in frag index.
1883 // Insert new item at index (sorted by moof offset)
1884 item = av_fast_realloc(c->frag_index.item,
1885 &c->frag_index.allocated_size,
1886 (c->frag_index.nb_items + 1) *
1887 sizeof(*c->frag_index.item));
1888 if (!item)
1889 return -1;
1890 c->frag_index.item = item;
1891
1892 frag_stream_info = av_realloc_array(NULL, c->fc->nb_streams,
1893 sizeof(*item->stream_info));
1894 if (!frag_stream_info)
1895 return -1;
1896
1897 for (i = 0; i < c->fc->nb_streams; i++) {
1898 // Avoid building frag index if streams lack track id.
1899 MOVStreamContext *sc = c->fc->streams[i]->priv_data;
1900 if (sc->id < 0) {
1901 av_free(frag_stream_info);
1902 return AVERROR_INVALIDDATA;
1903 }
1904
1905 frag_stream_info[i].id = sc->id;
1906 frag_stream_info[i].sidx_pts = AV_NOPTS_VALUE;
1907 frag_stream_info[i].tfdt_dts = AV_NOPTS_VALUE;
1908 frag_stream_info[i].next_trun_dts = AV_NOPTS_VALUE;
1909 frag_stream_info[i].first_tfra_pts = AV_NOPTS_VALUE;
1910 frag_stream_info[i].index_base = -1;
1911 frag_stream_info[i].index_entry = -1;
1912 frag_stream_info[i].encryption_index = NULL;
1913 frag_stream_info[i].stsd_id = -1;
1914 }
1915
1916 if (index < c->frag_index.nb_items)
1917 memmove(c->frag_index.item + index + 1, c->frag_index.item + index,
1918 (c->frag_index.nb_items - index) * sizeof(*c->frag_index.item));
1919
1920 item = &c->frag_index.item[index];
1921 item->headers_read = 0;
1922 item->current = 0;
1923 item->nb_stream_info = c->fc->nb_streams;
1924 item->moof_offset = offset;
1925 item->stream_info = frag_stream_info;
1926 c->frag_index.nb_items++;
1927
1928 return index;
1929}
1930
1931static void fix_frag_index_entries(MOVFragmentIndex *frag_index, int index,
1932 int id, int entries)
1933{
1934 int i;
1935 MOVFragmentStreamInfo * frag_stream_info;
1936
1937 if (index < 0)
1938 return;
1939 for (i = index; i < frag_index->nb_items; i++) {
1940 frag_stream_info = get_frag_stream_info(frag_index, i, id);
1941 if (frag_stream_info && frag_stream_info->index_entry >= 0)
1942 frag_stream_info->index_entry += entries;
1943 }
1944}
1945
1947{
1948 // Set by mov_read_tfhd(). mov_read_trun() will reject files missing tfhd.
1949 c->fragment.found_tfhd = 0;
1950
1951 if (!c->has_looked_for_mfra && c->use_mfra_for > 0) {
1952 c->has_looked_for_mfra = 1;
1953 if (pb->seekable & AVIO_SEEKABLE_NORMAL) {
1954 int ret;
1955 av_log(c->fc, AV_LOG_VERBOSE, "stream has moof boxes, will look "
1956 "for a mfra\n");
1957 if ((ret = mov_read_mfra(c, pb)) < 0) {
1958 av_log(c->fc, AV_LOG_VERBOSE, "found a moof box but failed to "
1959 "read the mfra (may be a live ismv)\n");
1960 }
1961 } else {
1962 av_log(c->fc, AV_LOG_VERBOSE, "found a moof box but stream is not "
1963 "seekable, can not look for mfra\n");
1964 }
1965 }
1966 c->fragment.moof_offset = c->fragment.implicit_offset = avio_tell(pb) - 8;
1967 av_log(c->fc, AV_LOG_TRACE, "moof offset %"PRIx64"\n", c->fragment.moof_offset);
1968 c->frag_index.current = update_frag_index(c, c->fragment.moof_offset);
1969 return mov_read_default(c, pb, atom);
1970}
1971
1973{
1974 int64_t time;
1975 if (version == 1) {
1976 time = avio_rb64(pb);
1977 avio_rb64(pb);
1978 if (time < 0) {
1979 av_log(c->fc, AV_LOG_DEBUG, "creation_time is negative\n");
1980 return;
1981 }
1982 } else {
1983 time = avio_rb32(pb);
1984 avio_rb32(pb); /* modification time */
1985 if (time > 0 && time < 2082844800) {
1986 av_log(c->fc, AV_LOG_WARNING, "Detected creation time before 1970, parsing as unix timestamp.\n");
1987 time += 2082844800;
1988 }
1989 }
1990 if (time) {
1991 time -= 2082844800; /* seconds between 1904-01-01 and Epoch */
1992
1993 if ((int64_t)(time * 1000000ULL) / 1000000 != time) {
1994 av_log(c->fc, AV_LOG_DEBUG, "creation_time is not representable\n");
1995 return;
1996 }
1997
1998 ff_dict_set_timestamp(metadata, "creation_time", time * 1000000);
1999 }
2000}
2001
2003{
2004 AVStream *st;
2005 MOVStreamContext *sc;
2006 int version;
2007 char language[4] = {0};
2008 unsigned lang;
2009
2010 if (c->fc->nb_streams < 1)
2011 return 0;
2012 st = c->fc->streams[c->fc->nb_streams-1];
2013 sc = st->priv_data;
2014
2015 if (sc->time_scale) {
2016 av_log(c->fc, AV_LOG_ERROR, "Multiple mdhd?\n");
2017 return AVERROR_INVALIDDATA;
2018 }
2019
2020 version = avio_r8(pb);
2021 if (version > 1) {
2022 avpriv_request_sample(c->fc, "Version %d", version);
2023 return AVERROR_PATCHWELCOME;
2024 }
2025 avio_rb24(pb); /* flags */
2027
2028 sc->time_scale = avio_rb32(pb);
2029 if (sc->time_scale <= 0) {
2030 av_log(c->fc, AV_LOG_ERROR, "Invalid mdhd time scale %d, defaulting to 1\n", sc->time_scale);
2031 sc->time_scale = 1;
2032 }
2033 st->duration = (version == 1) ? avio_rb64(pb) : avio_rb32(pb); /* duration */
2034
2035 if ((version == 1 && st->duration == UINT64_MAX) ||
2036 (version != 1 && st->duration == UINT32_MAX)) {
2037 st->duration = 0;
2038 }
2039
2040 lang = avio_rb16(pb); /* language */
2041 if (ff_mov_lang_to_iso639(lang, language))
2042 av_dict_set(&st->metadata, "language", language, 0);
2043 avio_rb16(pb); /* quality */
2044
2045 return 0;
2046}
2047
2049{
2050 int i;
2051 int version = avio_r8(pb); /* version */
2052 avio_rb24(pb); /* flags */
2053
2054 mov_metadata_creation_time(c, pb, &c->fc->metadata, version);
2055 c->time_scale = avio_rb32(pb); /* time scale */
2056 if (c->time_scale <= 0) {
2057 av_log(c->fc, AV_LOG_ERROR, "Invalid mvhd time scale %d, defaulting to 1\n", c->time_scale);
2058 c->time_scale = 1;
2059 }
2060 av_log(c->fc, AV_LOG_TRACE, "time scale = %i\n", c->time_scale);
2061
2062 c->duration = (version == 1) ? avio_rb64(pb) : avio_rb32(pb); /* duration */
2063 avio_rb32(pb); /* preferred scale */
2064
2065 avio_rb16(pb); /* preferred volume */
2066
2067 avio_skip(pb, 10); /* reserved */
2068
2069 /* movie display matrix, store it in main context and use it later on */
2070 for (i = 0; i < 3; i++) {
2071 c->movie_display_matrix[i][0] = avio_rb32(pb); // 16.16 fixed point
2072 c->movie_display_matrix[i][1] = avio_rb32(pb); // 16.16 fixed point
2073 c->movie_display_matrix[i][2] = avio_rb32(pb); // 2.30 fixed point
2074 }
2075
2076 avio_rb32(pb); /* preview time */
2077 avio_rb32(pb); /* preview duration */
2078 avio_rb32(pb); /* poster time */
2079 avio_rb32(pb); /* selection time */
2080 avio_rb32(pb); /* selection duration */
2081 avio_rb32(pb); /* current time */
2082 avio_rb32(pb); /* next track ID */
2083
2084 return 0;
2085}
2086
2088{
2089 AVStream *st;
2090
2091 if (fc->nb_streams < 1)
2092 return;
2093 st = fc->streams[fc->nb_streams-1];
2094
2095 switch (st->codecpar->codec_id) {
2098 break;
2101 break;
2104 break;
2107 break;
2110 break;
2111 default:
2112 break;
2113 }
2114}
2115
2117{
2118 int little_endian = avio_rb16(pb) & 0xFF;
2119 av_log(c->fc, AV_LOG_TRACE, "enda %d\n", little_endian);
2120 if (little_endian == 1)
2122 return 0;
2123}
2124
2126{
2127 int format_flags;
2128 int version, flags;
2129 int pcm_sample_size;
2130 AVFormatContext *fc = c->fc;
2131 AVStream *st;
2132 MOVStreamContext *sc;
2133
2134 if (atom.size < 6) {
2135 av_log(c->fc, AV_LOG_ERROR, "Empty pcmC box\n");
2136 return AVERROR_INVALIDDATA;
2137 }
2138
2139 version = avio_r8(pb);
2140 flags = avio_rb24(pb);
2141
2142 if (version != 0 || flags != 0) {
2143 av_log(c->fc, AV_LOG_ERROR,
2144 "Unsupported 'pcmC' box with version %d, flags: %x",
2145 version, flags);
2146 return AVERROR_INVALIDDATA;
2147 }
2148
2149 format_flags = avio_r8(pb);
2150 pcm_sample_size = avio_r8(pb);
2151
2152 if (fc->nb_streams < 1)
2153 return AVERROR_INVALIDDATA;
2154
2155 st = fc->streams[fc->nb_streams - 1];
2156 sc = st->priv_data;
2157
2158 if (sc->format == MOV_MP4_FPCM_TAG) {
2159 switch (pcm_sample_size) {
2160 case 32:
2162 break;
2163 case 64:
2165 break;
2166 default:
2167 av_log(fc, AV_LOG_ERROR, "invalid pcm_sample_size %d for %s\n",
2168 pcm_sample_size,
2169 av_fourcc2str(sc->format));
2170 return AVERROR_INVALIDDATA;
2171 }
2172 } else if (sc->format == MOV_MP4_IPCM_TAG) {
2173 switch (pcm_sample_size) {
2174 case 16:
2176 break;
2177 case 24:
2179 break;
2180 case 32:
2182 break;
2183 default:
2184 av_log(fc, AV_LOG_ERROR, "invalid pcm_sample_size %d for %s\n",
2185 pcm_sample_size,
2186 av_fourcc2str(sc->format));
2187 return AVERROR_INVALIDDATA;
2188 }
2189 } else {
2190 av_log(fc, AV_LOG_ERROR, "'pcmC' with invalid sample entry '%s'\n",
2191 av_fourcc2str(sc->format));
2192 return AVERROR_INVALIDDATA;
2193 }
2194
2195 if (format_flags & 1) // indicates little-endian format. If not present, big-endian format is used
2198
2199 return 0;
2200}
2201
2203{
2204 AVStream *st;
2205 HEIFItem *item = NULL;
2206 char color_parameter_type[5] = { 0 };
2207 uint16_t color_primaries, color_trc, color_matrix;
2208 int ret;
2209
2210 st = get_curr_st(c);
2211 if (!st) {
2212 item = get_heif_item(c, c->cur_item_id);
2213 if (!item)
2214 return 0;
2215 }
2216
2217 ret = ffio_read_size(pb, color_parameter_type, 4);
2218 if (ret < 0)
2219 return ret;
2220 if (strncmp(color_parameter_type, "nclx", 4) &&
2221 strncmp(color_parameter_type, "nclc", 4) &&
2222 strncmp(color_parameter_type, "prof", 4)) {
2223 av_log(c->fc, AV_LOG_WARNING, "unsupported color_parameter_type %s\n",
2224 color_parameter_type);
2225 return 0;
2226 }
2227
2228 if (!strncmp(color_parameter_type, "prof", 4)) {
2229 AVPacketSideData *sd;
2230 uint8_t *icc_profile;
2231 if (st) {
2235 atom.size - 4, 0);
2236 if (!sd)
2237 return AVERROR(ENOMEM);
2238 icc_profile = sd->data;
2239 } else {
2240 if (c->heif_icc_profile_items >= c->fc->max_streams) {
2241 av_log(c->fc, AV_LOG_WARNING,
2242 "HEIF ICC profile copies exceed cap %d; ignoring further items\n",
2243 c->fc->max_streams);
2244 return 0;
2245 }
2246 av_freep(&item->icc_profile);
2247 icc_profile = item->icc_profile = av_malloc(atom.size - 4);
2248 if (!icc_profile) {
2249 item->icc_profile_size = 0;
2250 return AVERROR(ENOMEM);
2251 }
2252 item->icc_profile_size = atom.size - 4;
2253 c->heif_icc_profile_items++;
2254 }
2255 ret = ffio_read_size(pb, icc_profile, atom.size - 4);
2256 if (ret < 0)
2257 return ret;
2258 } else if (st) {
2260 color_trc = avio_rb16(pb);
2261 color_matrix = avio_rb16(pb);
2262
2263 av_log(c->fc, AV_LOG_TRACE,
2264 "%s: pri %d trc %d matrix %d",
2265 color_parameter_type, color_primaries, color_trc, color_matrix);
2266
2267 if (!strncmp(color_parameter_type, "nclx", 4)) {
2268 uint8_t color_range = avio_r8(pb) >> 7;
2269 av_log(c->fc, AV_LOG_TRACE, " full %"PRIu8"", color_range);
2270 if (color_range)
2272 else
2274 }
2275
2278 if (!av_color_transfer_name(color_trc))
2279 color_trc = AVCOL_TRC_UNSPECIFIED;
2280 if (!av_color_space_name(color_matrix))
2281 color_matrix = AVCOL_SPC_UNSPECIFIED;
2282
2284 st->codecpar->color_trc = color_trc;
2285 st->codecpar->color_space = color_matrix;
2286 av_log(c->fc, AV_LOG_TRACE, "\n");
2287 }
2288 return 0;
2289}
2290
2292{
2293 AVStream *st;
2294 unsigned mov_field_order;
2295 enum AVFieldOrder decoded_field_order = AV_FIELD_UNKNOWN;
2296
2297 if (c->fc->nb_streams < 1) // will happen with jp2 files
2298 return 0;
2299 st = c->fc->streams[c->fc->nb_streams-1];
2300 if (atom.size < 2)
2301 return AVERROR_INVALIDDATA;
2302 mov_field_order = avio_rb16(pb);
2303 if ((mov_field_order & 0xFF00) == 0x0100)
2304 decoded_field_order = AV_FIELD_PROGRESSIVE;
2305 else if ((mov_field_order & 0xFF00) == 0x0200) {
2306 switch (mov_field_order & 0xFF) {
2307 case 0x01: decoded_field_order = AV_FIELD_TT;
2308 break;
2309 case 0x06: decoded_field_order = AV_FIELD_BB;
2310 break;
2311 case 0x09: decoded_field_order = AV_FIELD_TB;
2312 break;
2313 case 0x0E: decoded_field_order = AV_FIELD_BT;
2314 break;
2315 }
2316 }
2317 if (decoded_field_order == AV_FIELD_UNKNOWN && mov_field_order) {
2318 av_log(c->fc, AV_LOG_ERROR, "Unknown MOV field order 0x%04x\n", mov_field_order);
2319 }
2320 st->codecpar->field_order = decoded_field_order;
2321
2322 return 0;
2323}
2324
2326{
2327 int err = 0;
2328 uint64_t size = (uint64_t)par->extradata_size + atom.size + 8 + AV_INPUT_BUFFER_PADDING_SIZE;
2329 if (size > INT_MAX || (uint64_t)atom.size > INT_MAX)
2330 return AVERROR_INVALIDDATA;
2331 if ((err = av_reallocp(&par->extradata, size)) < 0) {
2332 par->extradata_size = 0;
2333 return err;
2334 }
2336 return 0;
2337}
2338
2339/* Read a whole atom into the extradata return the size of the atom read, possibly truncated if != atom.size */
2341 AVCodecParameters *par, uint8_t *buf)
2342{
2343 int64_t result = atom.size;
2344 int err;
2345
2346 AV_WB32(buf , atom.size + 8);
2347 AV_WL32(buf + 4, atom.type);
2348 err = ffio_read_size(pb, buf + 8, atom.size);
2349 if (err < 0) {
2350 par->extradata_size -= atom.size;
2351 return err;
2352 } else if (err < atom.size) {
2353 av_log(c->fc, AV_LOG_WARNING, "truncated extradata\n");
2354 par->extradata_size -= atom.size - err;
2355 result = err;
2356 }
2357 memset(buf + 8 + err, 0, AV_INPUT_BUFFER_PADDING_SIZE);
2358 return result;
2359}
2360
2361/* FIXME modify QDM2/SVQ3/H.264 decoders to take full atom as extradata */
2363 enum AVCodecID codec_id)
2364{
2365 AVStream *st;
2366 uint64_t original_size;
2367 int err;
2368
2369 if (c->fc->nb_streams < 1) // will happen with jp2 files
2370 return 0;
2371 st = c->fc->streams[c->fc->nb_streams-1];
2372
2373 if (st->codecpar->codec_id != codec_id)
2374 return 0; /* unexpected codec_id - don't mess with extradata */
2375
2376 original_size = st->codecpar->extradata_size;
2377 err = mov_realloc_extradata(st->codecpar, atom);
2378 if (err)
2379 return err;
2380
2381 err = mov_read_atom_into_extradata(c, pb, atom, st->codecpar, st->codecpar->extradata + original_size);
2382 if (err < 0)
2383 return err;
2384 return 0; // Note: this is the original behavior to ignore truncation.
2385}
2386
2387/* wrapper functions for reading ALAC/AVS/MJPEG/MJPEG2000 extradata atoms only for those codecs */
2389{
2390 return mov_read_extradata(c, pb, atom, AV_CODEC_ID_ALAC);
2391}
2392
2394{
2395 return mov_read_extradata(c, pb, atom, AV_CODEC_ID_CAVS);
2396}
2397
2399{
2400 return mov_read_extradata(c, pb, atom, AV_CODEC_ID_JPEG2000);
2401}
2402
2404{
2405 return mov_read_extradata(c, pb, atom, AV_CODEC_ID_R10K);
2406}
2407
2409{
2410 int ret = mov_read_extradata(c, pb, atom, AV_CODEC_ID_AVUI);
2411 if (!ret)
2412 ret = mov_read_extradata(c, pb, atom, AV_CODEC_ID_DNXHD);
2413 return ret;
2414}
2415
2417{
2418 int ret = mov_read_extradata(c, pb, atom, AV_CODEC_ID_TARGA_Y216);
2419
2420 if (!ret && c->fc->nb_streams >= 1) {
2421 AVCodecParameters *par = c->fc->streams[c->fc->nb_streams-1]->codecpar;
2422 if (par->extradata_size >= 40) {
2423 par->height = AV_RB16(&par->extradata[36]);
2424 par->width = AV_RB16(&par->extradata[38]);
2425 }
2426 }
2427 return ret;
2428}
2429
2431{
2432 if (c->fc->nb_streams >= 1) {
2433 AVStream *const st = c->fc->streams[c->fc->nb_streams - 1];
2434 FFStream *const sti = ffstream(st);
2435 AVCodecParameters *par = st->codecpar;
2436
2437 if (par->codec_tag == MKTAG('A', 'V', 'i', 'n') &&
2438 par->codec_id == AV_CODEC_ID_H264 &&
2439 atom.size > 11) {
2440 int cid;
2441 avio_skip(pb, 10);
2442 cid = avio_rb16(pb);
2443 /* For AVID AVCI50, force width of 1440 to be able to select the correct SPS and PPS */
2444 if (cid == 0xd4d || cid == 0xd4e)
2445 par->width = 1440;
2446 return 0;
2447 } else if ((par->codec_tag == MKTAG('A', 'V', 'd', '1') ||
2448 par->codec_tag == MKTAG('A', 'V', 'j', '2') ||
2449 par->codec_tag == MKTAG('A', 'V', 'd', 'n')) &&
2450 atom.size >= 24) {
2451 int num, den;
2452 avio_skip(pb, 12);
2453 num = avio_rb32(pb);
2454 den = avio_rb32(pb);
2455 if (num <= 0 || den <= 0)
2456 return 0;
2457 switch (avio_rb32(pb)) {
2458 case 2:
2459 if (den >= INT_MAX / 2)
2460 return 0;
2461 den *= 2;
2463 case 1:
2464 sti->display_aspect_ratio = (AVRational){ num, den };
2466 default:
2467 return 0;
2468 }
2469 }
2470 }
2471
2472 return mov_read_avid(c, pb, atom);
2473}
2474
2476{
2477 int ret = 0;
2478 int length = 0;
2479 uint64_t original_size;
2480 if (c->fc->nb_streams >= 1) {
2481 AVCodecParameters *par = c->fc->streams[c->fc->nb_streams-1]->codecpar;
2482 if (par->codec_id == AV_CODEC_ID_H264)
2483 return 0;
2484 if (atom.size == 16) {
2485 original_size = par->extradata_size;
2486 ret = mov_realloc_extradata(par, atom);
2487 if (!ret) {
2488 length = mov_read_atom_into_extradata(c, pb, atom, par, par->extradata + original_size);
2489 if (length == atom.size) {
2490 const uint8_t range_value = par->extradata[original_size + 19];
2491 switch (range_value) {
2492 case 1:
2494 break;
2495 case 2:
2497 break;
2498 default:
2499 av_log(c->fc, AV_LOG_WARNING, "ignored unknown aclr value (%d)\n", range_value);
2500 break;
2501 }
2502 ff_dlog(c->fc, "color_range: %d\n", par->color_range);
2503 } else {
2504 /* For some reason the whole atom was not added to the extradata */
2505 av_log(c->fc, AV_LOG_ERROR, "aclr not decoded - incomplete atom\n");
2506 }
2507 } else {
2508 av_log(c->fc, AV_LOG_ERROR, "aclr not decoded - unable to add atom to extradata\n");
2509 }
2510 } else {
2511 av_log(c->fc, AV_LOG_WARNING, "aclr not decoded - unexpected size %"PRId64"\n", atom.size);
2512 }
2513 }
2514
2515 return ret;
2516}
2517
2519{
2520 return mov_read_extradata(c, pb, atom, AV_CODEC_ID_SVQ3);
2521}
2522
2524{
2525 AVStream *st;
2526 int ret;
2527
2528 if (c->fc->nb_streams < 1)
2529 return 0;
2530 st = c->fc->streams[c->fc->nb_streams-1];
2531
2532 if ((uint64_t)atom.size > (1<<30))
2533 return AVERROR_INVALIDDATA;
2534
2535 if (st->codecpar->codec_id == AV_CODEC_ID_QDM2 ||
2538 // pass all frma atom to codec, needed at least for QDMC and QDM2
2539 ret = ff_get_extradata(c->fc, st->codecpar, pb, atom.size);
2540 if (ret < 0)
2541 return ret;
2542 } else if (atom.size > 8) { /* to read frma, esds atoms */
2543 if (st->codecpar->codec_id == AV_CODEC_ID_ALAC && atom.size >= 24) {
2544 uint64_t buffer;
2545 ret = ffio_ensure_seekback(pb, 8);
2546 if (ret < 0)
2547 return ret;
2548 buffer = avio_rb64(pb);
2549 atom.size -= 8;
2550 if ( (buffer & 0xFFFFFFFF) == MKBETAG('f','r','m','a')
2551 && buffer >> 32 <= atom.size
2552 && buffer >> 32 >= 8) {
2553 avio_skip(pb, -8);
2554 atom.size += 8;
2555 } else if (!st->codecpar->extradata_size) {
2556#define ALAC_EXTRADATA_SIZE 36
2558 if (!st->codecpar->extradata)
2559 return AVERROR(ENOMEM);
2562 AV_WB32(st->codecpar->extradata + 4, MKTAG('a','l','a','c'));
2563 AV_WB64(st->codecpar->extradata + 12, buffer);
2564 avio_read(pb, st->codecpar->extradata + 20, 16);
2565 avio_skip(pb, atom.size - 24);
2566 return 0;
2567 }
2568 }
2569 if ((ret = mov_read_default(c, pb, atom)) < 0)
2570 return ret;
2571 } else
2572 avio_skip(pb, atom.size);
2573 return 0;
2574}
2575
2576/**
2577 * This function reads atom content and puts data in extradata without tag
2578 * nor size unlike mov_read_extradata.
2579 */
2581{
2582 AVStream *st;
2583 int ret;
2584
2585 st = get_curr_st(c);
2586 if (!st)
2587 return 0;
2588
2589 if ((uint64_t)atom.size > (1<<30))
2590 return AVERROR_INVALIDDATA;
2591
2592 if (atom.type == MKTAG('v','v','c','C')) {
2593 avio_skip(pb, 4);
2594 atom.size -= 4;
2595 }
2596
2597 if (atom.size >= 10) {
2598 // Broken files created by legacy versions of libavformat will
2599 // wrap a whole fiel atom inside of a glbl atom.
2600 unsigned size = avio_rb32(pb);
2601 unsigned type = avio_rl32(pb);
2602 if (avio_feof(pb))
2603 return AVERROR_INVALIDDATA;
2604 avio_seek(pb, -8, SEEK_CUR);
2605 if (type == MKTAG('f','i','e','l') && size == atom.size)
2606 return mov_read_default(c, pb, atom);
2607 }
2608 if (st->codecpar->extradata_size > 1 && st->codecpar->extradata) {
2609 av_log(c->fc, AV_LOG_WARNING, "ignoring multiple glbl\n");
2610 return 0;
2611 }
2612 ret = ff_get_extradata(c->fc, st->codecpar, pb, atom.size);
2613 if (ret < 0)
2614 return ret;
2615 if (atom.type == MKTAG('h','v','c','C') && st->codecpar->codec_tag == MKTAG('d','v','h','1'))
2616 /* HEVC-based Dolby Vision derived from hvc1.
2617 Happens to match with an identifier
2618 previously utilized for DV. Thus, if we have
2619 the hvcC extradata box available as specified,
2620 set codec to HEVC */
2622
2623 return 0;
2624}
2625
2627{
2628 AVStream *st;
2629 uint8_t profile_level;
2630 int ret;
2631
2632 if (c->fc->nb_streams < 1)
2633 return 0;
2634 st = c->fc->streams[c->fc->nb_streams-1];
2635
2636 if (atom.size >= (1<<28) || atom.size < 7)
2637 return AVERROR_INVALIDDATA;
2638
2639 profile_level = avio_r8(pb);
2640 if ((profile_level & 0xf0) != 0xc0)
2641 return 0;
2642
2643 avio_seek(pb, 6, SEEK_CUR);
2644 ret = ff_get_extradata(c->fc, st->codecpar, pb, atom.size - 7);
2645 if (ret < 0)
2646 return ret;
2647
2648 return 0;
2649}
2650
2651static int mov_find_tref_id(const MovTref *tag, uint32_t id)
2652{
2653 for (int i = 0; i < tag->nb_id; i++) {
2654 if (tag->id[i] == id)
2655 return 1;
2656 }
2657 return 0;
2658}
2659
2660static int mov_add_tref_id(MovTref *tag, uint32_t id)
2661{
2662 int ret = mov_find_tref_id(tag, id);
2663
2664 if (!ret) {
2665 uint32_t *tmp = av_realloc_array(tag->id, tag->nb_id + 1, sizeof(*tag->id));
2666 if (!tmp)
2667 return AVERROR(ENOMEM);
2668 tag->id = tmp;
2669 tag->id[tag->nb_id++] = id;
2670 }
2671
2672 return 0;
2673}
2674
2676{
2677 for (int i = 0; i < sc->nb_tref_tags; i++) {
2678 MovTref *entry = &sc->tref_tags[i];
2679
2680 if (entry->name == name)
2681 return entry;
2682 }
2683 return NULL;
2684}
2685
2687{
2689
2690 if (!tag) {
2692 sizeof(*sc->tref_tags));
2693 if (!tmp)
2694 return NULL;
2695 sc->tref_tags = tmp;
2696 tag = &sc->tref_tags[sc->nb_tref_tags++];
2697 *tag = (MovTref){ .name = name };
2698 }
2699
2700 return tag;
2701}
2702
2704{
2705 AVStream* st;
2706 MOVStreamContext* sc;
2707
2708 if (c->fc->nb_streams < 1)
2709 return 0;
2710
2711 if (atom.size > 4) {
2712 av_log(c->fc, AV_LOG_ERROR, "Only a single tref of type cdsc is supported\n");
2713 return AVERROR_PATCHWELCOME;
2714 }
2715 if (atom.size < 4)
2716 return AVERROR_INVALIDDATA;
2717
2718 st = get_curr_st(c);
2719 if (!st)
2720 return AVERROR_INVALIDDATA;
2721 sc = st->priv_data;
2722
2723 MovTref *tag = mov_add_tref_tag(sc, atom.type);
2724 if (!tag)
2725 return AVERROR(ENOMEM);
2726
2727 int ret = mov_add_tref_id(tag, avio_rb32(pb));
2728 if (ret < 0)
2729 return ret;
2730
2731 return 0;
2732}
2733
2735{
2736 AVStream* st;
2737 MOVStreamContext* sc;
2738
2739 if (c->fc->nb_streams < 1)
2740 return 0;
2741
2742 /* For SBAS this should be fine - though beware if someone implements a
2743 * tref atom processor that doesn't drop down to default then this may
2744 * be lost. */
2745 if (atom.size > 4) {
2746 av_log(c->fc, AV_LOG_ERROR, "Only a single tref of type sbas is supported\n");
2747 return AVERROR_PATCHWELCOME;
2748 }
2749 if (atom.size < 4)
2750 return AVERROR_INVALIDDATA;
2751
2752 st = c->fc->streams[c->fc->nb_streams - 1];
2753 sc = st->priv_data;
2754
2755 MovTref *tag = mov_add_tref_tag(sc, atom.type);
2756 if (!tag)
2757 return AVERROR(ENOMEM);
2758
2759 int ret = mov_add_tref_id(tag, avio_rb32(pb));
2760 if (ret < 0)
2761 return ret;
2762
2763 return 0;
2764}
2765
2767{
2768 AVStream* st;
2769 MOVStreamContext* sc;
2770
2771 if (c->fc->nb_streams < 1)
2772 return 0;
2773
2774 if (atom.size > 4)
2775 av_log(c->fc, AV_LOG_WARNING, "More than one vdep reference is not supported.\n");
2776 if (atom.size < 4)
2777 return AVERROR_INVALIDDATA;
2778
2779 st = c->fc->streams[c->fc->nb_streams - 1];
2780 sc = st->priv_data;
2781
2782 MovTref *tag = mov_add_tref_tag(sc, atom.type);
2783 if (!tag)
2784 return AVERROR(ENOMEM);
2785
2786 int ret = mov_add_tref_id(tag, avio_rb32(pb));
2787 if (ret < 0)
2788 return ret;
2789
2790 return 0;
2791}
2792
2793/**
2794 * An strf atom is a BITMAPINFOHEADER struct. This struct is 40 bytes itself,
2795 * but can have extradata appended at the end after the 40 bytes belonging
2796 * to the struct.
2797 */
2799{
2800 AVStream *st;
2801 int ret;
2802
2803 if (c->fc->nb_streams < 1)
2804 return 0;
2805 if (atom.size <= 40)
2806 return 0;
2807 st = c->fc->streams[c->fc->nb_streams-1];
2808
2809 if ((uint64_t)atom.size > (1<<30))
2810 return AVERROR_INVALIDDATA;
2811
2812 avio_skip(pb, 40);
2813 ret = ff_get_extradata(c->fc, st->codecpar, pb, atom.size - 40);
2814 if (ret < 0)
2815 return ret;
2816
2817 return 0;
2818}
2819
2821{
2822 AVStream *st;
2823 MOVStreamContext *sc;
2824 unsigned int i, entries;
2825
2826 if (c->trak_index < 0) {
2827 av_log(c->fc, AV_LOG_WARNING, "STCO outside TRAK\n");
2828 return 0;
2829 }
2830 if (c->fc->nb_streams < 1)
2831 return 0;
2832 st = c->fc->streams[c->fc->nb_streams-1];
2833 sc = st->priv_data;
2834
2835 avio_r8(pb); /* version */
2836 avio_rb24(pb); /* flags */
2837
2838 // Clamp allocation size for `chunk_offsets` -- don't throw an error for an
2839 // invalid count since the EOF path doesn't throw either.
2840 entries = avio_rb32(pb);
2841 entries =
2842 FFMIN(entries,
2843 FFMAX(0, (atom.size - 8) /
2844 (atom.type == MKTAG('s', 't', 'c', 'o') ? 4 : 8)));
2845
2846 if (!entries)
2847 return 0;
2848
2849 if (sc->chunk_offsets) {
2850 av_log(c->fc, AV_LOG_WARNING, "Ignoring duplicated STCO atom\n");
2851 return 0;
2852 }
2853
2855 sc->chunk_count = 0;
2856 sc->chunk_offsets = av_malloc_array(entries, sizeof(*sc->chunk_offsets));
2857 if (!sc->chunk_offsets)
2858 return AVERROR(ENOMEM);
2859 sc->chunk_count = entries;
2860
2861 if (atom.type == MKTAG('s','t','c','o'))
2862 for (i = 0; i < entries && !pb->eof_reached; i++)
2863 sc->chunk_offsets[i] = avio_rb32(pb);
2864 else if (atom.type == MKTAG('c','o','6','4'))
2865 for (i = 0; i < entries && !pb->eof_reached; i++) {
2866 sc->chunk_offsets[i] = avio_rb64(pb);
2867 if (sc->chunk_offsets[i] < 0) {
2868 av_log(c->fc, AV_LOG_WARNING, "Impossible chunk_offset\n");
2869 sc->chunk_offsets[i] = 0;
2870 }
2871 }
2872 else
2873 return AVERROR_INVALIDDATA;
2874
2875 sc->chunk_count = i;
2876
2877 if (pb->eof_reached) {
2878 av_log(c->fc, AV_LOG_WARNING, "reached eof, corrupted STCO atom\n");
2879 return AVERROR_EOF;
2880 }
2881
2882 return 0;
2883}
2884
2885static int mov_codec_id(AVStream *st, uint32_t format)
2886{
2888
2889 if (id <= 0 &&
2890 ((format & 0xFFFF) == 'm' + ('s' << 8) ||
2891 (format & 0xFFFF) == 'T' + ('S' << 8)))
2893
2894 if (st->codecpar->codec_type != AVMEDIA_TYPE_VIDEO && id > 0) {
2896 } else if (st->codecpar->codec_type != AVMEDIA_TYPE_AUDIO &&
2897 /* skip old ASF MPEG-4 tag */
2898 format && format != MKTAG('m','p','4','s')) {
2900 if (id <= 0)
2902 if (id > 0)
2904 else if (st->codecpar->codec_type == AVMEDIA_TYPE_DATA ||
2908 if (id <= 0) {
2911 }
2912
2913 if (id > 0)
2915 else
2917 }
2918 }
2919
2920 st->codecpar->codec_tag = format;
2921
2922 return id;
2923}
2924
2926 AVStream *st, MOVStreamContext *sc)
2927{
2928 uint8_t codec_name[32] = { 0 };
2929 int64_t stsd_start;
2930 unsigned int len;
2931 uint32_t id = 0;
2932
2933 /* The first 16 bytes of the video sample description are already
2934 * read in ff_mov_read_stsd_entries() */
2935 stsd_start = avio_tell(pb) - 16;
2936
2937 if (c->isom) {
2938 avio_skip(pb, 2); /* pre_defined */
2939 avio_skip(pb, 2); /* reserved */
2940 avio_skip(pb, 12); /* pre_defined */
2941 } else {
2942 avio_rb16(pb); /* version */
2943 avio_rb16(pb); /* revision level */
2944 id = avio_rl32(pb); /* vendor */
2945 av_dict_set(&st->metadata, "vendor_id", av_fourcc2str(id), 0);
2946 avio_rb32(pb); /* temporal quality */
2947 avio_rb32(pb); /* spatial quality */
2948 }
2949
2950 st->codecpar->width = avio_rb16(pb); /* width */
2951 st->codecpar->height = avio_rb16(pb); /* height */
2952
2953 avio_rb32(pb); /* horiz resolution */
2954 avio_rb32(pb); /* vert resolution */
2955 avio_rb32(pb); /* data size, always 0 */
2956 avio_rb16(pb); /* frames per samples */
2957
2958 len = avio_r8(pb); /* codec name, pascal string */
2959 if (len > 31)
2960 len = 31;
2961 mov_read_mac_string(c, pb, len, codec_name, sizeof(codec_name));
2962 if (len < 31)
2963 avio_skip(pb, 31 - len);
2964
2965 if (codec_name[0])
2966 av_dict_set(&st->metadata, "encoder", codec_name, 0);
2967
2968 /* codec_tag YV12 triggers an UV swap in rawdec.c */
2969 if (!strncmp(codec_name, "Planar Y'CbCr 8-bit 4:2:0", 25)) {
2970 st->codecpar->codec_tag = MKTAG('I', '4', '2', '0');
2971 st->codecpar->width &= ~1;
2972 st->codecpar->height &= ~1;
2973 }
2974 /* Flash Media Server uses tag H.263 with Sorenson Spark */
2975 if (st->codecpar->codec_tag == MKTAG('H','2','6','3') &&
2976 !strncmp(codec_name, "Sorenson H263", 13))
2978
2979 st->codecpar->bits_per_coded_sample = avio_rb16(pb); /* depth */
2980
2981 avio_seek(pb, stsd_start, SEEK_SET);
2982
2983 if (ff_get_qtpalette(st->codecpar->codec_id, pb, sc->palette)) {
2984 st->codecpar->bits_per_coded_sample &= 0x1F;
2985 sc->has_palette = 1;
2986 }
2987}
2988
2990 AVStream *st, MOVStreamContext *sc)
2991{
2992 int bits_per_sample, flags;
2993 uint16_t version = avio_rb16(pb);
2994 uint32_t id = 0;
2995 AVDictionaryEntry *compatible_brands = av_dict_get(c->fc->metadata, "compatible_brands", NULL, AV_DICT_MATCH_CASE);
2996 int channel_count;
2997
2998 if (c->isom)
2999 avio_skip(pb, 6); /* reserved */
3000 else {
3001 avio_rb16(pb); /* revision level */
3002 id = avio_rl32(pb); /* vendor */
3003 av_dict_set(&st->metadata, "vendor_id", av_fourcc2str(id), 0);
3004 }
3005
3006 channel_count = avio_rb16(pb);
3007
3009 st->codecpar->ch_layout.nb_channels = channel_count;
3010 st->codecpar->bits_per_coded_sample = avio_rb16(pb); /* sample size */
3011 av_log(c->fc, AV_LOG_TRACE, "audio channels %d\n", channel_count);
3012
3013 sc->audio_cid = avio_rb16(pb);
3014 avio_rb16(pb); /* packet size = 0 */
3015
3016 st->codecpar->sample_rate = ((avio_rb32(pb) >> 16));
3017
3018 // Read QT version 1 fields. In version 0 these do not exist.
3019 av_log(c->fc, AV_LOG_TRACE, "version =%d, isom =%d\n", version, c->isom);
3020 if (!c->isom ||
3021 (compatible_brands && strstr(compatible_brands->value, "qt ")) ||
3022 (sc->stsd_version == 0 && version > 0)) {
3023 if (version == 1) {
3024 sc->samples_per_frame = avio_rb32(pb);
3025 avio_rb32(pb); /* bytes per packet */
3026 sc->bytes_per_frame = avio_rb32(pb);
3027 avio_rb32(pb); /* bytes per sample */
3028 } else if (version == 2) {
3029 avio_rb32(pb); /* sizeof struct only */
3031 channel_count = avio_rb32(pb);
3033 st->codecpar->ch_layout.nb_channels = channel_count;
3034 avio_rb32(pb); /* always 0x7F000000 */
3036
3037 flags = avio_rb32(pb); /* lpcm format specific flag */
3038 sc->bytes_per_frame = avio_rb32(pb);
3039 sc->samples_per_frame = avio_rb32(pb);
3040 if (st->codecpar->codec_tag == MKTAG('l','p','c','m'))
3041 st->codecpar->codec_id =
3043 flags);
3044 }
3045 if (version == 0 || (version == 1 && sc->audio_cid != -2)) {
3046 /* can't correctly handle variable sized packet as audio unit */
3047 switch (st->codecpar->codec_id) {
3048 case AV_CODEC_ID_MP2:
3049 case AV_CODEC_ID_MP3:
3051 break;
3052 }
3053 }
3054 }
3055
3056 if (sc->format == 0) {
3057 if (st->codecpar->bits_per_coded_sample == 8)
3058 st->codecpar->codec_id = mov_codec_id(st, MKTAG('r','a','w',' '));
3059 else if (st->codecpar->bits_per_coded_sample == 16)
3060 st->codecpar->codec_id = mov_codec_id(st, MKTAG('t','w','o','s'));
3061 }
3062
3063 switch (st->codecpar->codec_id) {
3064 case AV_CODEC_ID_PCM_S8:
3065 case AV_CODEC_ID_PCM_U8:
3066 if (st->codecpar->bits_per_coded_sample == 16)
3068 break;
3071 if (st->codecpar->bits_per_coded_sample == 8)
3073 else if (st->codecpar->bits_per_coded_sample == 24)
3074 st->codecpar->codec_id =
3077 else if (st->codecpar->bits_per_coded_sample == 32)
3078 st->codecpar->codec_id =
3081 break;
3082 /* set values for old format before stsd version 1 appeared */
3083 case AV_CODEC_ID_MACE3:
3084 sc->samples_per_frame = 6;
3086 break;
3087 case AV_CODEC_ID_MACE6:
3088 sc->samples_per_frame = 6;
3090 break;
3092 sc->samples_per_frame = 64;
3094 break;
3095 case AV_CODEC_ID_GSM:
3096 sc->samples_per_frame = 160;
3097 sc->bytes_per_frame = 33;
3098 break;
3099 default:
3100 break;
3101 }
3102
3103 bits_per_sample = av_get_bits_per_sample(st->codecpar->codec_id);
3104 if (bits_per_sample && (bits_per_sample >> 3) * (uint64_t)st->codecpar->ch_layout.nb_channels <= INT_MAX) {
3105 st->codecpar->bits_per_coded_sample = bits_per_sample;
3106 sc->sample_size = (bits_per_sample >> 3) * st->codecpar->ch_layout.nb_channels;
3107 }
3108}
3109
3111 AVStream *st, MOVStreamContext *sc,
3112 int64_t size)
3113{
3114 // ttxt stsd contains display flags, justification, background
3115 // color, fonts, and default styles, so fake an atom to read it
3116 MOVAtom fake_atom = { .size = size };
3117 // mp4s contains a regular esds atom, dfxp ISMV TTML has no content
3118 // in extradata unlike stpp MP4 TTML.
3119 if (st->codecpar->codec_tag != AV_RL32("mp4s") &&
3121 mov_read_glbl(c, pb, fake_atom);
3122 st->codecpar->width = sc->width;
3123 st->codecpar->height = sc->height;
3124}
3125
3127 AVStream *st, MOVStreamContext *sc,
3128 int64_t size)
3129{
3130 int ret;
3131
3132 if (st->codecpar->codec_tag == MKTAG('t','m','c','d')) {
3133 if ((int)size != size)
3134 return AVERROR(ENOMEM);
3135
3136 ret = ff_get_extradata(c->fc, st->codecpar, pb, size);
3137 if (ret < 0)
3138 return ret;
3139 if (size > 16) {
3140 MOVStreamContext *tmcd_ctx = st->priv_data;
3141 int val;
3142 val = AV_RB32(st->codecpar->extradata + 4);
3143 tmcd_ctx->tmcd_flags = val;
3144 st->avg_frame_rate.num = AV_RB32(st->codecpar->extradata + 8); /* timescale */
3145 st->avg_frame_rate.den = AV_RB32(st->codecpar->extradata + 12); /* frameDuration */
3146 tmcd_ctx->tmcd_nb_frames = st->codecpar->extradata[16]; /* number of frames */
3147 if (size > 30) {
3148 uint32_t len = AV_RB32(st->codecpar->extradata + 18); /* name atom length */
3149 uint32_t format = AV_RB32(st->codecpar->extradata + 22);
3150 if (format == AV_RB32("name") && (int64_t)size >= (int64_t)len + 18) {
3151 uint16_t str_size = AV_RB16(st->codecpar->extradata + 26); /* string length */
3152 if (str_size > 0 && size >= (int)str_size + 30 &&
3153 st->codecpar->extradata[30] /* Don't add empty string */) {
3154 char *reel_name = av_malloc(str_size + 1);
3155 if (!reel_name)
3156 return AVERROR(ENOMEM);
3157 memcpy(reel_name, st->codecpar->extradata + 30, str_size);
3158 reel_name[str_size] = 0; /* Add null terminator */
3159 av_dict_set(&st->metadata, "reel_name", reel_name,
3161 }
3162 }
3163 }
3164 }
3165 } else if (st->codecpar->codec_id == AV_CODEC_ID_ITUT_T35) {
3166 int t35_identifier_length = avio_r8(pb);
3167
3168 if (t35_identifier_length <= 0 || t35_identifier_length >= size)
3169 return AVERROR_INVALIDDATA;
3170
3171 ret = ff_get_extradata(c->fc, st->codecpar, pb, t35_identifier_length);
3172 if (ret < 0)
3173 return ret;
3174
3175 int hrsd_len = size - t35_identifier_length - 1;
3176 if (hrsd_len > 0) {
3177 uint8_t *hrsd_str = av_malloc(hrsd_len + 1);
3178 if (!hrsd_str)
3179 return AVERROR(ENOMEM);
3180
3181 ret = ffio_read_size(pb, hrsd_str, hrsd_len);
3182 if (ret < 0) {
3183 av_free(hrsd_str);
3184 return ret;
3185 }
3186 if (hrsd_str[0]) {
3187 hrsd_str[hrsd_len] = 0;
3188 ret = av_dict_set(&st->metadata, "description", hrsd_str, AV_DICT_DONT_OVERWRITE);
3189 }
3190 av_free(hrsd_str);
3191 }
3192 } else {
3193 /* other codec type, just skip (rtp, mp4s ...) */
3194 avio_skip(pb, size);
3195 }
3196 return 0;
3197}
3198
3200 AVStream *st, MOVStreamContext *sc)
3201{
3202 FFStream *const sti = ffstream(st);
3203
3205 !st->codecpar->sample_rate && sc->time_scale > 1)
3206 st->codecpar->sample_rate = sc->time_scale;
3207
3208 /* special codec parameters handling */
3209 switch (st->codecpar->codec_id) {
3210#if CONFIG_DV_DEMUXER
3212 if (c->dv_fctx) {
3213 avpriv_request_sample(c->fc, "multiple DV audio streams");
3214 return AVERROR(ENOSYS);
3215 }
3216
3217 c->dv_fctx = avformat_alloc_context();
3218 if (!c->dv_fctx) {
3219 av_log(c->fc, AV_LOG_ERROR, "dv demux context alloc error\n");
3220 return AVERROR(ENOMEM);
3221 }
3222 c->dv_demux = avpriv_dv_init_demux(c->dv_fctx);
3223 if (!c->dv_demux) {
3224 av_log(c->fc, AV_LOG_ERROR, "dv demux context init error\n");
3225 return AVERROR(ENOMEM);
3226 }
3227 sc->dv_audio_container = 1;
3229 break;
3230#endif
3231 /* no ifdef since parameters are always those */
3232 case AV_CODEC_ID_QCELP:
3235 // force sample rate for qcelp when not stored in mov
3236 if (st->codecpar->codec_tag != MKTAG('Q','c','l','p'))
3237 st->codecpar->sample_rate = 8000;
3238 // FIXME: Why is the following needed for some files?
3239 sc->samples_per_frame = 160;
3240 if (!sc->bytes_per_frame)
3241 sc->bytes_per_frame = 35;
3242 break;
3243 case AV_CODEC_ID_AMR_NB:
3246 /* force sample rate for amr, stsd in 3gp does not store sample rate */
3247 st->codecpar->sample_rate = 8000;
3248 break;
3249 case AV_CODEC_ID_AMR_WB:
3252 st->codecpar->sample_rate = 16000;
3253 break;
3254 case AV_CODEC_ID_MP2:
3255 case AV_CODEC_ID_MP3:
3256 /* force type after stsd for m1a hdlr */
3258 break;
3259 case AV_CODEC_ID_GSM:
3262 case AV_CODEC_ID_ILBC:
3263 case AV_CODEC_ID_MACE3:
3264 case AV_CODEC_ID_MACE6:
3265 case AV_CODEC_ID_QDM2:
3267 break;
3268 case AV_CODEC_ID_ALAC:
3269 if (st->codecpar->extradata_size == 36) {
3270 int channel_count = AV_RB8(st->codecpar->extradata + 21);
3271 if (st->codecpar->ch_layout.nb_channels != channel_count) {
3274 st->codecpar->ch_layout.nb_channels = channel_count;
3275 }
3276 st->codecpar->sample_rate = AV_RB32(st->codecpar->extradata + 32);
3277 }
3278 break;
3279 case AV_CODEC_ID_AC3:
3280 case AV_CODEC_ID_EAC3:
3282 case AV_CODEC_ID_VC1:
3283 case AV_CODEC_ID_VP8:
3284 case AV_CODEC_ID_VP9:
3286 break;
3288 case AV_CODEC_ID_PRORES:
3289 case AV_CODEC_ID_APV:
3290 case AV_CODEC_ID_EVC:
3291 case AV_CODEC_ID_LCEVC:
3292 case AV_CODEC_ID_AV1:
3293 /* field_order detection of H264 requires parsing */
3294 case AV_CODEC_ID_H264:
3296 break;
3297 default:
3298 break;
3299 }
3300 return 0;
3301}
3302
3304 int codec_tag, int format,
3305 int64_t size)
3306{
3307 if (codec_tag &&
3308 (codec_tag != format &&
3309 // AVID 1:1 samples with differing data format and codec tag exist
3310 (codec_tag != AV_RL32("AV1x") || format != AV_RL32("AVup")) &&
3311 // prores is allowed to have differing data format and codec tag
3312 codec_tag != AV_RL32("apcn") && codec_tag != AV_RL32("apch") &&
3313 // so is dv (sigh)
3314 codec_tag != AV_RL32("dvpp") && codec_tag != AV_RL32("dvcp") &&
3315 (c->fc->video_codec_id ? ff_codec_get_id(ff_codec_movvideo_tags, format) != c->fc->video_codec_id
3316 : codec_tag != MKTAG('j','p','e','g')))) {
3317 /* Multiple fourcc, we skip JPEG. This is not correct, we should
3318 * export it as a separate AVStream but this needs a few changes
3319 * in the MOV demuxer, patch welcome. */
3320
3321 av_log(c->fc, AV_LOG_WARNING, "multiple fourcc not supported\n");
3322 avio_skip(pb, size);
3323 return 1;
3324 }
3325
3326 return 0;
3327}
3328
3330{
3331 int ret;
3332
3333 /* special codec parameters handling */
3334 switch (st->codecpar->codec_id) {
3335 case AV_CODEC_ID_H264:
3336 // done for ai5q, ai52, ai55, ai1q, ai12 and ai15.
3339 if (ret < 0)
3340 return ret;
3341 }
3342 break;
3343 default:
3344 break;
3345 }
3346
3347 return 0;
3348}
3349
3351{
3352 AVStream *st;
3353 MOVStreamContext *sc;
3354 int pseudo_stream_id;
3355
3356 av_assert0 (c->fc->nb_streams >= 1);
3357 st = c->fc->streams[c->fc->nb_streams-1];
3358 sc = st->priv_data;
3359
3360 for (pseudo_stream_id = 0;
3361 pseudo_stream_id < entries && !pb->eof_reached;
3362 pseudo_stream_id++) {
3363 //Parsing Sample description table
3364 enum AVCodecID id;
3365 int ret, dref_id = 1;
3366 MOVAtom a = { AV_RL32("stsd") };
3367 int64_t start_pos = avio_tell(pb);
3368 int64_t size = avio_rb32(pb); /* size */
3369 uint32_t format = avio_rl32(pb); /* data format */
3370
3371 if (size >= 16) {
3372 avio_rb32(pb); /* reserved */
3373 avio_rb16(pb); /* reserved */
3374 dref_id = avio_rb16(pb);
3375 } else if (size <= 7) {
3376 av_log(c->fc, AV_LOG_ERROR,
3377 "invalid size %"PRId64" in stsd\n", size);
3378 return AVERROR_INVALIDDATA;
3379 }
3380
3382 size - (avio_tell(pb) - start_pos))) {
3383 sc->stsd_count++;
3384 continue;
3385 }
3386
3387 sc->pseudo_stream_id = st->codecpar->codec_tag ? -1 : pseudo_stream_id;
3388 sc->dref_id= dref_id;
3389 sc->format = format;
3390
3391 id = mov_codec_id(st, format);
3392
3393 av_log(c->fc, AV_LOG_TRACE,
3394 "size=%"PRId64" 4CC=%s codec_type=%d\n", size,
3396
3397 st->codecpar->codec_id = id;
3399 mov_parse_stsd_video(c, pb, st, sc);
3400 } else if (st->codecpar->codec_type==AVMEDIA_TYPE_AUDIO) {
3401 mov_parse_stsd_audio(c, pb, st, sc);
3402 if (st->codecpar->sample_rate < 0) {
3403 av_log(c->fc, AV_LOG_ERROR, "Invalid sample rate %d\n", st->codecpar->sample_rate);
3404 return AVERROR_INVALIDDATA;
3405 }
3406 if (st->codecpar->ch_layout.nb_channels < 0) {
3407 av_log(c->fc, AV_LOG_ERROR, "Invalid channels %d\n", st->codecpar->ch_layout.nb_channels);
3408 return AVERROR_INVALIDDATA;
3409 }
3410 } else if (st->codecpar->codec_type==AVMEDIA_TYPE_SUBTITLE){
3411 mov_parse_stsd_subtitle(c, pb, st, sc,
3412 size - (avio_tell(pb) - start_pos));
3413 } else {
3414 ret = mov_parse_stsd_data(c, pb, st, sc,
3415 size - (avio_tell(pb) - start_pos));
3416 if (ret < 0)
3417 return ret;
3418 }
3419 /* this will read extra atoms at the end (wave, alac, damr, avcC, hvcC, SMI ...) */
3420 a.size = size - (avio_tell(pb) - start_pos);
3421 if (a.size > 8) {
3422 if ((ret = mov_read_default(c, pb, a)) < 0)
3423 return ret;
3424 } else if (a.size > 0)
3425 avio_skip(pb, a.size);
3426
3427 ret = mov_finalize_stsd_entry(c, st);
3428 if (ret < 0)
3429 return ret;
3430
3431 if (sc->extradata && st->codecpar->extradata) {
3432 int extra_size = st->codecpar->extradata_size;
3433
3434 /* Move the current stream extradata to the stream context one. */
3435 sc->extradata_size[pseudo_stream_id] = extra_size;
3436 sc->extradata[pseudo_stream_id] = st->codecpar->extradata;
3437 st->codecpar->extradata = NULL;
3438 st->codecpar->extradata_size = 0;
3439 }
3440 sc->stsd_count++;
3441 }
3442
3443 if (pb->eof_reached) {
3444 av_log(c->fc, AV_LOG_WARNING, "reached eof, corrupted STSD atom\n");
3445 return AVERROR_EOF;
3446 }
3447
3448 return 0;
3449}
3450
3452{
3453 AVStream *st;
3454 MOVStreamContext *sc;
3455 int ret, entries;
3456
3457 if (c->fc->nb_streams < 1)
3458 return 0;
3459 st = c->fc->streams[c->fc->nb_streams - 1];
3460 sc = st->priv_data;
3461
3462 if (sc->extradata) {
3463 av_log(c->fc, AV_LOG_ERROR,
3464 "Duplicate stsd found in this track.\n");
3465 return AVERROR_INVALIDDATA;
3466 }
3467
3468 sc->stsd_version = avio_r8(pb);
3469 avio_rb24(pb); /* flags */
3470 entries = avio_rb32(pb);
3471
3472 /* Each entry contains a size (4 bytes) and format (4 bytes). */
3473 if (entries <= 0 || entries > atom.size / 8 || entries > 1024) {
3474 av_log(c->fc, AV_LOG_ERROR, "invalid STSD entries %d\n", entries);
3475 return AVERROR_INVALIDDATA;
3476 }
3477
3478 /* Prepare space for hosting multiple extradata. */
3479 sc->extradata = av_calloc(entries, sizeof(*sc->extradata));
3480 if (!sc->extradata)
3481 return AVERROR(ENOMEM);
3482
3483 sc->extradata_size = av_calloc(entries, sizeof(*sc->extradata_size));
3484 if (!sc->extradata_size) {
3485 ret = AVERROR(ENOMEM);
3486 goto fail;
3487 }
3488
3489 ret = ff_mov_read_stsd_entries(c, pb, entries);
3490 if (ret < 0)
3491 goto fail;
3492
3493 /* Restore back the primary extradata. */
3496 if (sc->extradata_size[0]) {
3498 if (!st->codecpar->extradata)
3499 return AVERROR(ENOMEM);
3500 memcpy(st->codecpar->extradata, sc->extradata[0], sc->extradata_size[0]);
3501 }
3502
3503 return mov_finalize_stsd_codec(c, pb, st, sc);
3504fail:
3505 if (sc->extradata) {
3506 int j;
3507 for (j = 0; j < sc->stsd_count; j++)
3508 av_freep(&sc->extradata[j]);
3509 }
3510
3511 sc->stsd_count = 0;
3512 av_freep(&sc->extradata);
3514 return ret;
3515}
3516
3518{
3519 AVStream *st;
3520 MOVStreamContext *sc;
3521 unsigned int i, entries;
3522
3523 if (c->trak_index < 0) {
3524 av_log(c->fc, AV_LOG_WARNING, "STSC outside TRAK\n");
3525 return 0;
3526 }
3527
3528 if (c->fc->nb_streams < 1)
3529 return 0;
3530 st = c->fc->streams[c->fc->nb_streams-1];
3531 sc = st->priv_data;
3532
3533 avio_r8(pb); /* version */
3534 avio_rb24(pb); /* flags */
3535
3536 entries = avio_rb32(pb);
3537 if ((uint64_t)entries * 12 + 4 > atom.size)
3538 return AVERROR_INVALIDDATA;
3539
3540 av_log(c->fc, AV_LOG_TRACE, "track[%u].stsc.entries = %u\n", c->fc->nb_streams - 1, entries);
3541
3542 if (!entries)
3543 return 0;
3544 if (sc->stsc_data) {
3545 av_log(c->fc, AV_LOG_WARNING, "Ignoring duplicated STSC atom\n");
3546 return 0;
3547 }
3548 av_free(sc->stsc_data);
3549 sc->stsc_count = 0;
3550 sc->stsc_data = av_malloc_array(entries, sizeof(*sc->stsc_data));
3551 if (!sc->stsc_data)
3552 return AVERROR(ENOMEM);
3553
3554 for (i = 0; i < entries && !pb->eof_reached; i++) {
3555 sc->stsc_data[i].first = avio_rb32(pb);
3556 sc->stsc_data[i].count = avio_rb32(pb);
3557 sc->stsc_data[i].id = avio_rb32(pb);
3558 }
3559
3560 sc->stsc_count = i;
3561 for (i = sc->stsc_count - 1; i < UINT_MAX; i--) {
3562 int64_t first_min = i + 1;
3563 if ((i+1 < sc->stsc_count && sc->stsc_data[i].first >= sc->stsc_data[i+1].first) ||
3564 (i > 0 && sc->stsc_data[i].first <= sc->stsc_data[i-1].first) ||
3565 sc->stsc_data[i].first < first_min ||
3566 sc->stsc_data[i].count < 1 ||
3567 sc->stsc_data[i].id < 1) {
3568 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);
3569 if (i+1 >= sc->stsc_count) {
3570 if (sc->stsc_data[i].count == 0 && i > 0) {
3571 sc->stsc_count --;
3572 continue;
3573 }
3574 sc->stsc_data[i].first = FFMAX(sc->stsc_data[i].first, first_min);
3575 if (i > 0 && sc->stsc_data[i].first <= sc->stsc_data[i-1].first)
3576 sc->stsc_data[i].first = FFMIN(sc->stsc_data[i-1].first + 1LL, INT_MAX);
3577 sc->stsc_data[i].count = FFMAX(sc->stsc_data[i].count, 1);
3578 sc->stsc_data[i].id = FFMAX(sc->stsc_data[i].id, 1);
3579 continue;
3580 }
3581 av_assert0(sc->stsc_data[i+1].first >= 2);
3582 // We replace this entry by the next valid
3583 sc->stsc_data[i].first = sc->stsc_data[i+1].first - 1;
3584 sc->stsc_data[i].count = sc->stsc_data[i+1].count;
3585 sc->stsc_data[i].id = sc->stsc_data[i+1].id;
3586 }
3587 }
3588
3589 if (pb->eof_reached) {
3590 av_log(c->fc, AV_LOG_WARNING, "reached eof, corrupted STSC atom\n");
3591 return AVERROR_EOF;
3592 }
3593
3594 return 0;
3595}
3596
3597static inline int mov_stsc_index_valid(unsigned int index, unsigned int count)
3598{
3599 return index < count - 1;
3600}
3601
3602/* Compute the samples value for the stsc entry at the given index. */
3603static inline int64_t mov_get_stsc_samples(MOVStreamContext *sc, unsigned int index)
3604{
3605 int chunk_count;
3606
3608 chunk_count = sc->stsc_data[index + 1].first - sc->stsc_data[index].first;
3609 else {
3610 // Validation for stsc / stco happens earlier in mov_read_stsc + mov_read_trak.
3612 chunk_count = sc->chunk_count - (sc->stsc_data[index].first - 1);
3613 }
3614
3615 return sc->stsc_data[index].count * (int64_t)chunk_count;
3616}
3617
3619{
3620 AVStream *st;
3621 MOVStreamContext *sc;
3622 unsigned i, entries;
3623
3624 if (c->trak_index < 0) {
3625 av_log(c->fc, AV_LOG_WARNING, "STPS outside TRAK\n");
3626 return 0;
3627 }
3628
3629 if (c->fc->nb_streams < 1)
3630 return 0;
3631 st = c->fc->streams[c->fc->nb_streams-1];
3632 sc = st->priv_data;
3633
3634 avio_rb32(pb); // version + flags
3635
3636 entries = avio_rb32(pb);
3637 if (sc->stps_data)
3638 av_log(c->fc, AV_LOG_WARNING, "Duplicated STPS atom\n");
3639 av_free(sc->stps_data);
3640 sc->stps_count = 0;
3641 sc->stps_data = av_malloc_array(entries, sizeof(*sc->stps_data));
3642 if (!sc->stps_data)
3643 return AVERROR(ENOMEM);
3644
3645 for (i = 0; i < entries && !pb->eof_reached; i++) {
3646 sc->stps_data[i] = avio_rb32(pb);
3647 }
3648
3649 sc->stps_count = i;
3650
3651 if (pb->eof_reached) {
3652 av_log(c->fc, AV_LOG_WARNING, "reached eof, corrupted STPS atom\n");
3653 return AVERROR_EOF;
3654 }
3655
3656 return 0;
3657}
3658
3660{
3661 AVStream *st;
3662 FFStream *sti;
3663 MOVStreamContext *sc;
3664 unsigned int i, entries;
3665
3666 if (c->trak_index < 0) {
3667 av_log(c->fc, AV_LOG_WARNING, "STSS outside TRAK\n");
3668 return 0;
3669 }
3670
3671 if (c->fc->nb_streams < 1)
3672 return 0;
3673 st = c->fc->streams[c->fc->nb_streams-1];
3674 sti = ffstream(st);
3675 sc = st->priv_data;
3676
3677 avio_r8(pb); /* version */
3678 avio_rb24(pb); /* flags */
3679
3680 entries = avio_rb32(pb);
3681
3682 av_log(c->fc, AV_LOG_TRACE, "keyframe_count = %u\n", entries);
3683
3684 if (!entries) {
3685 sc->keyframe_absent = 1;
3688 return 0;
3689 }
3690 if (sc->keyframes)
3691 av_log(c->fc, AV_LOG_WARNING, "Duplicated STSS atom\n");
3692 if (entries >= UINT_MAX / sizeof(int))
3693 return AVERROR_INVALIDDATA;
3694 av_freep(&sc->keyframes);
3695 sc->keyframe_count = 0;
3696 sc->keyframes = av_malloc_array(entries, sizeof(*sc->keyframes));
3697 if (!sc->keyframes)
3698 return AVERROR(ENOMEM);
3699
3700 for (i = 0; i < entries && !pb->eof_reached; i++) {
3701 sc->keyframes[i] = avio_rb32(pb);
3702 }
3703
3704 sc->keyframe_count = i;
3705
3706 if (pb->eof_reached) {
3707 av_log(c->fc, AV_LOG_WARNING, "reached eof, corrupted STSS atom\n");
3708 return AVERROR_EOF;
3709 }
3710
3711 return 0;
3712}
3713
3715{
3716 AVStream *st;
3717 MOVStreamContext *sc;
3718 unsigned int i, entries, sample_size, field_size, num_bytes;
3719 GetBitContext gb;
3720 unsigned char* buf;
3721 int ret;
3722
3723 if (c->trak_index < 0) {
3724 av_log(c->fc, AV_LOG_WARNING, "STSZ outside TRAK\n");
3725 return 0;
3726 }
3727
3728 if (c->fc->nb_streams < 1)
3729 return 0;
3730 st = c->fc->streams[c->fc->nb_streams-1];
3731 sc = st->priv_data;
3732
3733 avio_r8(pb); /* version */
3734 avio_rb24(pb); /* flags */
3735
3736 if (atom.type == MKTAG('s','t','s','z')) {
3737 sample_size = avio_rb32(pb);
3738 if (!sc->sample_size) /* do not overwrite value computed in stsd */
3739 sc->sample_size = sample_size;
3740 sc->stsz_sample_size = sample_size;
3741 field_size = 32;
3742 } else {
3743 sample_size = 0;
3744 avio_rb24(pb); /* reserved */
3745 field_size = avio_r8(pb);
3746 }
3747 entries = avio_rb32(pb);
3748
3749 av_log(c->fc, AV_LOG_TRACE, "sample_size = %u sample_count = %u\n", sc->sample_size, entries);
3750
3751 sc->sample_count = entries;
3752 if (sample_size)
3753 return 0;
3754
3755 if (field_size != 4 && field_size != 8 && field_size != 16 && field_size != 32) {
3756 av_log(c->fc, AV_LOG_ERROR, "Invalid sample field size %u\n", field_size);
3757 return AVERROR_INVALIDDATA;
3758 }
3759
3760 if (!entries)
3761 return 0;
3762 if (entries >= (INT_MAX - 4 - 8 * AV_INPUT_BUFFER_PADDING_SIZE) / field_size)
3763 return AVERROR_INVALIDDATA;
3764 if (sc->sample_sizes)
3765 av_log(c->fc, AV_LOG_WARNING, "Duplicated STSZ atom\n");
3766 av_free(sc->sample_sizes);
3767 sc->sample_count = 0;
3768 sc->sample_sizes = av_malloc_array(entries, sizeof(*sc->sample_sizes));
3769 if (!sc->sample_sizes)
3770 return AVERROR(ENOMEM);
3771
3772 num_bytes = (entries*field_size+4)>>3;
3773
3774 buf = av_malloc(num_bytes+AV_INPUT_BUFFER_PADDING_SIZE);
3775 if (!buf) {
3776 av_freep(&sc->sample_sizes);
3777 return AVERROR(ENOMEM);
3778 }
3779
3780 ret = ffio_read_size(pb, buf, num_bytes);
3781 if (ret < 0) {
3782 av_freep(&sc->sample_sizes);
3783 av_free(buf);
3784 av_log(c->fc, AV_LOG_WARNING, "STSZ atom truncated\n");
3785 return 0;
3786 }
3787
3788 init_get_bits(&gb, buf, 8*num_bytes);
3789
3790 for (i = 0; i < entries; i++) {
3791 sc->sample_sizes[i] = get_bits_long(&gb, field_size);
3792 if (sc->sample_sizes[i] > INT64_MAX - sc->data_size) {
3793 av_free(buf);
3794 av_log(c->fc, AV_LOG_ERROR, "Sample size overflow in STSZ\n");
3795 return AVERROR_INVALIDDATA;
3796 }
3797 sc->data_size += sc->sample_sizes[i];
3798 }
3799
3800 sc->sample_count = i;
3801
3802 av_free(buf);
3803
3804 return 0;
3805}
3806
3808{
3809 AVStream *st;
3810 MOVStreamContext *sc;
3811 unsigned int i, entries;
3812 int64_t duration = 0;
3813 int64_t total_sample_count = 0;
3814 int64_t current_dts = 0;
3815 int64_t corrected_dts = 0;
3816
3817 if (c->trak_index < 0) {
3818 av_log(c->fc, AV_LOG_WARNING, "STTS outside TRAK\n");
3819 return 0;
3820 }
3821
3822 if (c->fc->nb_streams < 1)
3823 return 0;
3824 st = c->fc->streams[c->fc->nb_streams-1];
3825 sc = st->priv_data;
3826
3827 avio_r8(pb); /* version */
3828 avio_rb24(pb); /* flags */
3829 entries = avio_rb32(pb);
3830
3831 av_log(c->fc, AV_LOG_TRACE, "track[%u].stts.entries = %u\n",
3832 c->fc->nb_streams-1, entries);
3833
3834 if (sc->stts_data)
3835 av_log(c->fc, AV_LOG_WARNING, "Duplicated STTS atom\n");
3836 av_freep(&sc->stts_data);
3837 sc->stts_count = 0;
3838 if (entries >= INT_MAX / sizeof(*sc->stts_data))
3839 return AVERROR(ENOMEM);
3840
3841 for (i = 0; i < entries && !pb->eof_reached; i++) {
3842 unsigned int sample_duration;
3843 unsigned int sample_count;
3844 unsigned int min_entries = FFMIN(FFMAX(i + 1, 1024 * 1024), entries);
3846 min_entries * sizeof(*sc->stts_data));
3847 if (!stts_data) {
3848 av_freep(&sc->stts_data);
3849 sc->stts_count = 0;
3850 return AVERROR(ENOMEM);
3851 }
3852 sc->stts_count = min_entries;
3853 sc->stts_data = stts_data;
3854
3855 sample_count = avio_rb32(pb);
3856 sample_duration = avio_rb32(pb);
3857
3858 sc->stts_data[i].count= sample_count;
3859 sc->stts_data[i].duration= sample_duration;
3860
3861 av_log(c->fc, AV_LOG_TRACE, "sample_count=%u, sample_duration=%u\n",
3862 sample_count, sample_duration);
3863
3864 /* STTS sample offsets are uint32 but some files store it as int32
3865 * with negative values used to correct DTS delays.
3866 There may be abnormally large values as well. */
3867 if (sample_duration > c->max_stts_delta) {
3868 // assume high delta is a correction if negative when cast as int32
3869 int32_t delta_magnitude = (int32_t)sample_duration;
3870 av_log(c->fc, AV_LOG_WARNING, "Too large sample offset %u in stts entry %u with count %u in st:%d. Clipping to 1.\n",
3871 sample_duration, i, sample_count, st->index);
3872 sc->stts_data[i].duration = 1;
3873 corrected_dts = av_sat_add64(corrected_dts, (delta_magnitude < 0 ? (int64_t)delta_magnitude : 1) * sample_count);
3874 } else {
3875 corrected_dts += sample_duration * (uint64_t)sample_count;
3876 }
3877
3878 current_dts += sc->stts_data[i].duration * (uint64_t)sample_count;
3879
3880 if (current_dts > corrected_dts) {
3881 int64_t drift = av_sat_sub64(current_dts, corrected_dts) / FFMAX(sample_count, 1);
3882 uint32_t correction = (sc->stts_data[i].duration > drift) ? drift : sc->stts_data[i].duration - 1;
3883 current_dts -= correction * (uint64_t)sample_count;
3884 sc->stts_data[i].duration -= correction;
3885 }
3886
3887 duration+=(int64_t)sc->stts_data[i].duration*(uint64_t)sc->stts_data[i].count;
3888 total_sample_count+=sc->stts_data[i].count;
3889 }
3890
3891 sc->stts_count = i;
3892
3893 if (duration > 0 &&
3894 duration <= INT64_MAX - sc->duration_for_fps &&
3895 total_sample_count <= INT_MAX - sc->nb_frames_for_fps) {
3897 sc->nb_frames_for_fps += total_sample_count;
3898 }
3899
3900 if (pb->eof_reached) {
3901 av_log(c->fc, AV_LOG_WARNING, "reached eof, corrupted STTS atom\n");
3902 return AVERROR_EOF;
3903 }
3904
3905 st->nb_frames= total_sample_count;
3906 if (duration)
3907 st->duration= FFMIN(st->duration, duration);
3908
3909 // All samples have zero duration. They have higher chance be chose by
3910 // mov_find_next_sample, which leads to seek again and again.
3911 //
3912 // It's AVERROR_INVALIDDATA actually, but such files exist in the wild.
3913 // So only mark data stream as discarded for safety.
3914 if (!duration && sc->stts_count &&
3916 av_log(c->fc, AV_LOG_WARNING,
3917 "All samples in data stream index:id [%d:%d] have zero "
3918 "duration, stream set to be discarded by default. Override "
3919 "using AVStream->discard or -discard for ffmpeg command.\n",
3920 st->index, sc->id);
3921 st->discard = AVDISCARD_ALL;
3922 }
3923 sc->track_end = duration;
3924 return 0;
3925}
3926
3928{
3929 AVStream *st;
3930 MOVStreamContext *sc;
3931 unsigned int i;
3932 int64_t entries;
3933
3934 if (c->fc->nb_streams < 1)
3935 return 0;
3936 st = c->fc->streams[c->fc->nb_streams - 1];
3937 sc = st->priv_data;
3938
3939 avio_r8(pb); /* version */
3940 avio_rb24(pb); /* flags */
3941 entries = atom.size - 4;
3942
3943 av_log(c->fc, AV_LOG_TRACE, "track[%u].sdtp.entries = %" PRId64 "\n",
3944 c->fc->nb_streams - 1, entries);
3945
3946 if (sc->sdtp_data)
3947 av_log(c->fc, AV_LOG_WARNING, "Duplicated SDTP atom\n");
3948 av_freep(&sc->sdtp_data);
3949 sc->sdtp_count = 0;
3950
3951 if (entries < 0 || entries > UINT_MAX)
3952 return AVERROR(ERANGE);
3953
3954 sc->sdtp_data = av_malloc(entries);
3955 if (!sc->sdtp_data)
3956 return AVERROR(ENOMEM);
3957
3958 for (i = 0; i < entries && !pb->eof_reached; i++)
3959 sc->sdtp_data[i] = avio_r8(pb);
3960 sc->sdtp_count = i;
3961
3962 return 0;
3963}
3964
3965static void mov_update_dts_shift(MOVStreamContext *sc, int duration, void *logctx)
3966{
3967 if (duration < 0) {
3968 if (duration == INT_MIN) {
3969 av_log(logctx, AV_LOG_WARNING, "mov_update_dts_shift(): dts_shift set to %d\n", INT_MAX);
3970 duration++;
3971 }
3972 sc->dts_shift = FFMAX(sc->dts_shift, -duration);
3973 }
3974}
3975
3977{
3978 AVStream *st;
3979 MOVStreamContext *sc;
3980 unsigned int i, entries, ctts_count = 0;
3981
3982 if (c->trak_index < 0) {
3983 av_log(c->fc, AV_LOG_WARNING, "CTTS outside TRAK\n");
3984 return 0;
3985 }
3986
3987 if (c->fc->nb_streams < 1)
3988 return 0;
3989 st = c->fc->streams[c->fc->nb_streams-1];
3990 sc = st->priv_data;
3991
3992 avio_r8(pb); /* version */
3993 avio_rb24(pb); /* flags */
3994 entries = avio_rb32(pb);
3995
3996 av_log(c->fc, AV_LOG_TRACE, "track[%u].ctts.entries = %u\n", c->fc->nb_streams - 1, entries);
3997
3998 if (!entries)
3999 return 0;
4000 if (entries >= UINT_MAX / sizeof(*sc->ctts_data))
4001 return AVERROR_INVALIDDATA;
4002 av_freep(&sc->ctts_data);
4003 sc->ctts_data = av_fast_realloc(NULL, &sc->ctts_allocated_size, entries * sizeof(*sc->ctts_data));
4004 if (!sc->ctts_data)
4005 return AVERROR(ENOMEM);
4006
4007 for (i = 0; i < entries && !pb->eof_reached; i++) {
4008 MOVCtts *ctts_data;
4009 const size_t min_size_needed = (ctts_count + 1) * sizeof(MOVCtts);
4010 const size_t requested_size =
4011 min_size_needed > sc->ctts_allocated_size ?
4012 FFMAX(min_size_needed, 2 * sc->ctts_allocated_size) :
4013 min_size_needed;
4014 int count = avio_rb32(pb);
4015 int duration = avio_rb32(pb);
4016
4017 if (count <= 0) {
4018 av_log(c->fc, AV_LOG_TRACE,
4019 "ignoring CTTS entry with count=%d duration=%d\n",
4020 count, duration);
4021 continue;
4022 }
4023
4024 if (ctts_count >= UINT_MAX / sizeof(MOVCtts) - 1)
4025 return AVERROR(ENOMEM);
4026
4027 ctts_data = av_fast_realloc(sc->ctts_data, &sc->ctts_allocated_size, requested_size);
4028
4029 if (!ctts_data)
4030 return AVERROR(ENOMEM);
4031
4032 sc->ctts_data = ctts_data;
4033
4034 ctts_data[ctts_count].count = count;
4035 ctts_data[ctts_count].offset = duration;
4036 ctts_count++;
4037
4038 av_log(c->fc, AV_LOG_TRACE, "count=%d, duration=%d\n",
4039 count, duration);
4040
4041 if (i+2<entries)
4043 }
4044
4045 sc->ctts_count = ctts_count;
4046
4047 if (pb->eof_reached) {
4048 av_log(c->fc, AV_LOG_WARNING, "reached eof, corrupted CTTS atom\n");
4049 return AVERROR_EOF;
4050 }
4051
4052 av_log(c->fc, AV_LOG_TRACE, "dts shift %d\n", sc->dts_shift);
4053
4054 return 0;
4055}
4056
4058{
4059 AVStream *st;
4060 MOVStreamContext *sc;
4061 uint8_t version;
4062 uint32_t grouping_type;
4063 uint32_t default_length;
4064 av_unused uint32_t default_group_description_index;
4065 uint32_t entry_count;
4066
4067 if (c->fc->nb_streams < 1)
4068 return 0;
4069 st = c->fc->streams[c->fc->nb_streams - 1];
4070 sc = st->priv_data;
4071
4072 version = avio_r8(pb); /* version */
4073 avio_rb24(pb); /* flags */
4074 grouping_type = avio_rl32(pb);
4075
4076 /*
4077 * This function only supports "sync" boxes, but the code is able to parse
4078 * other boxes (such as "tscl", "tsas" and "stsa")
4079 */
4080 if (grouping_type != MKTAG('s','y','n','c'))
4081 return 0;
4082
4083 default_length = version >= 1 ? avio_rb32(pb) : 0;
4084 default_group_description_index = version >= 2 ? avio_rb32(pb) : 0;
4085 entry_count = avio_rb32(pb);
4086
4087 if (entry_count > atom.size)
4088 return AVERROR_INVALIDDATA;
4089
4090 av_freep(&sc->sgpd_sync);
4091 sc->sgpd_sync_count = entry_count;
4092 sc->sgpd_sync = av_calloc(entry_count, sizeof(*sc->sgpd_sync));
4093 if (!sc->sgpd_sync)
4094 return AVERROR(ENOMEM);
4095
4096 for (uint32_t i = 0; i < entry_count && !pb->eof_reached; i++) {
4097 uint32_t description_length = default_length;
4098 if (version >= 1 && default_length == 0)
4099 description_length = avio_rb32(pb);
4100 if (grouping_type == MKTAG('s','y','n','c')) {
4101 const uint8_t nal_unit_type = avio_r8(pb) & 0x3f;
4102 sc->sgpd_sync[i] = nal_unit_type;
4103 description_length -= 1;
4104 }
4105 avio_skip(pb, description_length);
4106 }
4107
4108 if (pb->eof_reached) {
4109 av_log(c->fc, AV_LOG_WARNING, "reached eof, corrupted SGPD atom\n");
4110 return AVERROR_EOF;
4111 }
4112
4113 return 0;
4114}
4115
4117{
4118 AVStream *st;
4119 MOVStreamContext *sc;
4120 unsigned int i, entries;
4121 uint8_t version;
4122 uint32_t grouping_type;
4123 MOVSbgp *table, **tablep;
4124 int *table_count;
4125
4126 if (c->fc->nb_streams < 1)
4127 return 0;
4128 st = c->fc->streams[c->fc->nb_streams-1];
4129 sc = st->priv_data;
4130
4131 version = avio_r8(pb); /* version */
4132 avio_rb24(pb); /* flags */
4133 grouping_type = avio_rl32(pb);
4134
4135 if (grouping_type == MKTAG('r','a','p',' ')) {
4136 tablep = &sc->rap_group;
4137 table_count = &sc->rap_group_count;
4138 } else if (grouping_type == MKTAG('s','y','n','c')) {
4139 tablep = &sc->sync_group;
4140 table_count = &sc->sync_group_count;
4141 } else {
4142 return 0;
4143 }
4144
4145 if (version == 1)
4146 avio_rb32(pb); /* grouping_type_parameter */
4147
4148 entries = avio_rb32(pb);
4149 if (!entries)
4150 return 0;
4151 if (*tablep)
4152 av_log(c->fc, AV_LOG_WARNING, "Duplicated SBGP %s atom\n", av_fourcc2str(grouping_type));
4153 av_freep(tablep);
4154 table = av_malloc_array(entries, sizeof(*table));
4155 if (!table)
4156 return AVERROR(ENOMEM);
4157 *tablep = table;
4158
4159 for (i = 0; i < entries && !pb->eof_reached; i++) {
4160 table[i].count = avio_rb32(pb); /* sample_count */
4161 table[i].index = avio_rb32(pb); /* group_description_index */
4162 }
4163
4164 *table_count = i;
4165
4166 if (pb->eof_reached) {
4167 av_log(c->fc, AV_LOG_WARNING, "reached eof, corrupted SBGP atom\n");
4168 return AVERROR_EOF;
4169 }
4170
4171 return 0;
4172}
4173
4174/**
4175 * Get ith edit list entry (media time, duration).
4176 */
4178 const MOVStreamContext *msc,
4179 unsigned int edit_list_index,
4180 int64_t *edit_list_media_time,
4181 int64_t *edit_list_duration,
4182 int64_t global_timescale)
4183{
4184 if (edit_list_index == msc->elst_count) {
4185 return 0;
4186 }
4187 *edit_list_media_time = msc->elst_data[edit_list_index].time;
4188 *edit_list_duration = msc->elst_data[edit_list_index].duration;
4189
4190 /* duration is in global timescale units;convert to msc timescale */
4191 if (global_timescale == 0) {
4192 avpriv_request_sample(mov->fc, "Support for mvhd.timescale = 0 with editlists");
4193 return 0;
4194 }
4195 *edit_list_duration = av_rescale(*edit_list_duration, msc->time_scale,
4196 global_timescale);
4197
4198 if (*edit_list_duration + (uint64_t)*edit_list_media_time > INT64_MAX)
4199 *edit_list_duration = 0;
4200
4201 return 1;
4202}
4203
4204/**
4205 * Find the closest previous frame to the timestamp_pts, in e_old index
4206 * entries. Searching for just any frame / just key frames can be controlled by
4207 * last argument 'flag'.
4208 * Note that if ctts_data is not NULL, we will always search for a key frame
4209 * irrespective of the value of 'flag'. If we don't find any keyframe, we will
4210 * return the first frame of the video.
4211 *
4212 * Here the timestamp_pts is considered to be a presentation timestamp and
4213 * the timestamp of index entries are considered to be decoding timestamps.
4214 *
4215 * Returns 0 if successful in finding a frame, else returns -1.
4216 * Places the found index corresponding output arg.
4217 *
4218 * If ctts_old is not NULL, then refines the searched entry by searching
4219 * backwards from the found timestamp, to find the frame with correct PTS.
4220 *
4221 * Places the found ctts_index and ctts_sample in corresponding output args.
4222 */
4224 AVIndexEntry *e_old,
4225 int nb_old,
4226 MOVTimeToSample *tts_data,
4227 int64_t tts_count,
4228 int64_t timestamp_pts,
4229 int flag,
4230 int64_t* index,
4231 int64_t* tts_index,
4232 int64_t* tts_sample)
4233{
4234 MOVStreamContext *msc = st->priv_data;
4235 FFStream *const sti = ffstream(st);
4236 AVIndexEntry *e_keep = sti->index_entries;
4237 int nb_keep = sti->nb_index_entries;
4238 int64_t i = 0;
4239
4241
4242 // If dts_shift > 0, then all the index timestamps will have to be offset by
4243 // at least dts_shift amount to obtain PTS.
4244 // Hence we decrement the searched timestamp_pts by dts_shift to find the closest index element.
4245 if (msc->dts_shift > 0) {
4246 timestamp_pts -= msc->dts_shift;
4247 }
4248
4249 sti->index_entries = e_old;
4250 sti->nb_index_entries = nb_old;
4252
4253 // Keep going backwards in the index entries until the timestamp is the same.
4254 if (*index >= 0) {
4255 for (i = *index; i > 0 && e_old[i].timestamp == e_old[i - 1].timestamp;
4256 i--) {
4257 if ((flag & AVSEEK_FLAG_ANY) ||
4258 (e_old[i - 1].flags & AVINDEX_KEYFRAME)) {
4259 *index = i - 1;
4260 }
4261 }
4262 }
4263
4264 // If we have CTTS then refine the search, by searching backwards over PTS
4265 // computed by adding corresponding CTTS durations to index timestamps.
4266 if (msc->ctts_count && *index >= 0) {
4267 av_assert0(tts_index);
4268 av_assert0(tts_sample);
4269 // Find out the ctts_index for the found frame.
4270 *tts_index = 0;
4271 *tts_sample = 0;
4272 for (int64_t index_tts_count = 0; index_tts_count < *index; index_tts_count++) {
4273 if (*tts_index < tts_count) {
4274 (*tts_sample)++;
4275 if (tts_data[*tts_index].count == *tts_sample) {
4276 (*tts_index)++;
4277 *tts_sample = 0;
4278 }
4279 }
4280 }
4281
4282 while (*index >= 0 && (*tts_index) >= 0 && (*tts_index) < tts_count) {
4283 // Find a "key frame" with PTS <= timestamp_pts (So that we can decode B-frames correctly).
4284 // No need to add dts_shift to the timestamp here because timestamp_pts has already been
4285 // compensated by dts_shift above.
4286 if ((e_old[*index].timestamp + tts_data[*tts_index].offset) <= timestamp_pts &&
4287 (e_old[*index].flags & AVINDEX_KEYFRAME)) {
4288 break;
4289 }
4290
4291 (*index)--;
4292 if (*tts_sample == 0) {
4293 (*tts_index)--;
4294 if (*tts_index >= 0)
4295 *tts_sample = tts_data[*tts_index].count - 1;
4296 } else {
4297 (*tts_sample)--;
4298 }
4299 }
4300 }
4301
4302 /* restore AVStream state*/
4303 sti->index_entries = e_keep;
4304 sti->nb_index_entries = nb_keep;
4305 return *index >= 0 ? 0 : -1;
4306}
4307
4308/**
4309 * Add index entry with the given values, to the end of ffstream(st)->index_entries.
4310 * Returns the new size ffstream(st)->index_entries if successful, else returns -1.
4311 *
4312 * This function is similar to ff_add_index_entry in libavformat/utils.c
4313 * except that here we are always unconditionally adding an index entry to
4314 * the end, instead of searching the entries list and skipping the add if
4315 * there is an existing entry with the same timestamp.
4316 * This is needed because the mov_fix_index calls this func with the same
4317 * unincremented timestamp for successive discarded frames.
4318 */
4320 int size, int distance, int flags)
4321{
4322 FFStream *const sti = ffstream(st);
4323 AVIndexEntry *entries, *ie;
4324 int64_t index = -1;
4325 const size_t min_size_needed = (sti->nb_index_entries + 1) * sizeof(AVIndexEntry);
4326
4327 // Double the allocation each time, to lower memory fragmentation.
4328 // Another difference from ff_add_index_entry function.
4329 const size_t requested_size =
4330 min_size_needed > sti->index_entries_allocated_size ?
4331 FFMAX(min_size_needed, 2 * sti->index_entries_allocated_size) :
4332 min_size_needed;
4333
4334 if (sti->nb_index_entries + 1U >= UINT_MAX / sizeof(AVIndexEntry))
4335 return -1;
4336
4337 entries = av_fast_realloc(sti->index_entries,
4339 requested_size);
4340 if (!entries)
4341 return -1;
4342
4343 sti->index_entries = entries;
4344
4345 index = sti->nb_index_entries++;
4346 ie= &entries[index];
4347
4348 ie->pos = pos;
4349 ie->timestamp = timestamp;
4351 ie->size= size;
4352 ie->flags = flags;
4353 return index;
4354}
4355
4356/**
4357 * Rewrite timestamps of index entries in the range [end_index - frame_duration_buffer_size, end_index)
4358 * by subtracting end_ts successively by the amounts given in frame_duration_buffer.
4359 */
4360static void fix_index_entry_timestamps(AVStream* st, int end_index, int64_t end_ts,
4361 int64_t* frame_duration_buffer,
4362 int frame_duration_buffer_size) {
4363 FFStream *const sti = ffstream(st);
4364 int i = 0;
4365 av_assert0(end_index >= 0 && end_index <= sti->nb_index_entries);
4366 for (i = 0; i < frame_duration_buffer_size; i++) {
4367 end_ts -= frame_duration_buffer[frame_duration_buffer_size - 1 - i];
4368 sti->index_entries[end_index - 1 - i].timestamp = end_ts;
4369 }
4370}
4371
4372static int add_tts_entry(MOVTimeToSample **tts_data, unsigned int *tts_count, unsigned int *allocated_size,
4373 int count, int offset, unsigned int duration)
4374{
4375 MOVTimeToSample *tts_buf_new;
4376 const size_t min_size_needed = (*tts_count + 1) * sizeof(MOVTimeToSample);
4377 const size_t requested_size =
4378 min_size_needed > *allocated_size ?
4379 FFMAX(min_size_needed, 2 * (*allocated_size)) :
4380 min_size_needed;
4381
4382 if ((unsigned)(*tts_count) >= UINT_MAX / sizeof(MOVTimeToSample) - 1)
4383 return -1;
4384
4385 tts_buf_new = av_fast_realloc(*tts_data, allocated_size, requested_size);
4386
4387 if (!tts_buf_new)
4388 return -1;
4389
4390 *tts_data = tts_buf_new;
4391
4392 tts_buf_new[*tts_count].count = count;
4393 tts_buf_new[*tts_count].offset = offset;
4394 tts_buf_new[*tts_count].duration = duration;
4395
4396 *tts_count = (*tts_count) + 1;
4397 return 0;
4398}
4399
4400#define MAX_REORDER_DELAY 16
4402{
4403 MOVStreamContext *msc = st->priv_data;
4404 FFStream *const sti = ffstream(st);
4405 int ctts_ind = 0;
4406 int ctts_sample = 0;
4407 int64_t pts_buf[MAX_REORDER_DELAY + 1]; // Circular buffer to sort pts.
4408 int buf_start = 0;
4409 int j, r, num_swaps;
4410
4411 for (j = 0; j < MAX_REORDER_DELAY + 1; j++)
4412 pts_buf[j] = INT64_MIN;
4413
4414 if (st->codecpar->video_delay <= 0 && msc->ctts_count &&
4416 st->codecpar->video_delay = 0;
4417 for (int ind = 0; ind < sti->nb_index_entries && ctts_ind < msc->tts_count; ++ind) {
4418 // Point j to the last elem of the buffer and insert the current pts there.
4419 j = buf_start;
4420 buf_start = (buf_start + 1);
4421 if (buf_start == MAX_REORDER_DELAY + 1)
4422 buf_start = 0;
4423
4424 pts_buf[j] = sti->index_entries[ind].timestamp + msc->tts_data[ctts_ind].offset;
4425
4426 // The timestamps that are already in the sorted buffer, and are greater than the
4427 // current pts, are exactly the timestamps that need to be buffered to output PTS
4428 // in correct sorted order.
4429 // Hence the video delay (which is the buffer size used to sort DTS and output PTS),
4430 // can be computed as the maximum no. of swaps any particular timestamp needs to
4431 // go through, to keep this buffer in sorted order.
4432 num_swaps = 0;
4433 while (j != buf_start) {
4434 r = j - 1;
4435 if (r < 0) r = MAX_REORDER_DELAY;
4436 if (pts_buf[j] < pts_buf[r]) {
4437 FFSWAP(int64_t, pts_buf[j], pts_buf[r]);
4438 ++num_swaps;
4439 } else {
4440 break;
4441 }
4442 j = r;
4443 }
4444 st->codecpar->video_delay = FFMAX(st->codecpar->video_delay, num_swaps);
4445
4446 ctts_sample++;
4447 if (ctts_sample == msc->tts_data[ctts_ind].count) {
4448 ctts_ind++;
4449 ctts_sample = 0;
4450 }
4451 }
4452 av_log(c->fc, AV_LOG_DEBUG, "Setting codecpar->delay to %d for stream st: %d\n",
4453 st->codecpar->video_delay, st->index);
4454 }
4455}
4456
4458{
4459 sc->current_sample++;
4460 sc->current_index++;
4461 if (sc->index_ranges &&
4463 sc->current_index_range->end) {
4464 sc->current_index_range++;
4466 }
4467}
4468
4470{
4471 sc->current_sample--;
4472 sc->current_index--;
4473 if (sc->index_ranges &&
4476 sc->current_index_range--;
4477 sc->current_index = sc->current_index_range->end - 1;
4478 }
4479}
4480
4481static void mov_current_sample_set(MOVStreamContext *sc, int current_sample)
4482{
4483 int64_t range_size;
4484
4485 sc->current_sample = current_sample;
4486 sc->current_index = current_sample;
4487 if (!sc->index_ranges) {
4488 return;
4489 }
4490
4491 for (sc->current_index_range = sc->index_ranges;
4493 sc->current_index_range++) {
4494 range_size = sc->current_index_range->end - sc->current_index_range->start;
4495 if (range_size > current_sample) {
4496 sc->current_index = sc->current_index_range->start + current_sample;
4497 break;
4498 }
4499 current_sample -= range_size;
4500 }
4501}
4502
4503/**
4504 * Fix ffstream(st)->index_entries, so that it contains only the entries (and the entries
4505 * which are needed to decode them) that fall in the edit list time ranges.
4506 * Also fixes the timestamps of the index entries to match the timeline
4507 * specified the edit lists.
4508 */
4509static void mov_fix_index(MOVContext *mov, AVStream *st)
4510{
4511 MOVStreamContext *msc = st->priv_data;
4512 FFStream *const sti = ffstream(st);
4513 AVIndexEntry *e_old = sti->index_entries;
4514 int nb_old = sti->nb_index_entries;
4515 const AVIndexEntry *e_old_end = e_old + nb_old;
4516 const AVIndexEntry *current = NULL;
4517 MOVTimeToSample *tts_data_old = msc->tts_data;
4518 int64_t tts_index_old = 0;
4519 int64_t tts_sample_old = 0;
4520 int64_t tts_count_old = msc->tts_count;
4521 int64_t edit_list_media_time = 0;
4522 int64_t edit_list_duration = 0;
4523 int64_t frame_duration = 0;
4524 int64_t edit_list_dts_counter = 0;
4525 int64_t edit_list_dts_entry_end = 0;
4526 int64_t edit_list_start_tts_sample = 0;
4527 int64_t curr_cts;
4528 int64_t curr_ctts = 0;
4529 int64_t empty_edits_sum_duration = 0;
4530 int64_t edit_list_index = 0;
4531 int64_t index;
4532 int flags;
4533 int64_t start_dts = 0;
4534 int64_t edit_list_start_encountered = 0;
4535 int64_t search_timestamp = 0;
4536 int64_t* frame_duration_buffer = NULL;
4537 int num_discarded_begin = 0;
4538 int first_non_zero_audio_edit = -1;
4539 int packet_skip_samples = 0;
4540 MOVIndexRange *current_index_range = NULL;
4541 int found_keyframe_after_edit = 0;
4542 int found_non_empty_edit = 0;
4543
4544 if (!msc->elst_data || msc->elst_count <= 0 || nb_old <= 0) {
4545 return;
4546 }
4547
4548 // allocate the index ranges array
4549 msc->index_ranges = av_malloc_array(msc->elst_count + 1,
4550 sizeof(msc->index_ranges[0]));
4551 if (!msc->index_ranges) {
4552 av_log(mov->fc, AV_LOG_ERROR, "Cannot allocate index ranges buffer\n");
4553 return;
4554 }
4556
4557 // Clean AVStream from traces of old index
4558 sti->index_entries = NULL;
4560 sti->nb_index_entries = 0;
4561
4562 // Clean time to sample fields of MOVStreamContext
4563 msc->tts_data = NULL;
4564 msc->tts_count = 0;
4565 msc->tts_index = 0;
4566 msc->tts_sample = 0;
4567 msc->tts_allocated_size = 0;
4568
4569 // Reinitialize min_corrected_pts so that it can be computed again.
4570 msc->min_corrected_pts = -1;
4571
4572 // If the dts_shift is positive (in case of negative ctts values in mov),
4573 // then negate the DTS by dts_shift
4574 if (msc->dts_shift > 0) {
4575 edit_list_dts_entry_end -= msc->dts_shift;
4576 av_log(mov->fc, AV_LOG_DEBUG, "Shifting DTS by %d because of negative CTTS.\n", msc->dts_shift);
4577 }
4578
4579 start_dts = edit_list_dts_entry_end;
4580
4581 while (get_edit_list_entry(mov, msc, edit_list_index, &edit_list_media_time,
4582 &edit_list_duration, mov->time_scale)) {
4583 av_log(mov->fc, AV_LOG_DEBUG, "Processing st: %d, edit list %"PRId64" - media time: %"PRId64", duration: %"PRId64"\n",
4584 st->index, edit_list_index, edit_list_media_time, edit_list_duration);
4585 edit_list_index++;
4586 edit_list_dts_counter = edit_list_dts_entry_end;
4587 edit_list_dts_entry_end = av_sat_add64(edit_list_dts_entry_end, edit_list_duration);
4588 if (edit_list_dts_entry_end == INT64_MAX) {
4589 av_log(mov->fc, AV_LOG_ERROR, "Cannot calculate dts entry length with duration %"PRId64"\n",
4590 edit_list_duration);
4591 break;
4592 }
4593 num_discarded_begin = 0;
4594 if (!found_non_empty_edit && edit_list_media_time == -1) {
4595 empty_edits_sum_duration += edit_list_duration;
4596 continue;
4597 }
4598 found_non_empty_edit = 1;
4599
4600 // If we encounter a non-negative edit list reset the skip_samples/initial_padding fields and set them
4601 // according to the edit list below.
4603 if (first_non_zero_audio_edit < 0) {
4604 first_non_zero_audio_edit = 1;
4605 } else {
4606 first_non_zero_audio_edit = 0;
4607 }
4608
4609 if (first_non_zero_audio_edit > 0)
4610 sti->skip_samples = st->codecpar->initial_padding = 0;
4611 }
4612
4613 // While reordering frame index according to edit list we must handle properly
4614 // the scenario when edit list entry starts from none key frame.
4615 // We find closest previous key frame and preserve it and consequent frames in index.
4616 // All frames which are outside edit list entry time boundaries will be dropped after decoding.
4617 search_timestamp = edit_list_media_time;
4619 // Audio decoders like AAC need need a decoder delay samples previous to the current sample,
4620 // to correctly decode this frame. Hence for audio we seek to a frame 1 sec. before the
4621 // edit_list_media_time to cover the decoder delay.
4622 search_timestamp = FFMAX(search_timestamp - msc->time_scale, e_old[0].timestamp);
4623 }
4624
4625 if (find_prev_closest_index(st, e_old, nb_old, tts_data_old, tts_count_old, search_timestamp, 0,
4626 &index, &tts_index_old, &tts_sample_old) < 0) {
4627 av_log(mov->fc, AV_LOG_WARNING,
4628 "st: %d edit list: %"PRId64" Missing key frame while searching for timestamp: %"PRId64"\n",
4629 st->index, edit_list_index, search_timestamp);
4630 if (find_prev_closest_index(st, e_old, nb_old, tts_data_old, tts_count_old, search_timestamp, AVSEEK_FLAG_ANY,
4631 &index, &tts_index_old, &tts_sample_old) < 0) {
4632 av_log(mov->fc, AV_LOG_WARNING,
4633 "st: %d edit list %"PRId64" Cannot find an index entry before timestamp: %"PRId64".\n",
4634 st->index, edit_list_index, search_timestamp);
4635 index = 0;
4636 tts_index_old = 0;
4637 tts_sample_old = 0;
4638 }
4639 }
4640 current = e_old + index;
4641 edit_list_start_tts_sample = tts_sample_old;
4642
4643 // Iterate over index and arrange it according to edit list
4644 edit_list_start_encountered = 0;
4645 found_keyframe_after_edit = 0;
4646 for (; current < e_old_end; current++, index++) {
4647 // check if frame outside edit list mark it for discard
4648 frame_duration = (current + 1 < e_old_end) ?
4649 ((current + 1)->timestamp - current->timestamp) : edit_list_duration;
4650
4651 flags = current->flags;
4652
4653 // frames (pts) before or after edit list
4654 curr_cts = current->timestamp + msc->dts_shift;
4655 curr_ctts = 0;
4656
4657 if (tts_data_old && tts_index_old < tts_count_old) {
4658 curr_ctts = tts_data_old[tts_index_old].offset;
4659 av_log(mov->fc, AV_LOG_TRACE, "stts: %"PRId64" ctts: %"PRId64", tts_index: %"PRId64", tts_count: %"PRId64"\n",
4660 curr_cts, curr_ctts, tts_index_old, tts_count_old);
4661 curr_cts += curr_ctts;
4662 tts_sample_old++;
4663 if (tts_sample_old == tts_data_old[tts_index_old].count) {
4664 if (add_tts_entry(&msc->tts_data, &msc->tts_count,
4665 &msc->tts_allocated_size,
4666 tts_data_old[tts_index_old].count - edit_list_start_tts_sample,
4667 tts_data_old[tts_index_old].offset, tts_data_old[tts_index_old].duration) == -1) {
4668 av_log(mov->fc, AV_LOG_ERROR, "Cannot add Time To Sample entry %"PRId64" - {%"PRId64", %d}\n",
4669 tts_index_old,
4670 tts_data_old[tts_index_old].count - edit_list_start_tts_sample,
4671 tts_data_old[tts_index_old].offset);
4672 break;
4673 }
4674 tts_index_old++;
4675 tts_sample_old = 0;
4676 edit_list_start_tts_sample = 0;
4677 }
4678 }
4679
4680 if (curr_cts < edit_list_media_time || curr_cts >= (edit_list_duration + edit_list_media_time)) {
4682 curr_cts < edit_list_media_time && curr_cts + frame_duration > edit_list_media_time &&
4683 first_non_zero_audio_edit > 0) {
4684 packet_skip_samples = edit_list_media_time - curr_cts;
4685 sti->skip_samples += packet_skip_samples;
4686
4687 // Shift the index entry timestamp by packet_skip_samples to be correct.
4688 edit_list_dts_counter -= packet_skip_samples;
4689 if (edit_list_start_encountered == 0) {
4690 edit_list_start_encountered = 1;
4691 // Make timestamps strictly monotonically increasing for audio, by rewriting timestamps for
4692 // discarded packets.
4693 if (frame_duration_buffer) {
4694 fix_index_entry_timestamps(st, sti->nb_index_entries, edit_list_dts_counter,
4695 frame_duration_buffer, num_discarded_begin);
4696 av_freep(&frame_duration_buffer);
4697 }
4698 }
4699
4700 av_log(mov->fc, AV_LOG_DEBUG, "skip %d audio samples from curr_cts: %"PRId64"\n", packet_skip_samples, curr_cts);
4701 } else {
4703 av_log(mov->fc, AV_LOG_DEBUG, "drop a frame at curr_cts: %"PRId64" @ %"PRId64"\n", curr_cts, index);
4704
4705 if (edit_list_start_encountered == 0) {
4706 num_discarded_begin++;
4707 frame_duration_buffer = av_realloc(frame_duration_buffer,
4708 num_discarded_begin * sizeof(int64_t));
4709 if (!frame_duration_buffer) {
4710 av_log(mov->fc, AV_LOG_ERROR, "Cannot reallocate frame duration buffer\n");
4711 break;
4712 }
4713 frame_duration_buffer[num_discarded_begin - 1] = frame_duration;
4714
4715 // Increment skip_samples for the first non-zero audio edit list
4717 first_non_zero_audio_edit > 0 && st->codecpar->codec_id != AV_CODEC_ID_VORBIS) {
4718 sti->skip_samples += frame_duration;
4719 }
4720 }
4721 }
4722 } else {
4723 if (msc->min_corrected_pts < 0) {
4724 msc->min_corrected_pts = edit_list_dts_counter + curr_ctts + msc->dts_shift;
4725 } else {
4726 msc->min_corrected_pts = FFMIN(msc->min_corrected_pts, edit_list_dts_counter + curr_ctts + msc->dts_shift);
4727 }
4728 if (edit_list_start_encountered == 0) {
4729 edit_list_start_encountered = 1;
4730 // Make timestamps strictly monotonically increasing by rewriting timestamps for
4731 // discarded packets.
4732 if (frame_duration_buffer) {
4733 fix_index_entry_timestamps(st, sti->nb_index_entries, edit_list_dts_counter,
4734 frame_duration_buffer, num_discarded_begin);
4735 av_freep(&frame_duration_buffer);
4736 }
4737 }
4738 }
4739
4740 if (add_index_entry(st, current->pos, edit_list_dts_counter, current->size,
4741 current->min_distance, flags) == -1) {
4742 av_log(mov->fc, AV_LOG_ERROR, "Cannot add index entry\n");
4743 break;
4744 }
4745
4746 // Update the index ranges array
4747 if (!current_index_range || index != current_index_range->end) {
4748 current_index_range = current_index_range ? current_index_range + 1
4749 : msc->index_ranges;
4750 current_index_range->start = index;
4751 }
4752 current_index_range->end = index + 1;
4753
4754 // Only start incrementing DTS in frame_duration amounts, when we encounter a frame in edit list.
4755 if (edit_list_start_encountered > 0) {
4756 edit_list_dts_counter = edit_list_dts_counter + frame_duration;
4757 }
4758
4759 // Break when found first key frame after edit entry completion
4760 if ((curr_cts + frame_duration >= (edit_list_duration + edit_list_media_time)) &&
4762 if (msc->ctts_count) {
4763 // If we have CTTS and this is the first keyframe after edit elist,
4764 // wait for one more, because there might be trailing B-frames after this I-frame
4765 // that do belong to the edit.
4766 if (st->codecpar->codec_type != AVMEDIA_TYPE_AUDIO && found_keyframe_after_edit == 0) {
4767 found_keyframe_after_edit = 1;
4768 continue;
4769 }
4770 if (tts_sample_old != 0) {
4771 if (add_tts_entry(&msc->tts_data, &msc->tts_count,
4772 &msc->tts_allocated_size,
4773 tts_sample_old - edit_list_start_tts_sample,
4774 tts_data_old[tts_index_old].offset, tts_data_old[tts_index_old].duration) == -1) {
4775 av_log(mov->fc, AV_LOG_ERROR, "Cannot add Time To Sample entry %"PRId64" - {%"PRId64", %d}\n",
4776 tts_index_old, tts_sample_old - edit_list_start_tts_sample,
4777 tts_data_old[tts_index_old].offset);
4778 break;
4779 }
4780 }
4781 }
4782 break;
4783 }
4784 }
4785 }
4786 // If there are empty edits, then msc->min_corrected_pts might be positive
4787 // intentionally. So we subtract the sum duration of empty edits here.
4788 msc->min_corrected_pts -= empty_edits_sum_duration;
4789
4790 // If the minimum pts turns out to be greater than zero after fixing the index, then we subtract the
4791 // dts by that amount to make the first pts zero.
4793 if (msc->min_corrected_pts > 0) {
4794 av_log(mov->fc, AV_LOG_DEBUG, "Offset DTS by %"PRId64" to make first pts zero.\n", msc->min_corrected_pts);
4795 for (int i = 0; i < sti->nb_index_entries; ++i)
4797 }
4798 }
4799 // Start time should be equal to zero or the duration of any empty edits.
4800 st->start_time = empty_edits_sum_duration;
4801
4802 // Update av stream length, if it ends up shorter than the track's media duration
4803 st->duration = FFMIN(st->duration, edit_list_dts_entry_end - start_dts);
4805
4806 // Free the old index and the old CTTS structures
4807 av_free(e_old);
4808 av_free(tts_data_old);
4809 av_freep(&frame_duration_buffer);
4810
4811 // Null terminate the index ranges array
4812 current_index_range = current_index_range ? current_index_range + 1
4813 : msc->index_ranges;
4814 current_index_range->start = 0;
4815 current_index_range->end = 0;
4816 msc->current_index = msc->index_ranges[0].start;
4817}
4818
4819static uint32_t get_sgpd_sync_index(const MOVStreamContext *sc, int nal_unit_type)
4820{
4821 for (uint32_t i = 0; i < sc->sgpd_sync_count; i++)
4822 if (sc->sgpd_sync[i] == nal_unit_type)
4823 return i + 1;
4824 return 0;
4825}
4826
4828{
4829 int k;
4830 int sample_id = 0;
4831 uint32_t cra_index;
4832 MOVStreamContext *sc = st->priv_data;
4833
4835 return 0;
4836
4837 /* Build an unrolled index of the samples */
4838 sc->sample_offsets_count = 0;
4839 for (uint32_t i = 0; i < sc->ctts_count; i++) {
4840 if (sc->ctts_data[i].count > INT_MAX - sc->sample_offsets_count)
4841 return AVERROR(ENOMEM);
4843 }
4846 if (!sc->sample_offsets)
4847 return AVERROR(ENOMEM);
4848 k = 0;
4849 for (uint32_t i = 0; i < sc->ctts_count; i++)
4850 for (int j = 0; j < sc->ctts_data[i].count; j++)
4851 sc->sample_offsets[k++] = sc->ctts_data[i].offset;
4852
4853 /* The following HEVC NAL type reveal the use of open GOP sync points
4854 * (TODO: BLA types may also be concerned) */
4855 cra_index = get_sgpd_sync_index(sc, HEVC_NAL_CRA_NUT); /* Clean Random Access */
4856 if (!cra_index)
4857 return 0;
4858
4859 /* Build a list of open-GOP key samples */
4860 sc->open_key_samples_count = 0;
4861 for (uint32_t i = 0; i < sc->sync_group_count; i++)
4862 if (sc->sync_group[i].index == cra_index) {
4863 if (sc->sync_group[i].count > INT_MAX - sc->open_key_samples_count)
4864 return AVERROR(ENOMEM);
4866 }
4869 if (!sc->open_key_samples)
4870 return AVERROR(ENOMEM);
4871 k = 0;
4872 for (uint32_t i = 0; i < sc->sync_group_count; i++) {
4873 const MOVSbgp *sg = &sc->sync_group[i];
4874 if (sg->index == cra_index)
4875 for (uint32_t j = 0; j < sg->count; j++)
4876 sc->open_key_samples[k++] = sample_id;
4877 if (sg->count > INT_MAX - sample_id)
4878 return AVERROR_PATCHWELCOME;
4879 sample_id += sg->count;
4880 }
4881
4882 /* Identify the minimal time step between samples */
4883 sc->min_sample_duration = UINT_MAX;
4884 for (uint32_t i = 0; i < sc->stts_count; i++)
4886
4887 return 0;
4888}
4889
4890#define MOV_MERGE_CTTS 1
4891#define MOV_MERGE_STTS 2
4892/*
4893 * Merge stts and ctts arrays into a new combined array.
4894 * stts_count and ctts_count may be left untouched as they will be
4895 * used to check for the presence of either of them.
4896 */
4898{
4899 MOVStreamContext *sc = st->priv_data;
4900 int ctts = sc->ctts_data && (flags & MOV_MERGE_CTTS);
4901 int stts = sc->stts_data && (flags & MOV_MERGE_STTS);
4902 int idx = 0;
4903
4904 if (!sc->ctts_data && !sc->stts_data)
4905 return 0;
4906 // Expand time to sample entries such that we have a 1-1 mapping with samples
4907 if (!sc->sample_count || sc->sample_count >= UINT_MAX / sizeof(*sc->tts_data))
4908 return -1;
4909
4910 if (ctts) {
4912 sc->sample_count * sizeof(*sc->tts_data));
4913 if (!sc->tts_data)
4914 return -1;
4915
4916 memset(sc->tts_data, 0, sc->tts_allocated_size);
4917
4918 for (int i = 0; i < sc->ctts_count &&
4919 idx < sc->sample_count; i++)
4920 for (int j = 0; j < sc->ctts_data[i].count &&
4921 idx < sc->sample_count; j++) {
4922 sc->tts_data[idx].offset = sc->ctts_data[i].offset;
4923 sc->tts_data[idx++].count = 1;
4924 }
4925
4926 sc->tts_count = idx;
4927 } else
4928 sc->ctts_count = 0;
4929 av_freep(&sc->ctts_data);
4930 sc->ctts_allocated_size = 0;
4931
4932 idx = 0;
4933 if (stts) {
4935 sc->sample_count * sizeof(*sc->tts_data));
4936 if (!tts_data)
4937 return -1;
4938
4939 if (!sc->tts_data)
4940 memset(tts_data, 0, sc->tts_allocated_size);
4941 sc->tts_data = tts_data;
4942
4943 for (int i = 0; i < sc->stts_count &&
4944 idx < sc->sample_count; i++)
4945 for (int j = 0; j < sc->stts_data[i].count &&
4946 idx < sc->sample_count; j++) {
4947 sc->tts_data[idx].duration = sc->stts_data[i].duration;
4948 sc->tts_data[idx++].count = 1;
4949 }
4950
4951 sc->tts_count = FFMAX(sc->tts_count, idx);
4952 } else
4953 sc->stts_count = 0;
4954 av_freep(&sc->stts_data);
4955 sc->stts_allocated_size = 0;
4956
4957 return 0;
4958}
4959
4961{
4962 MOVStreamContext *sc = st->priv_data;
4963 FFStream *const sti = ffstream(st);
4964 int64_t current_offset;
4965 int64_t current_dts = 0;
4966 unsigned int stts_index = 0;
4967 unsigned int stsc_index = 0;
4968 unsigned int stss_index = 0;
4969 unsigned int stps_index = 0;
4970 unsigned int i, j;
4971 uint64_t stream_size = 0;
4972
4973 int ret = build_open_gop_key_points(st);
4974 if (ret < 0)
4975 return;
4976
4977 if (sc->elst_count) {
4978 int i, edit_start_index = 0, multiple_edits = 0;
4979 int64_t empty_duration = 0; // empty duration of the first edit list entry
4980 int64_t start_time = 0; // start time of the media
4981
4982 for (i = 0; i < sc->elst_count; i++) {
4983 const MOVElst *e = &sc->elst_data[i];
4984 if (i == 0 && e->time == -1) {
4985 /* if empty, the first entry is the start time of the stream
4986 * relative to the presentation itself */
4987 empty_duration = e->duration;
4988 edit_start_index = 1;
4989 } else if (i == edit_start_index && e->time >= 0) {
4990 start_time = e->time;
4991 } else {
4992 multiple_edits = 1;
4993 }
4994 }
4995
4996 if (multiple_edits && !mov->advanced_editlist) {
4998 av_log(mov->fc, AV_LOG_WARNING, "multiple edit list entries, "
4999 "not supported in fragmented MP4 files\n");
5000 else
5001 av_log(mov->fc, AV_LOG_WARNING, "multiple edit list entries, "
5002 "Use -advanced_editlist to correctly decode otherwise "
5003 "a/v desync might occur\n");
5004 }
5005
5006 /* adjust first dts according to edit list */
5007 if ((empty_duration || start_time) && mov->time_scale > 0) {
5008 if (empty_duration)
5009 empty_duration = av_rescale(empty_duration, sc->time_scale, mov->time_scale);
5010
5011 if (av_sat_sub64(start_time, empty_duration) != start_time - (uint64_t)empty_duration)
5012 av_log(mov->fc, AV_LOG_WARNING, "start_time - empty_duration is not representable\n");
5013
5014 sc->time_offset = start_time - (uint64_t)empty_duration;
5016 if (!mov->advanced_editlist)
5017 current_dts = -av_clip64(sc->time_offset, -INT64_MAX, INT64_MAX);
5018 }
5019
5020 if (!multiple_edits && !mov->advanced_editlist &&
5023 (AVRational){1, st->codecpar->sample_rate});
5024 }
5025
5026 /* only use old uncompressed audio chunk demuxing when stts specifies it */
5027 if (!(st->codecpar->codec_type == AVMEDIA_TYPE_AUDIO &&
5028 sc->stts_count == 1 && sc->stts_data && sc->stts_data[0].duration == 1)) {
5029 unsigned int current_sample = 0;
5030 unsigned int stts_sample = 0;
5031 unsigned int sample_size;
5032 unsigned int distance = 0;
5033 unsigned int rap_group_index = 0;
5034 unsigned int rap_group_sample = 0;
5035 int rap_group_present = sc->rap_group_count && sc->rap_group;
5036 int key_off = (sc->keyframe_count && sc->keyframes[0] > 0) || (sc->stps_count && sc->stps_data[0] > 0);
5037
5038 av_assert0(sc->dts_shift >= 0);
5039 if (current_dts < INT64_MIN + sc->dts_shift)
5040 return;
5041 current_dts -= sc->dts_shift;
5042 if (!sc->sample_count || sti->nb_index_entries || sc->tts_count)
5043 return;
5044 if (sc->sample_count >= UINT_MAX / sizeof(*sti->index_entries) - sti->nb_index_entries)
5045 return;
5047 sti->nb_index_entries + sc->sample_count,
5048 sizeof(*sti->index_entries)) < 0) {
5049 sti->nb_index_entries = 0;
5050 return;
5051 }
5052 sti->index_entries_allocated_size = (sti->nb_index_entries + sc->sample_count) * sizeof(*sti->index_entries);
5053
5055 if (ret < 0)
5056 return;
5057
5058 for (i = 0; i < sc->chunk_count; i++) {
5059 int64_t next_offset = i+1 < sc->chunk_count ? sc->chunk_offsets[i+1] : INT64_MAX;
5060 current_offset = sc->chunk_offsets[i];
5061 while (mov_stsc_index_valid(stsc_index, sc->stsc_count) &&
5062 i + 1 == sc->stsc_data[stsc_index + 1].first)
5063 stsc_index++;
5064
5065 if (next_offset > current_offset && sc->sample_size>0 && sc->sample_size < sc->stsz_sample_size &&
5066 sc->stsc_data[stsc_index].count * (int64_t)sc->stsz_sample_size > next_offset - current_offset) {
5067 av_log(mov->fc, AV_LOG_WARNING, "STSZ sample size %d invalid (too large), ignoring\n", sc->stsz_sample_size);
5068 sc->stsz_sample_size = sc->sample_size;
5069 }
5070 if (sc->stsz_sample_size>0 && sc->stsz_sample_size < sc->sample_size) {
5071 av_log(mov->fc, AV_LOG_WARNING, "STSZ sample size %d invalid (too small), ignoring\n", sc->stsz_sample_size);
5072 sc->stsz_sample_size = sc->sample_size;
5073 }
5074
5075 for (j = 0; j < sc->stsc_data[stsc_index].count; j++) {
5076 int keyframe = 0;
5077 if (current_sample >= sc->sample_count) {
5078 av_log(mov->fc, AV_LOG_ERROR, "wrong sample count\n");
5079 return;
5080 }
5081
5082 if (!sc->keyframe_absent && (!sc->keyframe_count || current_sample+key_off == sc->keyframes[stss_index])) {
5083 keyframe = 1;
5084 if (stss_index + 1 < sc->keyframe_count)
5085 stss_index++;
5086 } else if (sc->stps_count && current_sample+key_off == sc->stps_data[stps_index]) {
5087 keyframe = 1;
5088 if (stps_index + 1 < sc->stps_count)
5089 stps_index++;
5090 }
5091 if (rap_group_present && rap_group_index < sc->rap_group_count) {
5092 if (sc->rap_group[rap_group_index].index > 0)
5093 keyframe = 1;
5094 if (++rap_group_sample == sc->rap_group[rap_group_index].count) {
5095 rap_group_sample = 0;
5096 rap_group_index++;
5097 }
5098 }
5099 if (sc->keyframe_absent
5100 && !sc->stps_count
5101 && !rap_group_present
5102 && (st->codecpar->codec_type == AVMEDIA_TYPE_AUDIO || (i==0 && j==0)))
5103 keyframe = 1;
5104 if (keyframe)
5105 distance = 0;
5106 sample_size = sc->stsz_sample_size > 0 ? sc->stsz_sample_size : sc->sample_sizes[current_sample];
5107 if (current_offset > INT64_MAX - sample_size) {
5108 av_log(mov->fc, AV_LOG_ERROR, "Current offset %"PRId64" or sample size %u is too large\n",
5109 current_offset,
5110 sample_size);
5111 return;
5112 }
5113
5114 if (sc->pseudo_stream_id == -1 ||
5115 sc->stsc_data[stsc_index].id - 1 == sc->pseudo_stream_id) {
5116 AVIndexEntry *e;
5117 if (sample_size > 0x3FFFFFFF) {
5118 av_log(mov->fc, AV_LOG_ERROR, "Sample size %u is too large\n", sample_size);
5119 return;
5120 }
5121 e = &sti->index_entries[sti->nb_index_entries++];
5122 e->pos = current_offset;
5123 e->timestamp = current_dts;
5124 e->size = sample_size;
5126 e->flags = keyframe ? AVINDEX_KEYFRAME : 0;
5127 av_log(mov->fc, AV_LOG_TRACE, "AVIndex stream %d, sample %u, offset %"PRIx64", dts %"PRId64", "
5128 "size %u, distance %u, keyframe %d\n", st->index, current_sample,
5129 current_offset, current_dts, sample_size, distance, keyframe);
5130 if (st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO && sti->nb_index_entries < 100)
5131 ff_rfps_add_frame(mov->fc, st, current_dts);
5132 }
5133
5134 current_offset += sample_size;
5135 stream_size += sample_size;
5136
5137 if (current_dts > INT64_MAX - sc->tts_data[stts_index].duration)
5138 return;
5139 current_dts += sc->tts_data[stts_index].duration;
5140
5141 distance++;
5142 stts_sample++;
5143 current_sample++;
5144 if (stts_index + 1 < sc->tts_count && stts_sample == sc->tts_data[stts_index].count) {
5145 stts_sample = 0;
5146 stts_index++;
5147 }
5148 }
5149 }
5150 if (st->duration > 0)
5151 st->codecpar->bit_rate = stream_size*8*sc->time_scale/st->duration;
5152 } else {
5153 unsigned chunk_samples, total = 0;
5154
5155 if (!sc->chunk_count || sc->tts_count)
5156 return;
5157
5158 // compute total chunk count
5159 for (i = 0; i < sc->stsc_count; i++) {
5160 unsigned count, chunk_count;
5161
5162 chunk_samples = sc->stsc_data[i].count;
5163 if (i != sc->stsc_count - 1 &&
5164 sc->samples_per_frame && chunk_samples % sc->samples_per_frame) {
5165 av_log(mov->fc, AV_LOG_ERROR, "error unaligned chunk\n");
5166 return;
5167 }
5168
5169 if (sc->samples_per_frame >= 160) { // gsm
5170 count = chunk_samples / sc->samples_per_frame;
5171 } else if (sc->samples_per_frame > 1) {
5172 unsigned samples = (1024/sc->samples_per_frame)*sc->samples_per_frame;
5173 count = (chunk_samples+samples-1) / samples;
5174 } else {
5175 count = (chunk_samples+1023) / 1024;
5176 }
5177
5179 chunk_count = sc->stsc_data[i+1].first - sc->stsc_data[i].first;
5180 else
5181 chunk_count = sc->chunk_count - (sc->stsc_data[i].first - 1);
5182 total += chunk_count * count;
5183 }
5184
5185 av_log(mov->fc, AV_LOG_TRACE, "chunk count %u\n", total);
5186 if (total >= UINT_MAX / sizeof(*sti->index_entries) - sti->nb_index_entries)
5187 return;
5189 sti->nb_index_entries + total,
5190 sizeof(*sti->index_entries)) < 0) {
5191 sti->nb_index_entries = 0;
5192 return;
5193 }
5194 sti->index_entries_allocated_size = (sti->nb_index_entries + total) * sizeof(*sti->index_entries);
5195
5196 // populate index
5197 for (i = 0; i < sc->chunk_count; i++) {
5198 current_offset = sc->chunk_offsets[i];
5199 if (mov_stsc_index_valid(stsc_index, sc->stsc_count) &&
5200 i + 1 == sc->stsc_data[stsc_index + 1].first)
5201 stsc_index++;
5202 chunk_samples = sc->stsc_data[stsc_index].count;
5203
5204 while (chunk_samples > 0) {
5205 AVIndexEntry *e;
5206 unsigned size, samples;
5207
5208 if (sc->samples_per_frame > 1 && !sc->bytes_per_frame) {
5210 "Zero bytes per frame, but %d samples per frame",
5211 sc->samples_per_frame);
5212 return;
5213 }
5214
5215 if (sc->samples_per_frame >= 160) { // gsm
5216 samples = sc->samples_per_frame;
5217 size = sc->bytes_per_frame;
5218 } else {
5219 if (sc->samples_per_frame > 1) {
5220 samples = FFMIN((1024 / sc->samples_per_frame)*
5221 sc->samples_per_frame, chunk_samples);
5222 size = (samples / sc->samples_per_frame) * sc->bytes_per_frame;
5223 } else {
5224 samples = FFMIN(1024, chunk_samples);
5225 size = samples * sc->sample_size;
5226 }
5227 }
5228
5229 if (sti->nb_index_entries >= total) {
5230 av_log(mov->fc, AV_LOG_ERROR, "wrong chunk count %u\n", total);
5231 return;
5232 }
5233 if (size > 0x3FFFFFFF) {
5234 av_log(mov->fc, AV_LOG_ERROR, "Sample size %u is too large\n", size);
5235 return;
5236 }
5237 e = &sti->index_entries[sti->nb_index_entries++];
5238 e->pos = current_offset;
5239 e->timestamp = current_dts;
5240 e->size = size;
5241 e->min_distance = 0;
5243 av_log(mov->fc, AV_LOG_TRACE, "AVIndex stream %d, chunk %u, offset %"PRIx64", dts %"PRId64", "
5244 "size %u, duration %u\n", st->index, i, current_offset, current_dts,
5245 size, samples);
5246
5247 current_offset += size;
5248 if (current_dts > INT64_MAX - samples)
5249 return;
5250 current_dts += samples;
5251 chunk_samples -= samples;
5252 }
5253 }
5254
5255 ret = mov_merge_tts_data(mov, st, MOV_MERGE_CTTS);
5256 if (ret < 0)
5257 return;
5258 }
5259
5260 if (!mov->ignore_editlist && mov->advanced_editlist) {
5261 // Fix index according to edit lists.
5262 mov_fix_index(mov, st);
5263 }
5264
5265 // Update start time of the stream.
5268 if (sc->tts_data) {
5270 }
5271 }
5272
5273 mov_estimate_video_delay(mov, st);
5274}
5275
5280
5281static int mov_compare_presentation_samples(const void *a, const void *b)
5282{
5283 const MOVPresentationSample *sa = a;
5284 const MOVPresentationSample *sb = b;
5285
5286 if (sa->pts != sb->pts)
5287 return (sa->pts > sb->pts) - (sa->pts < sb->pts);
5288 return (sa->index > sb->index) - (sa->index < sb->index);
5289}
5290
5291/*
5292 * Set sample durations from adjacent presentation timestamps.
5293 */
5295{
5296 MOVStreamContext *sc = st->priv_data;
5297 FFStream *const sti = ffstream(st);
5298 MOVPresentationSample *samples = NULL;
5299 MOVTimeToSample *tts_data = NULL;
5300 unsigned int tts_index = 0, tts_sample = 0;
5301 int count = sti->nb_index_entries;
5302
5303 /* A single STTS entry describes a fixed sample delta. */
5305 !sc->ctts_count || sc->stts_count < 2 ||
5306 !sc->tts_data || count < 2 ||
5307 count >= UINT_MAX / sizeof(*tts_data))
5308 return;
5309
5310 samples = av_malloc_array(count, sizeof(*samples));
5311 tts_data = av_malloc_array(count, sizeof(*tts_data));
5312 if (!samples || !tts_data)
5313 goto fail;
5314
5315 for (int i = 0; i < count; i++) {
5316 int64_t dts, offset;
5317
5318 if (tts_index >= sc->tts_count || !sc->tts_data[tts_index].count)
5319 goto fail;
5320
5321 tts_data[i] = sc->tts_data[tts_index];
5322 tts_data[i].count = 1;
5323
5324 dts = sti->index_entries[i].timestamp;
5325 offset = (int64_t)sc->dts_shift + tts_data[i].offset;
5326 if (dts == AV_NOPTS_VALUE ||
5327 (offset > 0 && dts > INT64_MAX - offset) ||
5328 (offset < 0 && dts < INT64_MIN - offset))
5329 goto fail;
5330
5331 samples[i].index = i;
5332 samples[i].pts = dts + offset;
5333
5334 if (++tts_sample == sc->tts_data[tts_index].count) {
5335 tts_index++;
5336 tts_sample = 0;
5337 }
5338 }
5339 if (tts_index != sc->tts_count || tts_sample)
5340 goto fail;
5341
5342 qsort(samples, count, sizeof(*samples), mov_compare_presentation_samples);
5343
5344 for (int i = 0; i + 1 < count; i++) {
5345 uint64_t duration;
5346
5347 if (samples[i].pts >= samples[i + 1].pts)
5348 goto fail;
5349
5350 /*
5351 * In VFR streams with reordered frames, STTS deltas follow decode
5352 * order while AVPacket.duration follows presentation order. CTTS
5353 * may produce presentation intervals that cannot be obtained by
5354 * merely permuting the STTS deltas, so derive each known duration
5355 * from adjacent PTS.
5356 */
5357 duration = (uint64_t)samples[i + 1].pts - samples[i].pts;
5358 if (!duration || duration > UINT_MAX)
5359 goto fail;
5360
5361 tts_data[samples[i].index].duration = (unsigned int)duration;
5362 }
5363
5364 av_log(mov->fc, AV_LOG_DEBUG,
5365 "Updated sample durations in presentation order for stream %d\n",
5366 st->index);
5367
5368 av_freep(&sc->tts_data);
5369 sc->tts_data = tts_data;
5370 sc->tts_count = count;
5371 sc->tts_allocated_size = count * sizeof(*tts_data);
5372 tts_data = NULL;
5373
5374fail:
5375 av_free(samples);
5376 av_free(tts_data);
5377}
5378
5379static int test_same_origin(const char *src, const char *ref) {
5380 char src_proto[64];
5381 char ref_proto[64];
5382 char src_auth[256];
5383 char ref_auth[256];
5384 char src_host[256];
5385 char ref_host[256];
5386 int src_port=-1;
5387 int ref_port=-1;
5388
5389 av_url_split(src_proto, sizeof(src_proto), src_auth, sizeof(src_auth), src_host, sizeof(src_host), &src_port, NULL, 0, src);
5390 av_url_split(ref_proto, sizeof(ref_proto), ref_auth, sizeof(ref_auth), ref_host, sizeof(ref_host), &ref_port, NULL, 0, ref);
5391
5392 if (strlen(src) == 0) {
5393 return -1;
5394 } else if (strlen(src_auth) + 1 >= sizeof(src_auth) ||
5395 strlen(ref_auth) + 1 >= sizeof(ref_auth) ||
5396 strlen(src_host) + 1 >= sizeof(src_host) ||
5397 strlen(ref_host) + 1 >= sizeof(ref_host)) {
5398 return 0;
5399 } else if (strcmp(src_proto, ref_proto) ||
5400 strcmp(src_auth, ref_auth) ||
5401 strcmp(src_host, ref_host) ||
5402 src_port != ref_port) {
5403 return 0;
5404 } else
5405 return 1;
5406}
5407
5408static int mov_open_dref(MOVContext *c, AVIOContext **pb, const char *src, MOVDref *ref)
5409{
5410 /* try relative path, we do not try the absolute because it can leak information about our
5411 system to an attacker */
5412 if (ref->nlvl_to > 0 && ref->nlvl_from > 0) {
5413 char filename[1025];
5414 const char *src_path;
5415 int i, l;
5416
5417 /* find a source dir */
5418 src_path = strrchr(src, '/');
5419 if (src_path)
5420 src_path++;
5421 else
5422 src_path = src;
5423
5424 /* find a next level down to target */
5425 for (i = 0, l = strlen(ref->path) - 1; l >= 0; l--)
5426 if (ref->path[l] == '/') {
5427 if (i == ref->nlvl_to - 1)
5428 break;
5429 else
5430 i++;
5431 }
5432
5433 /* compose filename if next level down to target was found */
5434 if (i == ref->nlvl_to - 1 && src_path - src < sizeof(filename)) {
5435 memcpy(filename, src, src_path - src);
5436 filename[src_path - src] = 0;
5437
5438 for (i = 1; i < ref->nlvl_from; i++)
5439 av_strlcat(filename, "../", sizeof(filename));
5440
5441 av_strlcat(filename, ref->path + l + 1, sizeof(filename));
5442 if (!c->use_absolute_path) {
5443 int same_origin = test_same_origin(src, filename);
5444
5445 if (!same_origin) {
5446 av_log(c->fc, AV_LOG_ERROR,
5447 "Reference with mismatching origin, %s not tried for security reasons, "
5448 "set demuxer option use_absolute_path to allow it anyway\n",
5449 ref->path);
5450 return AVERROR(ENOENT);
5451 }
5452
5453 if (strstr(ref->path + l + 1, "..") ||
5454 strstr(ref->path + l + 1, ":") ||
5455 (ref->nlvl_from > 1 && same_origin < 0) ||
5456 (filename[0] == '/' && src_path == src))
5457 return AVERROR(ENOENT);
5458 }
5459
5460 if (strlen(filename) + 1 == sizeof(filename))
5461 return AVERROR(ENOENT);
5462 if (!c->fc->io_open(c->fc, pb, filename, AVIO_FLAG_READ, NULL))
5463 return 0;
5464 }
5465 } else if (c->use_absolute_path) {
5466 av_log(c->fc, AV_LOG_WARNING, "Using absolute path on user request, "
5467 "this is a possible security issue\n");
5468 if (!c->fc->io_open(c->fc, pb, ref->path, AVIO_FLAG_READ, NULL))
5469 return 0;
5470 } else {
5471 av_log(c->fc, AV_LOG_ERROR,
5472 "Absolute path %s not tried for security reasons, "
5473 "set demuxer option use_absolute_path to allow absolute paths\n",
5474 ref->path);
5475 }
5476
5477 return AVERROR(ENOENT);
5478}
5479
5481{
5482 if (sc->time_scale <= 0) {
5483 av_log(c->fc, AV_LOG_WARNING, "stream %d, timescale not set\n", sc->ffindex);
5484 sc->time_scale = c->time_scale;
5485 if (sc->time_scale <= 0)
5486 sc->time_scale = 1;
5487 }
5488}
5489
5490#if CONFIG_IAMFDEC
5491static int mov_update_iamf_streams(MOVContext *c, const AVStream *st)
5492{
5493 const MOVStreamContext *sc = st->priv_data;
5494 const IAMFContext *iamf = &sc->iamf->iamf;
5495
5496 for (int i = 0; i < iamf->nb_audio_elements; i++) {
5497 const AVStreamGroup *stg = NULL;
5498
5499 for (int j = 0; j < c->fc->nb_stream_groups; j++)
5500 if (c->fc->stream_groups[j]->id == iamf->audio_elements[i]->audio_element_id)
5501 stg = c->fc->stream_groups[j];
5502 av_assert0(stg);
5503
5504 for (int j = 0; j < stg->nb_streams; j++) {
5505 const FFStream *sti = cffstream(st);
5506 AVStream *out = stg->streams[j];
5507 FFStream *out_sti = ffstream(stg->streams[j]);
5508
5509 out->codecpar->bit_rate = 0;
5510
5511 if (out == st)
5512 continue;
5513
5514 out->time_base = st->time_base;
5515 out->start_time = st->start_time;
5516 out->duration = st->duration;
5517 out->nb_frames = st->nb_frames;
5518 out->discard = st->discard;
5519
5520 av_assert0(!out_sti->index_entries);
5522 if (!out_sti->index_entries)
5523 return AVERROR(ENOMEM);
5524
5526 out_sti->nb_index_entries = sti->nb_index_entries;
5527 out_sti->skip_samples = sti->skip_samples;
5528 memcpy(out_sti->index_entries, sti->index_entries, sti->index_entries_allocated_size);
5529 }
5530 }
5531
5532 return 0;
5533}
5534#endif
5535
5536static int sanity_checks(void *log_obj, MOVStreamContext *sc, int index)
5537{
5538 if ((sc->chunk_count && (!sc->stts_count || !sc->stsc_count ||
5539 (!sc->sample_size && !sc->sample_count))) ||
5540 (sc->sample_count && (!sc->chunk_count ||
5541 (!sc->sample_size && !sc->sample_sizes)))) {
5542 av_log(log_obj, AV_LOG_ERROR, "stream %d, missing mandatory atoms, broken header\n",
5543 index);
5544 return 1;
5545 }
5546
5547 if (sc->stsc_count && sc->stsc_data[ sc->stsc_count - 1 ].first > sc->chunk_count) {
5548 av_log(log_obj, AV_LOG_ERROR, "stream %d, contradictionary STSC and STCO\n",
5549 index);
5550 return 2;
5551 }
5552 return 0;
5553}
5554
5556{
5557 AVStream *st;
5558 MOVStreamContext *sc;
5559 int ret;
5560
5561 st = avformat_new_stream(c->fc, NULL);
5562 if (!st) return AVERROR(ENOMEM);
5563 st->id = -1;
5564 sc = av_mallocz(sizeof(MOVStreamContext));
5565 if (!sc) return AVERROR(ENOMEM);
5566
5567 st->priv_data = sc;
5569 sc->ffindex = st->index;
5570 c->trak_index = st->index;
5571 sc->refcount = 1;
5572
5573 if ((ret = mov_read_default(c, pb, atom)) < 0)
5574 return ret;
5575
5576 c->trak_index = -1;
5577
5578 // Here stsc refers to a chunk not described in stco. This is technically invalid,
5579 // but we can overlook it (clearing stsc) whenever stts_count == 0 (indicating no samples).
5580 if (!sc->chunk_count && !sc->stts_count && sc->stsc_count) {
5581 sc->stsc_count = 0;
5582 av_freep(&sc->stsc_data);
5583 }
5584
5585 ret = sanity_checks(c->fc, sc, st->index);
5586 if (ret)
5587 return ret > 1 ? AVERROR_INVALIDDATA : 0;
5588
5589 fix_timescale(c, sc);
5590
5591 avpriv_set_pts_info(st, 64, 1, sc->time_scale);
5592
5593 /*
5594 * Advanced edit list support does not work with fragemented MP4s, which
5595 * have stsc, stsz, stco, and stts with zero entries in the moov atom.
5596 * In these files, trun atoms may be streamed in.
5597 */
5598 if (!sc->stts_count && c->advanced_editlist) {
5599
5600 av_log(c->fc, AV_LOG_VERBOSE, "advanced_editlist does not work with fragmented "
5601 "MP4. disabling.\n");
5602 c->advanced_editlist = 0;
5603 c->advanced_editlist_autodisabled = 1;
5604 }
5605
5606 mov_build_index(c, st);
5607 /*
5608 * Fragment samples are appended later by mov_read_trun() and are not
5609 * covered by this non-fragmented track update.
5610 */
5612
5613#if CONFIG_IAMFDEC
5614 if (sc->iamf) {
5615 ret = mov_update_iamf_streams(c, st);
5616 if (ret < 0)
5617 return ret;
5618 }
5619#endif
5620
5621 if (sc->dref_id-1 < sc->drefs_count && sc->drefs[sc->dref_id-1].path) {
5622 MOVDref *dref = &sc->drefs[sc->dref_id - 1];
5623 if (c->enable_drefs) {
5624 if (mov_open_dref(c, &sc->pb, c->fc->url, dref) < 0)
5625 av_log(c->fc, AV_LOG_ERROR,
5626 "stream %d, error opening alias: path='%s', dir='%s', "
5627 "filename='%s', volume='%s', nlvl_from=%d, nlvl_to=%d\n",
5628 st->index, dref->path, dref->dir, dref->filename,
5629 dref->volume, dref->nlvl_from, dref->nlvl_to);
5630 } else {
5631 av_log(c->fc, AV_LOG_WARNING,
5632 "Skipped opening external track: "
5633 "stream %d, alias: path='%s', dir='%s', "
5634 "filename='%s', volume='%s', nlvl_from=%d, nlvl_to=%d."
5635 "Set enable_drefs to allow this.\n",
5636 st->index, dref->path, dref->dir, dref->filename,
5637 dref->volume, dref->nlvl_from, dref->nlvl_to);
5638 }
5639 } else {
5640 sc->pb = c->fc->pb;
5641 sc->pb_is_copied = 1;
5642 }
5643
5645 int stts_constant = sc->stts_count && sc->tts_count;
5646 if (sc->h_spacing && sc->v_spacing)
5648 sc->h_spacing, sc->v_spacing, INT_MAX);
5649 if (!st->sample_aspect_ratio.num && st->codecpar->width && st->codecpar->height &&
5650 sc->height && sc->width &&
5651 (st->codecpar->width != sc->width || st->codecpar->height != sc->height)) {
5653 (int64_t)st->codecpar->height * sc->width,
5654 (int64_t)st->codecpar->width * sc->height, INT_MAX);
5655 }
5656
5657#if FF_API_R_FRAME_RATE
5658 for (unsigned int i = 1; sc->stts_count && i + 1 < sc->tts_count; i++) {
5659 if (sc->tts_data[i].duration == sc->tts_data[0].duration)
5660 continue;
5661 stts_constant = 0;
5662 }
5663 if (stts_constant)
5665 sc->time_scale, sc->tts_data[0].duration, INT_MAX);
5666#endif
5667 }
5668
5669#if CONFIG_H261_DECODER || CONFIG_H263_DECODER || CONFIG_MPEG4_DECODER
5670 switch (st->codecpar->codec_id) {
5671#if CONFIG_H261_DECODER
5672 case AV_CODEC_ID_H261:
5673#endif
5674#if CONFIG_H263_DECODER
5675 case AV_CODEC_ID_H263:
5676#endif
5677#if CONFIG_MPEG4_DECODER
5678 case AV_CODEC_ID_MPEG4:
5679#endif
5680 st->codecpar->width = 0; /* let decoder init width/height */
5681 st->codecpar->height= 0;
5682 break;
5683 }
5684#endif
5685
5686 // If the duration of the mp3 packets is not constant, then they could need a parser
5688 && sc->time_scale == st->codecpar->sample_rate) {
5689 int stts_constant = 1;
5690 for (int i = 1; sc->stts_count && i < sc->tts_count; i++) {
5691 if (sc->tts_data[i].duration == sc->tts_data[0].duration)
5692 continue;
5693 stts_constant = 0;
5694 }
5695 if (!stts_constant)
5697 }
5698 /* Do not need those anymore. */
5699 av_freep(&sc->chunk_offsets);
5700 av_freep(&sc->sample_sizes);
5701 av_freep(&sc->keyframes);
5702 av_freep(&sc->stps_data);
5703 av_freep(&sc->elst_data);
5704 av_freep(&sc->rap_group);
5705 av_freep(&sc->sync_group);
5706 av_freep(&sc->sgpd_sync);
5707
5708 return 0;
5709}
5710
5712{
5713 int ret;
5714 c->itunes_metadata = 1;
5715 ret = mov_read_default(c, pb, atom);
5716 c->itunes_metadata = 0;
5717 return ret;
5718}
5719
5721{
5722 uint32_t count;
5723 uint32_t i;
5724
5725 if (atom.size < 8)
5726 return 0;
5727
5728 avio_skip(pb, 4);
5729 count = avio_rb32(pb);
5730 atom.size -= 8;
5731 if (count >= UINT_MAX / sizeof(*c->meta_keys)) {
5732 av_log(c->fc, AV_LOG_ERROR,
5733 "The 'keys' atom with the invalid key count: %"PRIu32"\n", count);
5734 return AVERROR_INVALIDDATA;
5735 }
5736
5737 c->meta_keys_count = count + 1;
5738 c->meta_keys = av_mallocz(c->meta_keys_count * sizeof(*c->meta_keys));
5739 if (!c->meta_keys)
5740 return AVERROR(ENOMEM);
5741
5742 for (i = 1; i <= count; ++i) {
5743 uint32_t key_size = avio_rb32(pb);
5744 uint32_t type = avio_rl32(pb);
5745 if (key_size < 8 || key_size > atom.size) {
5746 av_log(c->fc, AV_LOG_ERROR,
5747 "The key# %"PRIu32" in meta has invalid size:"
5748 "%"PRIu32"\n", i, key_size);
5749 return AVERROR_INVALIDDATA;
5750 }
5751 atom.size -= key_size;
5752 key_size -= 8;
5753 if (type != MKTAG('m','d','t','a')) {
5754 avio_skip(pb, key_size);
5755 continue;
5756 }
5757 c->meta_keys[i] = av_mallocz(key_size + 1);
5758 if (!c->meta_keys[i])
5759 return AVERROR(ENOMEM);
5760 avio_read(pb, c->meta_keys[i], key_size);
5761 }
5762
5763 return 0;
5764}
5765
5767{
5768 int64_t end = av_sat_add64(avio_tell(pb), atom.size);
5769 uint8_t *key = NULL, *val = NULL, *mean = NULL;
5770 int i;
5771 int ret = 0;
5772 AVStream *st;
5773
5774 if (c->fc->nb_streams < 1)
5775 return 0;
5776 st = c->fc->streams[c->fc->nb_streams-1];
5777
5778 for (i = 0; i < 3; i++) {
5779 uint8_t **p;
5780 uint32_t len, tag;
5781
5782 if (end - avio_tell(pb) <= 12)
5783 break;
5784
5785 len = avio_rb32(pb);
5786 tag = avio_rl32(pb);
5787 avio_skip(pb, 4); // flags
5788
5789 if (len < 12 || len - 12 > end - avio_tell(pb))
5790 break;
5791 len -= 12;
5792
5793 if (tag == MKTAG('m', 'e', 'a', 'n'))
5794 p = &mean;
5795 else if (tag == MKTAG('n', 'a', 'm', 'e'))
5796 p = &key;
5797 else if (tag == MKTAG('d', 'a', 't', 'a') && len > 4) {
5798 avio_skip(pb, 4);
5799 len -= 4;
5800 p = &val;
5801 } else
5802 break;
5803
5804 if (*p)
5805 break;
5806
5807 *p = av_malloc(len + 1);
5808 if (!*p) {
5809 ret = AVERROR(ENOMEM);
5810 break;
5811 }
5812 ret = ffio_read_size(pb, *p, len);
5813 if (ret < 0) {
5814 av_freep(p);
5815 break;
5816 }
5817 (*p)[len] = 0;
5818 }
5819
5820 if (mean && key && val) {
5821 if (strcmp(key, "iTunSMPB") == 0) {
5822 int priming, remainder, samples;
5823 if(sscanf(val, "%*X %X %X %X", &priming, &remainder, &samples) == 3){
5824 if(priming>0 && priming<16384)
5825 st->codecpar->initial_padding = priming = av_rescale_q(priming, st->time_base,
5826 (AVRational){ 1, st->codecpar->sample_rate });
5827 if (remainder > 0) {
5829 (AVRational){ 1, st->codecpar->sample_rate });
5830 remainder = av_rescale_q(remainder, st->time_base,
5831 (AVRational){ 1, st->codecpar->sample_rate });
5832 samples = av_rescale_q(samples, st->time_base,
5833 (AVRational){ 1, st->codecpar->sample_rate });
5834 if (duration > remainder && duration > samples) {
5835 ffstream(st)->first_discard_sample = duration - remainder;
5837 }
5838 }
5839 av_log(c->fc, AV_LOG_DEBUG, "Parsed iTunSMPB: priming %d, remainder %d samples %d\n",
5840 priming, remainder, samples);
5841 }
5842 }
5843 if (strcmp(mean, "com.apple.iTunes") == 0 &&
5844 strcmp(key, "DISCSUBTITLE") == 0) {
5845 av_dict_set(&c->fc->metadata, "disc_subtitle", val,
5847 val = NULL;
5848 }
5849 if (strcmp(key, "cdec") != 0) {
5850 av_dict_set(&c->fc->metadata, key, val,
5852 key = val = NULL;
5853 }
5854 } else {
5855 av_log(c->fc, AV_LOG_VERBOSE,
5856 "Unhandled or malformed custom metadata of size %"PRId64"\n", atom.size);
5857 }
5858
5859 avio_seek(pb, end, SEEK_SET);
5860 av_freep(&key);
5861 av_freep(&val);
5862 av_freep(&mean);
5863 return ret;
5864}
5865
5867{
5868 MOVStreamContext *sc;
5869 AVStream *st;
5870
5871 st = avformat_new_stream(c->fc, NULL);
5872 if (!st)
5873 return AVERROR(ENOMEM);
5874 sc = av_mallocz(sizeof(MOVStreamContext));
5875 if (!sc)
5876 goto fail;
5877
5878 item->st = st;
5879 st->id = item->item_id;
5880 st->priv_data = sc;
5882 st->codecpar->codec_id = mov_codec_id(st, item->type);
5883 sc->id = st->id;
5884 sc->ffindex = st->index;
5885 st->avg_frame_rate.num = st->avg_frame_rate.den = 1;
5886 st->time_base.num = st->time_base.den = 1;
5887 st->nb_frames = 1;
5888 sc->time_scale = 1;
5889 sc->pb = c->fc->pb;
5890 sc->pb_is_copied = 1;
5891 sc->refcount = 1;
5892
5893 if (item->name)
5894 av_dict_set(&st->metadata, "title", item->name, 0);
5895
5896 // Populate the necessary fields used by mov_build_index.
5897 sc->stsc_data = av_malloc_array(1, sizeof(*sc->stsc_data));
5898 if (!sc->stsc_data)
5899 goto fail;
5900 sc->stsc_count = 1;
5901 sc->stsc_data[0].first = 1;
5902 sc->stsc_data[0].count = 1;
5903 sc->stsc_data[0].id = 1;
5904 sc->chunk_offsets = av_malloc_array(1, sizeof(*sc->chunk_offsets));
5905 if (!sc->chunk_offsets)
5906 goto fail;
5907 sc->chunk_count = 1;
5908 sc->stts_data = av_malloc_array(1, sizeof(*sc->stts_data));
5909 if (!sc->stts_data)
5910 goto fail;
5911 sc->stts_count = 1;
5912 sc->stts_data[0].count = 1;
5913 // Not used for still images. But needed by mov_build_index.
5914 sc->stts_data[0].duration = 0;
5915
5916 return 0;
5917fail:
5918 mov_free_stream_context(c->fc, st);
5919 ff_remove_stream(c->fc, st);
5920 item->st = NULL;
5921
5922 return AVERROR(ENOMEM);
5923}
5924
5926{
5927 while (atom.size > 8) {
5928 uint32_t tag;
5929 if (avio_feof(pb))
5930 return AVERROR_EOF;
5931 tag = avio_rl32(pb);
5932 atom.size -= 4;
5933 if (tag == MKTAG('h','d','l','r')) {
5934 avio_seek(pb, -8, SEEK_CUR);
5935 atom.size += 8;
5936 return mov_read_default(c, pb, atom);
5937 }
5938 }
5939 return 0;
5940}
5941
5942// return 1 when matrix is identity, 0 otherwise
5943#define IS_MATRIX_IDENT(matrix) \
5944 ( (matrix)[0][0] == (1 << 16) && \
5945 (matrix)[1][1] == (1 << 16) && \
5946 (matrix)[2][2] == (1 << 30) && \
5947 !(matrix)[0][1] && !(matrix)[0][2] && \
5948 !(matrix)[1][0] && !(matrix)[1][2] && \
5949 !(matrix)[2][0] && !(matrix)[2][1])
5950
5952{
5953 int i, j, e;
5954 int width;
5955 int height;
5956 int display_matrix[3][3];
5957 int res_display_matrix[3][3] = { { 0 } };
5958 AVStream *st;
5959 MOVStreamContext *sc;
5960 int version;
5961 int flags;
5962
5963 if (c->fc->nb_streams < 1)
5964 return 0;
5965 st = c->fc->streams[c->fc->nb_streams-1];
5966 sc = st->priv_data;
5967
5968 // Each stream (trak) should have exactly 1 tkhd. This catches bad files and
5969 // avoids corrupting AVStreams mapped to an earlier tkhd.
5970 if (st->id != -1)
5971 return AVERROR_INVALIDDATA;
5972
5973 version = avio_r8(pb);
5974 flags = avio_rb24(pb);
5976
5977 if (version == 1) {
5978 avio_rb64(pb);
5979 avio_rb64(pb);
5980 } else {
5981 avio_rb32(pb); /* creation time */
5982 avio_rb32(pb); /* modification time */
5983 }
5984 st->id = (int)avio_rb32(pb); /* track id (NOT 0 !)*/
5985 sc->id = st->id;
5986 avio_rb32(pb); /* reserved */
5987
5988 /* highlevel (considering edits) duration in movie timebase */
5989 (version == 1) ? avio_rb64(pb) : avio_rb32(pb);
5990 avio_rb32(pb); /* reserved */
5991 avio_rb32(pb); /* reserved */
5992
5993 avio_rb16(pb); /* layer */
5994 avio_rb16(pb); /* alternate group */
5995 avio_rb16(pb); /* volume */
5996 avio_rb16(pb); /* reserved */
5997
5998 //read in the display matrix (outlined in ISO 14496-12, Section 6.2.2)
5999 // they're kept in fixed point format through all calculations
6000 // save u,v,z to store the whole matrix in the AV_PKT_DATA_DISPLAYMATRIX
6001 // side data, but the scale factor is not needed to calculate aspect ratio
6002 for (i = 0; i < 3; i++) {
6003 display_matrix[i][0] = avio_rb32(pb); // 16.16 fixed point
6004 display_matrix[i][1] = avio_rb32(pb); // 16.16 fixed point
6005 display_matrix[i][2] = avio_rb32(pb); // 2.30 fixed point
6006 }
6007
6008 width = avio_rb32(pb); // 16.16 fixed point track width
6009 height = avio_rb32(pb); // 16.16 fixed point track height
6010 sc->width = width >> 16;
6011 sc->height = height >> 16;
6012
6013 // apply the moov display matrix (after the tkhd one)
6014 for (i = 0; i < 3; i++) {
6015 const int sh[3] = { 16, 16, 30 };
6016 for (j = 0; j < 3; j++) {
6017 for (e = 0; e < 3; e++) {
6018 res_display_matrix[i][j] +=
6019 ((int64_t) display_matrix[i][e] *
6020 c->movie_display_matrix[e][j]) >> sh[e];
6021 }
6022 }
6023 }
6024
6025 // save the matrix when it is not the default identity
6026 if (!IS_MATRIX_IDENT(res_display_matrix)) {
6028 sc->display_matrix = av_malloc(sizeof(int32_t) * 9);
6029 if (!sc->display_matrix)
6030 return AVERROR(ENOMEM);
6031
6032 for (i = 0; i < 3; i++)
6033 for (j = 0; j < 3; j++)
6034 sc->display_matrix[i * 3 + j] = res_display_matrix[i][j];
6035 }
6036
6037 // transform the display width/height according to the matrix
6038 // to keep the same scale, use [width height 1<<16]
6039 if (width && height && sc->display_matrix) {
6040 double disp_transform[2];
6041
6042 for (i = 0; i < 2; i++)
6043 disp_transform[i] = hypot(sc->display_matrix[0 + i],
6044 sc->display_matrix[3 + i]);
6045
6046 if (disp_transform[0] > 1 && disp_transform[1] > 1 &&
6047 disp_transform[0] < (1<<24) && disp_transform[1] < (1<<24) &&
6048 fabs((disp_transform[0] / disp_transform[1]) - 1.0) > 0.01)
6050 disp_transform[0] / disp_transform[1],
6051 INT_MAX);
6052 }
6053 return 0;
6054}
6055
6057{
6058 MOVFragment *frag = &c->fragment;
6059 MOVTrackExt *trex = NULL;
6060 int flags, track_id, i;
6061 MOVFragmentStreamInfo * frag_stream_info;
6062
6063 avio_r8(pb); /* version */
6064 flags = avio_rb24(pb);
6065
6066 track_id = avio_rb32(pb);
6067 if (!track_id)
6068 return AVERROR_INVALIDDATA;
6069 for (i = 0; i < c->trex_count; i++)
6070 if (c->trex_data[i].track_id == track_id) {
6071 trex = &c->trex_data[i];
6072 break;
6073 }
6074 if (!trex) {
6075 av_log(c->fc, AV_LOG_WARNING, "could not find corresponding trex (id %u)\n", track_id);
6076 return 0;
6077 }
6078 c->fragment.found_tfhd = 1;
6079 frag->track_id = track_id;
6080 set_frag_stream(&c->frag_index, track_id);
6081
6084 frag->moof_offset : frag->implicit_offset;
6085 frag->stsd_id = flags & MOV_TFHD_STSD_ID ? avio_rb32(pb) : trex->stsd_id;
6086
6088 avio_rb32(pb) : trex->duration;
6089 frag->size = flags & MOV_TFHD_DEFAULT_SIZE ?
6090 avio_rb32(pb) : trex->size;
6092 avio_rb32(pb) : trex->flags;
6093 av_log(c->fc, AV_LOG_TRACE, "frag flags 0x%x\n", frag->flags);
6094
6095 frag_stream_info = get_current_frag_stream_info(&c->frag_index);
6096 if (frag_stream_info) {
6097 frag_stream_info->next_trun_dts = AV_NOPTS_VALUE;
6098 frag_stream_info->stsd_id = frag->stsd_id;
6099 }
6100 return 0;
6101}
6102
6104{
6105 unsigned i, num;
6106 void *new_tracks;
6107
6108 num = atom.size / 4;
6109 if (!(new_tracks = av_malloc_array(num, sizeof(int))))
6110 return AVERROR(ENOMEM);
6111
6112 av_free(c->chapter_tracks);
6113 c->chapter_tracks = new_tracks;
6114 c->nb_chapter_tracks = num;
6115
6116 for (i = 0; i < num && !pb->eof_reached; i++)
6117 c->chapter_tracks[i] = avio_rb32(pb);
6118
6119 c->nb_chapter_tracks = i;
6120
6121 return 0;
6122}
6123
6125{
6126 MOVTrackExt *trex;
6127 int err;
6128
6129 if ((uint64_t)c->trex_count+1 >= UINT_MAX / sizeof(*c->trex_data))
6130 return AVERROR_INVALIDDATA;
6131 if ((err = av_reallocp_array(&c->trex_data, c->trex_count + 1,
6132 sizeof(*c->trex_data))) < 0) {
6133 c->trex_count = 0;
6134 return err;
6135 }
6136
6137 c->fc->duration = AV_NOPTS_VALUE; // the duration from mvhd is not representing the whole file when fragments are used.
6138
6139 trex = &c->trex_data[c->trex_count++];
6140 avio_r8(pb); /* version */
6141 avio_rb24(pb); /* flags */
6142 trex->track_id = avio_rb32(pb);
6143 trex->stsd_id = avio_rb32(pb);
6144 trex->duration = avio_rb32(pb);
6145 trex->size = avio_rb32(pb);
6146 trex->flags = avio_rb32(pb);
6147 return 0;
6148}
6149
6151{
6152 MOVFragment *frag = &c->fragment;
6153 AVStream *st = NULL;
6154 MOVStreamContext *sc;
6155 int version, i;
6156 MOVFragmentStreamInfo * frag_stream_info;
6157 int64_t base_media_decode_time;
6158
6159 for (i = 0; i < c->fc->nb_streams; i++) {
6160 sc = c->fc->streams[i]->priv_data;
6161 if (sc->id == frag->track_id) {
6162 st = c->fc->streams[i];
6163 break;
6164 }
6165 }
6166 if (!st) {
6167 av_log(c->fc, AV_LOG_WARNING, "could not find corresponding track id %u\n", frag->track_id);
6168 return 0;
6169 }
6170 sc = st->priv_data;
6171 if (sc->pseudo_stream_id + 1 != frag->stsd_id && sc->pseudo_stream_id != -1)
6172 return 0;
6173 version = avio_r8(pb);
6174 avio_rb24(pb); /* flags */
6175 if (version) {
6176 base_media_decode_time = avio_rb64(pb);
6177 } else {
6178 base_media_decode_time = avio_rb32(pb);
6179 }
6180
6181 frag_stream_info = get_current_frag_stream_info(&c->frag_index);
6182 if (frag_stream_info)
6183 frag_stream_info->tfdt_dts = base_media_decode_time;
6184 sc->track_end = base_media_decode_time;
6185
6186 return 0;
6187}
6188
6190{
6191 MOVFragment *frag = &c->fragment;
6192 AVStream *st = NULL;
6193 FFStream *sti = NULL;
6194 MOVStreamContext *sc;
6195 MOVTimeToSample *tts_data;
6196 uint64_t offset;
6197 int64_t dts, pts = AV_NOPTS_VALUE;
6198 int data_offset = 0;
6199 unsigned entries, first_sample_flags = frag->flags;
6200 int flags, distance, i;
6201 int64_t prev_dts = AV_NOPTS_VALUE;
6202 int next_frag_index = -1, index_entry_pos;
6203 size_t requested_size;
6204 size_t old_allocated_size;
6205 AVIndexEntry *new_entries;
6206 MOVFragmentStreamInfo * frag_stream_info;
6207
6208 if (!frag->found_tfhd) {
6209 av_log(c->fc, AV_LOG_ERROR, "trun track id unknown, no tfhd was found\n");
6210 return AVERROR_INVALIDDATA;
6211 }
6212
6213 for (i = 0; i < c->fc->nb_streams; i++) {
6214 sc = c->fc->streams[i]->priv_data;
6215 if (sc->id == frag->track_id) {
6216 st = c->fc->streams[i];
6217 sti = ffstream(st);
6218 break;
6219 }
6220 }
6221 if (!st) {
6222 av_log(c->fc, AV_LOG_WARNING, "could not find corresponding track id %u\n", frag->track_id);
6223 return 0;
6224 }
6225 sc = st->priv_data;
6226 if (sc->pseudo_stream_id+1 != frag->stsd_id && sc->pseudo_stream_id != -1)
6227 return 0;
6228
6229 // Find the next frag_index index that has a valid index_entry for
6230 // the current track_id.
6231 //
6232 // A valid index_entry means the trun for the fragment was read
6233 // and it's samples are in index_entries at the given position.
6234 // New index entries will be inserted before the index_entry found.
6235 index_entry_pos = sti->nb_index_entries;
6236 for (i = c->frag_index.current + 1; i < c->frag_index.nb_items; i++) {
6237 frag_stream_info = get_frag_stream_info(&c->frag_index, i, frag->track_id);
6238 if (frag_stream_info && frag_stream_info->index_entry >= 0) {
6239 next_frag_index = i;
6240 index_entry_pos = frag_stream_info->index_entry;
6241 break;
6242 }
6243 }
6244 av_assert0(index_entry_pos <= sti->nb_index_entries);
6245
6246 avio_r8(pb); /* version */
6247 flags = avio_rb24(pb);
6248 entries = avio_rb32(pb);
6249 av_log(c->fc, AV_LOG_TRACE, "flags 0x%x entries %u\n", flags, entries);
6250
6251 if ((uint64_t)entries+sc->tts_count >= UINT_MAX/sizeof(*sc->tts_data))
6252 return AVERROR_INVALIDDATA;
6253 if (flags & MOV_TRUN_DATA_OFFSET) data_offset = avio_rb32(pb);
6254 if (flags & MOV_TRUN_FIRST_SAMPLE_FLAGS) first_sample_flags = avio_rb32(pb);
6255
6256 int entry_size = !!(flags & MOV_TRUN_SAMPLE_DURATION) * 4
6257 + !!(flags & MOV_TRUN_SAMPLE_SIZE) * 4
6258 + !!(flags & MOV_TRUN_SAMPLE_FLAGS) * 4
6259 + !!(flags & MOV_TRUN_SAMPLE_CTS) * 4;
6260 int64_t sample_data_size = avio_size(sc->pb);
6261 int64_t max_entries = INT64_MAX;
6262
6263 if (sample_data_size > 0)
6264 max_entries = sample_data_size - sti->nb_index_entries;
6265 if (entry_size) {
6266 int64_t size = sc->pb == pb ? sample_data_size : avio_size(pb);
6267 int64_t pos = avio_tell(pb);
6268 int64_t left = atom.size - 8 - !!(flags & MOV_TRUN_DATA_OFFSET) * 4
6270
6271 if (pos >= 0 && size >= pos)
6272 left = FFMIN(left, size - pos);
6273 max_entries = FFMIN(max_entries, left / entry_size);
6274 }
6275 if (entries > max_entries) {
6276 av_log(c->fc, AV_LOG_ERROR, "trun sample count %u exceeds the %"PRId64" "
6277 "samples the input can hold\n", entries, max_entries);
6278 return AVERROR_INVALIDDATA;
6279 }
6280
6281 frag_stream_info = get_current_frag_stream_info(&c->frag_index);
6282 if (frag_stream_info) {
6283 if (frag_stream_info->next_trun_dts != AV_NOPTS_VALUE) {
6284 dts = frag_stream_info->next_trun_dts - sc->time_offset;
6285 } else if (frag_stream_info->first_tfra_pts != AV_NOPTS_VALUE &&
6286 c->use_mfra_for == FF_MOV_FLAG_MFRA_PTS) {
6287 pts = frag_stream_info->first_tfra_pts;
6288 av_log(c->fc, AV_LOG_DEBUG, "found mfra time %"PRId64
6289 ", using it for pts\n", pts);
6290 } else if (frag_stream_info->first_tfra_pts != AV_NOPTS_VALUE &&
6291 c->use_mfra_for == FF_MOV_FLAG_MFRA_DTS) {
6292 dts = frag_stream_info->first_tfra_pts;
6293 av_log(c->fc, AV_LOG_DEBUG, "found mfra time %"PRId64
6294 ", using it for dts\n", pts);
6295 } else {
6296 int has_tfdt = frag_stream_info->tfdt_dts != AV_NOPTS_VALUE;
6297 int has_sidx = frag_stream_info->sidx_pts != AV_NOPTS_VALUE;
6298 int fallback_tfdt = !c->use_tfdt && !has_sidx && has_tfdt;
6299 int fallback_sidx = c->use_tfdt && !has_tfdt && has_sidx;
6300
6301 if (fallback_sidx) {
6302 av_log(c->fc, AV_LOG_DEBUG, "use_tfdt set but no tfdt found, using sidx instead\n");
6303 }
6304 if (fallback_tfdt) {
6305 av_log(c->fc, AV_LOG_DEBUG, "use_tfdt not set but no sidx found, using tfdt instead\n");
6306 }
6307
6308 if (has_tfdt && c->use_tfdt || fallback_tfdt) {
6309 dts = frag_stream_info->tfdt_dts - sc->time_offset;
6310 av_log(c->fc, AV_LOG_DEBUG, "found tfdt time %"PRId64
6311 ", using it for dts\n", dts);
6312 } else if (has_sidx && !c->use_tfdt || fallback_sidx) {
6313 // FIXME: sidx earliest_presentation_time is *PTS*, s.b.
6314 // pts = frag_stream_info->sidx_pts;
6315 dts = frag_stream_info->sidx_pts;
6316 av_log(c->fc, AV_LOG_DEBUG, "found sidx time %"PRId64
6317 ", using it for dts\n", frag_stream_info->sidx_pts);
6318 } else {
6319 dts = sc->track_end - sc->time_offset;
6320 av_log(c->fc, AV_LOG_DEBUG, "found track end time %"PRId64
6321 ", using it for dts\n", dts);
6322 }
6323 }
6324 } else {
6325 dts = sc->track_end - sc->time_offset;
6326 av_log(c->fc, AV_LOG_DEBUG, "found track end time %"PRId64
6327 ", using it for dts\n", dts);
6328 }
6329 offset = frag->base_data_offset + data_offset;
6330 distance = 0;
6331 av_log(c->fc, AV_LOG_TRACE, "first sample flags 0x%x\n", first_sample_flags);
6332
6333 // realloc space for new index entries
6334 if ((uint64_t)sti->nb_index_entries + entries >= UINT_MAX / sizeof(AVIndexEntry)) {
6335 entries = UINT_MAX / sizeof(AVIndexEntry) - sti->nb_index_entries;
6336 av_log(c->fc, AV_LOG_ERROR, "Failed to add index entry\n");
6337 }
6338 if (entries == 0)
6339 return 0;
6340
6341 requested_size = (sti->nb_index_entries + entries) * sizeof(AVIndexEntry);
6342 new_entries = av_fast_realloc(sti->index_entries,
6344 requested_size);
6345 if (!new_entries)
6346 return AVERROR(ENOMEM);
6347 sti->index_entries= new_entries;
6348
6349 requested_size = (sti->nb_index_entries + entries) * sizeof(*sc->tts_data);
6350 old_allocated_size = sc->tts_allocated_size;
6351 tts_data = av_fast_realloc(sc->tts_data, &sc->tts_allocated_size,
6352 requested_size);
6353 if (!tts_data)
6354 return AVERROR(ENOMEM);
6355 sc->tts_data = tts_data;
6356
6357 // In case there were samples without time to sample entries, ensure they get
6358 // zero valued entries. This ensures clips which mix boxes with and
6359 // without time to sample entries don't pickup uninitialized data.
6360 memset((uint8_t*)(sc->tts_data) + old_allocated_size, 0,
6361 sc->tts_allocated_size - old_allocated_size);
6362
6363 if (index_entry_pos < sti->nb_index_entries) {
6364 // Make hole in index_entries and tts_data for new samples
6365 memmove(sti->index_entries + index_entry_pos + entries,
6366 sti->index_entries + index_entry_pos,
6367 sizeof(*sti->index_entries) *
6368 (sti->nb_index_entries - index_entry_pos));
6369 memmove(sc->tts_data + index_entry_pos + entries,
6370 sc->tts_data + index_entry_pos,
6371 sizeof(*sc->tts_data) * (sc->tts_count - index_entry_pos));
6372 if (index_entry_pos < sc->current_sample) {
6373 sc->current_sample += entries;
6374 }
6375 }
6376
6377 sti->nb_index_entries += entries;
6378 sc->tts_count = sti->nb_index_entries;
6379 sc->stts_count = sti->nb_index_entries;
6381 sc->ctts_count = sti->nb_index_entries;
6382
6383 // Record the index_entry position in frag_index of this fragment
6384 if (frag_stream_info) {
6385 frag_stream_info->index_entry = index_entry_pos;
6386 if (frag_stream_info->index_base < 0)
6387 frag_stream_info->index_base = index_entry_pos;
6388 }
6389
6390 if (index_entry_pos > 0)
6391 prev_dts = sti->index_entries[index_entry_pos-1].timestamp;
6392
6393 for (i = 0; i < entries && !pb->eof_reached; i++) {
6394 unsigned sample_size = frag->size;
6395 int sample_flags = i ? frag->flags : first_sample_flags;
6396 unsigned sample_duration = frag->duration;
6397 unsigned ctts_duration = 0;
6398 int keyframe = 0;
6399 int index_entry_flags = 0;
6400
6401 if (flags & MOV_TRUN_SAMPLE_DURATION) sample_duration = avio_rb32(pb);
6402 if (flags & MOV_TRUN_SAMPLE_SIZE) sample_size = avio_rb32(pb);
6403 if (flags & MOV_TRUN_SAMPLE_FLAGS) sample_flags = avio_rb32(pb);
6404 if (flags & MOV_TRUN_SAMPLE_CTS) ctts_duration = avio_rb32(pb);
6405
6406 mov_update_dts_shift(sc, ctts_duration, c->fc);
6407 if (pts != AV_NOPTS_VALUE) {
6408 dts = pts - sc->dts_shift;
6409 if (flags & MOV_TRUN_SAMPLE_CTS) {
6410 dts -= ctts_duration;
6411 } else {
6412 dts -= sc->time_offset;
6413 }
6414 av_log(c->fc, AV_LOG_DEBUG,
6415 "pts %"PRId64" calculated dts %"PRId64
6416 " sc->dts_shift %d ctts.duration %d"
6417 " sc->time_offset %"PRId64
6418 " flags & MOV_TRUN_SAMPLE_CTS %d\n",
6419 pts, dts,
6420 sc->dts_shift, ctts_duration,
6423 }
6424
6425 keyframe =
6426 !(sample_flags & (MOV_FRAG_SAMPLE_FLAG_IS_NON_SYNC |
6428 if (keyframe) {
6429 distance = 0;
6430 index_entry_flags |= AVINDEX_KEYFRAME;
6431 }
6432 // Fragments can overlap in time. Discard overlapping frames after
6433 // decoding.
6434 if (prev_dts >= dts)
6435 index_entry_flags |= AVINDEX_DISCARD_FRAME;
6436
6437 sti->index_entries[index_entry_pos].pos = offset;
6438 sti->index_entries[index_entry_pos].timestamp = dts;
6439 sti->index_entries[index_entry_pos].size = sample_size;
6440 sti->index_entries[index_entry_pos].min_distance = distance;
6441 sti->index_entries[index_entry_pos].flags = index_entry_flags;
6442
6443 sc->tts_data[index_entry_pos].count = 1;
6444 sc->tts_data[index_entry_pos].offset = ctts_duration;
6445 sc->tts_data[index_entry_pos].duration = sample_duration;
6446 index_entry_pos++;
6447
6448 av_log(c->fc, AV_LOG_TRACE, "AVIndex stream %d, sample %d, offset %"PRIx64", dts %"PRId64", "
6449 "size %u, distance %d, keyframe %d\n", st->index,
6450 index_entry_pos, offset, dts, sample_size, distance, keyframe);
6451 distance++;
6452 if (av_sat_add64(dts, sample_duration) != dts + (uint64_t)sample_duration)
6453 return AVERROR_INVALIDDATA;
6454 if (!sample_size)
6455 return AVERROR_INVALIDDATA;
6456 dts += sample_duration;
6457 offset += sample_size;
6458 sc->data_size += sample_size;
6459
6460 if (sample_duration <= INT64_MAX - sc->duration_for_fps &&
6461 1 <= INT_MAX - sc->nb_frames_for_fps
6462 ) {
6463 sc->duration_for_fps += sample_duration;
6464 sc->nb_frames_for_fps ++;
6465 }
6466 }
6467 if (frag_stream_info)
6468 frag_stream_info->next_trun_dts = dts + sc->time_offset;
6469 if (i < entries) {
6470 // EOF found before reading all entries. Fix the hole this would
6471 // leave in index_entries and tts_data
6472 int gap = entries - i;
6473 memmove(sti->index_entries + index_entry_pos,
6474 sti->index_entries + index_entry_pos + gap,
6475 sizeof(*sti->index_entries) *
6476 (sti->nb_index_entries - (index_entry_pos + gap)));
6477 memmove(sc->tts_data + index_entry_pos,
6478 sc->tts_data + index_entry_pos + gap,
6479 sizeof(*sc->tts_data) *
6480 (sc->tts_count - (index_entry_pos + gap)));
6481
6482 sti->nb_index_entries -= gap;
6483 sc->tts_count -= gap;
6484 if (index_entry_pos < sc->current_sample) {
6485 sc->current_sample -= gap;
6486 }
6487 entries = i;
6488 }
6489
6490 // The end of this new fragment may overlap in time with the start
6491 // of the next fragment in index_entries. Mark the samples in the next
6492 // fragment that overlap with AVINDEX_DISCARD_FRAME
6493 prev_dts = AV_NOPTS_VALUE;
6494 if (index_entry_pos > 0)
6495 prev_dts = sti->index_entries[index_entry_pos-1].timestamp;
6496 for (int i = index_entry_pos; i < sti->nb_index_entries; i++) {
6497 if (prev_dts < sti->index_entries[i].timestamp)
6498 break;
6500 }
6501
6502 // If a hole was created to insert the new index_entries into,
6503 // the index_entry recorded for all subsequent moof must
6504 // be incremented by the number of entries inserted.
6505 fix_frag_index_entries(&c->frag_index, next_frag_index,
6506 frag->track_id, entries);
6507
6508 if (pb->eof_reached) {
6509 av_log(c->fc, AV_LOG_WARNING, "reached eof, corrupted TRUN atom\n");
6510 return AVERROR_EOF;
6511 }
6512
6513 frag->implicit_offset = offset;
6514
6515 sc->track_end = dts + sc->time_offset;
6516 if (st->duration < sc->track_end)
6517 st->duration = sc->track_end;
6518
6519 return 0;
6520}
6521
6523{
6524 int64_t stream_size = avio_size(pb);
6525 int64_t offset = av_sat_add64(avio_tell(pb), atom.size), pts, timestamp;
6526 uint8_t version, is_complete;
6527 int64_t offadd;
6528 unsigned i, j, track_id, item_count;
6529 AVStream *st = NULL;
6530 AVStream *ref_st = NULL;
6531 MOVStreamContext *sc, *ref_sc = NULL;
6532 AVRational timescale;
6533
6534 version = avio_r8(pb);
6535 if (version > 1) {
6536 avpriv_request_sample(c->fc, "sidx version %u", version);
6537 return 0;
6538 }
6539
6540 avio_rb24(pb); // flags
6541
6542 track_id = avio_rb32(pb); // Reference ID
6543 for (i = 0; i < c->fc->nb_streams; i++) {
6544 sc = c->fc->streams[i]->priv_data;
6545 if (sc->id == track_id) {
6546 st = c->fc->streams[i];
6547 break;
6548 }
6549 }
6550 if (!st) {
6551 av_log(c->fc, AV_LOG_WARNING, "could not find corresponding track id %d\n", track_id);
6552 return 0;
6553 }
6554
6555 sc = st->priv_data;
6556
6557 timescale = av_make_q(1, avio_rb32(pb));
6558
6559 if (timescale.den <= 0) {
6560 av_log(c->fc, AV_LOG_ERROR, "Invalid sidx timescale 1/%d\n", timescale.den);
6561 return AVERROR_INVALIDDATA;
6562 }
6563
6564 if (version == 0) {
6565 pts = avio_rb32(pb);
6566 offadd= avio_rb32(pb);
6567 } else {
6568 pts = avio_rb64(pb);
6569 offadd= avio_rb64(pb);
6570 }
6571 if (av_sat_add64(offset, offadd) != offset + (uint64_t)offadd)
6572 return AVERROR_INVALIDDATA;
6573
6574 offset += (uint64_t)offadd;
6575
6576 avio_rb16(pb); // reserved
6577
6578 item_count = avio_rb16(pb);
6579 if (item_count == 0)
6580 return AVERROR_INVALIDDATA;
6581
6582 for (i = 0; i < item_count; i++) {
6583 int index;
6584 MOVFragmentStreamInfo * frag_stream_info;
6585 uint32_t size = avio_rb32(pb);
6586 uint32_t duration = avio_rb32(pb);
6587 if (size & 0x80000000) {
6588 avpriv_request_sample(c->fc, "sidx reference_type 1");
6589 return AVERROR_PATCHWELCOME;
6590 }
6591 avio_rb32(pb); // sap_flags
6592 timestamp = av_rescale_q(pts, timescale, st->time_base);
6593
6595 frag_stream_info = get_frag_stream_info(&c->frag_index, index, track_id);
6596 if (frag_stream_info)
6597 frag_stream_info->sidx_pts = timestamp;
6598
6599 if (av_sat_add64(offset, size) != offset + (uint64_t)size ||
6600 av_sat_add64(pts, duration) != pts + (uint64_t)duration
6601 )
6602 return AVERROR_INVALIDDATA;
6603 offset += size;
6604 pts += duration;
6605 }
6606
6607 st->duration = sc->track_end = pts;
6608
6609 sc->has_sidx = 1;
6610
6611 // See if the remaining bytes are just an mfra which we can ignore.
6612 is_complete = offset == stream_size;
6613 if (!is_complete && (pb->seekable & AVIO_SEEKABLE_NORMAL) && stream_size > 0 ) {
6614 int64_t ret;
6615 int64_t original_pos = avio_tell(pb);
6616 if (!c->have_read_mfra_size) {
6617 if ((ret = avio_seek(pb, stream_size - 4, SEEK_SET)) < 0)
6618 return ret;
6619 c->mfra_size = avio_rb32(pb);
6620 c->have_read_mfra_size = 1;
6621 if ((ret = avio_seek(pb, original_pos, SEEK_SET)) < 0)
6622 return ret;
6623 }
6624 if (offset == stream_size - c->mfra_size)
6625 is_complete = 1;
6626 }
6627
6628 if (is_complete) {
6629 // Find first entry in fragment index that came from an sidx.
6630 // This will pretty much always be the first entry.
6631 for (i = 0; i < c->frag_index.nb_items; i++) {
6632 MOVFragmentIndexItem * item = &c->frag_index.item[i];
6633 for (j = 0; ref_st == NULL && j < item->nb_stream_info; j++) {
6635 si = &item->stream_info[j];
6636 if (si->sidx_pts != AV_NOPTS_VALUE) {
6637 ref_st = c->fc->streams[j];
6638 ref_sc = ref_st->priv_data;
6639 break;
6640 }
6641 }
6642 }
6643 if (ref_st) for (i = 0; i < c->fc->nb_streams; i++) {
6644 st = c->fc->streams[i];
6645 sc = st->priv_data;
6646 if (!sc->has_sidx) {
6647 st->duration = sc->track_end = av_rescale(ref_st->duration, sc->time_scale, ref_sc->time_scale);
6648 }
6649 }
6650
6651 if (offadd == 0)
6652 c->frag_index.complete = 1;
6653 }
6654
6655 return 0;
6656}
6657
6658/* this atom should be null (from specs), but some buggy files put the 'moov' atom inside it... */
6659/* like the files created with Adobe Premiere 5.0, for samples see */
6660/* http://graphics.tudelft.nl/~wouter/publications/soundtests/ */
6662{
6663 int err;
6664
6665 if (atom.size < 8)
6666 return 0; /* continue */
6667 if (avio_rb32(pb) != 0) { /* 0 sized mdat atom... use the 'wide' atom size */
6668 avio_skip(pb, atom.size - 4);
6669 return 0;
6670 }
6671 atom.type = avio_rl32(pb);
6672 atom.size -= 8;
6673 if (atom.type != MKTAG('m','d','a','t')) {
6674 avio_skip(pb, atom.size);
6675 return 0;
6676 }
6677 err = mov_read_mdat(c, pb, atom);
6678 return err;
6679}
6680
6682{
6683#if CONFIG_ZLIB
6685 uint8_t *cmov_data;
6686 uint8_t *moov_data; /* uncompressed data */
6687 long cmov_len, moov_len;
6688 int ret = -1;
6689
6690 avio_rb32(pb); /* dcom atom */
6691 if (avio_rl32(pb) != MKTAG('d','c','o','m'))
6692 return AVERROR_INVALIDDATA;
6693 if (avio_rl32(pb) != MKTAG('z','l','i','b')) {
6694 av_log(c->fc, AV_LOG_ERROR, "unknown compression for cmov atom !\n");
6695 return AVERROR_INVALIDDATA;
6696 }
6697 avio_rb32(pb); /* cmvd atom */
6698 if (avio_rl32(pb) != MKTAG('c','m','v','d'))
6699 return AVERROR_INVALIDDATA;
6700 moov_len = avio_rb32(pb); /* uncompressed size */
6701 cmov_len = atom.size - 6 * 4;
6702
6703 cmov_data = av_malloc(cmov_len);
6704 if (!cmov_data)
6705 return AVERROR(ENOMEM);
6706 moov_data = av_malloc(moov_len);
6707 if (!moov_data) {
6708 av_free(cmov_data);
6709 return AVERROR(ENOMEM);
6710 }
6711 ret = ffio_read_size(pb, cmov_data, cmov_len);
6712 if (ret < 0)
6713 goto free_and_return;
6714
6715 ret = AVERROR_INVALIDDATA;
6716 if (uncompress (moov_data, (uLongf *) &moov_len, (const Bytef *)cmov_data, cmov_len) != Z_OK)
6717 goto free_and_return;
6718 ffio_init_read_context(&ctx, moov_data, moov_len);
6719 ctx.pub.seekable = AVIO_SEEKABLE_NORMAL;
6720 atom.type = MKTAG('m','o','o','v');
6721 atom.size = moov_len;
6722 ret = mov_read_default(c, &ctx.pub, atom);
6723free_and_return:
6724 av_free(moov_data);
6725 av_free(cmov_data);
6726 return ret;
6727#else
6728 av_log(c->fc, AV_LOG_ERROR, "this file requires zlib support compiled in\n");
6729 return AVERROR(ENOSYS);
6730#endif
6731}
6732
6733/* edit list atom */
6735{
6736 MOVStreamContext *sc;
6737 int i, edit_count, version;
6738 int64_t elst_entry_size;
6739
6740 if (c->fc->nb_streams < 1 || c->ignore_editlist)
6741 return 0;
6742 sc = c->fc->streams[c->fc->nb_streams-1]->priv_data;
6743
6744 version = avio_r8(pb); /* version */
6745 avio_rb24(pb); /* flags */
6746 edit_count = avio_rb32(pb); /* entries */
6747 atom.size -= 8;
6748
6749 elst_entry_size = version == 1 ? 20 : 12;
6750 if (atom.size != edit_count * elst_entry_size) {
6751 if (c->fc->strict_std_compliance >= FF_COMPLIANCE_STRICT) {
6752 av_log(c->fc, AV_LOG_ERROR, "Invalid edit list entry_count: %d for elst atom of size: %"PRId64" bytes.\n",
6753 edit_count, atom.size + 8);
6754 return AVERROR_INVALIDDATA;
6755 } else {
6756 edit_count = atom.size / elst_entry_size;
6757 if (edit_count * elst_entry_size != atom.size) {
6758 av_log(c->fc, AV_LOG_WARNING, "ELST atom of %"PRId64" bytes, bigger than %d entries.\n", atom.size, edit_count);
6759 }
6760 }
6761 }
6762
6763 if (!edit_count)
6764 return 0;
6765 if (sc->elst_data)
6766 av_log(c->fc, AV_LOG_WARNING, "Duplicated ELST atom\n");
6767 av_free(sc->elst_data);
6768 sc->elst_count = 0;
6769 sc->elst_data = av_malloc_array(edit_count, sizeof(*sc->elst_data));
6770 if (!sc->elst_data)
6771 return AVERROR(ENOMEM);
6772
6773 av_log(c->fc, AV_LOG_TRACE, "track[%u].edit_count = %i\n", c->fc->nb_streams - 1, edit_count);
6774 for (i = 0; i < edit_count && atom.size > 0 && !pb->eof_reached; i++) {
6775 MOVElst *e = &sc->elst_data[i];
6776
6777 if (version == 1) {
6778 e->duration = avio_rb64(pb);
6779 e->time = avio_rb64(pb);
6780 atom.size -= 16;
6781 } else {
6782 e->duration = avio_rb32(pb); /* segment duration */
6783 e->time = (int32_t)avio_rb32(pb); /* media time */
6784 atom.size -= 8;
6785 }
6786 e->rate = avio_rb32(pb) / 65536.0;
6787 atom.size -= 4;
6788 av_log(c->fc, AV_LOG_TRACE, "duration=%"PRId64" time=%"PRId64" rate=%f\n",
6789 e->duration, e->time, e->rate);
6790
6791 if (e->time < 0 && e->time != -1 &&
6792 c->fc->strict_std_compliance >= FF_COMPLIANCE_STRICT) {
6793 av_log(c->fc, AV_LOG_ERROR, "Track %d, edit %d: Invalid edit list media time=%"PRId64"\n",
6794 c->fc->nb_streams-1, i, e->time);
6795 return AVERROR_INVALIDDATA;
6796 }
6797 if (e->duration < 0) {
6798 av_log(c->fc, AV_LOG_ERROR, "Track %d, edit %d: Invalid edit list duration=%"PRId64"\n",
6799 c->fc->nb_streams-1, i, e->duration);
6800 return AVERROR_INVALIDDATA;
6801 }
6802 }
6803 sc->elst_count = i;
6804
6805 return 0;
6806}
6807
6809{
6810 MOVStreamContext *sc;
6811 int err;
6812
6813 if (c->fc->nb_streams < 1)
6814 return AVERROR_INVALIDDATA;
6815 sc = c->fc->streams[c->fc->nb_streams - 1]->priv_data;
6816
6817 if (atom.size % sizeof(uint32_t))
6818 return AVERROR_INVALIDDATA;
6819
6820 MovTref *tag = mov_add_tref_tag(sc, atom.type);
6821 if (!tag)
6822 return AVERROR(ENOMEM);
6823
6824 int nb_timecode_track = atom.size >> 2;
6825 for (int i = 0; i < nb_timecode_track; i++) {
6826 if (avio_feof(pb))
6827 return AVERROR_INVALIDDATA;
6828 err = mov_add_tref_id(tag, avio_rb32(pb));
6829 if (err < 0)
6830 return err;
6831 }
6832
6833 return 0;
6834}
6835
6837{
6838 AVStream *st;
6839 int version, color_range, color_primaries, color_trc, color_space;
6840
6841 if (c->fc->nb_streams < 1)
6842 return 0;
6843 st = c->fc->streams[c->fc->nb_streams - 1];
6844
6845 if (atom.size < 5) {
6846 av_log(c->fc, AV_LOG_ERROR, "Empty VP Codec Configuration box\n");
6847 return AVERROR_INVALIDDATA;
6848 }
6849
6850 version = avio_r8(pb);
6851 if (version != 1) {
6852 av_log(c->fc, AV_LOG_WARNING, "Unsupported VP Codec Configuration box version %d\n", version);
6853 return 0;
6854 }
6855 avio_skip(pb, 3); /* flags */
6856
6857 avio_skip(pb, 2); /* profile + level */
6858 color_range = avio_r8(pb); /* bitDepth, chromaSubsampling, videoFullRangeFlag */
6860 color_trc = avio_r8(pb);
6861 color_space = avio_r8(pb);
6862 if (avio_rb16(pb)) /* codecIntializationDataSize */
6863 return AVERROR_INVALIDDATA;
6864
6867 if (!av_color_transfer_name(color_trc))
6868 color_trc = AVCOL_TRC_UNSPECIFIED;
6869 if (!av_color_space_name(color_space))
6870 color_space = AVCOL_SPC_UNSPECIFIED;
6871
6874 st->codecpar->color_trc = color_trc;
6875 st->codecpar->color_space = color_space;
6876
6877 return 0;
6878}
6879
6881{
6882 MOVStreamContext *sc;
6883 int i, version;
6884
6885 if (c->fc->nb_streams < 1)
6886 return AVERROR_INVALIDDATA;
6887
6888 sc = c->fc->streams[c->fc->nb_streams - 1]->priv_data;
6889
6890 if (atom.size < 5) {
6891 av_log(c->fc, AV_LOG_ERROR, "Empty Mastering Display Metadata box\n");
6892 return AVERROR_INVALIDDATA;
6893 }
6894
6895 version = avio_r8(pb);
6896 if (version) {
6897 av_log(c->fc, AV_LOG_WARNING, "Unsupported Mastering Display Metadata box version %d\n", version);
6898 return 0;
6899 }
6900 if (sc->mastering) {
6901 av_log(c->fc, AV_LOG_WARNING, "Ignoring duplicate Mastering Display Metadata\n");
6902 return 0;
6903 }
6904
6905 avio_skip(pb, 3); /* flags */
6906
6908 if (!sc->mastering)
6909 return AVERROR(ENOMEM);
6910
6911 for (i = 0; i < 3; i++) {
6912 sc->mastering->display_primaries[i][0] = av_make_q(avio_rb16(pb), 1 << 16);
6913 sc->mastering->display_primaries[i][1] = av_make_q(avio_rb16(pb), 1 << 16);
6914 }
6915 sc->mastering->white_point[0] = av_make_q(avio_rb16(pb), 1 << 16);
6916 sc->mastering->white_point[1] = av_make_q(avio_rb16(pb), 1 << 16);
6917
6918 sc->mastering->max_luminance = av_make_q(avio_rb32(pb), 1 << 8);
6919 sc->mastering->min_luminance = av_make_q(avio_rb32(pb), 1 << 14);
6920
6921 sc->mastering->has_primaries = 1;
6922 sc->mastering->has_luminance = 1;
6923
6924 return 0;
6925}
6926
6928{
6929 MOVStreamContext *sc;
6930 const int mapping[3] = {1, 2, 0};
6931 const int chroma_den = 50000;
6932 const int luma_den = 10000;
6933 int i;
6934
6935 if (c->fc->nb_streams < 1)
6936 return AVERROR_INVALIDDATA;
6937
6938 sc = c->fc->streams[c->fc->nb_streams - 1]->priv_data;
6939
6940 if (atom.size < 24) {
6941 av_log(c->fc, AV_LOG_ERROR, "Invalid Mastering Display Color Volume box\n");
6942 return AVERROR_INVALIDDATA;
6943 }
6944
6945 if (sc->mastering) {
6946 av_log(c->fc, AV_LOG_WARNING, "Ignoring duplicate Mastering Display Color Volume\n");
6947 return 0;
6948 }
6949
6951 if (!sc->mastering)
6952 return AVERROR(ENOMEM);
6953
6954 for (i = 0; i < 3; i++) {
6955 const int j = mapping[i];
6956 sc->mastering->display_primaries[j][0] = av_make_q(avio_rb16(pb), chroma_den);
6957 sc->mastering->display_primaries[j][1] = av_make_q(avio_rb16(pb), chroma_den);
6958 }
6959 sc->mastering->white_point[0] = av_make_q(avio_rb16(pb), chroma_den);
6960 sc->mastering->white_point[1] = av_make_q(avio_rb16(pb), chroma_den);
6961
6962 sc->mastering->max_luminance = av_make_q(avio_rb32(pb), luma_den);
6963 sc->mastering->min_luminance = av_make_q(avio_rb32(pb), luma_den);
6964
6965 sc->mastering->has_luminance = 1;
6966 sc->mastering->has_primaries = 1;
6967
6968 return 0;
6969}
6970
6972{
6973 MOVStreamContext *sc;
6974 int version;
6975
6976 if (c->fc->nb_streams < 1)
6977 return AVERROR_INVALIDDATA;
6978
6979 sc = c->fc->streams[c->fc->nb_streams - 1]->priv_data;
6980
6981 if (atom.size < 5) {
6982 av_log(c->fc, AV_LOG_ERROR, "Empty Content Light Level box\n");
6983 return AVERROR_INVALIDDATA;
6984 }
6985
6986 version = avio_r8(pb);
6987 if (version) {
6988 av_log(c->fc, AV_LOG_WARNING, "Unsupported Content Light Level box version %d\n", version);
6989 return 0;
6990 }
6991 avio_skip(pb, 3); /* flags */
6992
6993 if (sc->coll){
6994 av_log(c->fc, AV_LOG_WARNING, "Ignoring duplicate COLL\n");
6995 return 0;
6996 }
6997
6999 if (!sc->coll)
7000 return AVERROR(ENOMEM);
7001
7002 sc->coll->MaxCLL = avio_rb16(pb);
7003 sc->coll->MaxFALL = avio_rb16(pb);
7004
7005 return 0;
7006}
7007
7009{
7010 MOVStreamContext *sc;
7011
7012 if (c->fc->nb_streams < 1)
7013 return AVERROR_INVALIDDATA;
7014
7015 sc = c->fc->streams[c->fc->nb_streams - 1]->priv_data;
7016
7017 if (atom.size < 4) {
7018 av_log(c->fc, AV_LOG_ERROR, "Empty Content Light Level Info box\n");
7019 return AVERROR_INVALIDDATA;
7020 }
7021
7022 if (sc->coll){
7023 av_log(c->fc, AV_LOG_WARNING, "Ignoring duplicate CLLI/COLL\n");
7024 return 0;
7025 }
7026
7028 if (!sc->coll)
7029 return AVERROR(ENOMEM);
7030
7031 sc->coll->MaxCLL = avio_rb16(pb);
7032 sc->coll->MaxFALL = avio_rb16(pb);
7033
7034 return 0;
7035}
7036
7038{
7039 MOVStreamContext *sc;
7040 const int illuminance_den = 10000;
7041 const int ambient_den = 50000;
7042 if (c->fc->nb_streams < 1)
7043 return AVERROR_INVALIDDATA;
7044 sc = c->fc->streams[c->fc->nb_streams - 1]->priv_data;
7045 if (atom.size < 6) {
7046 av_log(c->fc, AV_LOG_ERROR, "Empty Ambient Viewing Environment Info box\n");
7047 return AVERROR_INVALIDDATA;
7048 }
7049 if (sc->ambient){
7050 av_log(c->fc, AV_LOG_WARNING, "Ignoring duplicate AMVE\n");
7051 return 0;
7052 }
7054 if (!sc->ambient)
7055 return AVERROR(ENOMEM);
7056 sc->ambient->ambient_illuminance = av_make_q(avio_rb32(pb), illuminance_den);
7057 sc->ambient->ambient_light_x = av_make_q(avio_rb16(pb), ambient_den);
7058 sc->ambient->ambient_light_y = av_make_q(avio_rb16(pb), ambient_den);
7059 return 0;
7060}
7061
7063{
7064 AVStream *st;
7065 MOVStreamContext *sc;
7066 enum AVStereo3DType type;
7067 int mode;
7068
7069 if (c->fc->nb_streams < 1)
7070 return 0;
7071
7072 st = c->fc->streams[c->fc->nb_streams - 1];
7073 sc = st->priv_data;
7074
7075 if (atom.size < 5) {
7076 av_log(c->fc, AV_LOG_ERROR, "Empty stereoscopic video box\n");
7077 return AVERROR_INVALIDDATA;
7078 }
7079
7080 if (sc->stereo3d)
7081 return AVERROR_INVALIDDATA;
7082
7083 avio_skip(pb, 4); /* version + flags */
7084
7085 mode = avio_r8(pb);
7086 switch (mode) {
7087 case 0:
7089 break;
7090 case 1:
7092 break;
7093 case 2:
7095 break;
7096 default:
7097 av_log(c->fc, AV_LOG_WARNING, "Unknown st3d mode value %d\n", mode);
7098 return 0;
7099 }
7100
7102 if (!sc->stereo3d)
7103 return AVERROR(ENOMEM);
7104
7105 sc->stereo3d->type = type;
7106 return 0;
7107}
7108
7110{
7111 AVStream *st;
7112 MOVStreamContext *sc;
7113 int size = 0;
7114 int64_t remaining;
7115 uint32_t tag = 0;
7117
7118 if (c->fc->nb_streams < 1)
7119 return 0;
7120
7121 st = c->fc->streams[c->fc->nb_streams - 1];
7122 sc = st->priv_data;
7123
7124 remaining = atom.size;
7125 while (remaining > 0) {
7126 size = avio_rb32(pb);
7127 if (size < 8 || size > remaining ) {
7128 av_log(c->fc, AV_LOG_ERROR, "Invalid child size in pack box\n");
7129 return AVERROR_INVALIDDATA;
7130 }
7131
7132 tag = avio_rl32(pb);
7133 switch (tag) {
7134 case MKTAG('p','k','i','n'): {
7135 if (size != 16) {
7136 av_log(c->fc, AV_LOG_ERROR, "Invalid size of pkin box: %d\n", size);
7137 return AVERROR_INVALIDDATA;
7138 }
7139 avio_skip(pb, 1); // version
7140 avio_skip(pb, 3); // flags
7141
7142 tag = avio_rl32(pb);
7143 switch (tag) {
7144 case MKTAG('s','i','d','e'):
7146 break;
7147 case MKTAG('o','v','e','r'):
7149 break;
7150 case 0:
7151 // This means value will be set in another layer
7152 break;
7153 default:
7154 av_log(c->fc, AV_LOG_WARNING, "Unknown tag in pkin: %s\n",
7156 avio_skip(pb, size - 8);
7157 break;
7158 }
7159
7160 break;
7161 }
7162 default:
7163 av_log(c->fc, AV_LOG_WARNING, "Unknown tag in pack: %s\n",
7165 avio_skip(pb, size - 8);
7166 break;
7167 }
7168 remaining -= size;
7169 }
7170
7171 if (remaining != 0) {
7172 av_log(c->fc, AV_LOG_ERROR, "Broken pack box\n");
7173 return AVERROR_INVALIDDATA;
7174 }
7175
7176 if (type == AV_STEREO3D_2D)
7177 return 0;
7178
7179 if (!sc->stereo3d) {
7181 if (!sc->stereo3d)
7182 return AVERROR(ENOMEM);
7183 }
7184
7185 sc->stereo3d->type = type;
7186
7187 return 0;
7188}
7189
7191{
7192 AVStream *st;
7193 MOVStreamContext *sc;
7194 int size, version, layout;
7195 int32_t yaw, pitch, roll;
7196 uint32_t l = 0, t = 0, r = 0, b = 0;
7197 uint32_t tag, padding = 0;
7198 enum AVSphericalProjection projection;
7199
7200 if (c->fc->nb_streams < 1)
7201 return 0;
7202
7203 st = c->fc->streams[c->fc->nb_streams - 1];
7204 sc = st->priv_data;
7205
7206 if (atom.size < 8) {
7207 av_log(c->fc, AV_LOG_ERROR, "Empty spherical video box\n");
7208 return AVERROR_INVALIDDATA;
7209 }
7210
7211 size = avio_rb32(pb);
7212 if (size <= 12 || size > atom.size)
7213 return AVERROR_INVALIDDATA;
7214
7215 tag = avio_rl32(pb);
7216 if (tag != MKTAG('s','v','h','d')) {
7217 av_log(c->fc, AV_LOG_ERROR, "Missing spherical video header\n");
7218 return 0;
7219 }
7220 version = avio_r8(pb);
7221 if (version != 0) {
7222 av_log(c->fc, AV_LOG_WARNING, "Unknown spherical version %d\n",
7223 version);
7224 return 0;
7225 }
7226 avio_skip(pb, 3); /* flags */
7227 avio_skip(pb, size - 12); /* metadata_source */
7228
7229 size = avio_rb32(pb);
7230 if (size > atom.size)
7231 return AVERROR_INVALIDDATA;
7232
7233 tag = avio_rl32(pb);
7234 if (tag != MKTAG('p','r','o','j')) {
7235 av_log(c->fc, AV_LOG_ERROR, "Missing projection box\n");
7236 return 0;
7237 }
7238
7239 size = avio_rb32(pb);
7240 if (size > atom.size)
7241 return AVERROR_INVALIDDATA;
7242
7243 tag = avio_rl32(pb);
7244 if (tag != MKTAG('p','r','h','d')) {
7245 av_log(c->fc, AV_LOG_ERROR, "Missing projection header box\n");
7246 return 0;
7247 }
7248 version = avio_r8(pb);
7249 if (version != 0) {
7250 av_log(c->fc, AV_LOG_WARNING, "Unknown spherical version %d\n",
7251 version);
7252 return 0;
7253 }
7254 avio_skip(pb, 3); /* flags */
7255
7256 /* 16.16 fixed point */
7257 yaw = avio_rb32(pb);
7258 pitch = avio_rb32(pb);
7259 roll = avio_rb32(pb);
7260
7261 size = avio_rb32(pb);
7262 if (size > atom.size)
7263 return AVERROR_INVALIDDATA;
7264
7265 tag = avio_rl32(pb);
7266 version = avio_r8(pb);
7267 if (version != 0) {
7268 av_log(c->fc, AV_LOG_WARNING, "Unknown spherical version %d\n",
7269 version);
7270 return 0;
7271 }
7272 avio_skip(pb, 3); /* flags */
7273 switch (tag) {
7274 case MKTAG('c','b','m','p'):
7275 layout = avio_rb32(pb);
7276 if (layout) {
7277 av_log(c->fc, AV_LOG_WARNING,
7278 "Unsupported cubemap layout %d\n", layout);
7279 return 0;
7280 }
7281 projection = AV_SPHERICAL_CUBEMAP;
7282 padding = avio_rb32(pb);
7283 break;
7284 case MKTAG('e','q','u','i'):
7285 t = avio_rb32(pb);
7286 b = avio_rb32(pb);
7287 l = avio_rb32(pb);
7288 r = avio_rb32(pb);
7289
7290 if (b >= UINT_MAX - t || r >= UINT_MAX - l) {
7291 av_log(c->fc, AV_LOG_ERROR,
7292 "Invalid bounding rectangle coordinates "
7293 "%"PRIu32",%"PRIu32",%"PRIu32",%"PRIu32"\n", l, t, r, b);
7294 return AVERROR_INVALIDDATA;
7295 }
7296
7297 if (l || t || r || b)
7299 else
7300 projection = AV_SPHERICAL_EQUIRECTANGULAR;
7301 break;
7302 default:
7303 av_log(c->fc, AV_LOG_ERROR, "Unknown projection type: %s\n", av_fourcc2str(tag));
7304 return 0;
7305 }
7306
7308 if (!sc->spherical)
7309 return AVERROR(ENOMEM);
7310
7311 sc->spherical->projection = projection;
7312
7313 sc->spherical->yaw = yaw;
7314 sc->spherical->pitch = pitch;
7315 sc->spherical->roll = roll;
7316
7317 sc->spherical->padding = padding;
7318
7319 sc->spherical->bound_left = l;
7320 sc->spherical->bound_top = t;
7321 sc->spherical->bound_right = r;
7322 sc->spherical->bound_bottom = b;
7323
7324 return 0;
7325}
7326
7328{
7329 AVStream *st;
7330 MOVStreamContext *sc;
7331 int size;
7332 uint32_t tag;
7333 enum AVSphericalProjection projection;
7334
7335 if (c->fc->nb_streams < 1)
7336 return 0;
7337
7338 st = c->fc->streams[c->fc->nb_streams - 1];
7339 sc = st->priv_data;
7340
7341 if (atom.size < 16) {
7342 av_log(c->fc, AV_LOG_ERROR, "Invalid size for proj box: %"PRIu64"\n", atom.size);
7343 return AVERROR_INVALIDDATA;
7344 }
7345
7346 size = avio_rb32(pb);
7347 if (size < 16) {
7348 av_log(c->fc, AV_LOG_ERROR, "Invalid size for prji box: %d\n", size);
7349 return AVERROR_INVALIDDATA;
7350 } else if (size > 16) {
7351 av_log(c->fc, AV_LOG_WARNING, "Box has more bytes (%d) than prji box required (16) \n", size);
7352 }
7353
7354 tag = avio_rl32(pb);
7355 if (tag != MKTAG('p','r','j','i')) {
7356 av_log(c->fc, AV_LOG_ERROR, "Invalid child box of proj box: %s\n",
7358 return AVERROR_INVALIDDATA;
7359 }
7360
7361 // version and flags, only support (0, 0)
7362 unsigned n = avio_rl32(pb);
7363 if (n != 0) {
7364 av_log(c->fc, AV_LOG_ERROR, "prji version %u, flag %u are not supported\n",
7365 n & 0xFF, n >> 8);
7366 return AVERROR_PATCHWELCOME;
7367 }
7368
7369 tag = avio_rl32(pb);
7370 switch (tag) {
7371 case MKTAG('r','e','c','t'):
7372 projection = AV_SPHERICAL_RECTILINEAR;
7373 break;
7374 case MKTAG('e','q','u','i'):
7375 projection = AV_SPHERICAL_EQUIRECTANGULAR;
7376 break;
7377 case MKTAG('h','e','q','u'):
7379 break;
7380 case MKTAG('f','i','s','h'):
7381 projection = AV_SPHERICAL_FISHEYE;
7382 break;
7383 case MKTAG('p','r','i','m'):
7385 break;
7386 default:
7387 av_log(c->fc, AV_LOG_ERROR, "Invalid projection type in prji box: %s\n", av_fourcc2str(tag));
7388 return AVERROR_INVALIDDATA;
7389 }
7390
7392 if (!sc->spherical)
7393 return AVERROR(ENOMEM);
7394
7395 sc->spherical->projection = projection;
7396
7397 return 0;
7398}
7399
7401{
7402 AVStream *st;
7403 MOVStreamContext *sc;
7404 int size, flags = 0;
7405 int64_t remaining;
7406 uint32_t tag, baseline = 0;
7409 enum AVStereo3DPrimaryEye primary_eye = AV_PRIMARY_EYE_NONE;
7410 AVRational horizontal_disparity_adjustment = { 0, 1 };
7411
7412 if (c->fc->nb_streams < 1)
7413 return 0;
7414
7415 st = c->fc->streams[c->fc->nb_streams - 1];
7416 sc = st->priv_data;
7417
7418 remaining = atom.size;
7419 while (remaining > 0) {
7420 size = avio_rb32(pb);
7421 if (size < 8 || size > remaining ) {
7422 av_log(c->fc, AV_LOG_ERROR, "Invalid child size in eyes box\n");
7423 return AVERROR_INVALIDDATA;
7424 }
7425
7426 tag = avio_rl32(pb);
7427 switch (tag) {
7428 case MKTAG('s','t','r','i'): {
7429 int has_right, has_left;
7430 uint8_t tmp;
7431 if (size != 13) {
7432 av_log(c->fc, AV_LOG_ERROR, "Invalid size of stri box: %d\n", size);
7433 return AVERROR_INVALIDDATA;
7434 }
7435 avio_skip(pb, 1); // version
7436 avio_skip(pb, 3); // flags
7437
7438 tmp = avio_r8(pb);
7439
7440 // eye_views_reversed
7441 if (tmp & 8) {
7443 }
7444 // has_additional_views
7445 if (tmp & 4) {
7446 // skip...
7447 }
7448
7449 has_right = tmp & 2; // has_right_eye_view
7450 has_left = tmp & 1; // has_left_eye_view
7451
7452 if (has_left && has_right)
7454 else if (has_left)
7455 view = AV_STEREO3D_VIEW_LEFT;
7456 else if (has_right)
7458 if (has_left || has_right)
7460
7461 break;
7462 }
7463 case MKTAG('h','e','r','o'): {
7464 int tmp;
7465 if (size != 13) {
7466 av_log(c->fc, AV_LOG_ERROR, "Invalid size of hero box: %d\n", size);
7467 return AVERROR_INVALIDDATA;
7468 }
7469 avio_skip(pb, 1); // version
7470 avio_skip(pb, 3); // flags
7471
7472 tmp = avio_r8(pb);
7473 if (tmp == 0)
7474 primary_eye = AV_PRIMARY_EYE_NONE;
7475 else if (tmp == 1)
7476 primary_eye = AV_PRIMARY_EYE_LEFT;
7477 else if (tmp == 2)
7478 primary_eye = AV_PRIMARY_EYE_RIGHT;
7479 else
7480 av_log(c->fc, AV_LOG_WARNING, "Unknown hero eye type: %d\n", tmp);
7481
7482 break;
7483 }
7484 case MKTAG('c','a','m','s'): {
7485 uint32_t subtag;
7486 int subsize;
7487 if (size != 24) {
7488 av_log(c->fc, AV_LOG_ERROR, "Invalid size of cams box: %d\n", size);
7489 return AVERROR_INVALIDDATA;
7490 }
7491
7492 subsize = avio_rb32(pb);
7493 if (subsize != 16) {
7494 av_log(c->fc, AV_LOG_ERROR, "Invalid size of blin box: %d\n", size);
7495 return AVERROR_INVALIDDATA;
7496 }
7497
7498 subtag = avio_rl32(pb);
7499 if (subtag != MKTAG('b','l','i','n')) {
7500 av_log(c->fc, AV_LOG_ERROR, "Expected blin box, got %s\n",
7501 av_fourcc2str(subtag));
7502 return AVERROR_INVALIDDATA;
7503 }
7504
7505 avio_skip(pb, 1); // version
7506 avio_skip(pb, 3); // flags
7507
7508 baseline = avio_rb32(pb);
7509
7510 break;
7511 }
7512 case MKTAG('c','m','f','y'): {
7513 uint32_t subtag;
7514 int subsize;
7515 int32_t adjustment;
7516 if (size != 24) {
7517 av_log(c->fc, AV_LOG_ERROR, "Invalid size of cmfy box: %d\n", size);
7518 return AVERROR_INVALIDDATA;
7519 }
7520
7521 subsize = avio_rb32(pb);
7522 if (subsize != 16) {
7523 av_log(c->fc, AV_LOG_ERROR, "Invalid size of dadj box: %d\n", size);
7524 return AVERROR_INVALIDDATA;
7525 }
7526
7527 subtag = avio_rl32(pb);
7528 if (subtag != MKTAG('d','a','d','j')) {
7529 av_log(c->fc, AV_LOG_ERROR, "Expected dadj box, got %s\n",
7530 av_fourcc2str(subtag));
7531 return AVERROR_INVALIDDATA;
7532 }
7533
7534 avio_skip(pb, 1); // version
7535 avio_skip(pb, 3); // flags
7536
7537 adjustment = (int32_t) avio_rb32(pb);
7538
7539 horizontal_disparity_adjustment.num = (int) adjustment;
7540 horizontal_disparity_adjustment.den = 10000;
7541
7542 break;
7543 }
7544 default:
7545 av_log(c->fc, AV_LOG_WARNING, "Unknown tag in eyes: %s\n",
7547 avio_skip(pb, size - 8);
7548 break;
7549 }
7550 remaining -= size;
7551 }
7552
7553 if (remaining != 0) {
7554 av_log(c->fc, AV_LOG_ERROR, "Broken eyes box\n");
7555 return AVERROR_INVALIDDATA;
7556 }
7557
7558 if (type == AV_STEREO3D_2D)
7559 return 0;
7560
7561 if (!sc->stereo3d) {
7563 if (!sc->stereo3d)
7564 return AVERROR(ENOMEM);
7565 }
7566
7567 sc->stereo3d->flags = flags;
7568 sc->stereo3d->type = type;
7569 sc->stereo3d->view = view;
7570 sc->stereo3d->primary_eye = primary_eye;
7571 sc->stereo3d->baseline = baseline;
7572 sc->stereo3d->horizontal_disparity_adjustment = horizontal_disparity_adjustment;
7573
7574 return 0;
7575}
7576
7578{
7579 int size;
7580 int64_t remaining;
7581 uint32_t tag;
7582
7583 if (c->fc->nb_streams < 1)
7584 return 0;
7585
7586 if (atom.size < 8) {
7587 av_log(c->fc, AV_LOG_ERROR, "Empty video extension usage box\n");
7588 return AVERROR_INVALIDDATA;
7589 }
7590
7591 remaining = atom.size;
7592 while (remaining > 0) {
7593 size = avio_rb32(pb);
7594 if (size < 8 || size > remaining ) {
7595 av_log(c->fc, AV_LOG_ERROR, "Invalid child size in vexu box\n");
7596 return AVERROR_INVALIDDATA;
7597 }
7598
7599 tag = avio_rl32(pb);
7600 switch (tag) {
7601 case MKTAG('p','r','o','j'): {
7602 MOVAtom proj = { tag, size - 8 };
7603 int ret = mov_read_vexu_proj(c, pb, proj);
7604 if (ret < 0)
7605 return ret;
7606 break;
7607 }
7608 case MKTAG('e','y','e','s'): {
7609 MOVAtom eyes = { tag, size - 8 };
7610 int ret = mov_read_eyes(c, pb, eyes);
7611 if (ret < 0)
7612 return ret;
7613 break;
7614 }
7615 case MKTAG('p','a','c','k'): {
7616 MOVAtom pack = { tag, size - 8 };
7617 int ret = mov_read_pack(c, pb, pack);
7618 if (ret < 0)
7619 return ret;
7620 break;
7621 }
7622 default:
7623 av_log(c->fc, AV_LOG_WARNING, "Unknown tag in vexu: %s\n",
7625 avio_skip(pb, size - 8);
7626 break;
7627 }
7628 remaining -= size;
7629 }
7630
7631 if (remaining != 0) {
7632 av_log(c->fc, AV_LOG_ERROR, "Broken vexu box\n");
7633 return AVERROR_INVALIDDATA;
7634 }
7635
7636 return 0;
7637}
7638
7640{
7641 AVStream *st;
7642 MOVStreamContext *sc;
7643
7644 if (c->fc->nb_streams < 1)
7645 return 0;
7646
7647 st = c->fc->streams[c->fc->nb_streams - 1];
7648 sc = st->priv_data;
7649
7650 if (atom.size != 4) {
7651 av_log(c->fc, AV_LOG_ERROR, "Invalid size of hfov box: %"PRIu64"\n", atom.size);
7652 return AVERROR_INVALIDDATA;
7653 }
7654
7655
7656 if (!sc->stereo3d) {
7658 if (!sc->stereo3d)
7659 return AVERROR(ENOMEM);
7660 }
7661
7663 sc->stereo3d->horizontal_field_of_view.den = 1000; // thousands of a degree
7664
7665 return 0;
7666}
7667
7669{
7670 int ret = 0;
7671 uint8_t *buffer = av_malloc(len + 1);
7672 const char *val;
7673
7674 if (!buffer)
7675 return AVERROR(ENOMEM);
7676 buffer[len] = '\0';
7677
7678 ret = ffio_read_size(pb, buffer, len);
7679 if (ret < 0)
7680 goto out;
7681
7682 /* Check for mandatory keys and values, try to support XML as best-effort */
7683 if (!sc->spherical &&
7684 av_stristr(buffer, "<GSpherical:StitchingSoftware>") &&
7685 (val = av_stristr(buffer, "<GSpherical:Spherical>")) &&
7686 av_stristr(val, "true") &&
7687 (val = av_stristr(buffer, "<GSpherical:Stitched>")) &&
7688 av_stristr(val, "true") &&
7689 (val = av_stristr(buffer, "<GSpherical:ProjectionType>")) &&
7690 av_stristr(val, "equirectangular")) {
7692 if (!sc->spherical)
7693 goto out;
7694
7696
7697 if (av_stristr(buffer, "<GSpherical:StereoMode>") && !sc->stereo3d) {
7698 enum AVStereo3DType mode;
7699
7700 if (av_stristr(buffer, "left-right"))
7702 else if (av_stristr(buffer, "top-bottom"))
7704 else
7706
7708 if (!sc->stereo3d)
7709 goto out;
7710
7711 sc->stereo3d->type = mode;
7712 }
7713
7714 /* orientation */
7715 val = av_stristr(buffer, "<GSpherical:InitialViewHeadingDegrees>");
7716 if (val)
7717 sc->spherical->yaw = strtol(val, NULL, 10) * (1 << 16);
7718 val = av_stristr(buffer, "<GSpherical:InitialViewPitchDegrees>");
7719 if (val)
7720 sc->spherical->pitch = strtol(val, NULL, 10) * (1 << 16);
7721 val = av_stristr(buffer, "<GSpherical:InitialViewRollDegrees>");
7722 if (val)
7723 sc->spherical->roll = strtol(val, NULL, 10) * (1 << 16);
7724 }
7725
7726out:
7727 av_free(buffer);
7728 return ret;
7729}
7730
7732{
7733 AVStream *st;
7734 MOVStreamContext *sc;
7735 int64_t ret;
7736 AVUUID uuid;
7737 static const AVUUID uuid_isml_manifest = {
7738 0xa5, 0xd4, 0x0b, 0x30, 0xe8, 0x14, 0x11, 0xdd,
7739 0xba, 0x2f, 0x08, 0x00, 0x20, 0x0c, 0x9a, 0x66
7740 };
7741 static const AVUUID uuid_xmp = {
7742 0xbe, 0x7a, 0xcf, 0xcb, 0x97, 0xa9, 0x42, 0xe8,
7743 0x9c, 0x71, 0x99, 0x94, 0x91, 0xe3, 0xaf, 0xac
7744 };
7745 static const AVUUID uuid_spherical = {
7746 0xff, 0xcc, 0x82, 0x63, 0xf8, 0x55, 0x4a, 0x93,
7747 0x88, 0x14, 0x58, 0x7a, 0x02, 0x52, 0x1f, 0xdd,
7748 };
7749
7750 if (atom.size < AV_UUID_LEN || atom.size >= FFMIN(INT_MAX, SIZE_MAX))
7751 return AVERROR_INVALIDDATA;
7752
7753 if (c->fc->nb_streams < 1)
7754 return 0;
7755 st = c->fc->streams[c->fc->nb_streams - 1];
7756 sc = st->priv_data;
7757
7758 ret = ffio_read_size(pb, uuid, AV_UUID_LEN);
7759 if (ret < 0)
7760 return ret;
7761 if (av_uuid_equal(uuid, uuid_isml_manifest)) {
7762 uint8_t *buffer, *ptr;
7763 char *endptr;
7764 size_t len = atom.size - AV_UUID_LEN;
7765
7766 if (len < 4) {
7767 return AVERROR_INVALIDDATA;
7768 }
7769 ret = avio_skip(pb, 4); // zeroes
7770 len -= 4;
7771
7772 buffer = av_mallocz(len + 1);
7773 if (!buffer) {
7774 return AVERROR(ENOMEM);
7775 }
7776 ret = ffio_read_size(pb, buffer, len);
7777 if (ret < 0) {
7778 av_free(buffer);
7779 return ret;
7780 }
7781
7782 ptr = buffer;
7783 while ((ptr = av_stristr(ptr, "systemBitrate=\""))) {
7784 ptr += sizeof("systemBitrate=\"") - 1;
7785 c->bitrates_count++;
7786 c->bitrates = av_realloc_f(c->bitrates, c->bitrates_count, sizeof(*c->bitrates));
7787 if (!c->bitrates) {
7788 c->bitrates_count = 0;
7789 av_free(buffer);
7790 return AVERROR(ENOMEM);
7791 }
7792 errno = 0;
7793 ret = strtol(ptr, &endptr, 10);
7794 if (ret < 0 || errno || *endptr != '"') {
7795 c->bitrates[c->bitrates_count - 1] = 0;
7796 } else {
7797 c->bitrates[c->bitrates_count - 1] = ret;
7798 }
7799 }
7800
7801 av_free(buffer);
7802 } else if (av_uuid_equal(uuid, uuid_xmp)) {
7803 uint8_t *buffer;
7804 size_t len = atom.size - AV_UUID_LEN;
7805 if (c->export_xmp) {
7806 buffer = av_mallocz(len + 1);
7807 if (!buffer) {
7808 return AVERROR(ENOMEM);
7809 }
7810 ret = ffio_read_size(pb, buffer, len);
7811 if (ret < 0) {
7812 av_free(buffer);
7813 return ret;
7814 }
7815 buffer[len] = '\0';
7816 av_dict_set(&c->fc->metadata, "xmp",
7818 } else {
7819 // skip all uuid atom, which makes it fast for long uuid-xmp file
7820 ret = avio_skip(pb, len);
7821 if (ret < 0)
7822 return ret;
7823 }
7824 } else if (av_uuid_equal(uuid, uuid_spherical)) {
7825 size_t len = atom.size - AV_UUID_LEN;
7826 ret = mov_parse_uuid_spherical(sc, pb, len);
7827 if (ret < 0)
7828 return ret;
7829 if (!sc->spherical)
7830 av_log(c->fc, AV_LOG_WARNING, "Invalid spherical metadata found\n");
7831 }
7832
7833 return 0;
7834}
7835
7837{
7838 int ret;
7839 uint8_t content[16];
7840
7841 if (atom.size < 8)
7842 return 0;
7843
7844 ret = ffio_read_size(pb, content, FFMIN(sizeof(content), atom.size));
7845 if (ret < 0)
7846 return ret;
7847
7848 if ( !c->found_moov
7849 && !c->found_mdat
7850 && !memcmp(content, "Anevia\x1A\x1A", 8)
7851 && c->use_mfra_for == FF_MOV_FLAG_MFRA_AUTO) {
7852 c->use_mfra_for = FF_MOV_FLAG_MFRA_PTS;
7853 }
7854
7855 return 0;
7856}
7857
7859{
7860 uint32_t format = avio_rl32(pb);
7861 MOVStreamContext *sc;
7862 enum AVCodecID id;
7863 AVStream *st;
7864
7865 if (c->fc->nb_streams < 1)
7866 return 0;
7867 st = c->fc->streams[c->fc->nb_streams - 1];
7868 sc = st->priv_data;
7869
7870 switch (sc->format)
7871 {
7872 case MKTAG('e','n','c','v'): // encrypted video
7873 case MKTAG('e','n','c','a'): // encrypted audio
7874 id = mov_codec_id(st, format);
7875 if (st->codecpar->codec_id != AV_CODEC_ID_NONE &&
7876 st->codecpar->codec_id != id) {
7877 av_log(c->fc, AV_LOG_WARNING,
7878 "ignoring 'frma' atom of '%.4s', stream has codec id %d\n",
7879 (char*)&format, st->codecpar->codec_id);
7880 break;
7881 }
7882
7883 st->codecpar->codec_id = id;
7884 sc->format = format;
7885 break;
7886
7887 default:
7888 if (format != sc->format) {
7889 av_log(c->fc, AV_LOG_WARNING,
7890 "ignoring 'frma' atom of '%.4s', stream format is '%.4s'\n",
7891 (char*)&format, (char*)&sc->format);
7892 }
7893 break;
7894 }
7895
7896 return 0;
7897}
7898
7899/**
7900 * Gets the current encryption info and associated current stream context. If
7901 * we are parsing a track fragment, this will return the specific encryption
7902 * info for this fragment; otherwise this will return the global encryption
7903 * info for the current stream.
7904 */
7906{
7907 MOVFragmentStreamInfo *frag_stream_info;
7908 AVStream *st;
7909 int i;
7910
7911 frag_stream_info = get_current_frag_stream_info(&c->frag_index);
7912 if (frag_stream_info) {
7913 for (i = 0; i < c->fc->nb_streams; i++) {
7914 *sc = c->fc->streams[i]->priv_data;
7915 if ((*sc)->id == frag_stream_info->id) {
7916 st = c->fc->streams[i];
7917 break;
7918 }
7919 }
7920 if (i == c->fc->nb_streams)
7921 return 0;
7922 *sc = st->priv_data;
7923
7924 if (!frag_stream_info->encryption_index) {
7925 // If this stream isn't encrypted, don't create the index.
7926 if (!(*sc)->cenc.default_encrypted_sample)
7927 return 0;
7928 frag_stream_info->encryption_index = av_mallocz(sizeof(*frag_stream_info->encryption_index));
7929 if (!frag_stream_info->encryption_index)
7930 return AVERROR(ENOMEM);
7931 }
7932 *encryption_index = frag_stream_info->encryption_index;
7933 return 1;
7934 } else {
7935 // No current track fragment, using stream level encryption info.
7936
7937 if (c->fc->nb_streams < 1)
7938 return 0;
7939 st = c->fc->streams[c->fc->nb_streams - 1];
7940 *sc = st->priv_data;
7941
7942 if (!(*sc)->cenc.encryption_index) {
7943 // If this stream isn't encrypted, don't create the index.
7944 if (!(*sc)->cenc.default_encrypted_sample)
7945 return 0;
7946 (*sc)->cenc.encryption_index = av_mallocz(sizeof(*frag_stream_info->encryption_index));
7947 if (!(*sc)->cenc.encryption_index)
7948 return AVERROR(ENOMEM);
7949 }
7950
7951 *encryption_index = (*sc)->cenc.encryption_index;
7952 return 1;
7953 }
7954}
7955
7957{
7958 int i, ret;
7959 unsigned int subsample_count;
7960 AVSubsampleEncryptionInfo *subsamples;
7961
7962 if (!sc->cenc.default_encrypted_sample) {
7963 av_log(c->fc, AV_LOG_ERROR, "Missing schm or tenc\n");
7964 return AVERROR_INVALIDDATA;
7965 }
7966
7967 if (sc->cenc.per_sample_iv_size || use_subsamples) {
7969 if (!*sample)
7970 return AVERROR(ENOMEM);
7971 } else
7972 *sample = NULL;
7973
7974 if (sc->cenc.per_sample_iv_size != 0) {
7975 if ((ret = ffio_read_size(pb, (*sample)->iv, sc->cenc.per_sample_iv_size)) < 0) {
7976 av_log(c->fc, AV_LOG_ERROR, "failed to read the initialization vector\n");
7978 *sample = NULL;
7979 return ret;
7980 }
7981 }
7982
7983 if (use_subsamples) {
7984 subsample_count = avio_rb16(pb);
7985 av_free((*sample)->subsamples);
7986 (*sample)->subsamples = av_calloc(subsample_count, sizeof(*subsamples));
7987 if (!(*sample)->subsamples) {
7989 *sample = NULL;
7990 return AVERROR(ENOMEM);
7991 }
7992
7993 for (i = 0; i < subsample_count && !pb->eof_reached; i++) {
7994 (*sample)->subsamples[i].bytes_of_clear_data = avio_rb16(pb);
7995 (*sample)->subsamples[i].bytes_of_protected_data = avio_rb32(pb);
7996 }
7997
7998 if (pb->eof_reached) {
7999 av_log(c->fc, AV_LOG_ERROR, "hit EOF while reading sub-sample encryption info\n");
8001 *sample = NULL;
8002 return AVERROR_INVALIDDATA;
8003 }
8004 (*sample)->subsample_count = subsample_count;
8005 }
8006
8007 return 0;
8008}
8009
8011{
8012 AVEncryptionInfo **encrypted_samples;
8013 MOVEncryptionIndex *encryption_index;
8014 MOVStreamContext *sc;
8015 int use_subsamples, ret;
8016 unsigned int sample_count, i, alloc_size = 0;
8017
8018 ret = get_current_encryption_info(c, &encryption_index, &sc);
8019 if (ret != 1)
8020 return ret;
8021
8022 if (encryption_index->nb_encrypted_samples) {
8023 // This can happen if we have both saio/saiz and senc atoms.
8024 av_log(c->fc, AV_LOG_DEBUG, "Ignoring duplicate encryption info in senc\n");
8025 return 0;
8026 }
8027
8028 avio_r8(pb); /* version */
8029 use_subsamples = avio_rb24(pb) & 0x02; /* flags */
8030
8031 sample_count = avio_rb32(pb);
8032 if (sample_count >= INT_MAX / sizeof(*encrypted_samples))
8033 return AVERROR(ENOMEM);
8034
8035 for (i = 0; i < sample_count; i++) {
8036 unsigned int min_samples = FFMIN(FFMAX(i + 1, 1024 * 1024), sample_count);
8037 encrypted_samples = av_fast_realloc(encryption_index->encrypted_samples, &alloc_size,
8038 min_samples * sizeof(*encrypted_samples));
8039 if (encrypted_samples) {
8040 encryption_index->encrypted_samples = encrypted_samples;
8041
8043 c, pb, sc, &encryption_index->encrypted_samples[i], use_subsamples);
8044 } else {
8045 ret = AVERROR(ENOMEM);
8046 }
8047 if (pb->eof_reached) {
8048 av_log(c->fc, AV_LOG_ERROR, "Hit EOF while reading senc\n");
8049 if (ret >= 0)
8050 av_encryption_info_free(encryption_index->encrypted_samples[i]);
8051 ret = AVERROR_INVALIDDATA;
8052 }
8053
8054 if (ret < 0) {
8055 for (; i > 0; i--)
8056 av_encryption_info_free(encryption_index->encrypted_samples[i - 1]);
8057 av_freep(&encryption_index->encrypted_samples);
8058 return ret;
8059 }
8060 }
8061 encryption_index->nb_encrypted_samples = sample_count;
8062
8063 return 0;
8064}
8065
8067{
8068 AVEncryptionInfo **sample, **encrypted_samples;
8069 int64_t prev_pos;
8070 size_t sample_count, sample_info_size, i;
8071 int ret = 0;
8072 unsigned int alloc_size = 0;
8073
8074 if (encryption_index->nb_encrypted_samples)
8075 return 0;
8076 sample_count = encryption_index->auxiliary_info_sample_count;
8077 if (encryption_index->auxiliary_offsets_count != 1) {
8078 av_log(c->fc, AV_LOG_ERROR, "Multiple auxiliary info chunks are not supported\n");
8079 return AVERROR_PATCHWELCOME;
8080 }
8081 if (sample_count >= INT_MAX / sizeof(*encrypted_samples))
8082 return AVERROR(ENOMEM);
8083
8084 prev_pos = avio_tell(pb);
8085 if (!(pb->seekable & AVIO_SEEKABLE_NORMAL) ||
8086 avio_seek(pb, encryption_index->auxiliary_offsets[0], SEEK_SET) != encryption_index->auxiliary_offsets[0]) {
8087 av_log(c->fc, AV_LOG_INFO, "Failed to seek for auxiliary info, will only parse senc atoms for encryption info\n");
8088 goto finish;
8089 }
8090
8091 for (i = 0; i < sample_count && !pb->eof_reached; i++) {
8092 unsigned int min_samples = FFMIN(FFMAX(i + 1, 1024 * 1024), sample_count);
8093 encrypted_samples = av_fast_realloc(encryption_index->encrypted_samples, &alloc_size,
8094 min_samples * sizeof(*encrypted_samples));
8095 if (!encrypted_samples) {
8096 ret = AVERROR(ENOMEM);
8097 goto finish;
8098 }
8099 encryption_index->encrypted_samples = encrypted_samples;
8100
8101 sample = &encryption_index->encrypted_samples[i];
8102 sample_info_size = encryption_index->auxiliary_info_default_size
8103 ? encryption_index->auxiliary_info_default_size
8104 : encryption_index->auxiliary_info_sizes[i];
8105
8106 ret = mov_read_sample_encryption_info(c, pb, sc, sample, sample_info_size > sc->cenc.per_sample_iv_size);
8107 if (ret < 0)
8108 goto finish;
8109 }
8110 if (pb->eof_reached) {
8111 av_log(c->fc, AV_LOG_ERROR, "Hit EOF while reading auxiliary info\n");
8112 ret = AVERROR_INVALIDDATA;
8113 } else {
8114 encryption_index->nb_encrypted_samples = sample_count;
8115 }
8116
8117finish:
8118 avio_seek(pb, prev_pos, SEEK_SET);
8119 if (ret < 0) {
8120 for (; i > 0; i--) {
8121 av_encryption_info_free(encryption_index->encrypted_samples[i - 1]);
8122 }
8123 av_freep(&encryption_index->encrypted_samples);
8124 }
8125 return ret;
8126}
8127
8129{
8130 MOVEncryptionIndex *encryption_index;
8131 MOVStreamContext *sc;
8132 int ret;
8133 unsigned int sample_count, aux_info_type, aux_info_param;
8134
8135 ret = get_current_encryption_info(c, &encryption_index, &sc);
8136 if (ret != 1)
8137 return ret;
8138
8139 if (encryption_index->nb_encrypted_samples) {
8140 // This can happen if we have both saio/saiz and senc atoms.
8141 av_log(c->fc, AV_LOG_DEBUG, "Ignoring duplicate encryption info in saiz\n");
8142 return 0;
8143 }
8144
8145 if (encryption_index->auxiliary_info_sample_count) {
8146 av_log(c->fc, AV_LOG_ERROR, "Duplicate saiz atom\n");
8147 return AVERROR_INVALIDDATA;
8148 }
8149
8150 avio_r8(pb); /* version */
8151 if (avio_rb24(pb) & 0x01) { /* flags */
8152 aux_info_type = avio_rb32(pb);
8153 aux_info_param = avio_rb32(pb);
8155 if (aux_info_type != sc->cenc.default_encrypted_sample->scheme) {
8156 av_log(c->fc, AV_LOG_DEBUG, "Ignoring saiz box with non-zero aux_info_type\n");
8157 return 0;
8158 }
8159 if (aux_info_param != 0) {
8160 av_log(c->fc, AV_LOG_DEBUG, "Ignoring saiz box with non-zero aux_info_type_parameter\n");
8161 return 0;
8162 }
8163 } else {
8164 // Didn't see 'schm' or 'tenc', so this isn't encrypted.
8165 if ((aux_info_type == MKBETAG('c','e','n','c') ||
8166 aux_info_type == MKBETAG('c','e','n','s') ||
8167 aux_info_type == MKBETAG('c','b','c','1') ||
8168 aux_info_type == MKBETAG('c','b','c','s')) &&
8169 aux_info_param == 0) {
8170 av_log(c->fc, AV_LOG_ERROR, "Saw encrypted saiz without schm/tenc\n");
8171 return AVERROR_INVALIDDATA;
8172 } else {
8173 return 0;
8174 }
8175 }
8176 } else if (!sc->cenc.default_encrypted_sample) {
8177 // Didn't see 'schm' or 'tenc', so this isn't encrypted.
8178 return 0;
8179 }
8180
8181 encryption_index->auxiliary_info_default_size = avio_r8(pb);
8182 sample_count = avio_rb32(pb);
8183
8184 if (encryption_index->auxiliary_info_default_size == 0) {
8185 if (sample_count == 0)
8186 return AVERROR_INVALIDDATA;
8187
8188 encryption_index->auxiliary_info_sizes = av_malloc(sample_count);
8189 if (!encryption_index->auxiliary_info_sizes)
8190 return AVERROR(ENOMEM);
8191
8192 ret = avio_read(pb, encryption_index->auxiliary_info_sizes, sample_count);
8193 if (ret != sample_count) {
8194 av_freep(&encryption_index->auxiliary_info_sizes);
8195
8196 if (ret >= 0)
8197 ret = AVERROR_INVALIDDATA;
8198 av_log(c->fc, AV_LOG_ERROR, "Failed to read the auxiliary info, %s\n",
8199 av_err2str(ret));
8200 return ret;
8201 }
8202 }
8203 encryption_index->auxiliary_info_sample_count = sample_count;
8204
8205 if (encryption_index->auxiliary_offsets_count) {
8206 return mov_parse_auxiliary_info(c, sc, pb, encryption_index);
8207 }
8208
8209 return 0;
8210}
8211
8213{
8214 uint64_t *auxiliary_offsets;
8215 MOVEncryptionIndex *encryption_index;
8216 MOVStreamContext *sc;
8217 int i, ret;
8218 unsigned int version, entry_count, aux_info_type, aux_info_param;
8219 unsigned int alloc_size = 0;
8220
8221 ret = get_current_encryption_info(c, &encryption_index, &sc);
8222 if (ret != 1)
8223 return ret;
8224
8225 if (encryption_index->nb_encrypted_samples) {
8226 // This can happen if we have both saio/saiz and senc atoms.
8227 av_log(c->fc, AV_LOG_DEBUG, "Ignoring duplicate encryption info in saio\n");
8228 return 0;
8229 }
8230
8231 if (encryption_index->auxiliary_offsets_count) {
8232 av_log(c->fc, AV_LOG_ERROR, "Duplicate saio atom\n");
8233 return AVERROR_INVALIDDATA;
8234 }
8235
8236 version = avio_r8(pb); /* version */
8237 if (avio_rb24(pb) & 0x01) { /* flags */
8238 aux_info_type = avio_rb32(pb);
8239 aux_info_param = avio_rb32(pb);
8241 if (aux_info_type != sc->cenc.default_encrypted_sample->scheme) {
8242 av_log(c->fc, AV_LOG_DEBUG, "Ignoring saio box with non-zero aux_info_type\n");
8243 return 0;
8244 }
8245 if (aux_info_param != 0) {
8246 av_log(c->fc, AV_LOG_DEBUG, "Ignoring saio box with non-zero aux_info_type_parameter\n");
8247 return 0;
8248 }
8249 } else {
8250 // Didn't see 'schm' or 'tenc', so this isn't encrypted.
8251 if ((aux_info_type == MKBETAG('c','e','n','c') ||
8252 aux_info_type == MKBETAG('c','e','n','s') ||
8253 aux_info_type == MKBETAG('c','b','c','1') ||
8254 aux_info_type == MKBETAG('c','b','c','s')) &&
8255 aux_info_param == 0) {
8256 av_log(c->fc, AV_LOG_ERROR, "Saw encrypted saio without schm/tenc\n");
8257 return AVERROR_INVALIDDATA;
8258 } else {
8259 return 0;
8260 }
8261 }
8262 } else if (!sc->cenc.default_encrypted_sample) {
8263 // Didn't see 'schm' or 'tenc', so this isn't encrypted.
8264 return 0;
8265 }
8266
8267 entry_count = avio_rb32(pb);
8268 if (entry_count >= INT_MAX / sizeof(*auxiliary_offsets))
8269 return AVERROR(ENOMEM);
8270
8271 for (i = 0; i < entry_count && !pb->eof_reached; i++) {
8272 unsigned int min_offsets = FFMIN(FFMAX(i + 1, 1024), entry_count);
8273 auxiliary_offsets = av_fast_realloc(
8274 encryption_index->auxiliary_offsets, &alloc_size,
8275 min_offsets * sizeof(*auxiliary_offsets));
8276 if (!auxiliary_offsets) {
8277 av_freep(&encryption_index->auxiliary_offsets);
8278 return AVERROR(ENOMEM);
8279 }
8280 encryption_index->auxiliary_offsets = auxiliary_offsets;
8281
8282 if (version == 0) {
8283 encryption_index->auxiliary_offsets[i] = avio_rb32(pb);
8284 } else {
8285 encryption_index->auxiliary_offsets[i] = avio_rb64(pb);
8286 }
8287 if (c->frag_index.current >= 0) {
8288 encryption_index->auxiliary_offsets[i] += c->fragment.base_data_offset;
8289 }
8290 }
8291
8292 if (pb->eof_reached) {
8293 av_log(c->fc, AV_LOG_ERROR, "Hit EOF while reading saio\n");
8294 av_freep(&encryption_index->auxiliary_offsets);
8295 return AVERROR_INVALIDDATA;
8296 }
8297
8298 encryption_index->auxiliary_offsets_count = entry_count;
8299
8300 if (encryption_index->auxiliary_info_sample_count) {
8301 return mov_parse_auxiliary_info(c, sc, pb, encryption_index);
8302 }
8303
8304 return 0;
8305}
8306
8308{
8309 AVEncryptionInitInfo *info, *old_init_info;
8310 uint8_t **key_ids;
8311 AVStream *st;
8312 const AVPacketSideData *old_side_data;
8313 uint8_t *side_data, *extra_data;
8314 size_t side_data_size;
8315 int ret = 0;
8316 unsigned int version, kid_count, extra_data_size, alloc_size = 0;
8317
8318 if (c->fc->nb_streams < 1)
8319 return 0;
8320 st = c->fc->streams[c->fc->nb_streams-1];
8321
8322 version = avio_r8(pb); /* version */
8323 avio_rb24(pb); /* flags */
8324
8325 info = av_encryption_init_info_alloc(/* system_id_size */ 16, /* num_key_ids */ 0,
8326 /* key_id_size */ 16, /* data_size */ 0);
8327 if (!info)
8328 return AVERROR(ENOMEM);
8329
8330 if ((ret = ffio_read_size(pb, info->system_id, 16)) < 0) {
8331 av_log(c->fc, AV_LOG_ERROR, "Failed to read the system id\n");
8332 goto finish;
8333 }
8334
8335 if (version > 0) {
8336 kid_count = avio_rb32(pb);
8337 if (kid_count >= INT_MAX / sizeof(*key_ids)) {
8338 ret = AVERROR(ENOMEM);
8339 goto finish;
8340 }
8341
8342 for (unsigned int i = 0; i < kid_count && !pb->eof_reached; i++) {
8343 unsigned int min_kid_count = FFMIN(FFMAX(i + 1, 1024), kid_count);
8344 key_ids = av_fast_realloc(info->key_ids, &alloc_size,
8345 min_kid_count * sizeof(*key_ids));
8346 if (!key_ids) {
8347 ret = AVERROR(ENOMEM);
8348 goto finish;
8349 }
8350 info->key_ids = key_ids;
8351
8352 info->key_ids[i] = av_mallocz(16);
8353 if (!info->key_ids[i]) {
8354 ret = AVERROR(ENOMEM);
8355 goto finish;
8356 }
8357 info->num_key_ids = i + 1;
8358
8359 if ((ret = ffio_read_size(pb, info->key_ids[i], 16)) < 0) {
8360 av_log(c->fc, AV_LOG_ERROR, "Failed to read the key id\n");
8361 goto finish;
8362 }
8363 }
8364
8365 if (pb->eof_reached) {
8366 av_log(c->fc, AV_LOG_ERROR, "Hit EOF while reading pssh\n");
8367 ret = AVERROR_INVALIDDATA;
8368 goto finish;
8369 }
8370 }
8371
8372 extra_data_size = avio_rb32(pb);
8373 extra_data = av_malloc(extra_data_size);
8374 if (!extra_data) {
8375 ret = AVERROR(ENOMEM);
8376 goto finish;
8377 }
8378 ret = avio_read(pb, extra_data, extra_data_size);
8379 if (ret != extra_data_size) {
8380 av_free(extra_data);
8381
8382 if (ret >= 0)
8383 ret = AVERROR_INVALIDDATA;
8384 goto finish;
8385 }
8386
8387 av_freep(&info->data); // malloc(0) may still allocate something.
8388 info->data = extra_data;
8389 info->data_size = extra_data_size;
8390
8391 // If there is existing initialization data, append to the list.
8394 if (old_side_data) {
8395 old_init_info = av_encryption_init_info_get_side_data(old_side_data->data, old_side_data->size);
8396 if (old_init_info) {
8397 // Append to the end of the list.
8398 for (AVEncryptionInitInfo *cur = old_init_info;; cur = cur->next) {
8399 if (!cur->next) {
8400 cur->next = info;
8401 break;
8402 }
8403 }
8404 info = old_init_info;
8405 } else {
8406 // Assume existing side-data will be valid, so the only error we could get is OOM.
8407 ret = AVERROR(ENOMEM);
8408 goto finish;
8409 }
8410 }
8411
8412 side_data = av_encryption_init_info_add_side_data(info, &side_data_size);
8413 if (!side_data) {
8414 ret = AVERROR(ENOMEM);
8415 goto finish;
8416 }
8420 side_data, side_data_size, 0))
8421 av_free(side_data);
8422
8423finish:
8425 return ret;
8426}
8427
8429{
8430 AVStream *st;
8431 MOVStreamContext *sc;
8432
8433 if (c->fc->nb_streams < 1)
8434 return 0;
8435 st = c->fc->streams[c->fc->nb_streams-1];
8436 sc = st->priv_data;
8437
8438 if (sc->pseudo_stream_id != 0) {
8439 av_log(c->fc, AV_LOG_ERROR, "schm boxes are only supported in first sample descriptor\n");
8440 return AVERROR_PATCHWELCOME;
8441 }
8442
8443 if (atom.size < 8)
8444 return AVERROR_INVALIDDATA;
8445
8446 avio_rb32(pb); /* version and flags */
8447
8448 if (!sc->cenc.default_encrypted_sample) {
8450 if (!sc->cenc.default_encrypted_sample) {
8451 return AVERROR(ENOMEM);
8452 }
8453 }
8454
8456 return 0;
8457}
8458
8460{
8461 AVStream *st;
8462 MOVStreamContext *sc;
8463 unsigned int version, pattern, is_protected, iv_size;
8464
8465 if (c->fc->nb_streams < 1)
8466 return 0;
8467 st = c->fc->streams[c->fc->nb_streams-1];
8468 sc = st->priv_data;
8469
8470 if (sc->pseudo_stream_id != 0) {
8471 av_log(c->fc, AV_LOG_ERROR, "tenc atom are only supported in first sample descriptor\n");
8472 return AVERROR_PATCHWELCOME;
8473 }
8474
8475 if (!sc->cenc.default_encrypted_sample) {
8477 if (!sc->cenc.default_encrypted_sample) {
8478 return AVERROR(ENOMEM);
8479 }
8480 }
8481
8482 if (atom.size < 20)
8483 return AVERROR_INVALIDDATA;
8484
8485 version = avio_r8(pb); /* version */
8486 avio_rb24(pb); /* flags */
8487
8488 avio_r8(pb); /* reserved */
8489 pattern = avio_r8(pb);
8490
8491 if (version > 0) {
8493 sc->cenc.default_encrypted_sample->skip_byte_block = pattern & 0xf;
8494 }
8495
8496 is_protected = avio_r8(pb);
8497 if (is_protected && !sc->cenc.encryption_index) {
8498 // The whole stream should be by-default encrypted.
8500 if (!sc->cenc.encryption_index)
8501 return AVERROR(ENOMEM);
8502 }
8504 if (sc->cenc.per_sample_iv_size != 0 && sc->cenc.per_sample_iv_size != 8 &&
8505 sc->cenc.per_sample_iv_size != 16) {
8506 av_log(c->fc, AV_LOG_ERROR, "invalid per-sample IV size value\n");
8507 return AVERROR_INVALIDDATA;
8508 }
8509 if (avio_read(pb, sc->cenc.default_encrypted_sample->key_id, 16) != 16) {
8510 av_log(c->fc, AV_LOG_ERROR, "failed to read the default key ID\n");
8511 return AVERROR_INVALIDDATA;
8512 }
8513
8514 if (is_protected && !sc->cenc.per_sample_iv_size) {
8515 iv_size = avio_r8(pb);
8516 if (iv_size != 8 && iv_size != 16) {
8517 av_log(c->fc, AV_LOG_ERROR, "invalid default_constant_IV_size in tenc atom\n");
8518 return AVERROR_INVALIDDATA;
8519 }
8520
8521 if (avio_read(pb, sc->cenc.default_encrypted_sample->iv, iv_size) != iv_size) {
8522 av_log(c->fc, AV_LOG_ERROR, "failed to read the default IV\n");
8523 return AVERROR_INVALIDDATA;
8524 }
8525 }
8526
8527 return 0;
8528}
8529
8531{
8532 AVStream *st;
8533 int last, type, size, ret;
8534 uint8_t buf[4];
8535
8536 if (c->fc->nb_streams < 1)
8537 return 0;
8538 st = c->fc->streams[c->fc->nb_streams-1];
8539
8540 if ((uint64_t)atom.size > (1<<30) || atom.size < 42)
8541 return AVERROR_INVALIDDATA;
8542
8543 /* Check FlacSpecificBox version. */
8544 if (avio_r8(pb) != 0)
8545 return AVERROR_INVALIDDATA;
8546
8547 avio_rb24(pb); /* Flags */
8548
8549 if (avio_read(pb, buf, sizeof(buf)) != sizeof(buf)) {
8550 av_log(c->fc, AV_LOG_ERROR, "failed to read FLAC metadata block header\n");
8551 return pb->error < 0 ? pb->error : AVERROR_INVALIDDATA;
8552 }
8553 flac_parse_block_header(buf, &last, &type, &size);
8554
8556 av_log(c->fc, AV_LOG_ERROR, "STREAMINFO must be first FLACMetadataBlock\n");
8557 return AVERROR_INVALIDDATA;
8558 }
8559
8560 ret = ff_get_extradata(c->fc, st->codecpar, pb, size);
8561 if (ret < 0)
8562 return ret;
8563
8564 if (!last)
8565 av_log(c->fc, AV_LOG_WARNING, "non-STREAMINFO FLACMetadataBlock(s) ignored\n");
8566
8567 return 0;
8568}
8569
8571 AVDictionaryEntry *key_entry_hex;
8572 char kid_hex[16*2+1];
8573
8574 if (c->decryption_default_key && c->decryption_default_key_len != len) {
8575 av_log(c->fc, AV_LOG_ERROR, "invalid default decryption key length: got %d, expected %d\n", c->decryption_default_key_len, len);
8576 return -1;
8577 }
8578
8579 if (!c->decryption_keys) {
8580 av_assert0(c->decryption_default_key);
8581 memcpy(out, c->decryption_default_key, len);
8582 return 0;
8583 }
8584
8585 if (sample->key_id_size != 16) {
8586 av_log(c->fc, AV_LOG_ERROR, "invalid key ID size: got %u, expected 16\n", sample->key_id_size);
8587 return -1;
8588 }
8589
8590 ff_data_to_hex(kid_hex, sample->key_id, 16, 1);
8591 key_entry_hex = av_dict_get(c->decryption_keys, kid_hex, NULL, AV_DICT_DONT_STRDUP_KEY|AV_DICT_DONT_STRDUP_VAL);
8592 if (!key_entry_hex) {
8593 if (!c->decryption_default_key) {
8594 av_log(c->fc, AV_LOG_ERROR, "unable to find KID %s\n", kid_hex);
8595 return -1;
8596 }
8597 memcpy(out, c->decryption_default_key, len);
8598 return 0;
8599 }
8600 if (strlen(key_entry_hex->value) != len*2) {
8601 return -1;
8602 }
8603 ff_hex_to_data(out, key_entry_hex->value);
8604 return 0;
8605}
8606
8608{
8609 int i, ret;
8610 int bytes_of_protected_data;
8611 uint8_t decryption_key[AES_CTR_KEY_SIZE];
8612
8613 if (!sc->cenc.aes_ctr) {
8614 ret = get_key_from_kid(decryption_key, sizeof(decryption_key), c, sample);
8615 if (ret < 0) {
8616 return ret;
8617 }
8618
8619 /* initialize the cipher */
8621 if (!sc->cenc.aes_ctr) {
8622 return AVERROR(ENOMEM);
8623 }
8624
8625 ret = av_aes_ctr_init(sc->cenc.aes_ctr, decryption_key);
8626 if (ret < 0) {
8627 return ret;
8628 }
8629 }
8630
8632
8633 if (!sample->subsample_count) {
8634 /* decrypt the whole packet */
8635 av_aes_ctr_crypt(sc->cenc.aes_ctr, input, input, size);
8636 return 0;
8637 }
8638
8639 for (i = 0; i < sample->subsample_count; i++) {
8640 if (sample->subsamples[i].bytes_of_clear_data + (int64_t)sample->subsamples[i].bytes_of_protected_data > size) {
8641 av_log(c->fc, AV_LOG_ERROR, "subsample size exceeds the packet size left\n");
8642 return AVERROR_INVALIDDATA;
8643 }
8644
8645 /* skip the clear bytes */
8646 input += sample->subsamples[i].bytes_of_clear_data;
8647 size -= sample->subsamples[i].bytes_of_clear_data;
8648
8649 /* decrypt the encrypted bytes */
8650
8651 bytes_of_protected_data = sample->subsamples[i].bytes_of_protected_data;
8652 av_aes_ctr_crypt(sc->cenc.aes_ctr, input, input, bytes_of_protected_data);
8653
8654 input += bytes_of_protected_data;
8655 size -= bytes_of_protected_data;
8656 }
8657
8658 if (size > 0) {
8659 av_log(c->fc, AV_LOG_ERROR, "leftover packet bytes after subsample processing\n");
8660 return AVERROR_INVALIDDATA;
8661 }
8662
8663 return 0;
8664}
8665
8667{
8668 int i, ret;
8669 int num_of_encrypted_blocks;
8670 uint8_t iv[16];
8671 uint8_t decryption_key[16];
8672
8673 if (!sc->cenc.aes_ctx) {
8674 ret = get_key_from_kid(decryption_key, sizeof(decryption_key), c, sample);
8675 if (ret < 0) {
8676 return ret;
8677 }
8678
8679 /* initialize the cipher */
8680 sc->cenc.aes_ctx = av_aes_alloc();
8681 if (!sc->cenc.aes_ctx) {
8682 return AVERROR(ENOMEM);
8683 }
8684
8685 ret = av_aes_init(sc->cenc.aes_ctx, decryption_key, 16 * 8, 1);
8686 if (ret < 0) {
8687 return ret;
8688 }
8689 }
8690
8691 memcpy(iv, sample->iv, 16);
8692
8693 /* whole-block full sample encryption */
8694 if (!sample->subsample_count) {
8695 /* decrypt the whole packet */
8696 av_aes_crypt(sc->cenc.aes_ctx, input, input, size/16, iv, 1);
8697 return 0;
8698 }
8699
8700 for (i = 0; i < sample->subsample_count; i++) {
8701 if (sample->subsamples[i].bytes_of_clear_data + (int64_t)sample->subsamples[i].bytes_of_protected_data > size) {
8702 av_log(c->fc, AV_LOG_ERROR, "subsample size exceeds the packet size left\n");
8703 return AVERROR_INVALIDDATA;
8704 }
8705
8706 if (sample->subsamples[i].bytes_of_protected_data % 16) {
8707 av_log(c->fc, AV_LOG_ERROR, "subsample BytesOfProtectedData is not a multiple of 16\n");
8708 return AVERROR_INVALIDDATA;
8709 }
8710
8711 /* skip the clear bytes */
8712 input += sample->subsamples[i].bytes_of_clear_data;
8713 size -= sample->subsamples[i].bytes_of_clear_data;
8714
8715 /* decrypt the encrypted bytes */
8716 num_of_encrypted_blocks = sample->subsamples[i].bytes_of_protected_data/16;
8717 if (num_of_encrypted_blocks > 0) {
8718 av_aes_crypt(sc->cenc.aes_ctx, input, input, num_of_encrypted_blocks, iv, 1);
8719 }
8720 input += sample->subsamples[i].bytes_of_protected_data;
8721 size -= sample->subsamples[i].bytes_of_protected_data;
8722 }
8723
8724 if (size > 0) {
8725 av_log(c->fc, AV_LOG_ERROR, "leftover packet bytes after subsample processing\n");
8726 return AVERROR_INVALIDDATA;
8727 }
8728
8729 return 0;
8730}
8731
8733{
8734 int i, ret, rem_bytes;
8735 uint8_t *data;
8736 uint8_t decryption_key[AES_CTR_KEY_SIZE];
8737
8738 if (!sc->cenc.aes_ctr) {
8739 ret = get_key_from_kid(decryption_key, sizeof(decryption_key), c, sample);
8740 if (ret < 0) {
8741 return ret;
8742 }
8743
8744 /* initialize the cipher */
8746 if (!sc->cenc.aes_ctr) {
8747 return AVERROR(ENOMEM);
8748 }
8749
8750 ret = av_aes_ctr_init(sc->cenc.aes_ctr, decryption_key);
8751 if (ret < 0) {
8752 return ret;
8753 }
8754 }
8755
8757
8758 /* whole-block full sample encryption */
8759 if (!sample->subsample_count) {
8760 /* decrypt the whole packet */
8761 av_aes_ctr_crypt(sc->cenc.aes_ctr, input, input, size);
8762 return 0;
8763 } else if (!sample->crypt_byte_block && !sample->skip_byte_block) {
8764 av_log(c->fc, AV_LOG_ERROR, "pattern encryption is not present in 'cens' scheme\n");
8765 return AVERROR_INVALIDDATA;
8766 }
8767
8768 for (i = 0; i < sample->subsample_count; i++) {
8769 if (sample->subsamples[i].bytes_of_clear_data + (int64_t)sample->subsamples[i].bytes_of_protected_data > size) {
8770 av_log(c->fc, AV_LOG_ERROR, "subsample size exceeds the packet size left\n");
8771 return AVERROR_INVALIDDATA;
8772 }
8773
8774 /* skip the clear bytes */
8775 input += sample->subsamples[i].bytes_of_clear_data;
8776 size -= sample->subsamples[i].bytes_of_clear_data;
8777
8778 /* decrypt the encrypted bytes */
8779 data = input;
8780 rem_bytes = sample->subsamples[i].bytes_of_protected_data;
8781 while (rem_bytes > 0) {
8782 if (rem_bytes < 16*sample->crypt_byte_block) {
8783 break;
8784 }
8785 av_aes_ctr_crypt(sc->cenc.aes_ctr, data, data, 16*sample->crypt_byte_block);
8786 data += 16*sample->crypt_byte_block;
8787 rem_bytes -= 16*sample->crypt_byte_block;
8788 data += FFMIN(16*sample->skip_byte_block, rem_bytes);
8789 rem_bytes -= FFMIN(16*sample->skip_byte_block, rem_bytes);
8790 }
8791 input += sample->subsamples[i].bytes_of_protected_data;
8792 size -= sample->subsamples[i].bytes_of_protected_data;
8793 }
8794
8795 if (size > 0) {
8796 av_log(c->fc, AV_LOG_ERROR, "leftover packet bytes after subsample processing\n");
8797 return AVERROR_INVALIDDATA;
8798 }
8799
8800 return 0;
8801}
8802
8804{
8805 int i, ret, rem_bytes;
8806 uint8_t iv[16];
8807 uint8_t *data;
8808 uint8_t decryption_key[16];
8809
8810 if (!sc->cenc.aes_ctx) {
8811 ret = get_key_from_kid(decryption_key, sizeof(decryption_key), c, sample);
8812 if (ret < 0) {
8813 return ret;
8814 }
8815
8816 /* initialize the cipher */
8817 sc->cenc.aes_ctx = av_aes_alloc();
8818 if (!sc->cenc.aes_ctx) {
8819 return AVERROR(ENOMEM);
8820 }
8821
8822 ret = av_aes_init(sc->cenc.aes_ctx, decryption_key, 16 * 8, 1);
8823 if (ret < 0) {
8824 return ret;
8825 }
8826 }
8827
8828 /* whole-block full sample encryption */
8829 if (!sample->subsample_count) {
8830 /* decrypt the whole packet */
8831 memcpy(iv, sample->iv, 16);
8832 av_aes_crypt(sc->cenc.aes_ctx, input, input, size/16, iv, 1);
8833 return 0;
8834 } else if (!sample->crypt_byte_block && !sample->skip_byte_block) {
8835 av_log(c->fc, AV_LOG_ERROR, "pattern encryption is not present in 'cbcs' scheme\n");
8836 return AVERROR_INVALIDDATA;
8837 }
8838
8839 for (i = 0; i < sample->subsample_count; i++) {
8840 if (sample->subsamples[i].bytes_of_clear_data + (int64_t)sample->subsamples[i].bytes_of_protected_data > size) {
8841 av_log(c->fc, AV_LOG_ERROR, "subsample size exceeds the packet size left\n");
8842 return AVERROR_INVALIDDATA;
8843 }
8844
8845 /* skip the clear bytes */
8846 input += sample->subsamples[i].bytes_of_clear_data;
8847 size -= sample->subsamples[i].bytes_of_clear_data;
8848
8849 /* decrypt the encrypted bytes */
8850 memcpy(iv, sample->iv, 16);
8851 data = input;
8852 rem_bytes = sample->subsamples[i].bytes_of_protected_data;
8853 while (rem_bytes > 0) {
8854 if (rem_bytes < 16*sample->crypt_byte_block) {
8855 break;
8856 }
8857 av_aes_crypt(sc->cenc.aes_ctx, data, data, sample->crypt_byte_block, iv, 1);
8858 data += 16*sample->crypt_byte_block;
8859 rem_bytes -= 16*sample->crypt_byte_block;
8860 data += FFMIN(16*sample->skip_byte_block, rem_bytes);
8861 rem_bytes -= FFMIN(16*sample->skip_byte_block, rem_bytes);
8862 }
8863 input += sample->subsamples[i].bytes_of_protected_data;
8864 size -= sample->subsamples[i].bytes_of_protected_data;
8865 }
8866
8867 if (size > 0) {
8868 av_log(c->fc, AV_LOG_ERROR, "leftover packet bytes after subsample processing\n");
8869 return AVERROR_INVALIDDATA;
8870 }
8871
8872 return 0;
8873}
8874
8875static int cenc_decrypt(MOVContext *c, MOVStreamContext *sc, AVEncryptionInfo *sample, uint8_t *input, int size)
8876{
8877 if (sample->scheme == MKBETAG('c','e','n','c') && !sample->crypt_byte_block && !sample->skip_byte_block) {
8878 return cenc_scheme_decrypt(c, sc, sample, input, size);
8879 } else if (sample->scheme == MKBETAG('c','b','c','1') && !sample->crypt_byte_block && !sample->skip_byte_block) {
8880 return cbc1_scheme_decrypt(c, sc, sample, input, size);
8881 } else if (sample->scheme == MKBETAG('c','e','n','s')) {
8882 return cens_scheme_decrypt(c, sc, sample, input, size);
8883 } else if (sample->scheme == MKBETAG('c','b','c','s')) {
8884 return cbcs_scheme_decrypt(c, sc, sample, input, size);
8885 } else {
8886 av_log(c->fc, AV_LOG_ERROR, "invalid encryption scheme\n");
8887 return AVERROR_INVALIDDATA;
8888 }
8889}
8890
8892{
8893 int current = frag_index->current;
8894
8895 if (!frag_index->nb_items)
8896 return NULL;
8897
8898 // Check frag_index->current is the right one for pkt. It can out of sync.
8899 if (current >= 0 && current < frag_index->nb_items) {
8900 if (frag_index->item[current].moof_offset < pkt->pos &&
8901 (current + 1 == frag_index->nb_items ||
8902 frag_index->item[current + 1].moof_offset > pkt->pos))
8903 return get_frag_stream_info(frag_index, current, id);
8904 }
8905
8906
8907 for (int i = 0; i < frag_index->nb_items; i++) {
8908 if (frag_index->item[i].moof_offset > pkt->pos)
8909 break;
8910 current = i;
8911 }
8912 frag_index->current = current;
8913 return get_frag_stream_info(frag_index, current, id);
8914}
8915
8916static int cenc_filter(MOVContext *mov, AVStream* st, MOVStreamContext *sc, AVPacket *pkt, int current_index)
8917{
8918 MOVFragmentStreamInfo *frag_stream_info;
8919 MOVEncryptionIndex *encryption_index;
8920 AVEncryptionInfo *encrypted_sample;
8921 int encrypted_index, ret;
8922
8923 frag_stream_info = get_frag_stream_info_from_pkt(&mov->frag_index, pkt, sc->id);
8924 encrypted_index = current_index;
8925 encryption_index = NULL;
8926 if (frag_stream_info) {
8927 // Note this only supports encryption info in the first sample descriptor.
8928 if (frag_stream_info->stsd_id == 1) {
8929 if (frag_stream_info->encryption_index) {
8930 encrypted_index = current_index - frag_stream_info->index_base;
8931 encryption_index = frag_stream_info->encryption_index;
8932 } else {
8933 encryption_index = sc->cenc.encryption_index;
8934 }
8935 }
8936 } else {
8937 encryption_index = sc->cenc.encryption_index;
8938 }
8939
8940 if (encryption_index) {
8941 if (encryption_index->auxiliary_info_sample_count &&
8942 !encryption_index->nb_encrypted_samples) {
8943 av_log(mov->fc, AV_LOG_ERROR, "saiz atom found without saio\n");
8944 return AVERROR_INVALIDDATA;
8945 }
8946 if (encryption_index->auxiliary_offsets_count &&
8947 !encryption_index->nb_encrypted_samples) {
8948 av_log(mov->fc, AV_LOG_ERROR, "saio atom found without saiz\n");
8949 return AVERROR_INVALIDDATA;
8950 }
8951
8952 encrypted_sample = NULL;
8953 if (!encryption_index->nb_encrypted_samples) {
8954 // Full-sample encryption with default settings.
8955 encrypted_sample = sc->cenc.default_encrypted_sample;
8956 } else if (encrypted_index >= 0 && encrypted_index < encryption_index->nb_encrypted_samples) {
8957 // Per-sample setting override.
8958 encrypted_sample = encryption_index->encrypted_samples[encrypted_index];
8959 if (!encrypted_sample) {
8960 encrypted_sample = sc->cenc.default_encrypted_sample;
8961 }
8962 }
8963
8964 if (!encrypted_sample) {
8965 av_log(mov->fc, AV_LOG_ERROR, "Incorrect number of samples in encryption info\n");
8966 return AVERROR_INVALIDDATA;
8967 }
8968
8969 if (mov->decryption_keys || mov->decryption_default_key) {
8970 return cenc_decrypt(mov, sc, encrypted_sample, pkt->data, pkt->size);
8971 } else {
8972 size_t size;
8973 uint8_t *side_data = av_encryption_info_add_side_data(encrypted_sample, &size);
8974 if (!side_data)
8975 return AVERROR(ENOMEM);
8977 if (ret < 0)
8978 av_free(side_data);
8979 return ret;
8980 }
8981 }
8982
8983 return 0;
8984}
8985
8987{
8988 const int OPUS_SEEK_PREROLL_MS = 80;
8989 int ret;
8990 AVStream *st;
8991 size_t size;
8992 uint16_t pre_skip;
8993
8994 if (c->fc->nb_streams < 1)
8995 return 0;
8996 st = c->fc->streams[c->fc->nb_streams-1];
8997
8998 if ((uint64_t)atom.size > (1<<30) || atom.size < 11 || st->codecpar->extradata)
8999 return AVERROR_INVALIDDATA;
9000
9001 /* Check OpusSpecificBox version. */
9002 if (avio_r8(pb) != 0) {
9003 av_log(c->fc, AV_LOG_ERROR, "unsupported OpusSpecificBox version\n");
9004 return AVERROR_INVALIDDATA;
9005 }
9006
9007 /* OpusSpecificBox size plus magic for Ogg OpusHead header. */
9008 size = atom.size + 8;
9009
9010 if ((ret = ff_alloc_extradata(st->codecpar, size)) < 0)
9011 return ret;
9012
9013 AV_WL32A(st->codecpar->extradata, MKTAG('O','p','u','s'));
9014 AV_WL32A(st->codecpar->extradata + 4, MKTAG('H','e','a','d'));
9015 AV_WB8(st->codecpar->extradata + 8, 1); /* OpusHead version */
9016 if ((ret = ffio_read_size(pb, st->codecpar->extradata + 9, size - 9)) < 0) {
9018 st->codecpar->extradata_size = 0;
9019 return ret;
9020 }
9021
9022 /* OpusSpecificBox is stored in big-endian, but OpusHead is
9023 little-endian; aside from the preceding magic and version they're
9024 otherwise currently identical. Data after output gain at offset 16
9025 doesn't need to be bytewapped. */
9026 pre_skip = AV_RB16A(st->codecpar->extradata + 10);
9027 AV_WL16A(st->codecpar->extradata + 10, pre_skip);
9028 AV_WL32A(st->codecpar->extradata + 12, AV_RB32A(st->codecpar->extradata + 12));
9029 AV_WL16A(st->codecpar->extradata + 16, AV_RB16A(st->codecpar->extradata + 16));
9030
9031 st->codecpar->initial_padding = pre_skip;
9033 (AVRational){1, 1000},
9034 (AVRational){1, 48000});
9035
9036 return 0;
9037}
9038
9040{
9041 AVStream *st;
9042 unsigned format_info;
9043 int channel_assignment, channel_assignment1, channel_assignment2;
9044 int ratebits;
9045 uint64_t chmask;
9046
9047 if (c->fc->nb_streams < 1)
9048 return 0;
9049 st = c->fc->streams[c->fc->nb_streams-1];
9050
9051 if (atom.size < 10)
9052 return AVERROR_INVALIDDATA;
9053
9054 format_info = avio_rb32(pb);
9055
9056 ratebits = (format_info >> 28) & 0xF;
9057 channel_assignment1 = (format_info >> 15) & 0x1F;
9058 channel_assignment2 = format_info & 0x1FFF;
9059 if (channel_assignment2)
9060 channel_assignment = channel_assignment2;
9061 else
9062 channel_assignment = channel_assignment1;
9063
9064 st->codecpar->frame_size = 40 << (ratebits & 0x7);
9065 st->codecpar->sample_rate = mlp_samplerate(ratebits);
9066
9068 chmask = truehd_layout(channel_assignment);
9070
9071 return 0;
9072}
9073
9075{
9076 AVStream *st;
9077 uint8_t buf[ISOM_DVCC_DVVC_SIZE];
9078 int ret;
9079 int64_t read_size = atom.size;
9080
9081 if (c->fc->nb_streams < 1)
9082 return 0;
9083 st = c->fc->streams[c->fc->nb_streams-1];
9084
9085 // At most 24 bytes
9086 read_size = FFMIN(read_size, ISOM_DVCC_DVVC_SIZE);
9087
9088 if ((ret = ffio_read_size(pb, buf, read_size)) < 0)
9089 return ret;
9090
9091 return ff_isom_parse_dvcc_dvvc(c->fc, st, buf, read_size);
9092}
9093
9095{
9096 AVStream *st;
9097 AVPacketSideData *sd;
9098 int ret;
9099
9100 if (c->fc->nb_streams < 1)
9101 return 0;
9102 st = c->fc->streams[c->fc->nb_streams - 1];
9103
9104 if (atom.size < 23 || atom.size > INT_MAX - AV_INPUT_BUFFER_PADDING_SIZE)
9105 return AVERROR_INVALIDDATA;
9106
9110 atom.size, 0);
9111 if (!sd)
9112 return AVERROR(ENOMEM);
9113
9114 ret = ffio_read_size(pb, sd->data, atom.size);
9115 if (ret < 0)
9116 return ret;
9117
9118 return 0;
9119}
9120
9122{
9123 AVStream *st;
9124 uint8_t *buf;
9125 int ret, old_size, num_arrays;
9126
9127 if (c->fc->nb_streams < 1)
9128 return 0;
9129 st = c->fc->streams[c->fc->nb_streams-1];
9130
9131 if (!st->codecpar->extradata_size)
9132 // TODO: handle lhvC when present before hvcC
9133 return 0;
9134
9135 if (atom.size < 6 || st->codecpar->extradata_size < 23 ||
9136 atom.size > INT_MAX - AV_INPUT_BUFFER_PADDING_SIZE) {
9137 return AVERROR_INVALIDDATA;
9138 }
9139
9141 if (!buf)
9142 return AVERROR(ENOMEM);
9143 memset(buf + atom.size, 0, AV_INPUT_BUFFER_PADDING_SIZE);
9144
9145 ret = ffio_read_size(pb, buf, atom.size);
9146 if (ret < 0) {
9147 av_free(buf);
9148 av_log(c->fc, AV_LOG_WARNING, "lhvC atom truncated\n");
9149 return 0;
9150 }
9151
9152 num_arrays = buf[5];
9153 old_size = st->codecpar->extradata_size;
9154 atom.size -= 8 /* account for mov_realloc_extradata offsetting */
9155 + 6 /* lhvC bytes before the arrays*/;
9156
9157 ret = mov_realloc_extradata(st->codecpar, atom);
9158 if (ret < 0) {
9159 av_free(buf);
9160 return ret;
9161 }
9162
9163 st->codecpar->extradata[22] += num_arrays;
9164 memcpy(st->codecpar->extradata + old_size, buf + 6, atom.size + 8);
9165
9167
9168 av_free(buf);
9169 return 0;
9170}
9171
9173{
9174 AVFormatContext *ctx = c->fc;
9175 AVStream *st = NULL;
9176 AVBPrint scheme_buf, value_buf;
9177 int64_t scheme_str_len = 0, value_str_len = 0;
9178 int version, flags, ret = AVERROR_BUG;
9179 int64_t size = atom.size;
9180
9181 if (atom.size < 6)
9182 // 4 bytes for version + flags, 2x 1 byte for null
9183 return AVERROR_INVALIDDATA;
9184
9185 if (c->fc->nb_streams < 1)
9186 return 0;
9187 st = c->fc->streams[c->fc->nb_streams-1];
9188
9189 version = avio_r8(pb);
9190 flags = avio_rb24(pb);
9191 size -= 4;
9192
9193 if (version != 0 || flags != 0) {
9195 "Unsupported 'kind' box with version %d, flags: %x",
9196 version, flags);
9197 return AVERROR_INVALIDDATA;
9198 }
9199
9202
9203 if ((scheme_str_len = ff_read_string_to_bprint_overwrite(pb, &scheme_buf,
9204 size)) < 0) {
9205 ret = scheme_str_len;
9206 goto cleanup;
9207 }
9208
9209 if (scheme_str_len + 1 >= size) {
9210 // we need to have another string, even if nullptr.
9211 // we check with + 1 since we expect that if size was not hit,
9212 // an additional null was read.
9213 ret = AVERROR_INVALIDDATA;
9214 goto cleanup;
9215 }
9216
9217 size -= scheme_str_len + 1;
9218
9219 if ((value_str_len = ff_read_string_to_bprint_overwrite(pb, &value_buf,
9220 size)) < 0) {
9221 ret = value_str_len;
9222 goto cleanup;
9223 }
9224
9225 if (value_str_len == size) {
9226 // in case of no trailing null, box is not valid.
9227 ret = AVERROR_INVALIDDATA;
9228 goto cleanup;
9229 }
9230
9232 "%s stream %d KindBox(scheme: %s, value: %s)\n",
9234 st->index,
9235 scheme_buf.str, value_buf.str);
9236
9237 for (int i = 0; ff_mov_track_kind_table[i].scheme_uri; i++) {
9239 if (!av_strstart(scheme_buf.str, map.scheme_uri, NULL))
9240 continue;
9241
9242 for (int j = 0; map.value_maps[j].disposition; j++) {
9243 const struct MP4TrackKindValueMapping value_map = map.value_maps[j];
9244 if (!av_strstart(value_buf.str, value_map.value, NULL))
9245 continue;
9246
9247 st->disposition |= value_map.disposition;
9248 }
9249 }
9250
9251 ret = 0;
9252
9253cleanup:
9254
9255 av_bprint_finalize(&scheme_buf, NULL);
9256 av_bprint_finalize(&value_buf, NULL);
9257
9258 return ret;
9259}
9260
9262{
9263 AVStream *st;
9264 AVChannelLayout ch_layout = { 0 };
9265 int ret, i, version, type;
9266 int ambisonic_order, channel_order, normalization, channel_count;
9267 int ambi_channels, non_diegetic_channels;
9268
9269 if (c->fc->nb_streams < 1)
9270 return 0;
9271
9272 st = c->fc->streams[c->fc->nb_streams - 1];
9273
9274 if (atom.size < 16) {
9275 av_log(c->fc, AV_LOG_ERROR, "SA3D audio box too small\n");
9276 return AVERROR_INVALIDDATA;
9277 }
9278
9279 version = avio_r8(pb);
9280 if (version) {
9281 av_log(c->fc, AV_LOG_WARNING, "Unsupported SA3D box version %d\n", version);
9282 return 0;
9283 }
9284
9285 type = avio_r8(pb);
9286 if (type & 0x7f) {
9287 av_log(c->fc, AV_LOG_WARNING,
9288 "Unsupported ambisonic type %d\n", type & 0x7f);
9289 return 0;
9290 }
9291 non_diegetic_channels = (type >> 7) * 2; // head_locked_stereo
9292
9293 ambisonic_order = avio_rb32(pb);
9294
9295 channel_order = avio_r8(pb);
9296 if (channel_order) {
9297 av_log(c->fc, AV_LOG_WARNING,
9298 "Unsupported channel_order %d\n", channel_order);
9299 return 0;
9300 }
9301
9302 normalization = avio_r8(pb);
9303 if (normalization) {
9304 av_log(c->fc, AV_LOG_WARNING,
9305 "Unsupported normalization %d\n", normalization);
9306 return 0;
9307 }
9308
9309 channel_count = avio_rb32(pb);
9310 if (ambisonic_order < 0 || ambisonic_order > 31 ||
9311 channel_count != ((ambisonic_order + 1LL) * (ambisonic_order + 1LL) +
9312 non_diegetic_channels)) {
9313 av_log(c->fc, AV_LOG_ERROR,
9314 "Invalid number of channels (%d / %d)\n",
9315 channel_count, ambisonic_order);
9316 return 0;
9317 }
9318 ambi_channels = channel_count - non_diegetic_channels;
9319
9320 ret = av_channel_layout_custom_init(&ch_layout, channel_count);
9321 if (ret < 0)
9322 return 0;
9323
9324 for (i = 0; i < channel_count; i++) {
9325 unsigned channel = avio_rb32(pb);
9326
9327 if (channel >= channel_count) {
9328 av_log(c->fc, AV_LOG_ERROR, "Invalid channel index (%d / %d)\n",
9329 channel, ambisonic_order);
9330 av_channel_layout_uninit(&ch_layout);
9331 return 0;
9332 }
9333 if (channel >= ambi_channels)
9334 ch_layout.u.map[i].id = channel - ambi_channels;
9335 else
9336 ch_layout.u.map[i].id = AV_CHAN_AMBISONIC_BASE + channel;
9337 }
9338
9340 if (ret < 0) {
9341 av_channel_layout_uninit(&ch_layout);
9342 return 0;
9343 }
9344
9346 st->codecpar->ch_layout = ch_layout;
9347
9348 return 0;
9349}
9350
9352{
9353 AVStream *st;
9354 int version;
9355
9356 if (c->fc->nb_streams < 1)
9357 return 0;
9358
9359 st = c->fc->streams[c->fc->nb_streams - 1];
9360
9361 if (atom.size < 5) {
9362 av_log(c->fc, AV_LOG_ERROR, "Empty SAND audio box\n");
9363 return AVERROR_INVALIDDATA;
9364 }
9365
9366 version = avio_r8(pb);
9367 if (version) {
9368 av_log(c->fc, AV_LOG_WARNING, "Unsupported SAND box version %d\n", version);
9369 return 0;
9370 }
9371
9373
9374 return 0;
9375}
9376
9377static int rb_size(AVIOContext *pb, int64_t *value, int size)
9378{
9379 if (size == 0)
9380 *value = 0;
9381 else if (size == 1)
9382 *value = avio_r8(pb);
9383 else if (size == 2)
9384 *value = avio_rb16(pb);
9385 else if (size == 4)
9386 *value = avio_rb32(pb);
9387 else if (size == 8) {
9388 *value = avio_rb64(pb);
9389 if (*value < 0)
9390 return -1;
9391 } else
9392 return -1;
9393 return size;
9394}
9395
9397{
9398 avio_rb32(pb); // version & flags.
9399 c->primary_item_id = avio_rb16(pb);
9400 av_log(c->fc, AV_LOG_TRACE, "pitm: primary_item_id %d\n", c->primary_item_id);
9401 return atom.size;
9402}
9403
9405{
9406 c->idat_offset = avio_tell(pb);
9407 return 0;
9408}
9409
9411{
9412 HEIFItem **heif_item;
9413 int version, offset_size, length_size, base_offset_size, index_size;
9414 int item_count, extent_count;
9415 int64_t base_offset, extent_offset, extent_length;
9416 uint8_t value;
9417
9418 if (c->found_iloc) {
9419 av_log(c->fc, AV_LOG_INFO, "Duplicate iloc box found\n");
9420 return 0;
9421 }
9422
9423 version = avio_r8(pb);
9424 avio_rb24(pb); // flags.
9425
9426 value = avio_r8(pb);
9427 offset_size = (value >> 4) & 0xF;
9428 length_size = value & 0xF;
9429 value = avio_r8(pb);
9430 base_offset_size = (value >> 4) & 0xF;
9431 index_size = !version ? 0 : (value & 0xF);
9432 if (index_size) {
9433 avpriv_report_missing_feature(c->fc, "iloc: index_size != 0");
9434 return AVERROR_PATCHWELCOME;
9435 }
9436 item_count = (version < 2) ? avio_rb16(pb) : avio_rb32(pb);
9437
9438 heif_item = av_realloc_array(c->heif_item, FFMAX(item_count, c->nb_heif_item), sizeof(*c->heif_item));
9439 if (!heif_item)
9440 return AVERROR(ENOMEM);
9441 c->heif_item = heif_item;
9442 if (item_count > c->nb_heif_item)
9443 memset(&c->heif_item[c->nb_heif_item], 0,
9444 sizeof(*c->heif_item) * (item_count - c->nb_heif_item));
9445 c->nb_heif_item = FFMAX(c->nb_heif_item, item_count);
9446
9447 av_log(c->fc, AV_LOG_TRACE, "iloc: item_count %d\n", item_count);
9448 for (int i = 0; i < item_count; i++) {
9449 HEIFItem *item = NULL;
9450 int item_id = (version < 2) ? avio_rb16(pb) : avio_rb32(pb);
9451 int offset_type = (version > 0) ? avio_rb16(pb) & 0xf : 0;
9452 int j;
9453
9454 if (avio_feof(pb))
9455 return AVERROR_INVALIDDATA;
9456 if (offset_type > 1) {
9457 avpriv_report_missing_feature(c->fc, "iloc offset type %d", offset_type);
9458 return AVERROR_PATCHWELCOME;
9459 }
9460
9461 avio_rb16(pb); // data_reference_index.
9462 if (rb_size(pb, &base_offset, base_offset_size) < 0)
9463 return AVERROR_INVALIDDATA;
9464 extent_count = avio_rb16(pb);
9465 if (extent_count > 1) {
9466 // For still AVIF images, we only support one extent item.
9467 avpriv_report_missing_feature(c->fc, "iloc: extent_count > 1");
9468 return AVERROR_PATCHWELCOME;
9469 }
9470
9471 if (rb_size(pb, &extent_offset, offset_size) < 0 ||
9472 rb_size(pb, &extent_length, length_size) < 0 ||
9473 base_offset > INT64_MAX - extent_offset)
9474 return AVERROR_INVALIDDATA;
9475
9476 for (j = 0; j < c->nb_heif_item; j++) {
9477 item = c->heif_item[j];
9478 if (!item)
9479 item = c->heif_item[j] = av_mallocz(sizeof(*item));
9480 else if (item->item_id != item_id)
9481 continue;
9482 break;
9483 }
9484 if (!item)
9485 return AVERROR(ENOMEM);
9486 if (j == c->nb_heif_item)
9487 return AVERROR_INVALIDDATA;
9488
9489 item->item_id = item_id;
9490
9491 if (offset_type == 1)
9492 item->is_idat_relative = 1;
9493 item->extent_length = extent_length;
9494 item->extent_offset = base_offset + extent_offset;
9495 av_log(c->fc, AV_LOG_TRACE, "iloc: item_idx %d, item->item_id %d, offset_type %d, "
9496 "extent_offset %"PRId64", extent_length %"PRId64"\n",
9497 i, item->item_id, offset_type, item->extent_offset, item->extent_length);
9498 }
9499
9500 c->found_iloc = 1;
9501 return atom.size;
9502}
9503
9505{
9506 HEIFItem *item = NULL;
9507 AVBPrint item_name;
9508 int64_t size = atom.size;
9509 uint32_t item_type;
9510 int item_id;
9511 int i, version, ret;
9512
9513 version = avio_r8(pb);
9514 avio_rb24(pb); // flags.
9515 size -= 4;
9516 if (size < 0)
9517 return AVERROR_INVALIDDATA;
9518
9519 if (version < 2) {
9520 avpriv_report_missing_feature(c->fc, "infe version < 2");
9521 avio_skip(pb, size);
9522 return 1;
9523 }
9524
9525 item_id = version > 2 ? avio_rb32(pb) : avio_rb16(pb);
9526 avio_rb16(pb); // item_protection_index
9527 item_type = avio_rl32(pb);
9528 size -= 8;
9529 if (size < 1)
9530 return AVERROR_INVALIDDATA;
9531
9534 if (ret < 0) {
9536 return ret;
9537 }
9538
9539 av_log(c->fc, AV_LOG_TRACE, "infe: item_id %d, item_type %s, item_name %s\n",
9540 item_id, av_fourcc2str(item_type), item_name.str);
9541
9542 size -= ret + 1;
9543 if (size > 0)
9544 avio_skip(pb, size);
9545
9546 for (i = 0; i < c->nb_heif_item; i++) {
9547 item = c->heif_item[i];
9548 if (!item)
9549 item = c->heif_item[i] = av_mallocz(sizeof(*item));
9550 else if (item->item_id != item_id)
9551 continue;
9552 break;
9553 }
9554 if (!item) {
9556 return AVERROR(ENOMEM);
9557 }
9558 if (i == c->nb_heif_item) {
9560 return AVERROR_INVALIDDATA;
9561 }
9562
9563 av_freep(&item->name);
9564 av_bprint_finalize(&item_name, ret ? &item->name : NULL);
9565 item->item_id = item_id;
9566 item->type = item_type;
9567
9568 switch (item_type) {
9569 case MKTAG('a','v','0','1'):
9570 case MKTAG('j','p','e','g'):
9571 case MKTAG('h','v','c','1'):
9572 ret = heif_add_stream(c, item);
9573 if (ret < 0)
9574 return ret;
9575 break;
9576 }
9577
9578 return 0;
9579}
9580
9582{
9583 HEIFItem **heif_item;
9584 int entry_count;
9585 int version, got_stream = 0, ret, i;
9586
9587 if (c->found_iinf) {
9588 av_log(c->fc, AV_LOG_WARNING, "Duplicate iinf box found\n");
9589 return 0;
9590 }
9591
9592 version = avio_r8(pb);
9593 avio_rb24(pb); // flags.
9594 entry_count = version ? avio_rb32(pb) : avio_rb16(pb);
9595
9596 heif_item = av_realloc_array(c->heif_item, FFMAX(entry_count, c->nb_heif_item), sizeof(*c->heif_item));
9597 if (!heif_item)
9598 return AVERROR(ENOMEM);
9599 c->heif_item = heif_item;
9600 if (entry_count > c->nb_heif_item)
9601 memset(&c->heif_item[c->nb_heif_item], 0,
9602 sizeof(*c->heif_item) * (entry_count - c->nb_heif_item));
9603 c->nb_heif_item = FFMAX(c->nb_heif_item, entry_count);
9604
9605 for (i = 0; i < entry_count; i++) {
9606 MOVAtom infe;
9607
9608 infe.size = avio_rb32(pb) - 8;
9609 infe.type = avio_rl32(pb);
9610 if (avio_feof(pb)) {
9611 ret = AVERROR_INVALIDDATA;
9612 goto fail;
9613 }
9614 ret = mov_read_infe(c, pb, infe);
9615 if (ret < 0)
9616 goto fail;
9617 if (!ret)
9618 got_stream = 1;
9619 }
9620
9621 c->found_iinf = got_stream;
9622 return 0;
9623fail:
9624 for (; i >= 0; i--) {
9625 HEIFItem *item = c->heif_item[i];
9626
9627 if (!item)
9628 continue;
9629
9630 av_freep(&item->name);
9631 }
9632 return ret;
9633}
9634
9636{
9637 HEIFItem *item = NULL;
9638 HEIFGrid *grid;
9639 int entries, i;
9640 int from_item_id = version ? avio_rb32(pb) : avio_rb16(pb);
9641 int ret = 0;
9642
9643 for (int i = 0; i < c->nb_heif_grid; i++) {
9644 if (c->heif_grid[i].item->item_id == from_item_id) {
9645 av_log(c->fc, AV_LOG_ERROR, "More than one 'dimg' box "
9646 "referencing the same Derived Image item\n");
9647 return AVERROR_INVALIDDATA;
9648 }
9649 }
9650 for (int i = 0; i < c->nb_heif_item; i++) {
9651 if (!c->heif_item[i] || c->heif_item[i]->item_id != from_item_id)
9652 continue;
9653 item = c->heif_item[i];
9654
9655 switch (item->type) {
9656 case MKTAG('g','r','i','d'):
9657 case MKTAG('i','o','v','l'):
9658 break;
9659 default:
9660 avpriv_report_missing_feature(c->fc, "Derived Image item of type %s",
9661 av_fourcc2str(item->type));
9662 return 0;
9663 }
9664 break;
9665 }
9666 if (!item) {
9667 av_log(c->fc, AV_LOG_ERROR, "Missing grid information\n");
9668 return AVERROR_INVALIDDATA;
9669 }
9670
9671 entries = avio_rb16(pb);
9672 if (!entries) {
9673 av_log(c->fc, AV_LOG_ERROR,
9674 "Derived image item references no input images\n");
9675 return AVERROR_INVALIDDATA;
9676 }
9677
9678 grid = av_realloc_array(c->heif_grid, c->nb_heif_grid + 1U,
9679 sizeof(*c->heif_grid));
9680 if (!grid)
9681 return AVERROR(ENOMEM);
9682 c->heif_grid = grid;
9683 grid = &grid[c->nb_heif_grid];
9684
9685 grid->tile_id_list = av_malloc_array(entries, sizeof(*grid->tile_id_list));
9686 grid->tile_idx_list = av_calloc(entries, sizeof(*grid->tile_idx_list));
9687 grid->tile_item_list = av_calloc(entries, sizeof(*grid->tile_item_list));
9688 if (!grid->tile_id_list || !grid->tile_item_list || !grid->tile_idx_list) {
9689 ret = AVERROR(ENOMEM);
9690 goto fail;
9691 }
9692 /* 'to' item ids */
9693 for (i = 0; i < entries; i++) {
9694 grid->tile_id_list[i] = version ? avio_rb32(pb) : avio_rb16(pb);
9695
9696 if (avio_feof(pb)) {
9697 ret = AVERROR_INVALIDDATA;
9698 goto fail;
9699 }
9700 }
9701
9702 grid->nb_tiles = entries;
9703 grid->item = item;
9704 ++c->nb_heif_grid;
9705
9706 av_log(c->fc, AV_LOG_TRACE, "dimg: from_item_id %d, entries %d\n",
9707 from_item_id, entries);
9708
9709 return 0;
9710fail:
9711 av_freep(&grid->tile_id_list);
9712 av_freep(&grid->tile_idx_list);
9713 av_freep(&grid->tile_item_list);
9714
9715 return ret;
9716}
9717
9718static int mov_read_iref_cdsc(MOVContext *c, AVIOContext *pb, uint32_t type, int version, uint32_t size)
9719{
9720 HEIFItem *from_item = NULL;
9721 int entries;
9722 int item_id_size = version ? 4 : 2;
9723 int from_item_id = version ? avio_rb32(pb) : avio_rb16(pb);
9724 const HEIFItemRef ref = { type, from_item_id };
9725
9726 from_item = get_heif_item(c, from_item_id);
9727 if (!from_item) {
9728 av_log(c->fc, AV_LOG_ERROR, "Missing stream referenced by thmb item\n");
9729 return AVERROR_INVALIDDATA;
9730 }
9731
9732 entries = avio_rb16(pb);
9733 if ((int64_t)entries * item_id_size > (int64_t)size - item_id_size - 2) {
9734 av_log(c->fc, AV_LOG_ERROR, "iref %s entry count %d exceeds the sub-box size\n",
9735 av_fourcc2str(type), entries);
9736 return AVERROR_INVALIDDATA;
9737 }
9738 /* 'to' item ids */
9739 for (int i = 0; i < entries; i++) {
9740 HEIFItem *item = get_heif_item(c, version ? avio_rb32(pb) : avio_rb16(pb));
9741
9742 if (avio_feof(pb))
9743 return AVERROR_INVALIDDATA;
9744
9745 if (!item) {
9746 av_log(c->fc, AV_LOG_WARNING, "Missing stream referenced by %s item\n",
9748 continue;
9749 }
9750
9751 if (!av_dynarray2_add((void **)&item->iref_list, &item->nb_iref_list,
9752 sizeof(*item->iref_list), (const uint8_t *)&ref))
9753 return AVERROR(ENOMEM);
9754 }
9755
9756 av_log(c->fc, AV_LOG_TRACE, "%s: from_item_id %d, entries %d\n",
9757 av_fourcc2str(type), from_item_id, entries);
9758
9759 return 0;
9760}
9761
9763{
9764 int version = avio_r8(pb);
9765 int ret;
9766
9767 avio_rb24(pb); // flags
9768 atom.size -= 4;
9769
9770 if (version > 1) {
9771 av_log(c->fc, AV_LOG_WARNING, "Unknown iref box version %d\n", version);
9772 return 0;
9773 }
9774
9775 while (atom.size) {
9776 int64_t next = avio_tell(pb);
9777 uint32_t type, size = avio_rb32(pb);
9778
9779 if (size < 14 || size > atom.size || next > INT64_MAX - size)
9780 return AVERROR_INVALIDDATA;
9781
9782 next += size;
9783 type = avio_rl32(pb);
9784 switch (type) {
9785 case MKTAG('d','i','m','g'):
9786 ret = mov_read_iref_dimg(c, pb, version);
9787 if (ret < 0)
9788 return ret;
9789 break;
9790 case MKTAG('c','d','s','c'):
9791 case MKTAG('t','h','m','b'):
9792 ret = mov_read_iref_cdsc(c, pb, type, version, size - 8);
9793 if (ret < 0)
9794 return ret;
9795 break;
9796 default:
9797 av_log(c->fc, AV_LOG_DEBUG, "Unknown iref type %s size %"PRIu32"\n",
9799 }
9800
9801 atom.size -= size;
9802 avio_seek(pb, next, SEEK_SET);
9803 }
9804 return 0;
9805}
9806
9808{
9809 HEIFItem *item;
9810 uint32_t width, height;
9811
9812 avio_r8(pb); /* version */
9813 avio_rb24(pb); /* flags */
9814 width = avio_rb32(pb);
9815 height = avio_rb32(pb);
9816
9817 av_log(c->fc, AV_LOG_TRACE, "ispe: item_id %d, width %"PRIu32", height %"PRIu32"\n",
9818 c->cur_item_id, width, height);
9819
9820 if (!width || !height || width > INT_MAX || height > INT_MAX) {
9821 av_log(c->fc, AV_LOG_ERROR, "Invalid ispe dimensions %"PRIu32"x%"PRIu32"\n",
9822 width, height);
9823 return AVERROR_INVALIDDATA;
9824 }
9825
9826 item = get_heif_item(c, c->cur_item_id);
9827 if (item) {
9828 item->width = width;
9829 item->height = height;
9830 }
9831
9832 return 0;
9833}
9834
9836{
9837 HEIFItem *item;
9838 int angle;
9839
9840 angle = avio_r8(pb) & 0x3;
9841
9842 av_log(c->fc, AV_LOG_TRACE, "irot: item_id %d, angle %u\n",
9843 c->cur_item_id, angle);
9844
9845 item = get_heif_item(c, c->cur_item_id);
9846 if (item) {
9847 // angle * 90 specifies the angle (in anti-clockwise direction)
9848 // in units of degrees.
9849 item->rotation = angle * 90;
9850 }
9851
9852 return 0;
9853}
9854
9856{
9857 HEIFItem *item;
9858 int axis;
9859
9860 axis = avio_r8(pb) & 0x1;
9861
9862 av_log(c->fc, AV_LOG_TRACE, "imir: item_id %d, axis %u\n",
9863 c->cur_item_id, axis);
9864
9865 item = get_heif_item(c, c->cur_item_id);
9866 if (item) {
9867 item->hflip = axis;
9868 item->vflip = !axis;
9869 }
9870
9871 return 0;
9872}
9873
9875{
9876 typedef struct MOVAtoms {
9877 FFIOContext b;
9878 uint32_t type;
9879 int64_t size;
9880 uint8_t *data;
9881 } MOVAtoms;
9882 MOVAtoms *atoms = NULL;
9883 MOVAtom a;
9884 unsigned count;
9885 int nb_atoms = 0;
9886 int version, flags;
9887 int ret;
9888
9889 a.size = avio_rb32(pb);
9890 a.type = avio_rl32(pb);
9891
9892 if (a.size < 8 || a.type != MKTAG('i','p','c','o'))
9893 return AVERROR_INVALIDDATA;
9894
9895 a.size -= 8;
9896 while (a.size >= 8) {
9897 MOVAtoms *ref = av_dynarray2_add((void**)&atoms, &nb_atoms, sizeof(MOVAtoms), NULL);
9898 if (!ref) {
9899 ret = AVERROR(ENOMEM);
9900 goto fail;
9901 }
9902 ref->data = NULL;
9903 ref->size = avio_rb32(pb);
9904 ref->type = avio_rl32(pb);
9905 if (ref->size > a.size || ref->size < 8)
9906 break;
9907 ref->data = av_malloc(ref->size);
9908 if (!ref->data) {
9909 ret = AVERROR_INVALIDDATA;
9910 goto fail;
9911 }
9912 av_log(c->fc, AV_LOG_TRACE, "ipco: index %d, box type %s\n", nb_atoms, av_fourcc2str(ref->type));
9913 avio_seek(pb, -8, SEEK_CUR);
9914 if (avio_read(pb, ref->data, ref->size) != ref->size) {
9915 ret = AVERROR_INVALIDDATA;
9916 goto fail;
9917 }
9918 ffio_init_read_context(&ref->b, ref->data, ref->size);
9919 a.size -= ref->size;
9920 }
9921
9922 if (a.size) {
9923 ret = AVERROR_INVALIDDATA;
9924 goto fail;
9925 }
9926
9927 a.size = avio_rb32(pb);
9928 a.type = avio_rl32(pb);
9929
9930 if (a.size < 8 || a.type != MKTAG('i','p','m','a')) {
9931 ret = AVERROR_INVALIDDATA;
9932 goto fail;
9933 }
9934
9935 version = avio_r8(pb);
9936 flags = avio_rb24(pb);
9937 count = avio_rb32(pb);
9938
9939 for (int i = 0; i < count; i++) {
9940 int item_id = version ? avio_rb32(pb) : avio_rb16(pb);
9941 int assoc_count = avio_r8(pb);
9942
9943 if (avio_feof(pb)) {
9944 ret = AVERROR_INVALIDDATA;
9945 goto fail;
9946 }
9947
9948 for (int j = 0; j < assoc_count; j++) {
9949 MOVAtoms *ref;
9950 int index = avio_r8(pb) & 0x7f;
9951 if (flags & 1) {
9952 index <<= 8;
9953 index |= avio_r8(pb);
9954 }
9955 if (index > nb_atoms || index <= 0) {
9956 ret = AVERROR_INVALIDDATA;
9957 goto fail;
9958 }
9959 ref = &atoms[--index];
9960
9961 av_log(c->fc, AV_LOG_TRACE, "ipma: property_index %d, item_id %d, item_type %s\n",
9962 index + 1, item_id, av_fourcc2str(ref->type));
9963
9964 c->cur_item_id = item_id;
9965
9966 ret = mov_read_default(c, &ref->b.pub,
9967 (MOVAtom) { .size = ref->size,
9968 .type = MKTAG('i','p','c','o') });
9969 if (ret < 0)
9970 goto fail;
9971 ffio_init_read_context(&ref->b, ref->data, ref->size);
9972 }
9973 }
9974
9975 ret = 0;
9976fail:
9977 c->cur_item_id = -1;
9978 for (int i = 0; i < nb_atoms; i++)
9979 av_free(atoms[i].data);
9980 av_free(atoms);
9981
9982 return ret;
9983}
9984
9986{ MKTAG('A','C','L','R'), mov_read_aclr },
9987{ MKTAG('A','P','R','G'), mov_read_avid },
9988{ MKTAG('A','A','L','P'), mov_read_avid },
9989{ MKTAG('A','R','E','S'), mov_read_ares },
9990{ MKTAG('a','v','s','s'), mov_read_avss },
9991{ MKTAG('a','v','1','C'), mov_read_glbl },
9992{ MKTAG('c','h','p','l'), mov_read_chpl },
9993{ MKTAG('c','o','6','4'), mov_read_stco },
9994{ MKTAG('c','o','l','r'), mov_read_colr },
9995{ MKTAG('c','t','t','s'), mov_read_ctts }, /* composition time to sample */
9996{ MKTAG('d','i','n','f'), mov_read_default },
9997{ MKTAG('D','p','x','E'), mov_read_dpxe },
9998{ MKTAG('d','r','e','f'), mov_read_dref },
9999{ MKTAG('e','d','t','s'), mov_read_default },
10000{ MKTAG('e','l','s','t'), mov_read_elst },
10001{ MKTAG('e','n','d','a'), mov_read_enda },
10002{ MKTAG('f','i','e','l'), mov_read_fiel },
10003{ MKTAG('a','d','r','m'), mov_read_adrm },
10004{ MKTAG('f','t','y','p'), mov_read_ftyp },
10005{ MKTAG('g','l','b','l'), mov_read_glbl },
10006{ MKTAG('h','d','l','r'), mov_read_hdlr },
10007{ MKTAG('i','l','s','t'), mov_read_ilst },
10008{ MKTAG('j','p','2','h'), mov_read_jp2h },
10009{ MKTAG('m','d','a','t'), mov_read_mdat },
10010{ MKTAG('m','d','h','d'), mov_read_mdhd },
10011{ MKTAG('m','d','i','a'), mov_read_default },
10012{ MKTAG('m','e','t','a'), mov_read_meta },
10013{ MKTAG('m','i','n','f'), mov_read_default },
10014{ MKTAG('m','o','o','f'), mov_read_moof },
10015{ MKTAG('m','o','o','v'), mov_read_moov },
10016{ MKTAG('m','v','e','x'), mov_read_default },
10017{ MKTAG('m','v','h','d'), mov_read_mvhd },
10018{ MKTAG('S','M','I',' '), mov_read_svq3 },
10019{ MKTAG('a','l','a','c'), mov_read_alac }, /* alac specific atom */
10020{ MKTAG('a','v','c','C'), mov_read_glbl },
10021{ MKTAG('p','a','s','p'), mov_read_pasp },
10022{ MKTAG('c','l','a','p'), mov_read_clap },
10023{ MKTAG('c','d','s','c'), mov_read_cdsc },
10024{ MKTAG('s','b','a','s'), mov_read_sbas },
10025{ MKTAG('v','d','e','p'), mov_read_vdep },
10026{ MKTAG('s','i','d','x'), mov_read_sidx },
10027{ MKTAG('s','t','b','l'), mov_read_default },
10028{ MKTAG('s','t','c','o'), mov_read_stco },
10029{ MKTAG('s','t','p','s'), mov_read_stps },
10030{ MKTAG('s','t','r','f'), mov_read_strf },
10031{ MKTAG('s','t','s','c'), mov_read_stsc },
10032{ MKTAG('s','t','s','d'), mov_read_stsd }, /* sample description */
10033{ MKTAG('s','t','s','s'), mov_read_stss }, /* sync sample */
10034{ MKTAG('s','t','s','z'), mov_read_stsz }, /* sample size */
10035{ MKTAG('s','t','t','s'), mov_read_stts },
10036{ MKTAG('s','t','z','2'), mov_read_stsz }, /* compact sample size */
10037{ MKTAG('s','d','t','p'), mov_read_sdtp }, /* independent and disposable samples */
10038{ MKTAG('t','k','h','d'), mov_read_tkhd }, /* track header */
10039{ MKTAG('t','f','d','t'), mov_read_tfdt },
10040{ MKTAG('t','f','h','d'), mov_read_tfhd }, /* track fragment header */
10041{ MKTAG('t','r','a','k'), mov_read_trak },
10042{ MKTAG('t','r','a','f'), mov_read_default },
10043{ MKTAG('t','r','e','f'), mov_read_default },
10044{ MKTAG('t','m','c','d'), mov_read_tmcd },
10045{ MKTAG('c','h','a','p'), mov_read_chap },
10046{ MKTAG('t','r','e','x'), mov_read_trex },
10047{ MKTAG('t','r','u','n'), mov_read_trun },
10048{ MKTAG('u','d','t','a'), mov_read_default },
10049{ MKTAG('w','a','v','e'), mov_read_wave },
10050{ MKTAG('e','s','d','s'), mov_read_esds },
10051{ MKTAG('d','a','c','3'), mov_read_dac3 }, /* AC-3 info */
10052{ MKTAG('d','e','c','3'), mov_read_dec3 }, /* EAC-3 info */
10053{ MKTAG('d','d','t','s'), mov_read_ddts }, /* DTS audio descriptor */
10054{ MKTAG('w','i','d','e'), mov_read_wide }, /* place holder */
10055{ MKTAG('w','f','e','x'), mov_read_wfex },
10056{ MKTAG('c','m','o','v'), mov_read_cmov },
10057{ MKTAG('c','h','a','n'), mov_read_chan }, /* channel layout from quicktime */
10058{ MKTAG('c','h','n','l'), mov_read_chnl }, /* channel layout from ISO-14496-12 */
10059{ MKTAG('d','v','c','1'), mov_read_dvc1 },
10060{ MKTAG('s','g','p','d'), mov_read_sgpd },
10061{ MKTAG('s','b','g','p'), mov_read_sbgp },
10062{ MKTAG('h','v','c','C'), mov_read_glbl },
10063{ MKTAG('v','v','c','C'), mov_read_glbl },
10064{ MKTAG('u','u','i','d'), mov_read_uuid },
10065{ MKTAG('C','i','n', 0x8e), mov_read_targa_y216 },
10066{ MKTAG('f','r','e','e'), mov_read_free },
10067{ MKTAG('-','-','-','-'), mov_read_custom },
10068{ MKTAG('s','i','n','f'), mov_read_default },
10069{ MKTAG('f','r','m','a'), mov_read_frma },
10070{ MKTAG('s','e','n','c'), mov_read_senc },
10071{ MKTAG('s','a','i','z'), mov_read_saiz },
10072{ MKTAG('s','a','i','o'), mov_read_saio },
10073{ MKTAG('p','s','s','h'), mov_read_pssh },
10074{ MKTAG('s','c','h','m'), mov_read_schm },
10075{ MKTAG('s','c','h','i'), mov_read_default },
10076{ MKTAG('t','e','n','c'), mov_read_tenc },
10077{ MKTAG('d','f','L','a'), mov_read_dfla },
10078{ MKTAG('s','t','3','d'), mov_read_st3d }, /* stereoscopic 3D video box */
10079{ MKTAG('s','v','3','d'), mov_read_sv3d }, /* spherical video box */
10080{ MKTAG('v','e','x','u'), mov_read_vexu }, /* video extension usage */
10081{ MKTAG('h','f','o','v'), mov_read_hfov },
10082{ MKTAG('d','O','p','s'), mov_read_dops },
10083{ MKTAG('d','m','l','p'), mov_read_dmlp },
10084{ MKTAG('S','m','D','m'), mov_read_smdm },
10085{ MKTAG('C','o','L','L'), mov_read_coll },
10086{ MKTAG('v','p','c','C'), mov_read_vpcc },
10087{ MKTAG('m','d','c','v'), mov_read_mdcv },
10088{ MKTAG('c','l','l','i'), mov_read_clli },
10089{ MKTAG('d','v','c','C'), mov_read_dvcc_dvvc },
10090{ MKTAG('d','v','v','C'), mov_read_dvcc_dvvc },
10091{ MKTAG('d','v','w','C'), mov_read_dvcc_dvvc },
10092{ MKTAG('h','v','c','E'), mov_read_hvce },
10093{ MKTAG('k','i','n','d'), mov_read_kind },
10094{ MKTAG('S','A','3','D'), mov_read_SA3D }, /* ambisonic audio box */
10095{ MKTAG('S','A','N','D'), mov_read_SAND }, /* non diegetic audio box */
10096{ MKTAG('i','l','o','c'), mov_read_iloc },
10097{ MKTAG('p','c','m','C'), mov_read_pcmc }, /* PCM configuration box */
10098{ MKTAG('p','i','t','m'), mov_read_pitm },
10099{ MKTAG('e','v','c','C'), mov_read_glbl },
10100{ MKTAG('i','d','a','t'), mov_read_idat },
10101{ MKTAG('i','m','i','r'), mov_read_imir },
10102{ MKTAG('i','r','e','f'), mov_read_iref },
10103{ MKTAG('i','s','p','e'), mov_read_ispe },
10104{ MKTAG('i','r','o','t'), mov_read_irot },
10105{ MKTAG('i','p','r','p'), mov_read_iprp },
10106{ MKTAG('i','i','n','f'), mov_read_iinf },
10107{ MKTAG('a','m','v','e'), mov_read_amve }, /* ambient viewing environment box */
10108{ MKTAG('l','h','v','C'), mov_read_lhvc },
10109{ MKTAG('l','v','c','C'), mov_read_glbl },
10110{ MKTAG('a','p','v','C'), mov_read_glbl },
10111#if CONFIG_IAMFDEC
10112{ MKTAG('i','a','c','b'), mov_read_iacb },
10113#endif
10114{ MKTAG('s','r','a','t'), mov_read_srat },
10115{ 0, NULL }
10116};
10117
10119{
10120 int64_t total_size = 0;
10121 MOVAtom a;
10122 int i;
10123
10124 if (c->atom_depth > 10) {
10125 av_log(c->fc, AV_LOG_ERROR, "Atoms too deeply nested\n");
10126 return AVERROR_INVALIDDATA;
10127 }
10128 c->atom_depth ++;
10129
10130 if (atom.size < 0)
10131 atom.size = INT64_MAX;
10132 while (total_size <= atom.size - 8) {
10133 int (*parse)(MOVContext*, AVIOContext*, MOVAtom) = NULL;
10134 a.size = avio_rb32(pb);
10135 a.type = avio_rl32(pb);
10136 if (avio_feof(pb))
10137 break;
10138 if (((a.type == MKTAG('f','r','e','e') && c->moov_retry) ||
10139 a.type == MKTAG('h','o','o','v')) &&
10140 a.size >= 8 &&
10141 c->fc->strict_std_compliance < FF_COMPLIANCE_STRICT) {
10142 uint32_t type;
10143 avio_skip(pb, 4);
10144 type = avio_rl32(pb);
10145 if (avio_feof(pb))
10146 break;
10147 avio_seek(pb, -8, SEEK_CUR);
10148 if (type == MKTAG('m','v','h','d') ||
10149 type == MKTAG('c','m','o','v')) {
10150 av_log(c->fc, AV_LOG_ERROR, "Detected moov in a free or hoov atom.\n");
10151 a.type = MKTAG('m','o','o','v');
10152 }
10153 }
10154 if (atom.type != MKTAG('r','o','o','t') &&
10155 atom.type != MKTAG('m','o','o','v')) {
10156 if (a.type == MKTAG('t','r','a','k') ||
10157 a.type == MKTAG('m','d','a','t')) {
10158 av_log(c->fc, AV_LOG_ERROR, "Broken file, trak/mdat not at top-level\n");
10159 avio_skip(pb, -8);
10160 c->atom_depth --;
10161 return 0;
10162 }
10163 }
10164 total_size += 8;
10165 if (a.size == 1 && total_size + 8 <= atom.size) { /* 64 bit extended size */
10166 a.size = avio_rb64(pb) - 8;
10167 total_size += 8;
10168 }
10169 av_log(c->fc, AV_LOG_TRACE, "type:'%s' parent:'%s' sz: %"PRId64" %"PRId64" %"PRId64"\n",
10170 av_fourcc2str(a.type), av_fourcc2str(atom.type), a.size, total_size, atom.size);
10171 if (a.size == 0) {
10172 a.size = atom.size - total_size + 8;
10173 }
10174 if (a.size < 0)
10175 break;
10176 a.size -= 8;
10177 if (a.size < 0)
10178 break;
10179 a.size = FFMIN(a.size, atom.size - total_size);
10180
10181 for (i = 0; mov_default_parse_table[i].type; i++)
10182 if (mov_default_parse_table[i].type == a.type) {
10184 break;
10185 }
10186
10187 // container is user data
10188 if (!parse && (atom.type == MKTAG('u','d','t','a') ||
10189 atom.type == MKTAG('i','l','s','t')))
10191
10192 // Supports parsing the QuickTime Metadata Keys.
10193 // https://developer.apple.com/library/mac/documentation/QuickTime/QTFF/Metadata/Metadata.html
10194 if (!parse && c->found_hdlr_mdta &&
10195 atom.type == MKTAG('m','e','t','a') &&
10196 a.type == MKTAG('k','e','y','s') &&
10197 c->meta_keys_count == 0) {
10199 }
10200
10201 if (!parse) { /* skip leaf atoms data */
10202 avio_skip(pb, a.size);
10203 } else {
10204 int64_t start_pos = avio_tell(pb);
10205 int64_t left;
10206 int err = parse(c, pb, a);
10207 if (err < 0) {
10208 c->atom_depth --;
10209 return err;
10210 }
10211 if (c->found_moov && c->found_mdat && a.size <= INT64_MAX - start_pos &&
10212 ((!(pb->seekable & AVIO_SEEKABLE_NORMAL) || c->fc->flags & AVFMT_FLAG_IGNIDX || c->frag_index.complete) ||
10213 start_pos + a.size == avio_size(pb))) {
10214 if (!(pb->seekable & AVIO_SEEKABLE_NORMAL) || c->fc->flags & AVFMT_FLAG_IGNIDX || c->frag_index.complete)
10215 c->next_root_atom = start_pos + a.size;
10216 c->atom_depth --;
10217 return 0;
10218 }
10219 left = a.size - avio_tell(pb) + start_pos;
10220 if (left > 0) /* skip garbage at atom end */
10221 avio_skip(pb, left);
10222 else if (left < 0) {
10223 av_log(c->fc, AV_LOG_WARNING,
10224 "overread end of atom '%s' by %"PRId64" bytes\n",
10225 av_fourcc2str(a.type), -left);
10226 avio_seek(pb, left, SEEK_CUR);
10227 }
10228 }
10229
10230 total_size += a.size;
10231 }
10232
10233 if (total_size < atom.size && atom.size < 0x7ffff)
10234 avio_skip(pb, atom.size - total_size);
10235
10236 c->atom_depth --;
10237 return 0;
10238}
10239
10240static int mov_probe(const AVProbeData *p)
10241{
10243 uint32_t tag;
10244 int score = 0;
10245 int moov_offset = -1;
10246
10247 /* check file header */
10248 offset = 0;
10249 for (;;) {
10250 int64_t size;
10251 int minsize = 8;
10252 /* ignore invalid offset */
10253 if ((offset + 8ULL) > (unsigned int)p->buf_size)
10254 break;
10255 size = AV_RB32(p->buf + offset);
10256 if (size == 1 && offset + 16 <= (unsigned int)p->buf_size) {
10257 size = AV_RB64(p->buf+offset + 8);
10258 minsize = 16;
10259 } else if (size == 0) {
10260 size = p->buf_size - offset;
10261 }
10262 if (size < minsize) {
10263 offset += 4;
10264 continue;
10265 }
10266 tag = AV_RL32(p->buf + offset + 4);
10267 switch(tag) {
10268 /* check for obvious tags */
10269 case MKTAG('m','o','o','v'):
10270 moov_offset = offset + 4;
10272 case MKTAG('m','d','a','t'):
10273 case MKTAG('p','n','o','t'): /* detect movs with preview pics like ew.mov and april.mov */
10274 case MKTAG('u','d','t','a'): /* Packet Video PVAuthor adds this and a lot of more junk */
10275 case MKTAG('f','t','y','p'):
10276 if (tag == MKTAG('f','t','y','p') &&
10277 ( AV_RL32(p->buf + offset + 8) == MKTAG('j','p','2',' ')
10278 || AV_RL32(p->buf + offset + 8) == MKTAG('j','p','x',' ')
10279 || AV_RL32(p->buf + offset + 8) == MKTAG('j','x','l',' ')
10280 )) {
10281 score = FFMAX(score, 5);
10282 } else {
10283 score = AVPROBE_SCORE_MAX;
10284 }
10285 break;
10286 /* those are more common words, so rate then a bit less */
10287 case MKTAG('e','d','i','w'): /* xdcam files have reverted first tags */
10288 case MKTAG('w','i','d','e'):
10289 case MKTAG('f','r','e','e'):
10290 case MKTAG('j','u','n','k'):
10291 case MKTAG('p','i','c','t'):
10292 score = FFMAX(score, AVPROBE_SCORE_MAX - 5);
10293 break;
10294 case MKTAG(0x82,0x82,0x7f,0x7d):
10295 score = FFMAX(score, AVPROBE_SCORE_EXTENSION - 5);
10296 break;
10297 case MKTAG('s','k','i','p'):
10298 case MKTAG('u','u','i','d'):
10299 case MKTAG('p','r','f','l'):
10300 /* if we only find those cause probedata is too small at least rate them */
10301 score = FFMAX(score, AVPROBE_SCORE_EXTENSION);
10302 break;
10303 }
10304 if (size > INT64_MAX - offset)
10305 break;
10306 offset += size;
10307 }
10308 if (score > AVPROBE_SCORE_MAX - 50 && moov_offset != -1) {
10309 /* moov atom in the header - we should make sure that this is not a
10310 * MOV-packed MPEG-PS */
10311 offset = moov_offset;
10312
10313 while (offset < (p->buf_size - 16)) { /* Sufficient space */
10314 /* We found an actual hdlr atom */
10315 if (AV_RL32(p->buf + offset ) == MKTAG('h','d','l','r') &&
10316 AV_RL32(p->buf + offset + 8) == MKTAG('m','h','l','r') &&
10317 AV_RL32(p->buf + offset + 12) == MKTAG('M','P','E','G')) {
10318 av_log(NULL, AV_LOG_WARNING, "Found media data tag MPEG indicating this is a MOV-packed MPEG-PS.\n");
10319 /* We found a media handler reference atom describing an
10320 * MPEG-PS-in-MOV, return a
10321 * low score to force expanding the probe window until
10322 * mpegps_probe finds what it needs */
10323 return 5;
10324 } else {
10325 /* Keep looking */
10326 offset += 2;
10327 }
10328 }
10329 }
10330
10331 return score;
10332}
10333
10334// must be done after parsing all trak because there's no order requirement
10336{
10337 MOVContext *mov = s->priv_data;
10338 MOVStreamContext *sc;
10339 int64_t cur_pos;
10340 int i, j;
10341 int chapter_track;
10342
10343 for (j = 0; j < mov->nb_chapter_tracks; j++) {
10344 AVStream *st = NULL;
10345 FFStream *sti = NULL;
10346 chapter_track = mov->chapter_tracks[j];
10347 for (i = 0; i < s->nb_streams; i++) {
10348 sc = mov->fc->streams[i]->priv_data;
10349 if (sc->id == chapter_track) {
10350 st = s->streams[i];
10351 break;
10352 }
10353 }
10354 if (!st) {
10355 av_log(s, AV_LOG_ERROR, "Referenced QT chapter track not found\n");
10356 continue;
10357 }
10358 sti = ffstream(st);
10359
10360 sc = st->priv_data;
10361 cur_pos = avio_tell(sc->pb);
10362
10365 if (!st->attached_pic.data && sti->nb_index_entries) {
10366 // Retrieve the first frame, if possible
10367 AVIndexEntry *sample = &sti->index_entries[0];
10368 if (avio_seek(sc->pb, sample->pos, SEEK_SET) != sample->pos) {
10369 av_log(s, AV_LOG_ERROR, "Failed to retrieve first frame\n");
10370 goto finish;
10371 }
10372
10373 if (ff_add_attached_pic(s, st, sc->pb, NULL, sample->size) < 0)
10374 goto finish;
10375 }
10376 } else {
10379 st->discard = AVDISCARD_ALL;
10380 for (int i = 0; i < sti->nb_index_entries; i++) {
10382 int64_t end = i+1 < sti->nb_index_entries ? sti->index_entries[i+1].timestamp : st->duration;
10383 uint8_t *title;
10384 uint16_t ch;
10385 int len, title_len;
10386
10387 if (end < sample->timestamp) {
10388 av_log(s, AV_LOG_WARNING, "ignoring stream duration which is shorter than chapters\n");
10389 end = AV_NOPTS_VALUE;
10390 }
10391
10392 if (avio_seek(sc->pb, sample->pos, SEEK_SET) != sample->pos) {
10393 av_log(s, AV_LOG_ERROR, "Chapter %d not found in file\n", i);
10394 goto finish;
10395 }
10396
10397 // the first two bytes are the length of the title
10398 len = avio_rb16(sc->pb);
10399 if (len > sample->size-2)
10400 continue;
10401 title_len = 2*len + 1;
10402 if (!(title = av_mallocz(title_len)))
10403 goto finish;
10404
10405 // The samples could theoretically be in any encoding if there's an encd
10406 // atom following, but in practice are only utf-8 or utf-16, distinguished
10407 // instead by the presence of a BOM
10408 if (!len) {
10409 title[0] = 0;
10410 } else {
10411 ch = avio_rb16(sc->pb);
10412 if (ch == 0xfeff)
10413 avio_get_str16be(sc->pb, len, title, title_len);
10414 else if (ch == 0xfffe)
10415 avio_get_str16le(sc->pb, len, title, title_len);
10416 else {
10417 AV_WB16(title, ch);
10418 if (len == 1 || len == 2)
10419 title[len] = 0;
10420 else
10421 avio_get_str(sc->pb, INT_MAX, title + 2, len - 1);
10422 }
10423 }
10424
10425 avpriv_new_chapter(s, i, st->time_base, sample->timestamp, end, title);
10426 av_freep(&title);
10427 }
10428 }
10429finish:
10430 avio_seek(sc->pb, cur_pos, SEEK_SET);
10431 }
10432}
10433
10435 int64_t value, int flags)
10436{
10437 AVTimecode tc;
10438 char buf[AV_TIMECODE_STR_SIZE];
10439 AVRational rate = st->avg_frame_rate;
10440 int ret = av_timecode_init(&tc, rate, flags, 0, s);
10441 if (ret < 0)
10442 return ret;
10443 av_dict_set(&st->metadata, "timecode",
10444 av_timecode_make_string(&tc, buf, value), 0);
10445 return 0;
10446}
10447
10449{
10450 MOVStreamContext *sc = st->priv_data;
10451 FFStream *const sti = ffstream(st);
10452 char buf[AV_TIMECODE_STR_SIZE];
10453 int64_t cur_pos = avio_tell(sc->pb);
10454 int hh, mm, ss, ff, drop;
10455
10456 if (!sti->nb_index_entries)
10457 return -1;
10458
10459 avio_seek(sc->pb, sti->index_entries->pos, SEEK_SET);
10460 avio_skip(s->pb, 13);
10461 hh = avio_r8(s->pb);
10462 mm = avio_r8(s->pb);
10463 ss = avio_r8(s->pb);
10464 drop = avio_r8(s->pb);
10465 ff = avio_r8(s->pb);
10466 snprintf(buf, AV_TIMECODE_STR_SIZE, "%02d:%02d:%02d%c%02d",
10467 hh, mm, ss, drop ? ';' : ':', ff);
10468 av_dict_set(&st->metadata, "timecode", buf, 0);
10469
10470 avio_seek(sc->pb, cur_pos, SEEK_SET);
10471 return 0;
10472}
10473
10475{
10476 MOVStreamContext *sc = st->priv_data;
10477 FFStream *const sti = ffstream(st);
10478 int flags = 0;
10479 int64_t cur_pos = avio_tell(sc->pb);
10480 int64_t value;
10481 AVRational tc_rate = st->avg_frame_rate;
10482 int tmcd_nb_frames = sc->tmcd_nb_frames;
10483 int rounded_tc_rate;
10484
10485 if (!sti->nb_index_entries)
10486 return -1;
10487
10488 if (!tc_rate.num || !tc_rate.den || !tmcd_nb_frames)
10489 return -1;
10490
10491 avio_seek(sc->pb, sti->index_entries->pos, SEEK_SET);
10492 value = avio_rb32(s->pb);
10493
10494 if (sc->tmcd_flags & 0x0001) flags |= AV_TIMECODE_FLAG_DROPFRAME;
10495 if (sc->tmcd_flags & 0x0002) flags |= AV_TIMECODE_FLAG_24HOURSMAX;
10496 if (sc->tmcd_flags & 0x0004) flags |= AV_TIMECODE_FLAG_ALLOWNEGATIVE;
10497
10498 /* Assume Counter flag is set to 1 in tmcd track (even though it is likely
10499 * not the case) and thus assume "frame number format" instead of QT one.
10500 * No sample with tmcd track can be found with a QT timecode at the moment,
10501 * despite what the tmcd track "suggests" (Counter flag set to 0 means QT
10502 * format). */
10503
10504 /* 60 fps content have tmcd_nb_frames set to 30 but tc_rate set to 60, so
10505 * we multiply the frame number with the quotient.
10506 * See tickets #9492, #9710. */
10507 rounded_tc_rate = (tc_rate.num + tc_rate.den / 2LL) / tc_rate.den;
10508 /* Work around files where tmcd_nb_frames is rounded down from frame rate
10509 * instead of up. See ticket #5978. */
10510 if (tmcd_nb_frames == tc_rate.num / tc_rate.den &&
10511 s->strict_std_compliance < FF_COMPLIANCE_STRICT)
10512 tmcd_nb_frames = rounded_tc_rate;
10513 value = av_rescale(value, rounded_tc_rate, tmcd_nb_frames);
10514
10516
10517 avio_seek(sc->pb, cur_pos, SEEK_SET);
10518 return 0;
10519}
10520
10522 int i;
10523 if (!index || !*index) return;
10524 for (i = 0; i < (*index)->nb_encrypted_samples; i++) {
10525 av_encryption_info_free((*index)->encrypted_samples[i]);
10526 }
10527 av_freep(&(*index)->encrypted_samples);
10528 av_freep(&(*index)->auxiliary_info_sizes);
10529 av_freep(&(*index)->auxiliary_offsets);
10530 av_freep(index);
10531}
10532
10534{
10535 MOVStreamContext *sc = st->priv_data;
10536
10537 if (!sc || --sc->refcount) {
10538 st->priv_data = NULL;
10539 return;
10540 }
10541
10542 av_freep(&sc->tts_data);
10543 for (int i = 0; i < sc->drefs_count; i++) {
10544 av_freep(&sc->drefs[i].path);
10545 av_freep(&sc->drefs[i].dir);
10546 }
10547 av_freep(&sc->drefs);
10548
10549 sc->drefs_count = 0;
10550
10551 if (!sc->pb_is_copied)
10552 ff_format_io_close(s, &sc->pb);
10553
10554 sc->pb = NULL;
10555 av_freep(&sc->chunk_offsets);
10556 av_freep(&sc->stsc_data);
10557 av_freep(&sc->sample_sizes);
10558 av_freep(&sc->keyframes);
10559 av_freep(&sc->ctts_data);
10560 av_freep(&sc->stts_data);
10561 av_freep(&sc->sdtp_data);
10562 av_freep(&sc->stps_data);
10563 av_freep(&sc->elst_data);
10564 av_freep(&sc->rap_group);
10565 av_freep(&sc->sync_group);
10566 av_freep(&sc->sgpd_sync);
10570 av_freep(&sc->index_ranges);
10571 for (int i = 0; i < sc->nb_tref_tags; i++)
10572 av_freep(&sc->tref_tags[i].id);
10573 av_freep(&sc->tref_tags);
10574
10575 if (sc->extradata)
10576 for (int i = 0; i < sc->stsd_count; i++)
10577 av_free(sc->extradata[i]);
10578 av_freep(&sc->extradata);
10580
10584
10585 av_freep(&sc->stereo3d);
10586 av_freep(&sc->spherical);
10587 av_freep(&sc->mastering);
10588 av_freep(&sc->coll);
10589 av_freep(&sc->ambient);
10590
10591#if CONFIG_IAMFDEC
10592 if (sc->iamf)
10594#endif
10595 av_freep(&sc->iamf);
10596}
10597
10599{
10600 MOVContext *mov = s->priv_data;
10601 int i, j;
10602
10603 for (i = 0; i < s->nb_streams; i++) {
10604 AVStream *st = s->streams[i];
10605
10607 }
10608
10609 av_freep(&mov->dv_demux);
10611 mov->dv_fctx = NULL;
10612
10613 if (mov->meta_keys) {
10614 for (i = 1; i < mov->meta_keys_count; i++) {
10615 av_freep(&mov->meta_keys[i]);
10616 }
10617 av_freep(&mov->meta_keys);
10618 }
10619
10620 av_freep(&mov->trex_data);
10621 av_freep(&mov->bitrates);
10622
10623 for (i = 0; i < mov->frag_index.nb_items; i++) {
10625 for (j = 0; j < mov->frag_index.item[i].nb_stream_info; j++) {
10626 mov_free_encryption_index(&frag[j].encryption_index);
10627 }
10629 }
10630 av_freep(&mov->frag_index.item);
10631
10632 av_freep(&mov->aes_decrypt);
10633 av_freep(&mov->chapter_tracks);
10634 for (i = 0; i < mov->nb_heif_item; i++) {
10635 if (!mov->heif_item[i])
10636 continue;
10637 av_freep(&mov->heif_item[i]->name);
10638 av_freep(&mov->heif_item[i]->iref_list);
10640 av_freep(&mov->heif_item[i]);
10641 }
10642 av_freep(&mov->heif_item);
10643 for (i = 0; i < mov->nb_heif_grid; i++) {
10647 }
10648 av_freep(&mov->heif_grid);
10649
10650 return 0;
10651}
10652
10653static int tmcd_is_referenced(AVFormatContext *s, int tmcd_id)
10654{
10655 int i;
10656
10657 for (i = 0; i < s->nb_streams; i++) {
10658 AVStream *st = s->streams[i];
10659 MOVStreamContext *sc = st->priv_data;
10660 MovTref *tag = mov_find_tref_tag(sc, MKTAG('t','m','c','d'));
10661
10662 if (!tag)
10663 continue;
10664 if (mov_find_tref_id(tag, tmcd_id))
10665 return 1;
10666 }
10667 return 0;
10668}
10669
10670/* look for a tmcd track not referenced by any video track, and export it globally */
10672{
10673 int i;
10674
10675 for (i = 0; i < s->nb_streams; i++) {
10676 AVStream *st = s->streams[i];
10677
10678 if (st->codecpar->codec_tag == MKTAG('t','m','c','d') &&
10679 !tmcd_is_referenced(s, st->id)) {
10680 AVDictionaryEntry *tcr = av_dict_get(st->metadata, "timecode", NULL, 0);
10681 if (tcr) {
10682 av_dict_set(&s->metadata, "timecode", tcr->value, 0);
10683 break;
10684 }
10685 }
10686 }
10687}
10688
10690{
10691 int version, fieldlength, i, j;
10693 uint32_t size = avio_rb32(f);
10694 unsigned track_id, item_count;
10695
10696 if (avio_rb32(f) != MKBETAG('t', 'f', 'r', 'a')) {
10697 return 1;
10698 }
10699 av_log(mov->fc, AV_LOG_VERBOSE, "found tfra\n");
10700
10701 version = avio_r8(f);
10702 avio_rb24(f);
10703 track_id = avio_rb32(f);
10704 fieldlength = avio_rb32(f);
10705 item_count = avio_rb32(f);
10706 for (i = 0; i < item_count; i++) {
10707 int64_t time, offset;
10708 int index;
10709 MOVFragmentStreamInfo * frag_stream_info;
10710
10711 if (avio_feof(f)) {
10712 return AVERROR_INVALIDDATA;
10713 }
10714
10715 if (version == 1) {
10716 time = avio_rb64(f);
10717 offset = avio_rb64(f);
10718 } else {
10719 time = avio_rb32(f);
10720 offset = avio_rb32(f);
10721 }
10722
10723 // The first sample of each stream in a fragment is always a random
10724 // access sample. So it's entry in the tfra can be used as the
10725 // initial PTS of the fragment.
10727 frag_stream_info = get_frag_stream_info(&mov->frag_index, index, track_id);
10728 if (frag_stream_info &&
10729 frag_stream_info->first_tfra_pts == AV_NOPTS_VALUE)
10730 frag_stream_info->first_tfra_pts = time;
10731
10732 for (j = 0; j < ((fieldlength >> 4) & 3) + 1; j++)
10733 avio_r8(f);
10734 for (j = 0; j < ((fieldlength >> 2) & 3) + 1; j++)
10735 avio_r8(f);
10736 for (j = 0; j < ((fieldlength >> 0) & 3) + 1; j++)
10737 avio_r8(f);
10738 }
10739
10740 avio_seek(f, pos + size, SEEK_SET);
10741 return 0;
10742}
10743
10745{
10746 int64_t stream_size = avio_size(f);
10747 int64_t original_pos = avio_tell(f);
10748 int64_t seek_ret;
10749 int ret = -1;
10750 if ((seek_ret = avio_seek(f, stream_size - 4, SEEK_SET)) < 0) {
10751 ret = seek_ret;
10752 goto fail;
10753 }
10754 c->mfra_size = avio_rb32(f);
10755 c->have_read_mfra_size = 1;
10756 if (!c->mfra_size || c->mfra_size > stream_size) {
10757 av_log(c->fc, AV_LOG_DEBUG, "doesn't look like mfra (unreasonable size)\n");
10758 goto fail;
10759 }
10760 if ((seek_ret = avio_seek(f, -((int64_t) c->mfra_size), SEEK_CUR)) < 0) {
10761 ret = seek_ret;
10762 goto fail;
10763 }
10764 if (avio_rb32(f) != c->mfra_size) {
10765 av_log(c->fc, AV_LOG_DEBUG, "doesn't look like mfra (size mismatch)\n");
10766 goto fail;
10767 }
10768 if (avio_rb32(f) != MKBETAG('m', 'f', 'r', 'a')) {
10769 av_log(c->fc, AV_LOG_DEBUG, "doesn't look like mfra (tag mismatch)\n");
10770 goto fail;
10771 }
10772 av_log(c->fc, AV_LOG_VERBOSE, "stream has mfra\n");
10773 do {
10774 ret = read_tfra(c, f);
10775 if (ret < 0)
10776 goto fail;
10777 } while (!ret);
10778 ret = 0;
10779 c->frag_index.complete = 1;
10780fail:
10781 seek_ret = avio_seek(f, original_pos, SEEK_SET);
10782 if (seek_ret < 0) {
10783 av_log(c->fc, AV_LOG_ERROR,
10784 "failed to seek back after looking for mfra\n");
10785 ret = seek_ret;
10786 }
10787 return ret;
10788}
10789
10790static int set_icc_profile_from_item(AVPacketSideData **coded_side_data, int *nb_coded_side_data,
10791 const HEIFItem *item)
10792{
10793 AVPacketSideData *sd = av_packet_side_data_new(coded_side_data, nb_coded_side_data,
10795 item->icc_profile_size, 0);
10796 if (!sd)
10797 return AVERROR(ENOMEM);
10798
10799 memcpy(sd->data, item->icc_profile, item->icc_profile_size);
10800
10801 return 0;
10802}
10803
10804static int set_display_matrix_from_item(AVPacketSideData **coded_side_data, int *nb_coded_side_data,
10805 const HEIFItem *item)
10806{
10807 int32_t *matrix;
10808 AVPacketSideData *sd = av_packet_side_data_new(coded_side_data,
10809 nb_coded_side_data,
10811 9 * sizeof(*matrix), 0);
10812 if (!sd)
10813 return AVERROR(ENOMEM);
10814
10815 matrix = (int32_t*)sd->data;
10816 /* rotation is in the counter-clockwise direction whereas
10817 * av_display_rotation_set() expects its argument to be
10818 * oriented clockwise, so we need to negate it. */
10821
10822 return 0;
10823}
10824
10826 AVStreamGroupTileGrid *tile_grid)
10827{
10828 MOVContext *c = s->priv_data;
10829 const HEIFItem *item = grid->item;
10830 int64_t coded_width = 0, coded_height = 0;
10831 int64_t offset = 0, pos = avio_tell(s->pb);
10832 int64_t x = 0, y = 0;
10833 int i = 0;
10834 int tile_rows, tile_cols;
10835 int flags, size;
10836
10837 if (!(s->pb->seekable & AVIO_SEEKABLE_NORMAL)) {
10838 av_log(c->fc, AV_LOG_INFO, "grid box with non seekable input\n");
10839 return AVERROR_PATCHWELCOME;
10840 }
10841 if (item->is_idat_relative) {
10842 if (!c->idat_offset) {
10843 av_log(c->fc, AV_LOG_ERROR, "missing idat box required by the image grid\n");
10844 return AVERROR_INVALIDDATA;
10845 }
10846 offset = c->idat_offset;
10847 }
10848
10849 if (offset > INT64_MAX - item->extent_offset)
10850 return AVERROR_INVALIDDATA;
10851
10852 avio_seek(s->pb, item->extent_offset + offset, SEEK_SET);
10853
10854 avio_r8(s->pb); /* version */
10855 flags = avio_r8(s->pb);
10856
10857 tile_rows = avio_r8(s->pb) + 1;
10858 tile_cols = avio_r8(s->pb) + 1;
10859 /* actual width and height of output image */
10860 tile_grid->width = (flags & 1) ? avio_rb32(s->pb) : avio_rb16(s->pb);
10861 tile_grid->height = (flags & 1) ? avio_rb32(s->pb) : avio_rb16(s->pb);
10862
10863 av_log(c->fc, AV_LOG_TRACE, "grid: grid_rows %d grid_cols %d output_width %d output_height %d\n",
10864 tile_rows, tile_cols, tile_grid->width, tile_grid->height);
10865
10866 avio_seek(s->pb, pos, SEEK_SET);
10867
10869 tile_grid->nb_tiles = grid->nb_tiles;
10870
10871 if (tile_grid->nb_tiles != size)
10872 return AVERROR_INVALIDDATA;
10873
10874 for (int i = 0; i < tile_cols; i++)
10875 coded_width += grid->tile_item_list[i]->width;
10876 for (int i = 0; i < size; i += tile_cols)
10877 coded_height += grid->tile_item_list[i]->height;
10878
10879 if (coded_width > INT_MAX || coded_height > INT_MAX)
10880 return AVERROR_INVALIDDATA;
10881
10882 tile_grid->coded_width = coded_width;
10883 tile_grid->coded_height = coded_height;
10884
10885 tile_grid->offsets = av_calloc(tile_grid->nb_tiles, sizeof(*tile_grid->offsets));
10886 if (!tile_grid->offsets)
10887 return AVERROR(ENOMEM);
10888
10889 while (y < tile_grid->coded_height) {
10890 int left_col = i;
10891
10892 while (x < tile_grid->coded_width) {
10893 if (i == tile_grid->nb_tiles)
10894 return AVERROR_INVALIDDATA;
10895
10896 tile_grid->offsets[i].idx = grid->tile_idx_list[i];
10897 tile_grid->offsets[i].horizontal = x;
10898 tile_grid->offsets[i].vertical = y;
10899
10900 x += grid->tile_item_list[i++]->width;
10901 }
10902
10903 if (x > tile_grid->coded_width) {
10904 av_log(c->fc, AV_LOG_ERROR, "Non uniform HEIF tiles\n");
10905 return AVERROR_INVALIDDATA;
10906 }
10907
10908 x = 0;
10909 y += grid->tile_item_list[left_col]->height;
10910 }
10911
10912 if (y > tile_grid->coded_height || i != tile_grid->nb_tiles) {
10913 av_log(c->fc, AV_LOG_ERROR, "Non uniform HEIF tiles\n");
10914 return AVERROR_INVALIDDATA;
10915 }
10916
10917 return 0;
10918}
10919
10921 AVStreamGroupTileGrid *tile_grid)
10922{
10923 MOVContext *c = s->priv_data;
10924 const HEIFItem *item = grid->item;
10925 uint16_t canvas_fill_value[4];
10926 int64_t offset = 0, pos = avio_tell(s->pb);
10927 int ret = 0, flags;
10928
10929 if (!(s->pb->seekable & AVIO_SEEKABLE_NORMAL)) {
10930 av_log(c->fc, AV_LOG_INFO, "iovl box with non seekable input\n");
10931 return AVERROR_PATCHWELCOME;
10932 }
10933 if (item->is_idat_relative) {
10934 if (!c->idat_offset) {
10935 av_log(c->fc, AV_LOG_ERROR, "missing idat box required by the image overlay\n");
10936 return AVERROR_INVALIDDATA;
10937 }
10938 offset = c->idat_offset;
10939 }
10940
10941 if (offset > INT64_MAX - item->extent_offset)
10942 return AVERROR_INVALIDDATA;
10943
10944 avio_seek(s->pb, item->extent_offset + offset, SEEK_SET);
10945
10946 avio_r8(s->pb); /* version */
10947 flags = avio_r8(s->pb);
10948
10949 for (int i = 0; i < 4; i++)
10950 canvas_fill_value[i] = avio_rb16(s->pb);
10951 av_log(c->fc, AV_LOG_TRACE, "iovl: canvas_fill_value { %u, %u, %u, %u }\n",
10952 canvas_fill_value[0], canvas_fill_value[1],
10953 canvas_fill_value[2], canvas_fill_value[3]);
10954 for (int i = 0; i < 4; i++)
10955 tile_grid->background[i] = canvas_fill_value[i];
10956
10957 /* actual width and height of output image */
10958 tile_grid->width =
10959 tile_grid->coded_width = (flags & 1) ? avio_rb32(s->pb) : avio_rb16(s->pb);
10960 tile_grid->height =
10961 tile_grid->coded_height = (flags & 1) ? avio_rb32(s->pb) : avio_rb16(s->pb);
10962
10963 av_log(c->fc, AV_LOG_TRACE, "iovl: output_width %d, output_height %d\n",
10964 tile_grid->width, tile_grid->height);
10965
10966 tile_grid->nb_tiles = grid->nb_tiles;
10967 tile_grid->offsets = av_malloc_array(tile_grid->nb_tiles, sizeof(*tile_grid->offsets));
10968 if (!tile_grid->offsets) {
10969 ret = AVERROR(ENOMEM);
10970 goto fail;
10971 }
10972
10973 for (int i = 0; i < tile_grid->nb_tiles; i++) {
10974 tile_grid->offsets[i].idx = grid->tile_idx_list[i];
10975 tile_grid->offsets[i].horizontal = (flags & 1) ? avio_rb32(s->pb) : avio_rb16(s->pb);
10976 tile_grid->offsets[i].vertical = (flags & 1) ? avio_rb32(s->pb) : avio_rb16(s->pb);
10977 av_log(c->fc, AV_LOG_TRACE, "iovl: stream_idx[%d] %u, "
10978 "horizontal_offset[%d] %d, vertical_offset[%d] %d\n",
10979 i, tile_grid->offsets[i].idx,
10980 i, tile_grid->offsets[i].horizontal, i, tile_grid->offsets[i].vertical);
10981 }
10982
10983fail:
10984 avio_seek(s->pb, pos, SEEK_SET);
10985
10986 return ret;
10987}
10988
10990 AVPacketSideData **coded_side_data, int *nb_coded_side_data,
10991 const HEIFItem *ref)
10992{
10993 MOVContext *c = s->priv_data;
10994 AVPacketSideData *sd;
10995 AVExifMetadata ifd = { 0 };
10996 AVBufferRef *buf;
10997 int64_t offset = 0, pos = avio_tell(s->pb);
10998 unsigned orientation_id = av_exif_get_tag_id("Orientation");
10999 int err;
11000
11001 if (!(s->pb->seekable & AVIO_SEEKABLE_NORMAL)) {
11002 av_log(c->fc, AV_LOG_WARNING, "Exif metadata with non seekable input\n");
11003 return AVERROR_PATCHWELCOME;
11004 }
11005 if (ref->is_idat_relative) {
11006 if (!c->idat_offset) {
11007 av_log(c->fc, AV_LOG_ERROR, "missing idat box required by the Exif metadata\n");
11008 return AVERROR_INVALIDDATA;
11009 }
11010 offset = c->idat_offset;
11011 }
11012
11013 buf = av_buffer_alloc(ref->extent_length);
11014 if (!buf)
11015 return AVERROR(ENOMEM);
11016
11017 if (offset > INT64_MAX - ref->extent_offset) {
11018 err = AVERROR(ENOMEM);
11019 goto fail;
11020 }
11021
11022 avio_seek(s->pb, ref->extent_offset + offset, SEEK_SET);
11023 err = avio_read(s->pb, buf->data, ref->extent_length);
11024 if (err != ref->extent_length) {
11025 if (err > 0)
11026 err = AVERROR_INVALIDDATA;
11027 goto fail;
11028 }
11029
11030 // HEIF spec states that Exif metadata is informative. The irot item property is
11031 // the normative source of rotation information. So we remove any Orientation tag
11032 // present in the Exif buffer.
11033 err = av_exif_parse_buffer(s, buf->data, ref->extent_length, &ifd, AV_EXIF_T_OFF);
11034 if (err < 0) {
11035 av_log(s, AV_LOG_ERROR, "Unable to parse Exif metadata\n");
11036 goto fail;
11037 }
11038
11039 err = av_exif_remove_entry(s, &ifd, orientation_id, 0);
11040 if (err < 0)
11041 goto fail;
11042 else if (!err)
11043 goto finish;
11044
11045 av_buffer_unref(&buf);
11046 err = av_exif_write(s, &ifd, &buf, AV_EXIF_T_OFF);
11047 if (err < 0)
11048 goto fail;
11049
11050finish:
11051 offset = AV_RB32(buf->data) + 4;
11052 if (offset >= buf->size) {
11053 err = AVERROR_INVALIDDATA;
11054 goto fail;
11055 }
11056 sd = av_packet_side_data_new(coded_side_data, nb_coded_side_data,
11057 AV_PKT_DATA_EXIF, buf->size - offset, 0);
11058 if (!sd) {
11059 err = AVERROR(ENOMEM);
11060 goto fail;
11061 }
11062 memcpy(sd->data, buf->data + offset, buf->size - offset);
11063
11064 err = 0;
11065fail:
11066 av_buffer_unref(&buf);
11067 av_exif_free(&ifd);
11068 avio_seek(s->pb, pos, SEEK_SET);
11069
11070 return err;
11071}
11072
11074{
11075 MOVContext *mov = s->priv_data;
11076
11077 for (int i = 0; i < mov->nb_heif_grid; i++) {
11079 AVStreamGroupTileGrid *tile_grid;
11080 const HEIFGrid *grid = &mov->heif_grid[i];
11081 int err, loop = 1;
11082
11083 if (!stg)
11084 return AVERROR(ENOMEM);
11085
11086 stg->id = grid->item->item_id;
11087 tile_grid = stg->params.tile_grid;
11088
11089 for (int j = 0; j < grid->nb_tiles; j++) {
11090 int tile_id = grid->tile_id_list[j];
11091 int k;
11092
11093 for (k = 0; k < mov->nb_heif_item; k++) {
11094 HEIFItem *item = mov->heif_item[k];
11095 AVStream *st;
11096
11097 if (!item || item->item_id != tile_id)
11098 continue;
11099 st = item->st;
11100 if (!st) {
11101 av_log(s, AV_LOG_WARNING, "HEIF item id %d from grid id %d doesn't "
11102 "reference a stream\n",
11103 tile_id, grid->item->item_id);
11105 loop = 0;
11106 break;
11107 }
11108
11109 grid->tile_item_list[j] = item;
11110 grid->tile_idx_list[j] = stg->nb_streams;
11111
11112 err = avformat_stream_group_add_stream(stg, st);
11113 if (err < 0) {
11114 int l;
11115 if (err != AVERROR(EEXIST))
11116 return err;
11117
11118 for (l = 0; l < stg->nb_streams; l++)
11119 if (stg->streams[l]->index == st->index)
11120 break;
11121 av_assert0(l < stg->nb_streams);
11122 grid->tile_idx_list[j] = l;
11123 }
11124
11125 if (item->item_id != mov->primary_item_id)
11127 break;
11128 }
11129
11130 if (k == mov->nb_heif_item) {
11132 av_log(s, AV_LOG_WARNING, "HEIF item id %d referenced by grid id %d doesn't "
11133 "exist\n",
11134 tile_id, grid->item->item_id);
11136 loop = 0;
11137 }
11138 if (!loop)
11139 break;
11140 }
11141
11142 if (!loop)
11143 continue;
11144
11145 switch (grid->item->type) {
11146 case MKTAG('g','r','i','d'):
11147 err = read_image_grid(s, grid, tile_grid);
11148 break;
11149 case MKTAG('i','o','v','l'):
11150 err = read_image_iovl(s, grid, tile_grid);
11151 break;
11152 default:
11153 av_assert0(0);
11154 }
11155 if (err < 0)
11156 return err;
11157
11158 for (int j = 0; j < grid->item->nb_iref_list; j++) {
11159 HEIFItem *ref = get_heif_item(mov, grid->item->iref_list[j].item_id);
11160
11161 av_assert0(ref);
11162 switch(ref->type) {
11163 case MKTAG('E','x','i','f'):
11164 err = mov_parse_exif_item(s, &tile_grid->coded_side_data,
11165 &tile_grid->nb_coded_side_data, ref);
11166 if (err < 0 && (s->error_recognition & AV_EF_EXPLODE))
11167 return err;
11168 break;
11169 default:
11170 break;
11171 }
11172 }
11173
11174 /* rotation */
11175 if (grid->item->rotation || grid->item->hflip || grid->item->vflip) {
11177 &tile_grid->nb_coded_side_data, grid->item);
11178 if (err < 0)
11179 return err;
11180 }
11181
11182 /* ICC profile */
11183 if (grid->item->icc_profile_size) {
11185 &tile_grid->nb_coded_side_data, grid->item);
11186 if (err < 0)
11187 return err;
11188 }
11189
11190 if (grid->item->name)
11191 av_dict_set(&stg->metadata, "title", grid->item->name, 0);
11192 if (grid->item->item_id == mov->primary_item_id)
11194 }
11195
11196 return 0;
11197}
11198
11200{
11201 MOVContext *mov = s->priv_data;
11202 int err;
11203
11204 for (int i = 0; i < mov->nb_heif_item; i++) {
11205 HEIFItem *item = mov->heif_item[i];
11206 MOVStreamContext *sc;
11207 AVStream *st;
11208 int64_t offset = 0;
11209
11210 if (!item)
11211 continue;
11212 if (!item->st) {
11213 continue;
11214 }
11215 if (item->is_idat_relative) {
11216 if (!mov->idat_offset) {
11217 av_log(s, AV_LOG_ERROR, "Missing idat box for item %d\n", item->item_id);
11218 return AVERROR_INVALIDDATA;
11219 }
11220 offset = mov->idat_offset;
11221 }
11222
11223 st = item->st;
11224 sc = st->priv_data;
11225 st->codecpar->width = item->width;
11226 st->codecpar->height = item->height;
11227
11228 sc->sample_size = sc->stsz_sample_size = item->extent_length;
11229 sc->sample_count = 1;
11230
11231 err = sanity_checks(s, sc, st->index);
11232 if (err)
11233 return AVERROR_INVALIDDATA;
11234
11235 if (offset > INT64_MAX - item->extent_offset)
11236 return AVERROR_INVALIDDATA;
11237
11238 sc->chunk_offsets[0] = item->extent_offset + offset;
11239
11240 if (item->item_id == mov->primary_item_id)
11242
11243 for (int j = 0; j < item->nb_iref_list; j++) {
11244 HEIFItem *ref = get_heif_item(mov, item->iref_list[j].item_id);
11245
11246 av_assert0(ref);
11247 switch(ref->type) {
11248 case MKTAG('E','x','i','f'):
11251 if (err < 0 && (s->error_recognition & AV_EF_EXPLODE))
11252 return err;
11253 break;
11254 default:
11255 break;
11256 }
11257 }
11258
11259 if (item->rotation || item->hflip || item->vflip) {
11261 &st->codecpar->nb_coded_side_data, item);
11262 if (err < 0)
11263 return err;
11264 }
11265
11266 mov_build_index(mov, st);
11267 }
11268
11269 if (mov->nb_heif_grid) {
11270 err = mov_parse_tiles(s);
11271 if (err < 0)
11272 return err;
11273 }
11274
11275 return 0;
11276}
11277
11279{
11280 int err;
11281
11282 for (int i = 0; i < s->nb_streams; i++) {
11283 AVStreamGroup *stg;
11284 const AVDictionaryEntry *tcr;
11285 AVStream *st = s->streams[i];
11286
11287 if (st->codecpar->codec_tag != MKTAG('t','m','c','d'))
11288 continue;
11289
11291 if (!stg)
11292 return AVERROR(ENOMEM);
11293
11294 stg->id = st->id;
11295 tcr = av_dict_get(st->metadata, "timecode", NULL, 0);
11296
11297 for (int j = 0; j < s->nb_streams; j++) {
11298 AVStream *st2 = s->streams[j];
11299 MOVStreamContext *sc2 = st2->priv_data;
11300 MovTref *tag = mov_find_tref_tag(sc2, MKTAG('t','m','c','d'));
11301
11302 if (!tag)
11303 continue;
11304
11305 for (int k = 0; k < tag->nb_id; k++) {
11306 if (tag->id[k] != st->id)
11307 continue;
11308
11309 err = avformat_stream_group_add_stream(stg, st2);
11310 if (err < 0)
11311 return err;
11312
11313 if (tcr)
11314 av_dict_set(&st2->metadata, "timecode", tcr->value, AV_DICT_DONT_OVERWRITE);
11315 }
11316 }
11317
11318 if (!stg->nb_streams) {
11320 continue;
11321 }
11322
11323 err = avformat_stream_group_add_stream(stg, st);
11324 if (err < 0)
11325 return err;
11326
11327 stg->params.tref->metadata_index = stg->nb_streams - 1;
11328 }
11330
11331 return 0;
11332}
11333
11335 uint32_t *tref_id, int nb_tref_id, int first_index)
11336{
11337 if (!nb_tref_id)
11338 return NULL;
11339
11340 for (int i = first_index; i < s->nb_streams; i++)
11341 for (int j = 0; j < nb_tref_id; j++)
11342 if (s->streams[i]->index != st->index &&
11343 s->streams[i]->id == tref_id[j])
11344 return s->streams[i];
11345
11346 return NULL;
11347}
11348
11350{
11351 int err;
11352
11353 // Don't try to add a group if there's only one track
11354 if (s->nb_streams <= 1)
11355 return 0;
11356
11357 for (int i = 0; i < s->nb_streams; i++) {
11358 AVStreamGroup *stg;
11359 AVStream *st = s->streams[i];
11360 AVStream *st_ref;
11361 MOVStreamContext *sc = st->priv_data;
11362 MovTref *tag = mov_find_tref_tag(sc, MKTAG('c','d','s','c'));
11363
11364 if (!tag)
11365 continue;
11366
11367 st_ref = mov_find_reference_track(s, st, tag->id, tag->nb_id, 0);
11368 if (!st_ref) {
11369 int loglevel = (s->error_recognition & AV_EF_EXPLODE) ? AV_LOG_ERROR : AV_LOG_WARNING;
11370 av_log(s, loglevel, "Failed to find referenced stream\n");
11371 if (s->error_recognition & AV_EF_EXPLODE)
11372 return AVERROR_INVALIDDATA;
11373 continue;
11374 }
11375
11377 if (!stg)
11378 return AVERROR(ENOMEM);
11379
11380 stg->id = st->id;
11381
11382 err = avformat_stream_group_add_stream(stg, st_ref);
11383 if (err < 0)
11384 return err;
11385
11386 err = avformat_stream_group_add_stream(stg, st);
11387 if (err < 0)
11388 return err;
11389
11390 stg->params.tref->metadata_index = stg->nb_streams - 1;
11391 }
11392
11393 return 0;
11394}
11395
11397{
11398 int err;
11399
11400 // Don't try to add a group if there's only one track
11401 if (s->nb_streams <= 1)
11402 return 0;
11403
11404 for (int i = 0; i < s->nb_streams; i++) {
11405 AVStreamGroup *stg;
11406 AVStream *st = s->streams[i];
11407 AVStream *st_base;
11408 MOVStreamContext *sc = st->priv_data;
11409 MovTref *tag = mov_find_tref_tag(sc, MKTAG('s','b','a','s'));
11410 int j = 0;
11411
11412 /* Find an enhancement stream. */
11413 if (st->codecpar->codec_id != AV_CODEC_ID_LCEVC || !tag)
11414 continue;
11415
11417 if (!stg)
11418 return AVERROR(ENOMEM);
11419
11420 stg->id = st->id;
11423
11424 while (st_base = mov_find_reference_track(s, st, tag->id, tag->nb_id, j)) {
11425 err = avformat_stream_group_add_stream(stg, st_base);
11426 if (err < 0)
11427 return err;
11428
11429 j = st_base->index + 1;
11430 }
11431 if (!j) {
11432 int loglevel = (s->error_recognition & AV_EF_EXPLODE) ? AV_LOG_ERROR : AV_LOG_WARNING;
11433 av_log(s, loglevel, "Failed to find base stream for LCEVC stream\n");
11435 if (s->error_recognition & AV_EF_EXPLODE)
11436 return AVERROR_INVALIDDATA;
11437 continue;
11438 }
11439
11440 err = avformat_stream_group_add_stream(stg, st);
11441 if (err < 0)
11442 return err;
11443
11444 stg->params.layered_video->el_index = stg->nb_streams - 1;
11445 }
11446
11447 return 0;
11448}
11449
11451{
11452 int err;
11453
11454 if (s->nb_streams <= 1)
11455 return 0;
11456
11457 /* Identify legacy dual-track Dolby Vision profile 7 carriage per Annex
11458 * C of "Dolby Vision Streams Within the ISO Base Media File Format",
11459 * v2.7.1. The 'vdep' track reference type is shared with depth video
11460 * and multi-view dependencies. The spec-mandated DV-specific sample
11461 * entry combined with the dvcC configuration record disambiguates
11462 * those uses. */
11463 for (int i = 0; i < s->nb_streams; i++) {
11464 AVStreamGroup *stg;
11465 AVStream *st = s->streams[i];
11466 AVStream *st_base;
11467 MOVStreamContext *sc = st->priv_data;
11468 MovTref *tag = mov_find_tref_tag(sc, MKTAG('v','d','e','p'));
11469 const AVPacketSideData *sd;
11471
11472 if (st->codecpar->codec_id != AV_CODEC_ID_HEVC || !tag)
11473 continue;
11474
11475 if (st->codecpar->codec_tag != MKTAG('d','v','h','e') &&
11476 st->codecpar->codec_tag != MKTAG('d','v','h','1'))
11477 continue;
11478
11482 if (!sd)
11483 continue;
11484 dovi = (const AVDOVIDecoderConfigurationRecord *)sd->data;
11485
11486 /* EL track of a dual-track stream: rpu_present_flag = 1,
11487 * el_present_flag = 1, bl_present_flag = 0, dv_profile = 7. */
11488 if (dovi->dv_profile != 7 || !dovi->rpu_present_flag ||
11489 !dovi->el_present_flag || dovi->bl_present_flag)
11490 continue;
11491
11492 st_base = mov_find_reference_track(s, st, tag->id, tag->nb_id, 0);
11493 if (!st_base) {
11494 int loglevel = (s->error_recognition & AV_EF_EXPLODE) ? AV_LOG_ERROR : AV_LOG_WARNING;
11495 av_log(s, loglevel, "Failed to find base layer for Dolby Vision EL stream\n");
11496 if (s->error_recognition & AV_EF_EXPLODE)
11497 return AVERROR_INVALIDDATA;
11498 continue;
11499 }
11500
11502 if (!stg)
11503 return AVERROR(ENOMEM);
11504
11505 stg->id = st->id;
11506
11507 err = avformat_stream_group_add_stream(stg, st_base);
11508 if (err < 0)
11509 return err;
11510
11511 err = avformat_stream_group_add_stream(stg, st);
11512 if (err < 0)
11513 return err;
11514
11515 stg->params.layered_video->el_index = stg->nb_streams - 1;
11516 stg->params.layered_video->width = st_base->codecpar->width;
11517 stg->params.layered_video->height = st_base->codecpar->height;
11518 }
11519
11520 return 0;
11521}
11522
11524{
11525 int highest_id = 0, lowest_iamf_id = INT_MAX;
11526
11527 for (int i = 0; i < s->nb_streams; i++) {
11528 const AVStream *st = s->streams[i];
11529 const MOVStreamContext *sc = st->priv_data;
11530 if (!sc->iamf)
11531 highest_id = FFMAX(highest_id, st->id);
11532 }
11533
11534 for (int i = 0; i < s->nb_stream_groups; i++) {
11535 AVStreamGroup *stg = s->stream_groups[i];
11537 continue;
11538 for (int j = 0; j < stg->nb_streams; j++) {
11539 AVStream *st = stg->streams[j];
11540 lowest_iamf_id = FFMIN(lowest_iamf_id, st->id);
11541 }
11542 }
11543
11544 if (highest_id < lowest_iamf_id)
11545 return;
11546
11547 highest_id += !lowest_iamf_id;
11548 for (int i = 0; highest_id > 1 && i < s->nb_stream_groups; i++) {
11549 AVStreamGroup *stg = s->stream_groups[i];
11551 continue;
11552 for (int j = 0; j < stg->nb_streams; j++) {
11553 AVStream *st = stg->streams[j];
11554 MOVStreamContext *sc = st->priv_data;
11555 st->id += highest_id;
11556 sc->iamf_stream_offset = highest_id;
11557 }
11558 }
11559}
11560
11562{
11563 MOVContext *mov = s->priv_data;
11564 AVIOContext *pb = s->pb;
11565 int j, err;
11566 MOVAtom atom = { AV_RL32("root") };
11567 int i;
11568
11569 mov->fc = s;
11570 mov->trak_index = -1;
11571 mov->primary_item_id = -1;
11572 mov->cur_item_id = -1;
11573 /* .mov and .mp4 aren't streamable anyway (only progressive download if moov is before mdat) */
11575 atom.size = avio_size(pb);
11576 else
11577 atom.size = INT64_MAX;
11578
11579 /* check MOV header */
11580 do {
11581 if (mov->moov_retry)
11582 avio_seek(pb, 0, SEEK_SET);
11583 if ((err = mov_read_default(mov, pb, atom)) < 0) {
11584 av_log(s, AV_LOG_ERROR, "error reading header\n");
11585 return err;
11586 }
11587 } while ((pb->seekable & AVIO_SEEKABLE_NORMAL) &&
11588 !mov->found_moov && (!mov->found_iloc || !mov->found_iinf) && !mov->moov_retry++);
11589 if (!mov->found_moov && !mov->found_iloc && !mov->found_iinf) {
11590 av_log(s, AV_LOG_ERROR, "moov atom not found\n");
11591 return AVERROR_INVALIDDATA;
11592 }
11593 av_log(mov->fc, AV_LOG_TRACE, "on_parse_exit_offset=%"PRId64"\n", avio_tell(pb));
11594
11595 if (mov->found_iloc && mov->found_iinf) {
11596 err = mov_parse_heif_items(s);
11597 if (err < 0)
11598 return err;
11599 }
11600 // prevent iloc and iinf boxes from being parsed while reading packets.
11601 // this is needed because an iinf box may have been parsed but ignored
11602 // for having old infe boxes which create no streams.
11603 mov->found_iloc = mov->found_iinf = 1;
11604
11605 if (pb->seekable & AVIO_SEEKABLE_NORMAL) {
11606 if (mov->nb_chapter_tracks > 0 && !mov->ignore_chapters)
11608 for (i = 0; i < s->nb_streams; i++)
11609 if (s->streams[i]->codecpar->codec_tag == AV_RL32("tmcd")) {
11610 mov_read_timecode_track(s, s->streams[i]);
11611 } else if (s->streams[i]->codecpar->codec_tag == AV_RL32("rtmd")) {
11612 mov_read_rtmd_track(s, s->streams[i]);
11613 }
11614 }
11615
11616 /* Create metadata stream groups. */
11618 if (err < 0)
11619 return err;
11620
11621 /* copy timecode metadata from tmcd tracks to the related video streams */
11623 if (err < 0)
11624 return err;
11625
11626 /* Create LCEVC stream groups. */
11628 if (err < 0)
11629 return err;
11630
11631 /* Create Dolby Vision Profile 7 stream groups. */
11633 if (err < 0)
11634 return err;
11635
11636 for (i = 0; i < s->nb_streams; i++) {
11637 AVStream *st = s->streams[i];
11638 FFStream *const sti = ffstream(st);
11639 MOVStreamContext *sc = st->priv_data;
11640 uint32_t dvdsub_clut[FF_DVDCLUT_CLUT_LEN] = {0};
11641 fix_timescale(mov, sc);
11642
11643 /* Set the primary extradata based on the first Sample if it doesn't reference the first stsd entry. */
11644 if (sc->stsc_count && sc->extradata_size && !sc->iamf &&
11645 sc->stsc_data[0].id > 1 && sc->stsc_data[0].id <= sc->stsd_count) {
11646 sc->last_stsd_index = sc->stsc_data[0].id - 1;
11649 if (sc->extradata_size[sc->last_stsd_index]) {
11651 if (!st->codecpar->extradata)
11652 return AVERROR(ENOMEM);
11654 }
11655 }
11656
11660 }
11663 sc->time_scale*(int64_t)sc->nb_frames_for_fps, sc->duration_for_fps, INT_MAX);
11665 if (st->codecpar->width <= 0 || st->codecpar->height <= 0) {
11666 st->codecpar->width = sc->width;
11667 st->codecpar->height = sc->height;
11668 }
11671
11672 for (j = 0; j < FF_DVDCLUT_CLUT_LEN; j++)
11673 dvdsub_clut[j] = AV_RB32(st->codecpar->extradata + j * 4);
11674
11675 err = ff_dvdclut_yuv_to_rgb(dvdsub_clut, FF_DVDCLUT_CLUT_SIZE);
11676 if (err < 0)
11677 return err;
11678
11680 st->codecpar->extradata_size = 0;
11681
11683 st->codecpar);
11684 if (err < 0)
11685 return err;
11686 }
11687 }
11688 if (mov->handbrake_version &&
11689 mov->handbrake_version <= 1000000*0 + 1000*10 + 2 && // 0.10.2
11691 av_log(s, AV_LOG_VERBOSE, "Forcing full parsing for mp3 stream\n");
11693 }
11694 }
11695
11696 if (mov->trex_data || mov->use_mfra_for > 0) {
11697 for (i = 0; i < s->nb_streams; i++) {
11698 AVStream *st = s->streams[i];
11699 MOVStreamContext *sc = st->priv_data;
11700 if (sc->duration_for_fps > 0) {
11701 /* Akin to sc->data_size * 8 * sc->time_scale / sc->duration_for_fps but accounting for overflows. */
11703 if (st->codecpar->bit_rate == INT64_MIN) {
11704 av_log(s, AV_LOG_WARNING, "Overflow during bit rate calculation %"PRId64" * 8 * %d\n",
11705 sc->data_size, sc->time_scale);
11706 st->codecpar->bit_rate = 0;
11707 if (s->error_recognition & AV_EF_EXPLODE)
11708 return AVERROR_INVALIDDATA;
11709 }
11710 }
11711 }
11712 }
11713
11714 for (i = 0; i < mov->bitrates_count && i < s->nb_streams; i++) {
11715 if (mov->bitrates[i]) {
11716 s->streams[i]->codecpar->bit_rate = mov->bitrates[i];
11717 }
11718 }
11719
11721
11722 for (i = 0; i < s->nb_streams; i++) {
11723 AVStream *st = s->streams[i];
11724 MOVStreamContext *sc = st->priv_data;
11725
11726 switch (st->codecpar->codec_type) {
11727 case AVMEDIA_TYPE_AUDIO:
11728 err = ff_replaygain_export(st, s->metadata);
11729 if (err < 0)
11730 return err;
11731 break;
11732 case AVMEDIA_TYPE_VIDEO:
11733 if (sc->display_matrix) {
11736 (uint8_t*)sc->display_matrix, sizeof(int32_t) * 9, 0))
11737 return AVERROR(ENOMEM);
11738
11739 sc->display_matrix = NULL;
11740 }
11741 if (sc->stereo3d) {
11744 (uint8_t *)sc->stereo3d, sc->stereo3d_size, 0))
11745 return AVERROR(ENOMEM);
11746
11747 sc->stereo3d = NULL;
11748 }
11749 if (sc->spherical) {
11752 (uint8_t *)sc->spherical, sc->spherical_size, 0))
11753 return AVERROR(ENOMEM);
11754
11755 sc->spherical = NULL;
11756 }
11757 if (sc->mastering) {
11760 (uint8_t *)sc->mastering, sc->mastering_size, 0))
11761 return AVERROR(ENOMEM);
11762
11763 sc->mastering = NULL;
11764 }
11765 if (sc->coll) {
11768 (uint8_t *)sc->coll, sc->coll_size, 0))
11769 return AVERROR(ENOMEM);
11770
11771 sc->coll = NULL;
11772 }
11773 if (sc->ambient) {
11776 (uint8_t *) sc->ambient, sc->ambient_size, 0))
11777 return AVERROR(ENOMEM);
11778
11779 sc->ambient = NULL;
11780 }
11781 break;
11782 }
11783 }
11784
11786
11788
11789 for (i = 0; i < mov->frag_index.nb_items; i++)
11790 if (mov->frag_index.item[i].moof_offset <= mov->fragment.moof_offset)
11791 mov->frag_index.item[i].headers_read = 1;
11792
11793 return 0;
11794}
11795
11797{
11799 int64_t best_dts = INT64_MAX;
11800 int i;
11801 MOVContext *mov = s->priv_data;
11802 int no_interleave = !mov->interleaved_read || !(s->pb->seekable & AVIO_SEEKABLE_NORMAL);
11803 for (i = 0; i < s->nb_streams; i++) {
11804 AVStream *avst = s->streams[i];
11805 FFStream *const avsti = ffstream(avst);
11806 MOVStreamContext *msc = avst->priv_data;
11807 if (msc->pb && msc->current_sample < avsti->nb_index_entries) {
11808 AVIndexEntry *current_sample = &avsti->index_entries[msc->current_sample];
11809 int64_t dts = av_rescale(current_sample->timestamp, AV_TIME_BASE, msc->time_scale);
11810 uint64_t dtsdiff = best_dts > dts ? best_dts - (uint64_t)dts : ((uint64_t)dts - best_dts);
11811 av_log(s, AV_LOG_TRACE, "stream %d, sample %d, dts %"PRId64"\n", i, msc->current_sample, dts);
11812 if (!sample || (no_interleave && current_sample->pos < sample->pos) ||
11813 ((s->pb->seekable & AVIO_SEEKABLE_NORMAL) &&
11814 ((msc->pb != s->pb && dts < best_dts) || (msc->pb == s->pb && dts != AV_NOPTS_VALUE &&
11815 ((dtsdiff <= AV_TIME_BASE && current_sample->pos < sample->pos) ||
11816 (dtsdiff > AV_TIME_BASE && dts < best_dts && mov->interleaved_read)))))) {
11817 sample = current_sample;
11818 best_dts = dts;
11819 *st = avst;
11820 }
11821 }
11822 }
11823 return sample;
11824}
11825
11826static int should_retry(AVIOContext *pb, int error_code) {
11827 if (error_code == AVERROR_EOF || avio_feof(pb))
11828 return 0;
11829
11830 return 1;
11831}
11832
11834{
11835 int ret;
11836 MOVContext *mov = s->priv_data;
11837
11838 if (index >= 0 && index < mov->frag_index.nb_items)
11839 target = mov->frag_index.item[index].moof_offset;
11840 if (target >= 0 && avio_seek(s->pb, target, SEEK_SET) != target) {
11841 av_log(mov->fc, AV_LOG_ERROR, "root atom offset 0x%"PRIx64": partial file\n", target);
11842 return AVERROR_INVALIDDATA;
11843 }
11844
11845 mov->next_root_atom = 0;
11846 if ((index < 0 && target >= 0) || index >= mov->frag_index.nb_items)
11847 index = search_frag_moof_offset(&mov->frag_index, target);
11848 if (index >= 0 && index < mov->frag_index.nb_items &&
11849 mov->frag_index.item[index].moof_offset == target) {
11850 if (index + 1 < mov->frag_index.nb_items)
11853 return 0;
11855 }
11856
11857 mov->found_mdat = 0;
11858
11859 ret = mov_read_default(mov, s->pb, (MOVAtom){ AV_RL32("root"), INT64_MAX });
11860 if (ret < 0)
11861 return ret;
11862 if (avio_feof(s->pb))
11863 return AVERROR_EOF;
11864 av_log(s, AV_LOG_TRACE, "read fragments, offset 0x%"PRIx64"\n", avio_tell(s->pb));
11865
11866 return 1;
11867}
11868
11870{
11871 MOVStreamContext *sc = st->priv_data;
11872 uint8_t *side, *extradata;
11873 int extradata_size;
11874
11875 /* Save the current index. */
11876 sc->last_stsd_index = sc->stsc_data[sc->stsc_index].id - 1;
11877
11878 /* Notify the decoder that extradata changed. */
11879 extradata_size = sc->extradata_size[sc->last_stsd_index];
11880 extradata = sc->extradata[sc->last_stsd_index];
11881 if (st->discard != AVDISCARD_ALL && extradata_size > 0 && extradata) {
11884 extradata_size);
11885 if (!side)
11886 return AVERROR(ENOMEM);
11887 memcpy(side, extradata, extradata_size);
11888 }
11889
11890 return 0;
11891}
11892
11893static int get_eia608_packet(AVIOContext *pb, AVPacket *pkt, int src_size)
11894{
11895 /* We can't make assumptions about the structure of the payload,
11896 because it may include multiple cdat and cdt2 samples. */
11897 const uint32_t cdat = AV_RB32("cdat");
11898 const uint32_t cdt2 = AV_RB32("cdt2");
11899 int ret, out_size = 0;
11900
11901 /* a valid payload must have size, 4cc, and at least 1 byte pair: */
11902 if (src_size < 10)
11903 return AVERROR_INVALIDDATA;
11904
11905 /* avoid an int overflow: */
11906 if ((src_size - 8) / 2 >= INT_MAX / 3)
11907 return AVERROR_INVALIDDATA;
11908
11909 ret = av_new_packet(pkt, ((src_size - 8) / 2) * 3);
11910 if (ret < 0)
11911 return ret;
11912
11913 /* parse and re-format the c608 payload in one pass. */
11914 while (src_size >= 10) {
11915 const uint32_t atom_size = avio_rb32(pb);
11916 const uint32_t atom_type = avio_rb32(pb);
11917 const uint32_t data_size = atom_size - 8;
11918 const uint8_t cc_field =
11919 atom_type == cdat ? 1 :
11920 atom_type == cdt2 ? 2 :
11921 0;
11922
11923 /* account for bytes consumed for atom size and type. */
11924 src_size -= 8;
11925
11926 /* make sure the data size stays within the buffer boundaries. */
11927 if (data_size < 2 || data_size > src_size) {
11928 ret = AVERROR_INVALIDDATA;
11929 break;
11930 }
11931
11932 /* make sure the data size is consistent with N byte pairs. */
11933 if (data_size % 2 != 0) {
11934 ret = AVERROR_INVALIDDATA;
11935 break;
11936 }
11937
11938 if (!cc_field) {
11939 /* neither cdat or cdt2 ... skip it */
11940 avio_skip(pb, data_size);
11941 src_size -= data_size;
11942 continue;
11943 }
11944
11945 for (uint32_t i = 0; i < data_size; i += 2) {
11946 pkt->data[out_size] = (0x1F << 3) | (1 << 2) | (cc_field - 1);
11947 pkt->data[out_size + 1] = avio_r8(pb);
11948 pkt->data[out_size + 2] = avio_r8(pb);
11949 out_size += 3;
11950 src_size -= 2;
11951 }
11952 }
11953
11954 if (src_size > 0)
11955 /* skip any remaining unread portion of the input payload */
11956 avio_skip(pb, src_size);
11957
11959 return ret;
11960}
11961
11963 int64_t current_index, AVPacket *pkt)
11964{
11965 MOVContext *mov = s->priv_data;
11966 MOVStreamContext *sc = st->priv_data;
11967
11968 pkt->stream_index = sc->ffindex;
11969 pkt->dts = sample->timestamp;
11970 if (sample->flags & AVINDEX_DISCARD_FRAME) {
11971 pkt->flags |= AV_PKT_FLAG_DISCARD;
11972 }
11973 if (sc->stts_count && sc->tts_index < sc->tts_count)
11974 pkt->duration = sc->tts_data[sc->tts_index].duration;
11975 if (sc->ctts_count && sc->tts_index < sc->tts_count) {
11976 pkt->pts = av_sat_add64(pkt->dts, av_sat_add64(sc->dts_shift, sc->tts_data[sc->tts_index].offset));
11977 } else {
11978 if (pkt->duration == 0) {
11979 int64_t next_dts = (sc->current_sample < ffstream(st)->nb_index_entries) ?
11981 if (next_dts >= pkt->dts)
11982 pkt->duration = next_dts - pkt->dts;
11983 }
11984 pkt->pts = pkt->dts;
11985 }
11986
11988 sc->current_sample >= ffstream(st)->nb_index_entries) {
11989 int64_t pts = av_rescale_q(pkt->pts, st->time_base, (AVRational){ 1, st->codecpar->sample_rate });
11990 int64_t total = av_rescale_q(st->duration, st->time_base, (AVRational){ 1, st->codecpar->sample_rate });
11991 int64_t duration = pkt->duration;
11992
11993 if (st->duration < pkt->pts) {
11994 duration = 0;
11995 } else
11996 duration = FFMIN(duration, (uint64_t)st->duration - pkt->pts);
11997
11998 duration = av_rescale_q(duration, st->time_base, (AVRational){ 1, st->codecpar->sample_rate });
11999
12000 if (!ffstream(st)->first_discard_sample)
12002 if (!ffstream(st)->last_discard_sample)
12003 ffstream(st)->last_discard_sample = total;
12004 }
12005
12006 if (sc->tts_data && sc->tts_index < sc->tts_count) {
12007 /* update tts context */
12008 sc->tts_sample++;
12009 if (sc->tts_index < sc->tts_count &&
12010 sc->tts_data[sc->tts_index].count == sc->tts_sample) {
12011 sc->tts_index++;
12012 sc->tts_sample = 0;
12013 }
12014 }
12015
12016 if (sc->sdtp_data && sc->current_sample <= sc->sdtp_count) {
12017 uint8_t sample_flags = sc->sdtp_data[sc->current_sample - 1];
12018 uint8_t sample_is_depended_on = (sample_flags >> 2) & 0x3;
12019 pkt->flags |= sample_is_depended_on == MOV_SAMPLE_DEPENDENCY_NO ? AV_PKT_FLAG_DISPOSABLE : 0;
12020 }
12021 pkt->flags |= sample->flags & AVINDEX_KEYFRAME ? AV_PKT_FLAG_KEY : 0;
12022 pkt->pos = sample->pos;
12023
12024 /* Multiple stsd handling. */
12025 if (sc->stsc_data) {
12026 if (sc->stsc_data[sc->stsc_index].id > 0 &&
12027 sc->stsc_data[sc->stsc_index].id - 1 < sc->stsd_count &&
12028 sc->stsc_data[sc->stsc_index].id - 1 != sc->last_stsd_index) {
12029 int ret = mov_change_extradata(st, pkt);
12030 if (ret < 0)
12031 return ret;
12032 }
12033
12034 /* Update the stsc index for the next sample */
12035 sc->stsc_sample++;
12038 sc->stsc_index++;
12039 sc->stsc_sample = 0;
12040 }
12041 }
12042
12043 return 0;
12044}
12045
12047{
12048 MOVContext *mov = s->priv_data;
12049 MOVStreamContext *sc;
12051 AVStream *st = NULL;
12052 FFStream *avsti = NULL;
12053 int64_t current_index;
12054 int ret;
12055 int i;
12056 mov->fc = s;
12057 retry:
12058 if (s->pb->pos == 0) {
12059
12060 // Discard current fragment index
12061 if (mov->frag_index.allocated_size > 0) {
12062 for(int i = 0; i < mov->frag_index.nb_items; i++) {
12064 }
12065 av_freep(&mov->frag_index.item);
12066 mov->frag_index.nb_items = 0;
12067 mov->frag_index.allocated_size = 0;
12068 mov->frag_index.current = -1;
12069 mov->frag_index.complete = 0;
12070 }
12071
12072 for (i = 0; i < s->nb_streams; i++) {
12073 AVStream *avst = s->streams[i];
12074 MOVStreamContext *msc = avst->priv_data;
12075
12076 // Clear current sample
12077 mov_current_sample_set(msc, 0);
12078 msc->tts_index = 0;
12079
12080 // Discard current index entries
12081 avsti = ffstream(avst);
12082 if (avsti->index_entries_allocated_size > 0) {
12083 av_freep(&avsti->index_entries);
12085 avsti->nb_index_entries = 0;
12086 }
12087 }
12088
12089 if ((ret = mov_switch_root(s, -1, -1)) < 0)
12090 return ret;
12091 }
12093 if (!sample || (mov->next_root_atom && sample->pos > mov->next_root_atom)) {
12094 if (!mov->next_root_atom)
12095 return AVERROR_EOF;
12096 if ((ret = mov_switch_root(s, mov->next_root_atom, -1)) < 0)
12097 return ret;
12098 goto retry;
12099 }
12100 sc = st->priv_data;
12101 /* must be done just before reading, to avoid infinite loop on sample */
12102 current_index = sc->current_index;
12104
12105 if (mov->next_root_atom) {
12106 sample->pos = FFMIN(sample->pos, mov->next_root_atom);
12107 sample->size = FFMIN(sample->size, (mov->next_root_atom - sample->pos));
12108 }
12109
12110 if (st->discard != AVDISCARD_ALL || sc->iamf) {
12111 int64_t ret64 = avio_seek(sc->pb, sample->pos, SEEK_SET);
12112 if (ret64 != sample->pos) {
12113 av_log(mov->fc, AV_LOG_ERROR, "stream %d, offset 0x%"PRIx64": partial file\n",
12114 sc->ffindex, sample->pos);
12115 if (should_retry(sc->pb, ret64)) {
12117 } else if (ret64 < 0) {
12118 return (int)ret64;
12119 }
12120 return AVERROR_INVALIDDATA;
12121 }
12122
12123 if (st->discard == AVDISCARD_NONKEY && !(sample->flags & AVINDEX_KEYFRAME)) {
12124 av_log(mov->fc, AV_LOG_DEBUG, "Nonkey frame from stream %d discarded due to AVDISCARD_NONKEY\n", sc->ffindex);
12125 goto retry;
12126 }
12127
12128 if (st->codecpar->codec_id == AV_CODEC_ID_EIA_608 && sample->size > 8)
12129 ret = get_eia608_packet(sc->pb, pkt, sample->size);
12130#if CONFIG_IAMFDEC
12131 else if (sc->iamf) {
12132 int64_t pts, dts, pos, duration;
12133 int flags, size = sample->size;
12134 ret = mov_finalize_packet(s, st, sample, current_index, pkt);
12135 pts = pkt->pts; dts = pkt->dts;
12136 pos = pkt->pos; flags = pkt->flags;
12137 duration = pkt->duration;
12138 while (!ret && size > 0) {
12139 ret = ff_iamf_read_packet(s, sc->iamf, sc->pb, size, sc->iamf_stream_offset, pkt);
12140 if (ret < 0) {
12141 if (should_retry(sc->pb, ret))
12143 return ret;
12144 }
12145 size -= ret;
12146
12147 if (pkt->flags & AV_PKT_FLAG_DISCARD) {
12149 ret = 0;
12150 continue;
12151 }
12152 pkt->pts = pts; pkt->dts = dts;
12153 pkt->pos = pos; pkt->flags |= flags;
12154 pkt->duration = duration;
12155 ret = ff_buffer_packet(s, pkt);
12156 }
12157 if (!ret)
12158 return FFERROR_REDO;
12159 }
12160#endif
12161 else if (st->codecpar->codec_id == AV_CODEC_ID_APV && sample->size > 4) {
12162 uint32_t au_size = avio_rb32(sc->pb);
12163 int explode = !!(mov->fc->error_recognition & AV_EF_EXPLODE);
12164 if (au_size > sample->size - 4) {
12165 av_log(s, explode ? AV_LOG_ERROR : AV_LOG_WARNING,
12166 "APV au_size %u exceeds sample body %d\n",
12167 au_size, sample->size - 4);
12168 if (explode)
12169 return AVERROR_INVALIDDATA;
12170 au_size = sample->size - 4;
12171 }
12172 ret = av_get_packet(sc->pb, pkt, au_size);
12173 } else
12174 ret = av_get_packet(sc->pb, pkt, sample->size);
12175 if (ret < 0) {
12176 if (should_retry(sc->pb, ret)) {
12178 }
12179 return ret;
12180 }
12181#if CONFIG_DV_DEMUXER
12182 if (mov->dv_demux && sc->dv_audio_container) {
12183 ret = avpriv_dv_produce_packet(mov->dv_demux, NULL, pkt->data, pkt->size, pkt->pos);
12185 if (ret < 0)
12186 return ret;
12187 ret = avpriv_dv_get_packet(mov->dv_demux, pkt);
12188 if (ret < 0)
12189 return ret;
12190 }
12191#endif
12192 if (sc->has_palette) {
12193 uint8_t *pal;
12194
12196 if (!pal) {
12197 av_log(mov->fc, AV_LOG_ERROR, "Cannot append palette to packet\n");
12198 } else {
12199 memcpy(pal, sc->palette, AVPALETTE_SIZE);
12200 sc->has_palette = 0;
12201 }
12202 }
12203 if (st->codecpar->codec_id == AV_CODEC_ID_MP3 && !ffstream(st)->need_parsing && pkt->size > 4) {
12204 if (ff_mpa_check_header(AV_RB32(pkt->data)) < 0)
12206 }
12207 }
12208
12209 ret = mov_finalize_packet(s, st, sample, current_index, pkt);
12210 if (ret < 0)
12211 return ret;
12212
12213 if (st->discard == AVDISCARD_ALL)
12214 goto retry;
12215
12216 if (mov->aax_mode)
12217 aax_filter(pkt->data, pkt->size, mov);
12218
12219 ret = cenc_filter(mov, st, sc, pkt, current_index);
12220 if (ret < 0) {
12221 return ret;
12222 }
12223
12224 return 0;
12225}
12226
12228{
12229 MOVContext *mov = s->priv_data;
12230 int index;
12231
12232 if (!mov->frag_index.complete)
12233 return 0;
12234
12235 index = search_frag_timestamp(s, &mov->frag_index, st, timestamp);
12236 if (index < 0)
12237 index = 0;
12238 if (!mov->frag_index.item[index].headers_read)
12239 return mov_switch_root(s, -1, index);
12240 if (index + 1 < mov->frag_index.nb_items)
12242
12243 return 0;
12244}
12245
12247{
12248 // TODO: a bisect search would scale much better
12249 for (int i = 0; i < sc->open_key_samples_count; i++) {
12250 const int oks = sc->open_key_samples[i];
12251 if (oks == sample)
12252 return 1;
12253 if (oks > sample) /* list is monotically increasing so we can stop early */
12254 break;
12255 }
12256 return 0;
12257}
12258
12259/*
12260 * Some key sample may be key frames but not IDR frames, so a random access to
12261 * them may not be allowed.
12262 */
12263static int can_seek_to_key_sample(AVStream *st, int sample, int64_t requested_pts)
12264{
12265 MOVStreamContext *sc = st->priv_data;
12266 FFStream *const sti = ffstream(st);
12267 int64_t key_sample_dts, key_sample_pts;
12268
12270 return 1;
12271
12272 if (sample >= sc->sample_offsets_count)
12273 return 1;
12274
12275 av_assert0(sample >= 0);
12276 key_sample_dts = sti->index_entries[sample].timestamp;
12277 key_sample_pts = key_sample_dts + sc->sample_offsets[sample] + sc->dts_shift;
12278
12279 /*
12280 * If the sample needs to be presented before an open key sample, they may
12281 * not be decodable properly, even though they come after in decoding
12282 * order.
12283 */
12284 if (is_open_key_sample(sc, sample) && key_sample_pts > requested_pts)
12285 return 0;
12286
12287 return 1;
12288}
12289
12290static int mov_seek_stream(AVFormatContext *s, AVStream *st, int64_t timestamp, int flags)
12291{
12292 MOVStreamContext *sc = st->priv_data;
12293 FFStream *const sti = ffstream(st);
12294 int sample, time_sample, ret, requested_sample;
12295 int64_t next_ts;
12296 unsigned int i;
12297
12298 // Here we consider timestamp to be PTS, hence try to offset it so that we
12299 // can search over the DTS timeline.
12300 timestamp -= (sc->min_corrected_pts + sc->dts_shift);
12301
12302 ret = mov_seek_fragment(s, st, timestamp);
12303 if (ret < 0)
12304 return ret;
12305
12306 for (;;) {
12307 sample = av_index_search_timestamp(st, timestamp, flags);
12308 av_log(s, AV_LOG_TRACE, "stream %d, timestamp %"PRId64", sample %d\n", st->index, timestamp, sample);
12309 if (sample < 0 && sti->nb_index_entries && timestamp < sti->index_entries[0].timestamp)
12310 sample = 0;
12311 if (sample < 0) /* not sure what to do */
12312 return AVERROR_INVALIDDATA;
12313
12314 if (!sample || can_seek_to_key_sample(st, sample, timestamp))
12315 break;
12316
12317 next_ts = timestamp - FFMAX(sc->min_sample_duration, 1);
12318 requested_sample = av_index_search_timestamp(st, next_ts, flags);
12319 if (requested_sample < 0)
12320 return AVERROR_INVALIDDATA;
12321
12322 // If we've reached a different sample trying to find a good pts to
12323 // seek to, give up searching because we'll end up seeking back to
12324 // sample 0 on every seek.
12325 if (sample != requested_sample && !can_seek_to_key_sample(st, requested_sample, next_ts))
12326 break;
12327
12328 timestamp = next_ts;
12329 }
12330
12332 av_log(s, AV_LOG_TRACE, "stream %d, found sample %d\n", st->index, sc->current_sample);
12333 /* adjust time to sample index */
12334 if (sc->tts_data) {
12335 time_sample = 0;
12336 for (i = 0; i < sc->tts_count; i++) {
12337 int next = time_sample + sc->tts_data[i].count;
12338 if (next > sc->current_sample) {
12339 sc->tts_index = i;
12340 sc->tts_sample = sc->current_sample - time_sample;
12341 break;
12342 }
12343 time_sample = next;
12344 }
12345 }
12346
12347 /* adjust stsd index */
12348 if (sc->chunk_count) {
12349 time_sample = 0;
12350 for (i = 0; i < sc->stsc_count; i++) {
12351 int64_t next = time_sample + mov_get_stsc_samples(sc, i);
12352 if (next > sc->current_sample) {
12353 sc->stsc_index = i;
12354 sc->stsc_sample = sc->current_sample - time_sample;
12355 break;
12356 }
12357 av_assert0(next == (int)next);
12358 time_sample = next;
12359 }
12360 }
12361
12362 return sample;
12363}
12364
12366{
12367 FFStream *const sti = ffstream(st);
12368 int64_t first_ts = sti->index_entries[0].timestamp;
12370 int64_t off;
12371
12373 return 0;
12374
12375 /* compute skip samples according to stream initial_padding, seek ts and first ts */
12376 off = av_rescale_q(ts - first_ts, st->time_base,
12377 (AVRational){1, st->codecpar->sample_rate});
12378 return FFMAX(st->codecpar->initial_padding - off, 0);
12379}
12380
12381static int mov_read_seek(AVFormatContext *s, int stream_index, int64_t sample_time, int flags)
12382{
12383 MOVContext *mc = s->priv_data;
12384 AVStream *st;
12385 FFStream *sti;
12386 int sample;
12387 int i;
12388
12389 if (stream_index >= s->nb_streams)
12390 return AVERROR_INVALIDDATA;
12391
12392 st = s->streams[stream_index];
12393 sti = ffstream(st);
12394 sample = mov_seek_stream(s, st, sample_time, flags);
12395 if (sample < 0)
12396 return sample;
12397
12398 if (mc->seek_individually) {
12399 /* adjust seek timestamp to found sample timestamp */
12400 int64_t seek_timestamp = sti->index_entries[sample].timestamp;
12402
12403 for (i = 0; i < s->nb_streams; i++) {
12404 AVStream *const st = s->streams[i];
12405 FFStream *const sti = ffstream(st);
12406 int64_t timestamp;
12407
12408 if (stream_index == i)
12409 continue;
12410
12411 timestamp = av_rescale_q(seek_timestamp, s->streams[stream_index]->time_base, st->time_base);
12412 sample = mov_seek_stream(s, st, timestamp, flags);
12413 if (sample >= 0)
12415 }
12416 } else {
12417 for (i = 0; i < s->nb_streams; i++) {
12418 MOVStreamContext *sc;
12419 st = s->streams[i];
12420 sc = st->priv_data;
12422 }
12423 while (1) {
12424 MOVStreamContext *sc;
12426 if (!entry)
12427 return AVERROR_INVALIDDATA;
12428 sc = st->priv_data;
12429 if (sc->ffindex == stream_index && sc->current_sample == sample)
12430 break;
12432 }
12433 }
12434 return 0;
12435}
12436
12437#define OFFSET(x) offsetof(MOVContext, x)
12438#define FLAGS AV_OPT_FLAG_VIDEO_PARAM | AV_OPT_FLAG_DECODING_PARAM
12439static const AVOption mov_options[] = {
12440 {"use_absolute_path",
12441 "allow using absolute path when opening alias, this is a possible security issue",
12442 OFFSET(use_absolute_path), AV_OPT_TYPE_BOOL, {.i64 = 0},
12443 0, 1, FLAGS},
12444 {"seek_streams_individually",
12445 "Seek each stream individually to the closest point",
12446 OFFSET(seek_individually), AV_OPT_TYPE_BOOL, { .i64 = 1 },
12447 0, 1, FLAGS},
12448 {"ignore_editlist", "Ignore the edit list atom.", OFFSET(ignore_editlist), AV_OPT_TYPE_BOOL, {.i64 = 0},
12449 0, 1, FLAGS},
12450 {"advanced_editlist",
12451 "Modify the AVIndex according to the editlists. Use this option to decode in the order specified by the edits.",
12452 OFFSET(advanced_editlist), AV_OPT_TYPE_BOOL, {.i64 = 1},
12453 0, 1, FLAGS},
12454 {"ignore_chapters", "", OFFSET(ignore_chapters), AV_OPT_TYPE_BOOL, {.i64 = 0},
12455 0, 1, FLAGS},
12456 {"use_mfra_for",
12457 "use mfra for fragment timestamps",
12458 OFFSET(use_mfra_for), AV_OPT_TYPE_INT, {.i64 = FF_MOV_FLAG_MFRA_AUTO},
12460 .unit = "use_mfra_for"},
12461 {"auto", "auto", 0, AV_OPT_TYPE_CONST, {.i64 = FF_MOV_FLAG_MFRA_AUTO}, 0, 0,
12462 FLAGS, .unit = "use_mfra_for" },
12463 {"dts", "dts", 0, AV_OPT_TYPE_CONST, {.i64 = FF_MOV_FLAG_MFRA_DTS}, 0, 0,
12464 FLAGS, .unit = "use_mfra_for" },
12465 {"pts", "pts", 0, AV_OPT_TYPE_CONST, {.i64 = FF_MOV_FLAG_MFRA_PTS}, 0, 0,
12466 FLAGS, .unit = "use_mfra_for" },
12467 {"use_tfdt", "use tfdt for fragment timestamps", OFFSET(use_tfdt), AV_OPT_TYPE_BOOL, {.i64 = 1},
12468 0, 1, FLAGS},
12469 { "export_all", "Export unrecognized metadata entries", OFFSET(export_all),
12470 AV_OPT_TYPE_BOOL, { .i64 = 0 }, 0, 1, .flags = FLAGS },
12471 { "export_xmp", "Export full XMP metadata", OFFSET(export_xmp),
12472 AV_OPT_TYPE_BOOL, { .i64 = 0 }, 0, 1, .flags = FLAGS },
12473 { "activation_bytes", "Secret bytes for Audible AAX files", OFFSET(activation_bytes),
12475 { "audible_key", "AES-128 Key for Audible AAXC files", OFFSET(audible_key),
12477 { "audible_iv", "AES-128 IV for Audible AAXC files", OFFSET(audible_iv),
12479 { "audible_fixed_key", // extracted from libAAX_SDK.so and AAXSDKWin.dll files!
12480 "Fixed key used for handling Audible AAX files", OFFSET(audible_fixed_key),
12481 AV_OPT_TYPE_BINARY, {.str="77214d4b196a87cd520045fd20a51d67"},
12482 .flags = AV_OPT_FLAG_DECODING_PARAM },
12483 { "decryption_key", "The default media decryption key (hex)", OFFSET(decryption_default_key), AV_OPT_TYPE_BINARY, .flags = AV_OPT_FLAG_DECODING_PARAM },
12484 { "decryption_keys", "The media decryption keys by KID (hex)", OFFSET(decryption_keys), AV_OPT_TYPE_DICT, .flags = AV_OPT_FLAG_DECODING_PARAM },
12485 { "enable_drefs", "Enable external track support.", OFFSET(enable_drefs), AV_OPT_TYPE_BOOL,
12486 {.i64 = 0}, 0, 1, FLAGS },
12487 { "max_stts_delta", "treat offsets above this value as invalid", OFFSET(max_stts_delta), AV_OPT_TYPE_INT, {.i64 = UINT_MAX-48000*10 }, 0, UINT_MAX, .flags = AV_OPT_FLAG_DECODING_PARAM },
12488 { "interleaved_read", "Interleave packets from multiple tracks at demuxer level", OFFSET(interleaved_read), AV_OPT_TYPE_BOOL, {.i64 = 1 }, 0, 1, .flags = AV_OPT_FLAG_DECODING_PARAM },
12489
12490 { NULL },
12491};
12492
12493static const AVClass mov_class = {
12494 .class_name = "mov,mp4,m4a,3gp,3g2,mj2",
12495 .item_name = av_default_item_name,
12496 .option = mov_options,
12497 .version = LIBAVUTIL_VERSION_INT,
12498};
12499
12501 .p.name = "mov,mp4,m4a,3gp,3g2,mj2",
12502 .p.long_name = NULL_IF_CONFIG_SMALL("QuickTime / MOV"),
12503 .p.priv_class = &mov_class,
12504 .p.extensions = "mov,mp4,m4a,3gp,3g2,mj2,psp,m4v,m4b,ism,ismv,isma,f4v,avif,heic,heif",
12506 .priv_data_size = sizeof(MOVContext),
12507 .flags_internal = FF_INFMT_FLAG_INIT_CLEANUP,
12513};
uint8_t ptrdiff_t const uint8_t ptrdiff_t int intptr_t intptr_t int int16_t * dst
Definition dsp.h:87
const uint16_t ff_ac3_channel_layout_tab[8]
Map audio coding mode (acmod) to channel layout mask.
static double val(void *priv, double ch)
Definition aeval.c:77
static const char *const format[]
Definition af_aiir.c:444
#define ctype
#define ALAC_EXTRADATA_SIZE
Definition alac.c:63
const FFInputFormat ff_mov_demuxer
Definition mov.c:12500
AVAmbientViewingEnvironment * av_ambient_viewing_environment_alloc(size_t *size)
Allocate an AVAmbientViewingEnvironment structure.
#define entry
static int parse(AVCodecParserContext *s, AVCodecContext *avctx, const uint8_t **poutbuf, int *poutbuf_size, const uint8_t *buf, int buf_size)
Definition apv_parser.c:92
int32_t
simple assert() macros that are a bit more flexible than ISO C assert().
#define av_assert0(cond)
assert() equivalent, that is always enabled.
Definition avassert.h:42
int ff_format_io_close(AVFormatContext *s, AVIOContext **pb)
Definition avformat.c:961
void avpriv_set_pts_info(AVStream *st, int pts_wrap_bits, unsigned int pts_num, unsigned int pts_den)
Set the time base and wrapping info for a given stream.
Definition avformat.c:834
void ff_remove_stream(AVFormatContext *s, AVStream *st)
Remove a stream from its AVFormatContext and free it.
Definition avformat.c:122
void ff_remove_stream_group(AVFormatContext *s, AVStreamGroup *stg)
Remove a stream group from its AVFormatContext and free it.
Definition avformat.c:130
Main libavformat public API header.
#define AVFMT_EVENT_FLAG_METADATA_UPDATED
Definition avformat.h:1727
#define AVINDEX_KEYFRAME
Definition avformat.h:628
#define AVPROBE_SCORE_MAX
maximum score
Definition avformat.h:483
#define AVFMT_FLAG_IGNIDX
Ignore index.
Definition avformat.h:1486
@ AV_STREAM_GROUP_PARAMS_DOLBY_VISION
Definition avformat.h:1153
@ AV_STREAM_GROUP_PARAMS_TREF
Definition avformat.h:1152
@ AV_STREAM_GROUP_PARAMS_IAMF_MIX_PRESENTATION
Definition avformat.h:1149
@ AV_STREAM_GROUP_PARAMS_TILE_GRID
Definition avformat.h:1150
@ AV_STREAM_GROUP_PARAMS_IAMF_AUDIO_ELEMENT
Definition avformat.h:1148
@ AV_STREAM_GROUP_PARAMS_LCEVC
Definition avformat.h:1151
#define AVFMT_NO_BYTE_SEEK
Format does not allow seeking by bytes.
Definition avformat.h:506
#define AV_DISPOSITION_MULTILAYER
The video stream contains multiple layers, e.g.
Definition avformat.h:736
#define AV_DISPOSITION_DEPENDENT
The stream is intended to be mixed with another stream before presentation.
Definition avformat.h:727
#define AV_DISPOSITION_NON_DIEGETIC
The stream is intended to be mixed with a spatial audio track.
Definition avformat.h:704
#define AVPROBE_SCORE_EXTENSION
score for file extension
Definition avformat.h:481
#define AVFMT_SHOW_IDS
Show format stream IDs numbers.
Definition avformat.h:496
#define AVSEEK_FLAG_ANY
seek to any frame, even non-keyframes
Definition avformat.h:2618
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:98
#define AV_DISPOSITION_ATTACHED_PIC
The stream is stored in the file as an attached picture/"cover art" (e.g.
Definition avformat.h:692
#define AVFMT_SEEK_TO_PTS
Seeking is based on PTS.
Definition avformat.h:520
#define AVINDEX_DISCARD_FRAME
Definition avformat.h:629
#define AVSEEK_FLAG_BACKWARD
seek backward
Definition avformat.h:2616
#define AV_DISPOSITION_DEFAULT
The stream should be chosen by default among other streams of the same type, unless the user has expl...
Definition avformat.h:639
#define AV_DISPOSITION_TIMED_THUMBNAILS
The stream is sparse, and contains thumbnail images, often corresponding to chapter markers.
Definition avformat.h:697
@ AVSTREAM_PARSE_HEADERS
Only parse headers, do not repack.
Definition avformat.h:612
@ AVSTREAM_PARSE_FULL
full parsing and repack
Definition avformat.h:611
int avio_get_str16be(AVIOContext *pb, int maxlen, char *buf, int buflen)
int64_t avio_seek(AVIOContext *s, int64_t offset, int whence)
fseek() equivalent for AVIOContext.
Definition aviobuf.c:236
#define AVIO_SEEKABLE_NORMAL
Seeking works like for a local file.
Definition avio.h:41
uint64_t avio_rb64(AVIOContext *s)
Definition aviobuf.c:911
#define AVIO_FLAG_READ
read-only
Definition avio.h:617
int64_t avio_size(AVIOContext *s)
Get the filesize.
Definition aviobuf.c:326
unsigned int avio_rb16(AVIOContext *s)
Definition aviobuf.c:749
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.
int avio_feof(AVIOContext *s)
Similar to feof() but also returns nonzero on read errors.
Definition aviobuf.c:349
static av_always_inline int64_t avio_tell(AVIOContext *s)
ftell() equivalent for AVIOContext.
Definition avio.h:494
int64_t avio_skip(AVIOContext *s, int64_t offset)
Skip given number of bytes forward.
Definition aviobuf.c:321
int avio_read(AVIOContext *s, unsigned char *buf, int size)
Read size bytes from AVIOContext into buf.
Definition aviobuf.c:615
unsigned int avio_rl32(AVIOContext *s)
Definition aviobuf.c:733
int avio_get_str(AVIOContext *pb, int maxlen, char *buf, int buflen)
Read a string from pb into buf.
Definition aviobuf.c:869
unsigned int avio_rb24(AVIOContext *s)
Definition aviobuf.c:757
unsigned int avio_rb32(AVIOContext *s)
Definition aviobuf.c:764
int avio_r8(AVIOContext *s)
Definition aviobuf.c:606
int ffio_ensure_seekback(AVIOContext *s, int64_t buf_size)
Ensures that the requested seekback buffer size will be available.
Definition aviobuf.c:1026
int64_t ff_read_string_to_bprint_overwrite(AVIOContext *s, struct AVBPrint *bp, int64_t max_len)
Read a whole null-terminated string of text from AVIOContext to an AVBPrint buffer overwriting its co...
Definition aviobuf.c:863
void ffio_init_read_context(FFIOContext *s, const uint8_t *buffer, int buffer_size)
Wrap a buffer in an AVIOContext for reading.
Definition aviobuf.c:99
int ffio_read_size(AVIOContext *s, unsigned char *buf, int size)
Read size bytes from AVIOContext into buf.
Definition aviobuf.c:665
unsigned int ffio_read_leb(AVIOContext *s)
Read a unsigned integer coded as a variable number of up to eight little-endian bytes,...
Definition aviobuf.c:930
static int read_packet(void *opaque, uint8_t *buf, int buf_size)
size_t av_strlcatf(char *dst, size_t size, const char *fmt,...)
Definition avstring.c:103
static int BS_FUNC left(const BSCTX *bc)
Return the number of the bits left in a buffer.
void av_bprint_init(AVBPrint *buf, unsigned size_init, unsigned size_max)
Definition bprint.c:69
AVBPrint public header.
#define AV_BPRINT_SIZE_UNLIMITED
static int FUNC metadata(CodedBitstreamContext *ctx, RWContext *rw, APVRawMetadata *current)
#define flag(name)
Definition cbs_h264.c:60
#define flags(name, subs,...)
Definition cbs_h264.c:74
#define i(width, name, range_min, range_max)
Definition cbs_h264.c:63
#define f(width, name)
Definition cbs_vp8.c:236
#define ss(width, name, subs,...)
Definition cbs_vp9.c:202
#define s(width, name)
Definition cbs_vp9.c:198
static int read_probe(const AVProbeData *p)
Definition cdg.c:30
Public libavutil channel layout APIs header.
#define FLAGS
Definition cmdutils.c:598
int avcodec_parameters_copy(AVCodecParameters *dst, const AVCodecParameters *src)
Definition codec_par.c:107
#define av_sat_sub64
Definition common.h:142
#define av_sat_add64
Definition common.h:139
#define PUT_UTF8(val, tmp, PUT_BYTE)
Convert a 32-bit Unicode character to its UTF-8 encoded form (up to 4 bytes long).
Definition common.h:530
#define av_clip64
Definition common.h:103
#define NULL
Definition coverity.c:32
long long int64_t
Definition coverity.c:34
static const AVColorPrimariesDesc color_primaries[AVCOL_PRI_NB]
Definition csp.c:76
static __device__ float fabs(float a)
static const uint16_t fc[]
Definition dcaenc.h:43
#define AV_PROFILE_DTS_EXPRESS
Definition defs.h:92
#define AV_PROFILE_DTS_HD_MA
Definition defs.h:91
#define AV_PROFILE_DTS
Definition defs.h:87
#define AV_PROFILE_UNKNOWN
Definition defs.h:65
#define AV_PROFILE_DTS_HD_HRA
Definition defs.h:90
#define FF_COMPLIANCE_STRICT
Strictly conform to all the things in the spec no matter what consequences.
Definition defs.h:59
#define AV_EF_EXPLODE
abort decoding on minor error detection
Definition defs.h:51
AVFieldOrder
Definition defs.h:211
@ AV_FIELD_TT
Top coded_first, top displayed first.
Definition defs.h:214
@ AV_FIELD_BB
Bottom coded first, bottom displayed first.
Definition defs.h:215
@ AV_FIELD_UNKNOWN
Definition defs.h:212
@ AV_FIELD_PROGRESSIVE
Definition defs.h:213
@ AV_FIELD_BT
Bottom coded first, top displayed first.
Definition defs.h:217
@ AV_FIELD_TB
Top coded first, bottom displayed first.
Definition defs.h:216
#define AV_PROFILE_DTS_96_24
Definition defs.h:89
AVAudioServiceType
Definition defs.h:235
@ AV_AUDIO_SERVICE_TYPE_KARAOKE
Definition defs.h:244
#define AV_PROFILE_DTS_ES
Definition defs.h:88
int ff_buffer_packet(AVFormatContext *s, AVPacket *pkt)
Definition demux.c:622
void ff_rfps_calculate(AVFormatContext *ic)
Definition demux.c:2397
int ff_rfps_add_frame(AVFormatContext *ic, AVStream *st, int64_t ts)
add frame for rfps calculation.
Definition demux.c:2336
AVChapter * avpriv_new_chapter(AVFormatContext *s, int64_t id, AVRational time_base, int64_t start, int64_t end, const char *title)
Add a new chapter.
Definition demux_utils.c:43
#define FF_INFMT_FLAG_INIT_CLEANUP
For an FFInputFormat with this flag set read_close() needs to be called by the caller upon read_heade...
Definition demux.h:35
void ff_configure_buffers_for_index(AVFormatContext *s, int64_t time_tolerance)
Definition seek.c:175
int ff_generate_avci_extradata(AVStream *st)
Generate standard extradata for AVC-Intra based on width/height and field order.
#define FFERROR_REDO
Returned by demuxers to indicate that data was consumed but discarded (ignored streams or junk data).
Definition demux.h:224
int ff_get_extradata(void *logctx, AVCodecParameters *par, AVIOContext *pb, int size)
Allocate extradata with additional AV_INPUT_BUFFER_PADDING_SIZE at end which is always set to 0 and f...
int ff_add_attached_pic(AVFormatContext *s, AVStream *st, AVIOContext *pb, AVBufferRef **buf, int size)
Add an attached pic to an AVStream.
static AVPacket * pkt
Public dictionary API.
Display matrix.
int ff_isom_parse_dvcc_dvvc(void *logctx, AVStream *st, const uint8_t *buf_ptr, uint64_t size)
Definition dovi_isom.c:32
#define ISOM_DVCC_DVVC_SIZE
Definition dovi_isom.h:29
DOVI configuration.
enum AVCodecID id
Definition dts2pts.c:607
int ff_dvdclut_yuv_to_rgb(uint32_t *clut, const size_t clut_size)
Definition dvdclut.c:50
int ff_dvdclut_palette_extradata_cat(const uint32_t *clut, const size_t clut_size, AVCodecParameters *par)
Definition dvdclut.c:28
#define FF_DVDCLUT_CLUT_SIZE
Definition dvdclut.h:29
#define FF_DVDCLUT_CLUT_LEN
Definition dvdclut.h:28
channel
Use these values when setting the channel map with ebur128_set_channel().
Definition ebur128.h:39
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.
AVEncryptionInfo * av_encryption_info_clone(const AVEncryptionInfo *info)
Allocates an AVEncryptionInfo structure with a copy of the given 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.
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.
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.
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.
void av_encryption_init_info_free(AVEncryptionInitInfo *info)
Frees the given encryption init info object.
void av_encryption_info_free(AVEncryptionInfo *info)
Frees the given encryption info object.
double value
Definition eval.c:102
int av_exif_parse_buffer(void *logctx, const uint8_t *buf, size_t size, AVExifMetadata *ifd, enum AVExifHeaderMode header_mode)
Decodes the EXIF data provided in the buffer and writes it into the struct *ifd.
Definition exif.c:882
void av_exif_free(AVExifMetadata *ifd)
Frees all resources associated with the given EXIF metadata struct.
Definition exif.c:659
int av_exif_write(void *logctx, const AVExifMetadata *ifd, AVBufferRef **buffer, enum AVExifHeaderMode header_mode)
Allocates a buffer using av_malloc of an appropriate size and writes the EXIF data represented by ifd...
Definition exif.c:753
int32_t av_exif_get_tag_id(const char *name)
Retrieves the tag ID associated with the provided tag string name.
Definition exif.c:244
int av_exif_remove_entry(void *logctx, AVExifMetadata *ifd, uint16_t id, int flags)
Remove an entry from the provided EXIF metadata struct.
Definition exif.c:1272
EXIF metadata parser.
@ AV_EXIF_T_OFF
The first four bytes point to the actual start, then it's AV_EXIF_TIFF_HEADER.
Definition exif.h:68
static struct @111144215057303131116103221376075045141373005341 current
const char * key
static int64_t duration
Definition ffplay.c:330
static int loop
Definition ffplay.c:338
static int64_t start_time
Definition ffplay.c:329
static unsigned int nb_streams
Definition ffprobe.c:352
static int read_header(FFV1Context *f, RangeCoder *c)
Definition ffv1dec.c:578
FLAC (Free Lossless Audio Codec) common stuff.
@ FLAC_METADATA_TYPE_STREAMINFO
Definition flac.h:46
static av_always_inline void flac_parse_block_header(const uint8_t *block_header, int *last, int *type, int *size)
Parse the metadata block parameters from the header.
Definition flac.h:63
#define FLAC_STREAMINFO_SIZE
Definition flac.h:32
#define sample
static av_cold void cleanup(FlashSV2Context *s)
bitstream reader API header.
static unsigned int get_bits_long(GetBitContext *s, int n)
Read 0-32 bits.
Definition get_bits.h:424
static void skip_bits_long(GetBitContext *s, int n)
Skips the specified number of bits.
Definition get_bits.h:280
static void skip_bits(GetBitContext *s, int n)
Definition get_bits.h:383
static unsigned int get_bits(GetBitContext *s, int n)
Read 1-25 bits.
Definition get_bits.h:337
static int init_get_bits(GetBitContext *s, const uint8_t *buffer, int bit_size)
Initialize GetBitContext.
Definition get_bits.h:517
#define fail
Definition test.h:479
#define AV_OPT_FLAG_DECODING_PARAM
A generic parameter which can be set by the user for demuxing or decoding.
Definition opt.h:355
@ AV_OPT_TYPE_CONST
Special option type for declaring named constants.
Definition opt.h:298
@ AV_OPT_TYPE_BINARY
Underlying C type is a uint8_t* that is either NULL or points to an array allocated with the av_mallo...
Definition opt.h:285
@ AV_OPT_TYPE_INT
Underlying C type is int.
Definition opt.h:258
@ AV_OPT_TYPE_DICT
Underlying C type is AVDictionary*.
Definition opt.h:289
@ AV_OPT_TYPE_BOOL
Underlying C type is int.
Definition opt.h:326
#define AV_CH_SIDE_LEFT
#define AV_CH_SIDE_SURROUND_RIGHT
#define AV_CH_WIDE_LEFT
#define AV_CH_WIDE_RIGHT
#define AV_CH_TOP_FRONT_LEFT
#define AV_CH_FRONT_RIGHT
#define AV_CH_SIDE_SURROUND_LEFT
#define AV_CH_TOP_BACK_CENTER
#define AV_CH_FRONT_RIGHT_OF_CENTER
#define AV_CH_BACK_CENTER
#define AV_CH_TOP_FRONT_CENTER
#define AV_CH_FRONT_LEFT_OF_CENTER
#define AV_CH_LOW_FREQUENCY_2
#define AV_CH_BACK_RIGHT
#define AV_CH_TOP_SIDE_RIGHT
#define AV_CH_FRONT_CENTER
#define AV_CH_TOP_BACK_RIGHT
#define AV_CH_TOP_CENTER
#define AV_CH_SIDE_RIGHT
#define AV_CH_BACK_LEFT
#define AV_CH_TOP_SIDE_LEFT
#define AV_CH_TOP_BACK_LEFT
#define AV_CH_LOW_FREQUENCY
#define AV_CH_TOP_FRONT_RIGHT
#define AV_CH_FRONT_LEFT
int av_get_bits_per_sample(enum AVCodecID codec_id)
Return codec bits per sample.
Definition utils.c:556
AVCodecID
Identify the syntax and semantics of the bitstream.
Definition codec_id.h:47
@ AV_CODEC_ID_PCM_F32LE
Definition codec_id.h:351
@ AV_CODEC_ID_PCM_S24BE
Definition codec_id.h:343
@ AV_CODEC_ID_VORBIS
Definition codec_id.h:458
@ AV_CODEC_ID_H261
Definition codec_id.h:53
@ AV_CODEC_ID_FLV1
Definition codec_id.h:71
@ AV_CODEC_ID_PNG
Definition codec_id.h:111
@ AV_CODEC_ID_EAC3
Definition codec_id.h:493
@ AV_CODEC_ID_PCM_U8
Definition codec_id.h:335
@ AV_CODEC_ID_APV
Definition codec_id.h:323
@ AV_CODEC_ID_LCEVC
Definition codec_id.h:609
@ AV_CODEC_ID_PCM_S16LE
Definition codec_id.h:330
@ AV_CODEC_ID_GSM
as in Berlin toast format
Definition codec_id.h:471
@ AV_CODEC_ID_DVD_SUBTITLE
Definition codec_id.h:566
@ AV_CODEC_ID_TTML
Definition codec_id.h:590
@ AV_CODEC_ID_PCM_F32BE
Definition codec_id.h:350
@ AV_CODEC_ID_SVQ3
Definition codec_id.h:73
@ AV_CODEC_ID_H264
Definition codec_id.h:77
@ AV_CODEC_ID_NONE
Definition codec_id.h:48
@ AV_CODEC_ID_JPEG2000
Definition codec_id.h:138
@ AV_CODEC_ID_PCM_S16BE
Definition codec_id.h:331
@ AV_CODEC_ID_PCM_S24LE
Definition codec_id.h:342
@ AV_CODEC_ID_PCM_S32LE
Definition codec_id.h:338
@ AV_CODEC_ID_PCM_S8
Definition codec_id.h:334
@ AV_CODEC_ID_AV1
Definition codec_id.h:275
@ AV_CODEC_ID_ADPCM_MS
Definition codec_id.h:376
@ AV_CODEC_ID_VC1
Definition codec_id.h:120
@ AV_CODEC_ID_VP8
Definition codec_id.h:190
@ AV_CODEC_ID_PCM_F64LE
Definition codec_id.h:353
@ AV_CODEC_ID_ALAC
Definition codec_id.h:469
@ AV_CODEC_ID_EIA_608
Definition codec_id.h:576
@ AV_CODEC_ID_AMR_NB
Definition codec_id.h:434
@ AV_CODEC_ID_CAVS
Definition codec_id.h:137
@ AV_CODEC_ID_PRORES_RAW
Definition codec_id.h:324
@ AV_CODEC_ID_MP2
Definition codec_id.h:453
@ AV_CODEC_ID_DVAUDIO
Definition codec_id.h:459
@ AV_CODEC_ID_ADPCM_IMA_QT
Definition codec_id.h:370
@ AV_CODEC_ID_HEVC
Definition codec_id.h:223
@ AV_CODEC_ID_BIN_DATA
Definition codec_id.h:607
@ AV_CODEC_ID_AAC
Definition codec_id.h:455
@ AV_CODEC_ID_PRORES
Definition codec_id.h:198
@ AV_CODEC_ID_BMP
Definition codec_id.h:128
@ AV_CODEC_ID_PCM_F64BE
Definition codec_id.h:352
@ AV_CODEC_ID_H263
Definition codec_id.h:54
@ AV_CODEC_ID_QCELP
Definition codec_id.h:477
@ AV_CODEC_ID_AMR_WB
Definition codec_id.h:435
@ AV_CODEC_ID_AC3
Definition codec_id.h:456
@ AV_CODEC_ID_MACE3
Definition codec_id.h:462
@ AV_CODEC_ID_MACE6
Definition codec_id.h:463
@ AV_CODEC_ID_QDM2
Definition codec_id.h:472
@ AV_CODEC_ID_PCM_S32BE
Definition codec_id.h:339
@ AV_CODEC_ID_DNXHD
Definition codec_id.h:149
@ AV_CODEC_ID_MPEG4
Definition codec_id.h:62
@ AV_CODEC_ID_MJPEG
Definition codec_id.h:57
@ AV_CODEC_ID_ADPCM_IMA_WAV
Definition codec_id.h:371
@ AV_CODEC_ID_R10K
Definition codec_id.h:195
@ AV_CODEC_ID_EVC
Definition codec_id.h:316
@ AV_CODEC_ID_SPEEX
Definition codec_id.h:488
@ AV_CODEC_ID_AVUI
Definition codec_id.h:252
@ AV_CODEC_ID_ILBC
Definition codec_id.h:512
@ AV_CODEC_ID_MP3
preferred ID for decoding MPEG audio layer 1, 2 or 3
Definition codec_id.h:454
@ AV_CODEC_ID_VP9
Definition codec_id.h:217
@ AV_CODEC_ID_MPEG1VIDEO
Definition codec_id.h:51
@ AV_CODEC_ID_QDMC
Definition codec_id.h:503
@ AV_CODEC_ID_ITUT_T35
Definition codec_id.h:611
@ AV_CODEC_ID_TARGA_Y216
Definition codec_id.h:253
#define AV_INPUT_BUFFER_PADDING_SIZE
Required number of additionally allocated bytes at the end of the input bitstream for decoding.
Definition defs.h:40
@ AVDISCARD_ALL
discard all
Definition defs.h:232
@ AVDISCARD_NONKEY
discard all frames except keyframes
Definition defs.h:231
AVPacketSideData * av_packet_side_data_new(AVPacketSideData **psd, int *pnb_sd, enum AVPacketSideDataType type, size_t size, int flags)
Allocate a new packet side data.
Definition packet.c:620
AVPacketSideData * av_packet_side_data_add(AVPacketSideData **psd, int *pnb_sd, enum AVPacketSideDataType type, void *data, size_t size, int flags)
Wrap existing data as packet side data.
Definition packet.c:613
const AVPacketSideData * av_packet_side_data_get(const AVPacketSideData *sd, int nb_sd, enum AVPacketSideDataType type)
Get side information from a side data array.
Definition packet.c:570
@ AV_PKT_DATA_HEVC_CONF
Dolby Vision enhancement-layer HEVC decoder configuration.
Definition packet.h:384
@ AV_PKT_DATA_AMBIENT_VIEWING_ENVIRONMENT
Ambient viewing environment metadata, as defined by H.274.
Definition packet.h:327
@ AV_PKT_DATA_ICC_PROFILE
ICC profile data consisting of an opaque octet buffer following the format described by ISO 15076-1.
Definition packet.h:271
@ AV_PKT_DATA_MASTERING_DISPLAY_METADATA
Mastering display metadata (based on SMPTE-2086:2014).
Definition packet.h:219
@ AV_PKT_DATA_AUDIO_SERVICE_TYPE
This side data should be associated with an audio stream and corresponds to enum AVAudioServiceType.
Definition packet.h:117
@ AV_PKT_DATA_SPHERICAL
This side data should be associated with a video stream and corresponds to the AVSphericalMapping str...
Definition packet.h:225
@ AV_PKT_DATA_PALETTE
An AV_PKT_DATA_PALETTE side data packet contains exactly AVPALETTE_SIZE bytes worth of palette.
Definition packet.h:47
@ AV_PKT_DATA_ENCRYPTION_INFO
This side data contains encryption info for how to decrypt the packet.
Definition packet.h:252
@ AV_PKT_DATA_DISPLAYMATRIX
This side data contains a 3x3 transformation matrix describing an affine transformation that needs to...
Definition packet.h:105
@ AV_PKT_DATA_EXIF
Extensible image file format metadata.
Definition packet.h:369
@ AV_PKT_DATA_ENCRYPTION_INIT_INFO
This side data is encryption initialization data.
Definition packet.h:246
@ AV_PKT_DATA_NEW_EXTRADATA
The AV_PKT_DATA_NEW_EXTRADATA is used to notify the codec or the format that the extradata buffer was...
Definition packet.h:56
@ AV_PKT_DATA_STEREO3D
This side data should be associated with a video stream and contains Stereoscopic 3D information in f...
Definition packet.h:111
@ AV_PKT_DATA_FRAME_CROPPING
The number of pixels to discard from the top/bottom/left/right border of the decoded frame to obtain ...
Definition packet.h:340
@ AV_PKT_DATA_CONTENT_LIGHT_LEVEL
Content light level (based on CTA-861.3).
Definition packet.h:232
@ AV_PKT_DATA_DOVI_CONF
DOVI configuration ref: dolby-vision-bitstreams-within-the-iso-base-media-file-format-v2....
Definition packet.h:280
#define AV_PKT_FLAG_DISCARD
Flag is used to discard packets which are required to maintain valid decoder state but are not requir...
Definition packet.h:657
void av_packet_unref(AVPacket *pkt)
Wipe the packet.
Definition packet.c:434
uint8_t * av_packet_new_side_data(AVPacket *pkt, enum AVPacketSideDataType type, size_t size)
Allocate new information of a packet.
Definition packet.c:231
#define AV_PKT_FLAG_KEY
The packet contains a keyframe.
Definition packet.h:650
#define AV_PKT_FLAG_DISPOSABLE
Flag is used to indicate packets that contain frames that can be discarded by the decoder.
Definition packet.h:669
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 packet.c:197
void av_shrink_packet(AVPacket *pkt, int size)
Reduce packet size, correctly zeroing padding.
Definition packet.c:113
int av_new_packet(AVPacket *pkt, int size)
Allocate the payload of a packet and initialize its fields with default values.
Definition packet.c:98
AVStreamGroup * avformat_stream_group_create(AVFormatContext *s, enum AVStreamGroupParamsType type, AVDictionary **options)
Add a new empty stream group to a media file.
Definition options.c:470
AVStream * avformat_new_stream(AVFormatContext *s, const struct AVCodec *c)
Add a new stream to a media file.
int avformat_stream_group_add_stream(AVStreamGroup *stg, AVStream *st)
Add an already allocated stream to a stream group.
Definition options.c:558
AVFormatContext * avformat_alloc_context(void)
Allocate an AVFormatContext.
Definition options.c:165
void avformat_free_context(AVFormatContext *s)
Free an AVFormatContext and all its streams.
Definition avformat.c:150
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:361
int av_index_search_timestamp(AVStream *st, int64_t timestamp, int flags)
Get the index for a specific timestamp.
Definition seek.c:245
struct AVAESCTR * av_aes_ctr_alloc(void)
Allocate an AVAESCTR context.
Definition aes_ctr.c:41
int av_aes_ctr_init(struct AVAESCTR *a, const uint8_t *key)
Initialize an AVAESCTR context.
Definition aes_ctr.c:74
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:53
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:102
void av_aes_ctr_free(struct AVAESCTR *a)
Release an AVAESCTR context.
Definition aes_ctr.c:84
#define AES_CTR_KEY_SIZE
Definition aes_ctr.h:35
struct AVAES * av_aes_alloc(void)
Allocate an AVAES context.
Definition aes.c:37
int av_aes_init(AVAES *a, const uint8_t *key, int key_bits, int decrypt)
Initialize an AVAES context.
Definition aes.c:231
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:171
int av_channel_layout_retype(AVChannelLayout *channel_layout, enum AVChannelOrder order, int flags)
Change the AVChannelOrder of a channel layout.
#define AV_CHANNEL_LAYOUT_RETYPE_FLAG_CANONICAL
The specified retype target order is ignored and the simplest possible (canonical) order is used for ...
#define AV_CHANNEL_LAYOUT_STEREO
#define AV_CHANNEL_LAYOUT_MONO
int av_channel_layout_custom_init(AVChannelLayout *channel_layout, int nb_channels)
Initialize a custom channel layout with the specified number of channels.
void av_channel_layout_uninit(AVChannelLayout *channel_layout)
Free any allocated data in the channel layout and reset the channel count to 0.
int av_channel_layout_from_mask(AVChannelLayout *channel_layout, uint64_t mask)
Initialize a native channel layout from a bitmask indicating which channels are present.
@ AV_CHANNEL_ORDER_UNSPEC
Only the channel count is specified, without any further information about the channel order.
@ AV_CHAN_AMBISONIC_BASE
Range of channels between AV_CHAN_AMBISONIC_BASE and AV_CHAN_AMBISONIC_END represent Ambisonic compon...
int av_bprint_finalize(AVBPrint *buf, char **ret_str)
Finalize a print buffer.
Definition bprint.c:235
void av_buffer_unref(AVBufferRef **buf)
Free a given reference and automatically free the buffer if there are no more references to it.
Definition buffer.c:139
AVBufferRef * av_buffer_alloc(size_t size)
Allocate an AVBuffer of the given size using av_malloc().
Definition buffer.c:77
void av_dict_free(AVDictionary **pm)
Free all the memory allocated for an AVDictionary struct and all keys and values.
Definition dict.c:233
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:60
int av_dict_copy(AVDictionary **dst, const AVDictionary *src, int flags)
Copy entries from one AVDictionary struct into another.
Definition dict.c:247
#define AV_DICT_APPEND
If the entry already exists, append to it.
Definition dict.h:82
#define AV_DICT_DONT_STRDUP_VAL
Take ownership of a value that's been allocated with av_malloc() or another memory allocation functio...
Definition dict.h:79
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:86
#define AV_DICT_DONT_OVERWRITE
Don't overwrite existing entries.
Definition dict.h:81
#define AV_DICT_DONT_STRDUP_KEY
Take ownership of a key that's been allocated with av_malloc() or another memory allocation function.
Definition dict.h:77
#define AV_DICT_MATCH_CASE
Only get an entry with exact-case key match.
Definition dict.h:74
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:177
#define AVERROR_PATCHWELCOME
Not yet implemented in FFmpeg, patches welcome.
Definition error.h:64
#define AVERROR_BUG
Internal bug, also see AVERROR_BUG2.
Definition error.h:52
#define AVERROR_INVALIDDATA
Invalid data found when processing input.
Definition error.h:61
#define AVERROR_EOF
End of file.
Definition error.h:57
#define av_err2str(errnum)
Convenience macro, the return value should be used only directly in function arguments but never stan...
Definition error.h:122
#define AVERROR(e)
Definition error.h:45
void av_iamf_audio_element_free(AVIAMFAudioElement **paudio_element)
Free an AVIAMFAudioElement and all its contents.
Definition iamf.c:338
@ AV_IAMF_AUDIO_ELEMENT_TYPE_SCENE
Definition iamf.h:349
void av_iamf_mix_presentation_free(AVIAMFMixPresentation **pmix_presentation)
Free an AVIAMFMixPresentation and all its contents.
Definition iamf.c:536
#define AV_LOG_TRACE
Extremely verbose debugging, useful for libav* development.
Definition log.h:236
#define AV_LOG_DEBUG
Stuff which is only useful for libav* developers.
Definition log.h:231
#define AV_LOG_WARNING
Something somehow does not look correct.
Definition log.h:216
#define AV_LOG_FATAL
Something went wrong and recovery is not possible.
Definition log.h:204
#define AV_LOG_VERBOSE
Detailed information.
Definition log.h:226
#define AV_LOG_INFO
Standard information.
Definition log.h:221
#define AV_LOG_ERROR
Something went wrong and cannot losslessly be recovered.
Definition log.h:210
const char * av_default_item_name(void *ptr)
Return the context name.
Definition log.c:241
AVRational av_add_q(AVRational b, AVRational c)
Add two rationals.
Definition rational.c:93
AVRational av_mul_q(AVRational b, AVRational c)
Multiply two rationals.
Definition rational.c:80
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
static AVRational av_make_q(int num, int den)
Create an AVRational.
Definition rational.h:71
AVRational av_d2q(double d, int max)
Convert a double precision floating point number to a rational.
Definition rational.c:110
static double av_q2d(AVRational a)
Convert an AVRational to a double.
Definition rational.h:104
static int av_cmp_q(AVRational a, AVRational b)
Compare two rationals.
Definition rational.h:89
AVRational av_sub_q(AVRational b, AVRational c)
Subtract one rational from another.
Definition rational.c:101
int64_t av_rescale(int64_t a, int64_t b, int64_t c)
Rescale a 64-bit integer with rounding to nearest.
int64_t av_rescale_q(int64_t a, AVRational bq, AVRational cq)
Rescale a 64-bit integer by 2 rational numbers.
void * av_dynarray2_add(void **tab_ptr, int *nb_ptr, size_t elem_size, const uint8_t *elem_data)
Add an element of size elem_size to a dynamic array.
Definition mem.c:341
void * av_fast_realloc(void *ptr, unsigned int *size, size_t min_size)
Reallocate the given buffer if it is not large enough, otherwise do nothing.
Definition mem.c:495
void * av_realloc_array(void *ptr, size_t nmemb, size_t size)
Definition mem.c:217
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:188
int av_reallocp_array(void *ptr, size_t nmemb, size_t size)
Allocate, reallocate an array through a pointer to a pointer.
Definition mem.c:225
const char * av_get_media_type_string(enum AVMediaType media_type)
Return a string describing the media_type enum, NULL if media_type is unknown.
Definition utils.c:28
char * av_fourcc_make_string(char *buf, uint32_t fourcc)
Fill the provided buffer with a string containing a FourCC (four-character code) representation.
Definition utils.c:54
#define av_fourcc2str(fourcc)
Definition avutil.h:323
#define AV_FOURCC_MAX_STRING_SIZE
Definition avutil.h:321
@ AVMEDIA_TYPE_AUDIO
Definition avutil.h:201
@ AVMEDIA_TYPE_SUBTITLE
Definition avutil.h:203
@ AVMEDIA_TYPE_VIDEO
Definition avutil.h:200
@ AVMEDIA_TYPE_DATA
Opaque data information usually continuous.
Definition avutil.h:202
void av_sha_update(struct AVSHA *ctx, const uint8_t *data, size_t len)
Update hash value.
Definition sha.c:315
struct AVSHA * av_sha_alloc(void)
Allocate an AVSHA context.
Definition sha.c:46
void av_sha_final(AVSHA *ctx, uint8_t *digest)
Finish hashing and output digest value.
Definition sha.c:347
av_cold int av_sha_init(AVSHA *ctx, int bits)
Initialize SHA-1 or SHA-2 hashing.
Definition sha.c:274
size_t av_strlcat(char *dst, const char *src, size_t size)
Append the string src to the string dst, but to a total length of no more than size - 1 bytes,...
Definition avstring.c:95
char * av_stristr(const char *s1, const char *s2)
Locate the first case-independent occurrence in the string haystack of the string needle.
Definition avstring.c:58
int av_strstart(const char *str, const char *pfx, const char **ptr)
Return non-zero if pfx is a prefix of str.
Definition avstring.c:36
#define AV_NOPTS_VALUE
Undefined timestamp value.
Definition avutil.h:247
#define AV_TIME_BASE
Internal time base represented as integer.
Definition avutil.h:253
#define LIBAVUTIL_VERSION_INT
Definition version.h:85
void av_display_rotation_set(int32_t matrix[9], double angle)
Initialize a transformation matrix describing a pure clockwise rotation by the specified angle (in de...
Definition display.c:51
void av_display_matrix_flip(int32_t matrix[9], int hflip, int vflip)
Flip the input matrix horizontally and/or vertically.
Definition display.c:66
AVSphericalMapping * av_spherical_alloc(size_t *size)
Allocate a AVSphericalVideo structure and initialize its fields to default values.
Definition spherical.c:26
AVSphericalProjection
Projection of the video surface(s) on a sphere.
Definition spherical.h:47
@ AV_SPHERICAL_RECTILINEAR
Video frame displays on a flat, rectangular 2D surface.
Definition spherical.h:78
@ AV_SPHERICAL_EQUIRECTANGULAR
Video represents a sphere mapped on a flat surface using equirectangular projection.
Definition spherical.h:52
@ AV_SPHERICAL_EQUIRECTANGULAR_TILE
Video represents a portion of a sphere mapped on a flat surface using equirectangular projection.
Definition spherical.h:68
@ AV_SPHERICAL_CUBEMAP
Video frame is split into 6 faces of a cube, and arranged on a 3x2 layout.
Definition spherical.h:61
@ AV_SPHERICAL_HALF_EQUIRECTANGULAR
Video frame displays as a 180 degree equirectangular projection.
Definition spherical.h:73
@ AV_SPHERICAL_PARAMETRIC_IMMERSIVE
Parametric Immersive projection (Apple).
Definition spherical.h:90
@ AV_SPHERICAL_FISHEYE
Fisheye projection (Apple).
Definition spherical.h:84
AVStereo3DType
List of possible 3D Types.
Definition stereo3d.h:48
AVStereo3D * av_stereo3d_alloc_size(size_t *size)
Allocate an AVStereo3D structure and set its fields to default values.
Definition stereo3d.c:39
#define AV_STEREO3D_FLAG_INVERT
Inverted views, Right/Bottom represents the left view.
Definition stereo3d.h:194
AVStereo3DPrimaryEye
List of possible primary eyes.
Definition stereo3d.h:174
AVStereo3DView
List of possible view types.
Definition stereo3d.h:149
@ AV_STEREO3D_2D
Video is not stereoscopic (and metadata has to be there).
Definition stereo3d.h:52
@ AV_STEREO3D_TOPBOTTOM
Views are on top of each other.
Definition stereo3d.h:76
@ AV_STEREO3D_UNSPEC
Video is stereoscopic but the packing is unspecified.
Definition stereo3d.h:143
@ AV_STEREO3D_SIDEBYSIDE
Views are next to each other.
Definition stereo3d.h:64
@ AV_PRIMARY_EYE_NONE
Neither eye.
Definition stereo3d.h:178
@ AV_PRIMARY_EYE_LEFT
Left eye.
Definition stereo3d.h:183
@ AV_PRIMARY_EYE_RIGHT
Right eye.
Definition stereo3d.h:188
@ AV_STEREO3D_VIEW_RIGHT
Frame contains only the right view.
Definition stereo3d.h:163
@ AV_STEREO3D_VIEW_PACKED
Frame contains two packed views.
Definition stereo3d.h:153
@ AV_STEREO3D_VIEW_LEFT
Frame contains only the left view.
Definition stereo3d.h:158
@ AV_STEREO3D_VIEW_UNSPEC
Content is unspecified.
Definition stereo3d.h:168
int index
Definition gxfenc.c:90
int a
int tile_rows
#define MAX_REORDER_DELAY
cl_device_type type
const VDPAUPixFmtMap * map
int ff_iamfdec_read_descriptors(IAMFContext *c, AVIOContext *pb, int max_size, void *log_ctx)
int ff_iamf_read_packet(AVFormatContext *s, IAMFDemuxContext *c, AVIOContext *pb, int max_size, int stream_id_offset, AVPacket *pkt)
void ff_iamf_read_deinit(IAMFDemuxContext *c)
const char *const ff_id3v1_genre_str[ID3v1_GENRE_MAX+1]
ID3v1 genres.
Definition id3v1.c:26
#define ID3v1_GENRE_MAX
Definition id3v1.h:29
#define r
Definition input.c:42
#define b
Definition input.c:43
static av_always_inline float av_int2float(uint32_t i)
Reinterpret a 32-bit integer as a float.
Definition intfloat.h:40
static av_always_inline double av_int2double(uint64_t i)
Reinterpret a 64-bit integer as a double.
Definition intfloat.h:60
#define AV_WB32(p, v)
#define AV_RB8(x)
#define AV_WL32(p, v)
#define AV_RL32(p)
#define AV_RB32(p)
#define AV_RB16A(p)
#define AV_WB64(p, v)
#define AV_WL32A(p, v)
#define AV_WB8(p, d)
#define AV_RB64(p)
#define AV_WB16(p, v)
#define AV_WL16A(p, v)
#define AV_RB16(p)
#define AV_RB32A(p)
int ff_mov_lang_to_iso639(unsigned code, char to[4])
Definition isom.c:261
const AVCodecTag ff_codec_movdata_tags[]
Definition isom.c:82
const struct MP4TrackKindMapping ff_mov_track_kind_table[]
Definition isom.c:465
const AVCodecTag ff_codec_movsubtitle_tags[]
Definition isom.c:75
#define MOV_TRUN_SAMPLE_DURATION
Definition isom.h:418
int ff_mov_read_esds(AVFormatContext *fc, AVIOContext *pb)
Definition mov_esds.c:23
#define FF_MOV_FLAG_MFRA_PTS
Definition isom.h:466
#define MOV_TRUN_SAMPLE_CTS
Definition isom.h:421
#define MOV_TKHD_FLAG_ENABLED
Definition isom.h:433
#define MOV_TFHD_DEFAULT_BASE_IS_MOOF
Definition isom.h:414
#define FF_MOV_FLAG_MFRA_DTS
Definition isom.h:465
const AVCodecTag ff_codec_movaudio_tags[]
Definition isom_tags.c:306
#define MOV_FRAG_SAMPLE_FLAG_DEPENDS_YES
Definition isom.h:431
const AVCodecTag ff_codec_movvideo_tags[]
Definition isom_tags.c:29
#define MOV_TFHD_DEFAULT_SIZE
Definition isom.h:411
#define MOV_ISMV_TTML_TAG
Definition isom.h:482
#define TAG_IS_AVCI(tag)
Definition isom.h:442
#define MOV_TRUN_FIRST_SAMPLE_FLAGS
Definition isom.h:417
#define MOV_MP4_FPCM_TAG
Definition isom.h:484
#define MOV_FRAG_SAMPLE_FLAG_IS_NON_SYNC
Definition isom.h:424
#define MOV_TFHD_STSD_ID
Definition isom.h:409
#define MOV_TRUN_SAMPLE_FLAGS
Definition isom.h:420
#define MOV_MP4_TTML_TAG
Definition isom.h:483
#define MOV_TFHD_DEFAULT_FLAGS
Definition isom.h:412
#define MOV_TRUN_DATA_OFFSET
Definition isom.h:416
#define MOV_TFHD_BASE_DATA_OFFSET
Definition isom.h:408
#define MOV_MP4_IPCM_TAG
Definition isom.h:485
static enum AVCodecID ff_mov_get_lpcm_codec_id(int bps, int flags)
Compute codec id for 'lpcm' tag.
Definition isom.h:472
#define MOV_TRUN_SAMPLE_SIZE
Definition isom.h:419
#define MOV_SAMPLE_DEPENDENCY_NO
Definition isom.h:440
#define FF_MOV_FLAG_MFRA_AUTO
Definition isom.h:464
#define MOV_TFHD_DEFAULT_DURATION
Definition isom.h:410
unsigned offset
Definition libaomenc.c:763
static int mix(int c0, int c1)
Definition 4xm.c:717
@ HEVC_NAL_CRA_NUT
Definition hevc.h:50
int avpriv_dv_produce_packet(DVDemuxContext *c, AVPacket *pkt, uint8_t *buf, int buf_size, int64_t pos)
Definition dv.c:738
int avpriv_dv_get_packet(DVDemuxContext *c, AVPacket *pkt)
Definition dv.c:733
DVDemuxContext * avpriv_dv_init_demux(AVFormatContext *s)
Definition dv.c:728
int ff_dict_set_timestamp(AVDictionary **dict, const char *key, int64_t timestamp)
Set a dictionary value to an ISO-8601 compliant timestamp string.
Definition utils.c:616
int ff_hex_to_data(uint8_t *data, const char *p)
Parse a string of hexadecimal strings.
Definition utils.c:485
static av_always_inline FFStream * ffstream(AVStream *st)
Definition internal.h:365
static av_always_inline const FFStream * cffstream(const AVStream *st)
Definition internal.h:370
char * ff_data_to_hex(char *buf, const uint8_t *src, int size, int lowercase)
Write hexadecimal string corresponding to given binary data.
Definition utils.c:464
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:237
enum AVCodecID ff_codec_get_id(const AVCodecTag *tags, unsigned int tag)
Definition utils.c:143
Macro definitions for various function/variable attributes.
#define av_fallthrough
Definition attributes.h:67
#define av_unused
Definition attributes.h:164
common internal API header
#define NULL_IF_CONFIG_SMALL(x)
Return NULL if CONFIG_SMALL is true, otherwise the argument without modification.
Definition internal.h:88
void avpriv_report_missing_feature(void *avc, const char *msg,...) av_printf_format(2
Log a generic warning message about a missing feature.
Stereoscopic video.
static av_cold int read_close(AVFormatContext *ctx)
Definition libcdio.c:143
static int read_seek(AVFormatContext *ctx, int stream_index, int64_t timestamp, int flags)
Definition libcdio.c:151
version
Definition libkvazaar.c:313
item_name
Definition libkvazaar.c:311
static av_const double hypot(double x, double y)
Definition libm.h:368
static const uint16_t mask[17]
Definition lzw.c:38
#define FFSWAP(type, a, b)
Definition macros.h:52
#define FFMIN(a, b)
Definition macros.h:49
#define MKTAG(a, b, c, d)
Definition macros.h:55
#define MKBETAG(a, b, c, d)
Definition macros.h:56
#define FFMAX(a, b)
Definition macros.h:47
AVContentLightMetadata * av_content_light_metadata_alloc(size_t *size)
Allocate an AVContentLightMetadata structure and set its fields to default values.
AVMasteringDisplayMetadata * av_mastering_display_metadata_alloc_size(size_t *size)
Allocate an AVMasteringDisplayMetadata structure and set its fields to default values.
uint64_t layout
void * av_calloc(size_t nmemb, size_t size)
Definition mem.c:264
Memory handling functions.
static int mlp_samplerate(int in)
Definition mlp_parse.h:87
static uint64_t truehd_layout(int chanmap)
Definition mlp_parse.h:105
static int mov_read_ilst(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition mov.c:5711
static int64_t mov_get_skip_samples(AVStream *st, int sample)
Definition mov.c:12365
static int search_frag_moof_offset(MOVFragmentIndex *frag_index, int64_t offset)
Definition mov.c:1769
static int mov_read_sbas(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition mov.c:2734
static int update_frag_index(MOVContext *c, int64_t offset)
Definition mov.c:1870
static int get_eia608_packet(AVIOContext *pb, AVPacket *pkt, int src_size)
Definition mov.c:11893
static int mov_read_iloc(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition mov.c:9410
static int mov_read_pack(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition mov.c:7109
static int find_prev_closest_index(AVStream *st, AVIndexEntry *e_old, int nb_old, MOVTimeToSample *tts_data, int64_t tts_count, int64_t timestamp_pts, int flag, int64_t *index, int64_t *tts_index, int64_t *tts_sample)
Find the closest previous frame to the timestamp_pts, in e_old index entries.
Definition mov.c:4223
static int mov_read_seek(AVFormatContext *s, int stream_index, int64_t sample_time, int flags)
Definition mov.c:12381
static HEIFItem * get_heif_item(MOVContext *c, unsigned id)
Get the requested item.
Definition mov.c:196
static void mov_free_stream_context(AVFormatContext *s, AVStream *st)
Definition mov.c:10533
static int mov_read_stsd(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition mov.c:3451
static void mov_parse_stsd_video(MOVContext *c, AVIOContext *pb, AVStream *st, MOVStreamContext *sc)
Definition mov.c:2925
static int heif_add_stream(MOVContext *c, HEIFItem *item)
Definition mov.c:5866
static int mov_read_dops(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition mov.c:8986
static int set_display_matrix_from_item(AVPacketSideData **coded_side_data, int *nb_coded_side_data, const HEIFItem *item)
Definition mov.c:10804
static int mov_compare_presentation_samples(const void *a, const void *b)
Definition mov.c:5281
static int mov_switch_root(AVFormatContext *s, int64_t target, int index)
Definition mov.c:11833
static int mov_read_vexu_proj(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition mov.c:7327
static int mov_read_srat(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition mov.c:1093
static int get_key_from_kid(uint8_t *out, int len, MOVContext *c, AVEncryptionInfo *sample)
Definition mov.c:8570
static int mov_read_aclr(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition mov.c:2475
static int mov_read_idat(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition mov.c:9404
static int mov_parse_tmcd_streams(AVFormatContext *s)
Definition mov.c:11278
static int mov_read_lhvc(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition mov.c:9121
static int aax_filter(uint8_t *input, int size, MOVContext *c)
Definition mov.c:1634
static void mov_current_sample_dec(MOVStreamContext *sc)
Definition mov.c:4469
static int mov_finalize_stsd_entry(MOVContext *c, AVStream *st)
Definition mov.c:3329
static int mov_read_pitm(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition mov.c:9396
static int mov_seek_stream(AVFormatContext *s, AVStream *st, int64_t timestamp, int flags)
Definition mov.c:12290
static int mov_read_packet(AVFormatContext *s, AVPacket *pkt)
Definition mov.c:12046
static int mov_parse_lcevc_streams(AVFormatContext *s)
Definition mov.c:11396
static int mov_read_hvce(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition mov.c:9094
static int cbcs_scheme_decrypt(MOVContext *c, MOVStreamContext *sc, AVEncryptionInfo *sample, uint8_t *input, int size)
Definition mov.c:8803
static int mov_read_default(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition mov.c:10118
static int mov_finalize_packet(AVFormatContext *s, AVStream *st, AVIndexEntry *sample, int64_t current_index, AVPacket *pkt)
Definition mov.c:11962
static int mov_read_stss(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition mov.c:3659
static uint64_t mov_dts_channel_layout_to_mask(unsigned int code)
Definition mov.c:1209
static int64_t get_stream_info_time(MOVFragmentStreamInfo *frag_stream_info)
Definition mov.c:1793
static int mov_read_saio(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition mov.c:8212
static int mov_skip_multiple_stsd(MOVContext *c, AVIOContext *pb, int codec_tag, int format, int64_t size)
Definition mov.c:3303
#define DRM_BLOB_SIZE
Definition mov.c:1506
static int mov_add_tref_id(MovTref *tag, uint32_t id)
Definition mov.c:2660
static int mov_read_mdhd(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition mov.c:2002
static int mov_read_tmcd(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition mov.c:6808
int ff_mov_read_stsd_entries(MOVContext *c, AVIOContext *pb, int entries)
Definition mov.c:3350
static int mov_metadata_gnre(MOVContext *c, AVIOContext *pb, unsigned len, const char *key)
Definition mov.c:136
static int mov_read_dref(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition mov.c:654
static int mov_read_dpxe(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition mov.c:2403
static MovTref * mov_find_tref_tag(const MOVStreamContext *sc, uint32_t name)
Definition mov.c:2675
static int mov_read_eyes(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition mov.c:7400
static int cenc_scheme_decrypt(MOVContext *c, MOVStreamContext *sc, AVEncryptionInfo *sample, uint8_t *input, int size)
Definition mov.c:8607
static int mov_read_wave(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition mov.c:2523
static int read_image_iovl(AVFormatContext *s, const HEIFGrid *grid, AVStreamGroupTileGrid *tile_grid)
Definition mov.c:10920
static int mov_metadata_hmmt(MOVContext *c, AVIOContext *pb, unsigned len)
Definition mov.c:326
static int mov_read_iref_dimg(MOVContext *c, AVIOContext *pb, int version)
Definition mov.c:9635
static int mov_read_stsz(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition mov.c:3714
static int mov_dts_stream_construction_to_profile(unsigned int sc)
Definition mov.c:1176
static int mov_parse_cdsc_streams(AVFormatContext *s)
Definition mov.c:11349
static int rb_size(AVIOContext *pb, int64_t *value, int size)
Definition mov.c:9377
static int mov_read_chpl(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition mov.c:615
static int mov_read_header(AVFormatContext *s)
Definition mov.c:11561
static int mov_read_dfla(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition mov.c:8530
static int mov_read_stco(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition mov.c:2820
static int mov_read_st3d(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition mov.c:7062
static int mov_read_elst(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition mov.c:6734
static int test_same_origin(const char *src, const char *ref)
Definition mov.c:5379
static int sanity_checks(void *log_obj, MOVStreamContext *sc, int index)
Definition mov.c:5536
static void mov_current_sample_set(MOVStreamContext *sc, int current_sample)
Definition mov.c:4481
static int mov_merge_tts_data(MOVContext *mov, AVStream *st, int flags)
Definition mov.c:4897
static int mov_aaxc_crypto(MOVContext *c)
Definition mov.c:1609
static int mov_read_sv3d(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition mov.c:7190
static int mov_read_ddts(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition mov.c:1237
static int mov_read_sdtp(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition mov.c:3927
static int mov_read_stts(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition mov.c:3807
static int cenc_filter(MOVContext *mov, AVStream *st, MOVStreamContext *sc, AVPacket *pkt, int current_index)
Definition mov.c:8916
static const AVClass mov_class
Definition mov.c:12493
static int mov_read_sample_encryption_info(MOVContext *c, AVIOContext *pb, MOVStreamContext *sc, AVEncryptionInfo **sample, int use_subsamples)
Definition mov.c:7956
static int mov_read_meta(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition mov.c:5925
static int mov_read_smdm(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition mov.c:6880
static const uint32_t mac_to_unicode[128]
Definition mov.c:152
static int mov_read_sidx(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition mov.c:6522
static int mov_read_strf(MOVContext *c, AVIOContext *pb, MOVAtom atom)
An strf atom is a BITMAPINFOHEADER struct.
Definition mov.c:2798
static uint32_t get_sgpd_sync_index(const MOVStreamContext *sc, int nal_unit_type)
Definition mov.c:4819
static void fix_frag_index_entries(MOVFragmentIndex *frag_index, int index, int id, int entries)
Definition mov.c:1931
static int mov_read_rtmd_track(AVFormatContext *s, AVStream *st)
Definition mov.c:10448
static int mov_read_dec3(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition mov.c:1127
static int mov_read_dmlp(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition mov.c:9039
static int mov_metadata_int8_bypass_padding(MOVContext *c, AVIOContext *pb, unsigned len, const char *key)
Definition mov.c:113
static int mov_read_schm(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition mov.c:8428
static int mov_metadata_loci(MOVContext *c, AVIOContext *pb, unsigned len)
Definition mov.c:276
static int read_tfra(MOVContext *mov, AVIOContext *f)
Definition mov.c:10689
static int mov_seek_fragment(AVFormatContext *s, AVStream *st, int64_t timestamp)
Definition mov.c:12227
static int mov_read_extradata(MOVContext *c, AVIOContext *pb, MOVAtom atom, enum AVCodecID codec_id)
Definition mov.c:2362
static int mov_read_enda(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition mov.c:2116
static int mov_read_covr(MOVContext *c, AVIOContext *pb, int type, int len)
Definition mov.c:233
static int mov_read_adrm(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition mov.c:1508
static int mov_parse_dovi_streams(AVFormatContext *s)
Definition mov.c:11450
static int mov_read_chnl(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition mov.c:1318
static void mov_metadata_creation_time(MOVContext *c, AVIOContext *pb, AVDictionary **metadata, int version)
Definition mov.c:1972
static int mov_parse_exif_item(AVFormatContext *s, AVPacketSideData **coded_side_data, int *nb_coded_side_data, const HEIFItem *ref)
Definition mov.c:10989
static int mov_stsc_index_valid(unsigned int index, unsigned int count)
Definition mov.c:3597
static int mov_read_hdlr(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition mov.c:798
#define MOV_MERGE_STTS
Definition mov.c:4891
static int mov_read_dvcc_dvvc(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition mov.c:9074
static int should_retry(AVIOContext *pb, int error_code)
Definition mov.c:11826
static int mov_read_mvhd(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition mov.c:2048
static int mov_read_tfdt(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition mov.c:6150
static int mov_read_moov(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition mov.c:1696
static int mov_read_clli(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition mov.c:7008
static int mov_read_trun(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition mov.c:6189
static void mov_update_dts_shift(MOVStreamContext *sc, int duration, void *logctx)
Definition mov.c:3965
static int mov_read_kind(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition mov.c:9172
static int mov_read_sbgp(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition mov.c:4116
static int mov_metadata_track_or_disc_number(MOVContext *c, AVIOContext *pb, unsigned len, const char *key)
Definition mov.c:93
static int mov_read_ares(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition mov.c:2430
static int mov_read_pssh(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition mov.c:8307
static int mov_finalize_stsd_codec(MOVContext *c, AVIOContext *pb, AVStream *st, MOVStreamContext *sc)
Definition mov.c:3199
static int mov_read_tkhd(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition mov.c:5951
static int mov_read_iprp(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition mov.c:9874
static int cens_scheme_decrypt(MOVContext *c, MOVStreamContext *sc, AVEncryptionInfo *sample, uint8_t *input, int size)
Definition mov.c:8732
static int mov_read_alac(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition mov.c:2388
static int mov_read_mfra(MOVContext *c, AVIOContext *f)
Definition mov.c:10744
#define MIN_DATA_ENTRY_BOX_SIZE
Definition mov.c:653
static int mov_change_extradata(AVStream *st, AVPacket *pkt)
Definition mov.c:11869
static int mov_read_mdcv(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition mov.c:6927
static int mov_read_timecode_track(AVFormatContext *s, AVStream *st)
Definition mov.c:10474
static int mov_read_imir(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition mov.c:9855
static int mov_read_stps(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition mov.c:3618
static int mov_read_svq3(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition mov.c:2518
static int mov_read_pcmc(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition mov.c:2125
static const MOVParseTableEntry mov_default_parse_table[]
Definition mov.c:9985
static int mov_read_jp2h(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition mov.c:2398
static int mov_read_iref(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition mov.c:9762
static int mov_read_trex(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition mov.c:6124
static int mov_read_saiz(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition mov.c:8128
static int mov_read_hfov(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition mov.c:7639
static int mov_read_free(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition mov.c:7836
static int set_icc_profile_from_item(AVPacketSideData **coded_side_data, int *nb_coded_side_data, const HEIFItem *item)
Definition mov.c:10790
static int mov_read_infe(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition mov.c:9504
static int mov_read_stsc(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition mov.c:3517
static AVStream * get_curr_st(MOVContext *c)
Get the current stream in the parsing process.
Definition mov.c:215
static int mov_parse_stsd_data(MOVContext *c, AVIOContext *pb, AVStream *st, MOVStreamContext *sc, int64_t size)
Definition mov.c:3126
static int mov_read_mdat(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition mov.c:1498
static int cbc1_scheme_decrypt(MOVContext *c, MOVStreamContext *sc, AVEncryptionInfo *sample, uint8_t *input, int size)
Definition mov.c:8666
static int mov_metadata_int8_no_padding(MOVContext *c, AVIOContext *pb, unsigned len, const char *key)
Definition mov.c:127
static int search_frag_timestamp(AVFormatContext *s, MOVFragmentIndex *frag_index, AVStream *st, int64_t timestamp)
Definition mov.c:1845
static int mov_read_avid(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition mov.c:2408
static void fix_timescale(MOVContext *c, MOVStreamContext *sc)
Definition mov.c:5480
static int mov_read_custom(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition mov.c:5766
static int mov_read_dac3(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition mov.c:869
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:7905
static int mov_read_close(AVFormatContext *s)
Definition mov.c:10598
static int mov_read_pasp(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition mov.c:1476
static int mov_open_dref(MOVContext *c, AVIOContext **pb, const char *src, MOVDref *ref)
Definition mov.c:5408
static MOVFragmentStreamInfo * get_frag_stream_info_from_pkt(MOVFragmentIndex *frag_index, AVPacket *pkt, int id)
Definition mov.c:8891
static int mov_read_avss(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition mov.c:2393
static int mov_read_tenc(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition mov.c:8459
static int mov_read_uuid(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition mov.c:7731
static int mov_read_chan(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition mov.c:1299
static int build_open_gop_key_points(AVStream *st)
Definition mov.c:4827
static void set_last_stream_little_endian(AVFormatContext *fc)
Definition mov.c:2087
static void mov_build_index(MOVContext *mov, AVStream *st)
Definition mov.c:4960
static void mov_update_sample_durations(MOVContext *mov, AVStream *st)
Definition mov.c:5294
static int mov_read_ctts(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition mov.c:3976
static int mov_find_tref_id(const MovTref *tag, uint32_t id)
Definition mov.c:2651
static int mov_read_amve(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition mov.c:7037
static int mov_read_keys(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition mov.c:5720
static int mov_read_wfex(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition mov.c:1352
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:2580
static int mov_read_ftyp(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition mov.c:1648
#define IS_MATRIX_IDENT(matrix)
Definition mov.c:5943
static int can_seek_to_key_sample(AVStream *st, int sample, int64_t requested_pts)
Definition mov.c:12263
static int mov_parse_auxiliary_info(MOVContext *c, MOVStreamContext *sc, AVIOContext *pb, MOVEncryptionIndex *encryption_index)
Definition mov.c:8066
static int64_t mov_get_stsc_samples(MOVStreamContext *sc, unsigned int index)
Definition mov.c:3603
static int mov_read_vpcc(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition mov.c:6836
static int64_t add_index_entry(AVStream *st, int64_t pos, int64_t timestamp, int size, int distance, int flags)
Add index entry with the given values, to the end of ffstream(st)->index_entries.
Definition mov.c:4319
static int mov_parse_tiles(AVFormatContext *s)
Definition mov.c:11073
static void mov_fix_index(MOVContext *mov, AVStream *st)
Fix ffstream(st)->index_entries, so that it contains only the entries (and the entries which are need...
Definition mov.c:4509
#define DDTS_SIZE
static int mov_read_iref_cdsc(MOVContext *c, AVIOContext *pb, uint32_t type, int version, uint32_t size)
Definition mov.c:9718
static int cenc_decrypt(MOVContext *c, MOVStreamContext *sc, AVEncryptionInfo *sample, uint8_t *input, int size)
Definition mov.c:8875
static int mov_read_senc(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition mov.c:8010
static int mov_read_sgpd(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition mov.c:4057
static AVStream * mov_find_reference_track(AVFormatContext *s, AVStream *st, uint32_t *tref_id, int nb_tref_id, int first_index)
Definition mov.c:11334
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:4360
static int mov_read_trak(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition mov.c:5555
static int mov_read_colr(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition mov.c:2202
static int add_tts_entry(MOVTimeToSample **tts_data, unsigned int *tts_count, unsigned int *allocated_size, int count, int offset, unsigned int duration)
Definition mov.c:4372
static void mov_parse_stsd_subtitle(MOVContext *c, AVIOContext *pb, AVStream *st, MOVStreamContext *sc, int64_t size)
Definition mov.c:3110
static int mov_read_clap(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition mov.c:1367
static int mov_read_dvc1(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition mov.c:2626
static int mov_read_vdep(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition mov.c:2766
static int mov_read_SAND(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition mov.c:9351
static int64_t mov_read_atom_into_extradata(MOVContext *c, AVIOContext *pb, MOVAtom atom, AVCodecParameters *par, uint8_t *buf)
Definition mov.c:2340
static void mov_free_encryption_index(MOVEncryptionIndex **index)
Definition mov.c:10521
static int mov_read_mac_string(MOVContext *c, AVIOContext *pb, int len, char *dst, int dstlen)
Definition mov.c:171
static void fix_stream_ids(AVFormatContext *s)
Definition mov.c:11523
#define OFFSET(x)
Definition mov.c:12437
static AVIndexEntry * mov_find_next_sample(AVFormatContext *s, AVStream **st)
Definition mov.c:11796
static int mov_read_chap(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition mov.c:6103
#define MOV_MERGE_CTTS
Definition mov.c:4890
static int is_open_key_sample(const MOVStreamContext *sc, int sample)
Definition mov.c:12246
static int mov_read_moof(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition mov.c:1946
static int mov_read_SA3D(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition mov.c:9261
static int mov_read_cdsc(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition mov.c:2703
static int mov_realloc_extradata(AVCodecParameters *par, MOVAtom atom)
Definition mov.c:2325
static int mov_read_udta_string(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition mov.c:347
static int mov_read_coll(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition mov.c:6971
static int mov_read_frma(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition mov.c:7858
static int mov_read_ispe(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition mov.c:9807
static int mov_codec_id(AVStream *st, uint32_t format)
Definition mov.c:2885
static void export_orphan_timecode(AVFormatContext *s)
Definition mov.c:10671
static int mov_parse_heif_items(AVFormatContext *s)
Definition mov.c:11199
static void mov_estimate_video_delay(MOVContext *c, AVStream *st)
Definition mov.c:4401
static int mov_read_tfhd(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition mov.c:6056
static MOVFragmentStreamInfo * get_frag_stream_info(MOVFragmentIndex *frag_index, int index, int id)
Definition mov.c:1714
static int mov_read_irot(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition mov.c:9835
static int read_image_grid(AVFormatContext *s, const HEIFGrid *grid, AVStreamGroupTileGrid *tile_grid)
Definition mov.c:10825
static int mov_probe(const AVProbeData *p)
Definition mov.c:10240
static int parse_timecode_in_framenum_format(AVFormatContext *s, AVStream *st, int64_t value, int flags)
Definition mov.c:10434
static int mov_parse_uuid_spherical(MOVStreamContext *sc, AVIOContext *pb, size_t len)
Definition mov.c:7668
static void mov_current_sample_inc(MOVStreamContext *sc)
Definition mov.c:4457
static int mov_read_fiel(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition mov.c:2291
static int mov_read_targa_y216(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition mov.c:2416
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:4177
static void mov_parse_stsd_audio(MOVContext *c, AVIOContext *pb, AVStream *st, MOVStreamContext *sc)
Definition mov.c:2989
static int mov_read_wide(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition mov.c:6661
static int64_t get_frag_time(AVFormatContext *s, AVStream *dst_st, MOVFragmentIndex *frag_index, int index)
Definition mov.c:1803
static MOVFragmentStreamInfo * get_current_frag_stream_info(MOVFragmentIndex *frag_index)
Definition mov.c:1753
static int mov_read_esds(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition mov.c:864
static int mov_read_iinf(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition mov.c:9581
static int tmcd_is_referenced(AVFormatContext *s, int tmcd_id)
Definition mov.c:10653
static void mov_read_chapters(AVFormatContext *s)
Definition mov.c:10335
static int mov_read_cmov(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition mov.c:6681
static void set_frag_stream(MOVFragmentIndex *frag_index, int id)
Definition mov.c:1733
static const AVOption mov_options[]
Definition mov.c:12439
static MovTref * mov_add_tref_tag(MOVStreamContext *sc, uint32_t name)
Definition mov.c:2686
static int mov_read_vexu(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition mov.c:7577
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:550
int ff_mov_read_chnl(AVFormatContext *s, AVIOContext *pb, AVStream *st, int version)
Read 'chnl' tag from the input stream.
Definition mov_chan.c:768
uint32_t tag
Definition movenc.c:2073
MPEG Audio header decoder.
static int ff_mpa_check_header(uint32_t header)
const char data[16]
Definition mxf.c:149
int profile
Definition mxfenc.c:2299
uint16_t cid
Definition mxfenc.c:2335
static float distance(float x, float y, int band)
#define OPUS_SEEK_PREROLL_MS
#define av_realloc(p, s)
Definition ops_static.c:54
#define av_malloc(s)
Definition ops_static.c:52
AVOptions.
const char * av_color_space_name(enum AVColorSpace space)
Definition pixdesc.c:3860
const char * av_color_transfer_name(enum AVColorTransferCharacteristic transfer)
Definition pixdesc.c:3827
const char * av_color_primaries_name(enum AVColorPrimaries primaries)
Definition pixdesc.c:3794
@ AVCOL_RANGE_MPEG
Narrow or limited range content.
Definition pixfmt.h:766
@ AVCOL_RANGE_JPEG
Full range content.
Definition pixfmt.h:783
#define AVPALETTE_SIZE
Definition pixfmt.h:32
@ AVCOL_PRI_UNSPECIFIED
Definition pixfmt.h:645
@ AVCOL_TRC_UNSPECIFIED
Definition pixfmt.h:675
@ AVCOL_SPC_UNSPECIFIED
Definition pixfmt.h:709
static const uint16_t table[]
Definition prosumer.c:203
const char * name
Definition qsvenc.c:142
int ff_get_qtpalette(int codec_id, AVIOContext *pb, uint32_t *palette)
Retrieve the palette (or "color table" in QuickTime terms), either from the video sample description,...
Definition qtpalette.c:323
int ff_replaygain_export(AVStream *st, AVDictionary *metadata)
Parse replaygain tags and export them as per-stream side data.
Definition replaygain.c:94
const AVCodecTag ff_codec_bmp_tags[]
Definition riff.c:36
const AVCodecTag ff_codec_wav_tags[]
Definition riff.c:525
internal header for RIFF based (de)muxers do NOT include this in end user applications
int ff_get_wav_header(AVFormatContext *s, AVIOContext *pb, AVCodecParameters *par, int size, int big_endian)
Definition riffdec.c:141
#define av_bswap32
Definition bswap.h:47
Public header for SHA-1 & SHA-256 hash function implementations.
#define FF_ARRAY_ELEMS(a)
#define snprintf
Definition snprintf.h:34
const uint8_t * code
Definition spdifenc.c:433
unsigned int pos
Definition spdifenc.c:431
Spherical video.
AVRational ambient_illuminance
Environmental illuminance of the ambient viewing environment in lux.
AVRational ambient_light_x
Normalized x chromaticity coordinate of the environmental ambient light in the nominal viewing enviro...
AVRational ambient_light_y
Normalized y chromaticity coordinate of the environmental ambient light in the nominal viewing enviro...
A reference to a data buffer.
Definition buffer.h:82
uint8_t * data
The data buffer.
Definition buffer.h:90
size_t size
Size of data in bytes.
Definition buffer.h:94
enum AVChannel id
An AVChannelLayout holds information about the channel layout of audio data.
enum AVChannelOrder order
Channel order used in this layout.
union AVChannelLayout::@162063043056170047076125117143030261346263330336 u
Details about which channels are present in this layout.
int nb_channels
Number of channels in this layout.
AVChannelCustom * map
This member must be used when the channel order is AV_CHANNEL_ORDER_CUSTOM.
Describe the class of an AVClass context structure.
Definition log.h:76
This struct describes the properties of an encoded stream.
Definition codec_par.h:49
enum AVColorSpace color_space
Definition codec_par.h:192
int extradata_size
Size of the extradata content in bytes.
Definition codec_par.h:75
int frame_size
Audio frame size, if known.
Definition codec_par.h:227
enum AVFieldOrder field_order
The order of the fields in interlaced video.
Definition codec_par.h:182
int height
The height of the video frame in pixels.
Definition codec_par.h:150
int nb_coded_side_data
Amount of entries in coded_side_data.
Definition codec_par.h:88
int bits_per_coded_sample
The number of bits per sample in the codedwords.
Definition codec_par.h:113
AVChannelLayout ch_layout
The channel layout and number of channels.
Definition codec_par.h:207
int width
The width of the video frame in pixels.
Definition codec_par.h:143
int64_t bit_rate
The average bitrate of the encoded data (in bits per second).
Definition codec_par.h:99
int seek_preroll
Number of audio samples to skip after a discontinuity.
Definition codec_par.h:256
enum AVMediaType codec_type
General type of the encoded data.
Definition codec_par.h:53
int profile
Codec-specific bitstream restrictions that the stream conforms to.
Definition codec_par.h:135
int block_align
The number of bytes per coded audio frame, required by some formats.
Definition codec_par.h:221
int video_delay
Number of delayed frames.
Definition codec_par.h:200
uint32_t codec_tag
Additional information about the codec (corresponds to the AVI FOURCC).
Definition codec_par.h:61
uint8_t * extradata
Extra binary data needed for initializing the decoder, codec-dependent.
Definition codec_par.h:71
enum AVCodecID codec_id
Specific type of the encoded data (the codec used).
Definition codec_par.h:57
enum AVColorPrimaries color_primaries
Definition codec_par.h:190
int sample_rate
The number of audio samples per second.
Definition codec_par.h:213
enum AVColorTransferCharacteristic color_trc
Definition codec_par.h:191
int initial_padding
Number of padding audio samples at the start.
Definition codec_par.h:239
AVPacketSideData * coded_side_data
Additional data associated with the entire stream.
Definition codec_par.h:83
enum AVColorRange color_range
Additional colorspace characteristics.
Definition codec_par.h:189
unsigned MaxFALL
Max average light level per frame (cd/m^2).
unsigned MaxCLL
Max content light level (cd/m^2).
char * value
Definition dict.h:92
This describes encryption info for a packet.
uint32_t skip_byte_block
Only used for pattern encryption.
uint8_t * iv
The initialization vector.
uint32_t crypt_byte_block
Only used for pattern encryption.
uint8_t * key_id
The ID of the key used to encrypt the packet.
uint32_t scheme
The fourcc encryption scheme, in big-endian byte order.
This describes info used to initialize an encryption key system.
uint8_t * data
Key-system specific initialization data.
struct AVEncryptionInitInfo * next
An optional pointer to the next initialization info in the list.
uint8_t ** key_ids
An array of key IDs this initialization data is for.
uint8_t * system_id
A unique identifier for the key system this is for, can be NULL if it is not known.
uint32_t num_key_ids
The number of key IDs.
Format I/O context.
Definition avformat.h:1333
AVStream ** streams
A list of all streams in the file.
Definition avformat.h:1401
int error_recognition
Error recognition; higher values will detect more errors but may misdetect some more or less valid pa...
Definition avformat.h:1607
Information on how to combine one or more audio streams, as defined in section 3.6 of IAMF.
Definition iamf.h:359
enum AVIAMFAudioElementType audio_element_type
Audio element type as defined in section 3.6 of IAMF.
Definition iamf.h:391
Information on how to render and mix one or more AVIAMFAudioElement to generate the final audio outpu...
Definition iamf.h:616
Submix element as defined in section 3.7 of IAMF.
Definition iamf.h:449
unsigned int audio_element_id
The id of the Audio Element this submix element references.
Definition iamf.h:455
Submix layout as defined in section 3.7 of IAMF.
Definition iamf.h:559
unsigned int nb_elements
Number of elements in the submix.
Definition iamf.h:575
AVIAMFSubmixElement ** elements
Array of submix elements.
Definition iamf.h:568
Bytestream IO Context.
Definition avio.h:160
int seekable
A combination of AVIO_SEEKABLE_ flags or 0 when the stream is not seekable.
Definition avio.h:261
int eof_reached
true if was unable to read due to error or eof
Definition avio.h:238
int error
contains the error code or 0 if no error happened
Definition avio.h:239
int64_t pos
Definition avformat.h:621
int min_distance
Minimum distance between this and the previous keyframe, used to avoid unneeded searching.
Definition avformat.h:632
int64_t timestamp
Timestamp in AVStream.time_base units, preferably the time from which on correctly decoded frames are...
Definition avformat.h:622
int has_primaries
Flag indicating whether the display primaries (and white point) are set.
AVRational max_luminance
Max luminance of mastering display (cd/m^2).
AVRational min_luminance
Min luminance of mastering display (cd/m^2).
AVRational display_primaries[3][2]
CIE 1931 xy chromaticity coords of color primaries (r, g, b order).
AVRational white_point[2]
CIE 1931 xy chromaticity coords of white point.
int has_luminance
Flag indicating whether the luminance (min_ and max_) have been set.
AVOption.
Definition opt.h:428
This structure stores auxiliary information for decoding, presenting, or otherwise processing the cod...
Definition packet.h:424
uint8_t * data
Definition packet.h:425
This structure stores compressed data.
Definition packet.h:580
int size
Definition packet.h:604
uint8_t * data
Definition packet.h:603
This structure contains the data a format has to probe a file.
Definition avformat.h:471
Rational number (pair of numerator and denominator).
Definition rational.h:58
int num
Numerator.
Definition rational.h:59
int den
Denominator.
Definition rational.h:60
hash context
Definition sha.c:35
uint64_t count
number of bytes in buffer
Definition sha.c:37
uint32_t bound_left
Distance from the left edge.
Definition spherical.h:185
enum AVSphericalProjection projection
Projection type.
Definition spherical.h:104
uint32_t bound_top
Distance from the top edge.
Definition spherical.h:186
uint32_t bound_bottom
Distance from the bottom edge.
Definition spherical.h:188
uint32_t bound_right
Distance from the right edge.
Definition spherical.h:187
int32_t pitch
Rotation around the right vector [-90, 90].
Definition spherical.h:145
int32_t roll
Rotation around the forward vector [-180, 180].
Definition spherical.h:146
int32_t yaw
Rotation around the up vector [-180, 180].
Definition spherical.h:144
uint32_t padding
Number of pixels to pad from the edge of each cube face.
Definition spherical.h:200
enum AVStereo3DType type
How views are packed within the video.
Definition stereo3d.h:207
uint32_t baseline
The distance between the centres of the lenses of the camera system, in micrometers.
Definition stereo3d.h:228
AVRational horizontal_disparity_adjustment
Relative shift of the left and right images, which changes the zero parallax plane.
Definition stereo3d.h:234
enum AVStereo3DPrimaryEye primary_eye
Which eye is the primary eye when rendering in 2D.
Definition stereo3d.h:222
int flags
Additional information about the frame packing.
Definition stereo3d.h:212
AVRational horizontal_field_of_view
Horizontal field of view, in degrees.
Definition stereo3d.h:239
enum AVStereo3DView view
Determines which views are packed.
Definition stereo3d.h:217
int height
Height of the final image for presentation.
Definition avformat.h:1118
unsigned int el_index
Index of the enhancement layer stream in AVStreamGroup.
Definition avformat.h:1102
int width
Width of the final stream for presentation.
Definition avformat.h:1114
unsigned int metadata_index
Index of the metadata stream in the AVStreamGroup.
Definition avformat.h:1143
AVStreamGroupTileGrid holds information on how to combine several independent images on a single canv...
Definition avformat.h:973
int nb_coded_side_data
Amount of entries in coded_side_data.
Definition avformat.h:1081
int width
Width of the final image for presentation.
Definition avformat.h:1058
int height
Height of the final image for presentation.
Definition avformat.h:1068
int coded_width
Width of the canvas.
Definition avformat.h:988
struct AVStreamGroupTileGrid::@036353327352337314037001273105074056331305251354 * offsets
An nb_tiles sized array of offsets in pixels from the topleft edge of the canvas, indicating where ea...
unsigned int nb_tiles
Amount of tiles in the grid.
Definition avformat.h:981
uint8_t background[4]
The pixel value per channel in RGBA format used if no pixel of any tile is located at a particular pi...
Definition avformat.h:1032
int horizontal
Offset in pixels from the left edge of the canvas where the tile should be placed.
Definition avformat.h:1017
unsigned int idx
Index of the stream in the group this tile references.
Definition avformat.h:1012
int coded_height
Width of the canvas.
Definition avformat.h:994
AVPacketSideData * coded_side_data
Additional data associated with the grid.
Definition avformat.h:1076
int vertical
Offset in pixels from the top edge of the canvas where the tile should be placed.
Definition avformat.h:1022
union AVStreamGroup::@166361102046003066253145020066347265153020354020 params
Group type-specific parameters.
enum AVStreamGroupParamsType type
Group type.
Definition avformat.h:1186
struct AVIAMFMixPresentation * iamf_mix_presentation
Definition avformat.h:1193
struct AVStreamGroupTileGrid * tile_grid
Definition avformat.h:1194
unsigned int nb_streams
Number of elements in AVStreamGroup.streams.
Definition avformat.h:1221
struct AVStreamGroupTREF * tref
Definition avformat.h:1203
AVDictionary * metadata
Metadata that applies to the whole group.
Definition avformat.h:1214
struct AVIAMFAudioElement * iamf_audio_element
Definition avformat.h:1192
int disposition
Stream group disposition - a combination of AV_DISPOSITION_* flags.
Definition avformat.h:1244
int64_t id
Group type-specific group ID.
Definition avformat.h:1178
AVStream ** streams
A list of streams in the group.
Definition avformat.h:1234
struct AVStreamGroupLayeredVideo * layered_video
Definition avformat.h:1195
Stream structure.
Definition avformat.h:766
AVCodecParameters * codecpar
Codec parameters associated with this stream.
Definition avformat.h:789
AVRational sample_aspect_ratio
sample aspect ratio (0 if unknown)
Definition avformat.h:844
int64_t nb_frames
number of frames in this stream if known or 0
Definition avformat.h:827
enum AVDiscard discard
Selects which packets can be discarded at will and do not need to be demuxed.
Definition avformat.h:837
int64_t duration
Decoding: duration of the stream, in stream time base.
Definition avformat.h:825
AVDictionary * metadata
Definition avformat.h:846
void * priv_data
Definition avformat.h:791
int id
Format-specific stream ID.
Definition avformat.h:778
int index
stream index in AVFormatContext
Definition avformat.h:772
int64_t start_time
Decoding: pts of the first frame of the stream in presentation order, in stream time base.
Definition avformat.h:815
AVPacket attached_pic
For streams with AV_DISPOSITION_ATTACHED_PIC disposition, this packet will contain the attached pictu...
Definition avformat.h:864
AVRational avg_frame_rate
Average framerate.
Definition avformat.h:855
AVRational time_base
This is the fundamental unit of time (in seconds) in terms of which frame timestamps are represented.
Definition avformat.h:805
AVRational r_frame_rate
Real base framerate of the stream.
Definition avformat.h:900
int disposition
Stream disposition - a combination of AV_DISPOSITION_* flags.
Definition avformat.h:835
This file is part of FFmpeg.
int64_t last_discard_sample
The sample after last sample that is intended to be discarded after first_discard_sample.
Definition internal.h:239
int64_t first_discard_sample
If not 0, the first audio sample that should be discarded from the stream.
Definition internal.h:232
int skip_samples
Number of samples to skip at the start of the frame decoded from the next packet.
Definition internal.h:215
int nb_index_entries
Definition internal.h:193
AVRational display_aspect_ratio
display aspect ratio (0 if unknown)
Definition internal.h:303
AVIndexEntry * index_entries
Only used if the format does not support seeking natively.
Definition internal.h:191
enum AVStreamParseType need_parsing
Definition internal.h:321
unsigned int index_entries_allocated_size
Definition internal.h:194
int16_t * tile_id_list
Definition isom.h:320
unsigned * tile_idx_list
Definition isom.h:321
HEIFItem * item
Definition isom.h:318
int nb_tiles
Definition isom.h:322
HEIFItem ** tile_item_list
Definition isom.h:319
int item_id
Definition isom.h:295
int is_idat_relative
Definition isom.h:312
int type
Definition isom.h:311
char * name
Definition isom.h:302
int nb_iref_list
Definition isom.h:301
uint8_t * icc_profile
Definition isom.h:313
int rotation
Definition isom.h:308
int hflip
Definition isom.h:309
int64_t extent_length
Definition isom.h:304
AVStream * st
Definition isom.h:299
HEIFItemRef * iref_list
Definition isom.h:300
size_t icc_profile_size
Definition isom.h:314
int vflip
Definition isom.h:310
int64_t extent_offset
Definition isom.h:305
int width
Definition isom.h:306
int height
Definition isom.h:307
int item_id
Definition isom.h:303
IAMFLayer * layers
Definition iamf.h:103
unsigned int audio_element_id
Definition iamf.h:96
AVIAMFAudioElement * element
element backs celement iff the AVIAMFAudioElement is owned by this structure.
Definition iamf.h:95
unsigned int nb_substreams
Definition iamf.h:99
IAMFSubStream * substreams
Definition iamf.h:98
int nb_mix_presentations
Definition iamf.h:134
IAMFMixPresentation ** mix_presentations
Definition iamf.h:133
IAMFAudioElement ** audio_elements
Definition iamf.h:131
int nb_audio_elements
Definition iamf.h:132
IAMFContext iamf
Definition iamf_reader.h:33
unsigned int substream_count
Definition iamf.h:78
AVIAMFMixPresentation * mix
mix backs cmix iff the AVIAMFMixPresentation is owned by this structure.
Definition iamf.h:113
const AVIAMFMixPresentation * cmix
Definition iamf.h:108
unsigned int mix_presentation_id
Definition iamf.h:114
AVCodecParameters * codecpar
Definition iamf.h:86
unsigned int audio_substream_id
Definition iamf.h:83
uint32_t type
Definition isom.h:101
int64_t size
Definition isom.h:102
int handbrake_version
Definition isom.h:345
AVDictionary * decryption_keys
Definition isom.h:392
int * bitrates
bitrates read before streams creation
Definition isom.h:357
int cur_item_id
Definition isom.h:385
int ignore_editlist
Definition isom.h:349
uint8_t * decryption_default_key
Definition isom.h:377
unsigned meta_keys_count
Definition isom.h:337
char ** meta_keys
Definition isom.h:336
AVFormatContext * fc
Definition isom.h:327
unsigned int aax_mode
'aax' file has been detected
Definition isom.h:365
int found_mdat
'mdat' atom has been found
Definition isom.h:333
int found_iinf
'iinf' atom has been found
Definition isom.h:332
int bitrates_count
Definition isom.h:358
int * chapter_tracks
Definition isom.h:346
int interleaved_read
Definition isom.h:391
int64_t next_root_atom
offset of the next root atom
Definition isom.h:354
int ignore_chapters
Definition isom.h:352
DVDemuxContext * dv_demux
Definition isom.h:338
int nb_heif_item
Definition isom.h:387
unsigned int nb_chapter_tracks
Definition isom.h:347
int64_t idat_offset
Definition isom.h:390
MOVFragmentIndex frag_index
Definition isom.h:363
MOVTrackExt * trex_data
Definition isom.h:342
HEIFGrid * heif_grid
Definition isom.h:388
struct AVAES * aes_decrypt
Definition isom.h:376
MOVFragment fragment
current fragment in moof atom
Definition isom.h:341
AVFormatContext * dv_fctx
Definition isom.h:339
int moov_retry
Definition isom.h:359
int time_scale
Definition isom.h:328
int advanced_editlist_autodisabled
Definition isom.h:351
int found_moov
'moov' atom has been found
Definition isom.h:330
int primary_item_id
Definition isom.h:384
int advanced_editlist
Definition isom.h:350
int found_iloc
'iloc' atom has been found
Definition isom.h:331
HEIFItem ** heif_item
Definition isom.h:386
int trak_index
Index of the current 'trak'.
Definition isom.h:335
int nb_heif_grid
Definition isom.h:389
int use_mfra_for
Definition isom.h:360
Definition isom.h:68
unsigned int count
Definition isom.h:69
int offset
Definition isom.h:70
Definition isom.h:85
char volume[28]
Definition isom.h:89
char * dir
Definition isom.h:88
int16_t nlvl_to
Definition isom.h:91
char * path
Definition isom.h:87
uint32_t type
Definition isom.h:86
int16_t nlvl_from
Definition isom.h:91
char filename[64]
Definition isom.h:90
Definition isom.h:79
float rate
Definition isom.h:82
int64_t duration
Definition isom.h:80
int64_t time
Definition isom.h:81
uint64_t * auxiliary_offsets
Absolute seek position.
Definition isom.h:141
unsigned int nb_encrypted_samples
Definition isom.h:135
size_t auxiliary_offsets_count
Definition isom.h:142
size_t auxiliary_info_sample_count
Definition isom.h:139
uint8_t auxiliary_info_default_size
Definition isom.h:140
uint8_t * auxiliary_info_sizes
Definition isom.h:138
AVEncryptionInfo ** encrypted_samples
Definition isom.h:136
MOVFragmentStreamInfo * stream_info
Definition isom.h:163
int64_t moof_offset
Definition isom.h:159
int allocated_size
Definition isom.h:167
MOVFragmentIndexItem * item
Definition isom.h:171
MOVEncryptionIndex * encryption_index
Definition isom.h:154
int64_t next_trun_dts
Definition isom.h:150
int64_t first_tfra_pts
Definition isom.h:148
unsigned track_id
Definition isom.h:109
unsigned flags
Definition isom.h:116
unsigned duration
Definition isom.h:114
int found_tfhd
Definition isom.h:108
unsigned size
Definition isom.h:115
unsigned stsd_id
Definition isom.h:113
uint64_t base_data_offset
Definition isom.h:110
uint64_t moof_offset
Definition isom.h:111
uint64_t implicit_offset
Definition isom.h:112
int64_t start
Definition isom.h:175
int64_t end
Definition isom.h:176
int(* parse)(MOVContext *ctx, AVIOContext *pb, MOVAtom atom)
Definition mov.c:86
uint32_t type
Definition mov.c:85
unsigned int index
Definition isom.h:129
unsigned int count
Definition isom.h:128
int64_t time_offset
time offset of the edit list entries
Definition isom.h:217
int64_t duration_for_fps
Definition isom.h:257
AVIOContext * pb
Definition isom.h:180
size_t spherical_size
Definition isom.h:270
uint32_t min_sample_duration
Definition isom.h:254
uint8_t ** extradata
extradata array (and size) for multiple stsd
Definition isom.h:260
MOVSbgp * rap_group
Definition isom.h:245
int iamf_stream_offset
Definition isom.h:290
MOVEncryptionIndex * encryption_index
Definition isom.h:286
int64_t track_end
used for dts generation in fragmented movie files
Definition isom.h:243
int pseudo_stream_id
-1 means demux all ids
Definition isom.h:226
unsigned int rap_group_count
Definition isom.h:244
int height
tkhd height
Definition isom.h:234
int stsc_sample
Definition isom.h:202
MOVDref * drefs
Definition isom.h:229
int sample_offsets_count
Definition isom.h:251
unsigned int ctts_allocated_size
Definition isom.h:197
unsigned int per_sample_iv_size
Definition isom.h:284
int * extradata_size
Definition isom.h:261
size_t coll_size
Definition isom.h:274
int dv_audio_container
Definition isom.h:225
AVContentLightMetadata * coll
Definition isom.h:273
int64_t * chunk_offsets
Definition isom.h:187
size_t ambient_size
Definition isom.h:276
MOVStsc * stsc_data
Definition isom.h:200
uint8_t * sgpd_sync
Definition isom.h:248
size_t stereo3d_size
Definition isom.h:268
MOVTimeToSample * tts_data
Definition isom.h:190
AVStereo3D * stereo3d
Definition isom.h:267
int32_t * display_matrix
Definition isom.h:266
int current_sample
Definition isom.h:219
uint32_t sgpd_sync_count
Definition isom.h:249
unsigned int samples_per_frame
Definition isom.h:224
int nb_frames_for_fps
Definition isom.h:256
uint32_t format
Definition isom.h:278
int keyframe_absent
Definition isom.h:213
int open_key_samples_count
Definition isom.h:253
MOVElst * elst_data
Definition isom.h:205
int64_t current_index
Definition isom.h:220
int * open_key_samples
Definition isom.h:252
unsigned int stts_count
Definition isom.h:191
uint8_t * sdtp_data
Definition isom.h:195
unsigned int sample_size
may contain value calculated from stsd or value from stsz atom
Definition isom.h:209
AVEncryptionInfo * default_encrypted_sample
Definition isom.h:285
int nb_tref_tags
Definition isom.h:231
int16_t audio_cid
stsd audio compression id
Definition isom.h:227
struct AVAESCTR * aes_ctr
Definition isom.h:282
MOVStts * stts_data
Definition isom.h:193
int last_stsd_index
Definition isom.h:262
unsigned int chunk_count
Definition isom.h:186
size_t mastering_size
Definition isom.h:272
AVAmbientViewingEnvironment * ambient
Definition isom.h:275
int64_t data_size
Definition isom.h:240
int pb_is_copied
Definition isom.h:182
int * keyframes
Definition isom.h:215
struct MOVStreamContext::@212112112267365060330232277203165117121340225276 cenc
unsigned drefs_count
Definition isom.h:228
MOVIndexRange * current_index_range
Definition isom.h:222
unsigned int * sample_sizes
Definition isom.h:212
MOVCtts * ctts_data
Definition isom.h:198
AVMasteringDisplayMetadata * mastering
Definition isom.h:271
int width
tkhd width
Definition isom.h:233
int id
AVStream id.
Definition isom.h:183
uint8_t tmcd_nb_frames
tmcd number of frames per tick / second
Definition isom.h:242
unsigned int sdtp_count
Definition isom.h:194
int v_spacing
pasp vSpacing
Definition isom.h:236
unsigned int sample_count
Definition isom.h:211
MOVSbgp * sync_group
Definition isom.h:247
int dts_shift
dts shift when ctts is negative
Definition isom.h:237
unsigned int tts_count
Definition isom.h:188
int stsd_version
Definition isom.h:264
unsigned int stsc_index
Definition isom.h:201
int64_t min_corrected_pts
minimum Composition time shown by the edits excluding empty edits.
Definition isom.h:218
struct AVAES * aes_ctx
Definition isom.h:283
int32_t * sample_offsets
Definition isom.h:250
int has_palette
Definition isom.h:239
MovTref * tref_tags
Definition isom.h:232
uint32_t palette[256]
Definition isom.h:238
int ffindex
AVStream index.
Definition isom.h:184
AVSphericalMapping * spherical
Definition isom.h:269
unsigned int keyframe_count
Definition isom.h:214
unsigned int bytes_per_frame
Definition isom.h:223
uint32_t tmcd_flags
tmcd track flags
Definition isom.h:241
unsigned * stps_data
partial sync sample for mpeg-2 open gop
Definition isom.h:204
unsigned int stts_allocated_size
Definition isom.h:192
unsigned int sync_group_count
Definition isom.h:246
MOVIndexRange * index_ranges
Definition isom.h:221
struct IAMFDemuxContext * iamf
Definition isom.h:289
unsigned int stsc_count
Definition isom.h:199
unsigned int stsz_sample_size
always contains sample size from stsz atom
Definition isom.h:210
int h_spacing
pasp hSpacing
Definition isom.h:235
unsigned int elst_count
Definition isom.h:206
unsigned int ctts_count
Definition isom.h:196
unsigned int stps_count
Definition isom.h:203
unsigned int tts_allocated_size
Definition isom.h:189
int first
Definition isom.h:74
int count
Definition isom.h:75
int id
Definition isom.h:76
Definition isom.h:63
unsigned int count
Definition isom.h:64
unsigned int duration
Definition isom.h:65
unsigned int count
Definition isom.h:58
unsigned int duration
Definition isom.h:59
unsigned flags
Definition isom.h:124
unsigned duration
Definition isom.h:122
unsigned size
Definition isom.h:123
unsigned track_id
Definition isom.h:120
unsigned stsd_id
Definition isom.h:121
const char * value
Definition isom.h:489
Definition isom.h:94
uint32_t * id
trackID of the referenced track
Definition isom.h:97
Definition swscale.c:71
#define av_free(p)
#define av_malloc_array(a, b)
#define av_mallocz(s)
#define ff_dlog(a,...)
#define av_realloc_f(p, o, n)
#define avpriv_request_sample(...)
#define av_freep(p)
#define av_log(a,...)
static uint8_t tmp[40]
Definition aes_ctr.c:52
static const uint8_t fixed_key[]
Definition aes_ctr.c:45
int tile_cols
Definition av1_levels.c:73
#define src
Definition vp8dsp.c:248
static int ref[MAX_W *MAX_W]
static FILE * out
Definition movenc.c:55
static int out_size
Definition movenc.c:56
static AVFormatContext * ctx
Definition movenc.c:49
static void finish(void)
Definition movenc.c:374
static char buffer[20]
Definition seek.c:32
#define height
Definition dsp.h:89
#define width
Definition dsp.h:89
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:201
char * av_timecode_make_string(const AVTimecode *tc, char *buf, int framenum_arg)
Load timecode string in buf.
Definition timecode.c:104
Timecode helpers header.
#define AV_TIMECODE_STR_SIZE
Definition timecode.h:33
@ AV_TIMECODE_FLAG_ALLOWNEGATIVE
negative time values are allowed
Definition timecode.h:38
@ AV_TIMECODE_FLAG_DROPFRAME
timecode is drop frame
Definition timecode.h:36
@ AV_TIMECODE_FLAG_24HOURSMAX
timecode wraps after 24 hours
Definition timecode.h:37
static int64_t pts
static const int16_t cdt2[8]
int size
UUID parsing and serialization utilities.
static int av_uuid_equal(const AVUUID uu1, const AVUUID uu2)
Compares two UUIDs for equality.
Definition uuid.h:119
#define AV_UUID_LEN
Definition uuid.h:57
uint8_t AVUUID[AV_UUID_LEN]
Definition uuid.h:60
enum AVCodecID codec_id
#define mc
static float mean(const float *input, int size)
Definition vf_nnedi.c:861
color_range
int len
static double c[64]