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/rndr 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 int64_t priming, remainder, samples;
5823 if (ff_itunes_parse_smpb(val, &priming, &remainder, &samples) >= 0) {
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 %"PRId64", "
5840 "remainder %"PRId64" samples %"PRId64"\n",
5841 priming, remainder, samples);
5842 }
5843 }
5844 if (strcmp(mean, "com.apple.iTunes") == 0 &&
5845 strcmp(key, "DISCSUBTITLE") == 0) {
5846 av_dict_set(&c->fc->metadata, "disc_subtitle", val,
5848 val = NULL;
5849 }
5850 if (strcmp(key, "cdec") != 0) {
5851 av_dict_set(&c->fc->metadata, key, val,
5853 key = val = NULL;
5854 }
5855 } else {
5856 av_log(c->fc, AV_LOG_VERBOSE,
5857 "Unhandled or malformed custom metadata of size %"PRId64"\n", atom.size);
5858 }
5859
5860 avio_seek(pb, end, SEEK_SET);
5861 av_freep(&key);
5862 av_freep(&val);
5863 av_freep(&mean);
5864 return ret;
5865}
5866
5868{
5869 MOVStreamContext *sc;
5870 AVStream *st;
5871
5872 st = avformat_new_stream(c->fc, NULL);
5873 if (!st)
5874 return AVERROR(ENOMEM);
5875 sc = av_mallocz(sizeof(MOVStreamContext));
5876 if (!sc)
5877 goto fail;
5878
5879 item->st = st;
5880 st->id = item->item_id;
5881 st->priv_data = sc;
5883 st->codecpar->codec_id = mov_codec_id(st, item->type);
5884 sc->id = st->id;
5885 sc->ffindex = st->index;
5886 st->avg_frame_rate.num = st->avg_frame_rate.den = 1;
5887 st->time_base.num = st->time_base.den = 1;
5888 st->nb_frames = 1;
5889 sc->time_scale = 1;
5890 sc->pb = c->fc->pb;
5891 sc->pb_is_copied = 1;
5892 sc->refcount = 1;
5893
5894 if (item->name)
5895 av_dict_set(&st->metadata, "title", item->name, 0);
5896
5897 // Populate the necessary fields used by mov_build_index.
5898 sc->stsc_data = av_malloc_array(1, sizeof(*sc->stsc_data));
5899 if (!sc->stsc_data)
5900 goto fail;
5901 sc->stsc_count = 1;
5902 sc->stsc_data[0].first = 1;
5903 sc->stsc_data[0].count = 1;
5904 sc->stsc_data[0].id = 1;
5905 sc->chunk_offsets = av_malloc_array(1, sizeof(*sc->chunk_offsets));
5906 if (!sc->chunk_offsets)
5907 goto fail;
5908 sc->chunk_count = 1;
5909 sc->stts_data = av_malloc_array(1, sizeof(*sc->stts_data));
5910 if (!sc->stts_data)
5911 goto fail;
5912 sc->stts_count = 1;
5913 sc->stts_data[0].count = 1;
5914 // Not used for still images. But needed by mov_build_index.
5915 sc->stts_data[0].duration = 0;
5916
5917 return 0;
5918fail:
5919 mov_free_stream_context(c->fc, st);
5920 ff_remove_stream(c->fc, st);
5921 item->st = NULL;
5922
5923 return AVERROR(ENOMEM);
5924}
5925
5927{
5928 while (atom.size > 8) {
5929 uint32_t tag;
5930 if (avio_feof(pb))
5931 return AVERROR_EOF;
5932 tag = avio_rl32(pb);
5933 atom.size -= 4;
5934 if (tag == MKTAG('h','d','l','r')) {
5935 avio_seek(pb, -8, SEEK_CUR);
5936 atom.size += 8;
5937 return mov_read_default(c, pb, atom);
5938 }
5939 }
5940 return 0;
5941}
5942
5943// return 1 when matrix is identity, 0 otherwise
5944#define IS_MATRIX_IDENT(matrix) \
5945 ( (matrix)[0][0] == (1 << 16) && \
5946 (matrix)[1][1] == (1 << 16) && \
5947 (matrix)[2][2] == (1 << 30) && \
5948 !(matrix)[0][1] && !(matrix)[0][2] && \
5949 !(matrix)[1][0] && !(matrix)[1][2] && \
5950 !(matrix)[2][0] && !(matrix)[2][1])
5951
5953{
5954 int i, j, e;
5955 int width;
5956 int height;
5957 int display_matrix[3][3];
5958 int res_display_matrix[3][3] = { { 0 } };
5959 AVStream *st;
5960 MOVStreamContext *sc;
5961 int version;
5962 int flags;
5963
5964 if (c->fc->nb_streams < 1)
5965 return 0;
5966 st = c->fc->streams[c->fc->nb_streams-1];
5967 sc = st->priv_data;
5968
5969 // Each stream (trak) should have exactly 1 tkhd. This catches bad files and
5970 // avoids corrupting AVStreams mapped to an earlier tkhd.
5971 if (st->id != -1)
5972 return AVERROR_INVALIDDATA;
5973
5974 version = avio_r8(pb);
5975 flags = avio_rb24(pb);
5977
5978 if (version == 1) {
5979 avio_rb64(pb);
5980 avio_rb64(pb);
5981 } else {
5982 avio_rb32(pb); /* creation time */
5983 avio_rb32(pb); /* modification time */
5984 }
5985 st->id = (int)avio_rb32(pb); /* track id (NOT 0 !)*/
5986 sc->id = st->id;
5987 avio_rb32(pb); /* reserved */
5988
5989 /* highlevel (considering edits) duration in movie timebase */
5990 (version == 1) ? avio_rb64(pb) : avio_rb32(pb);
5991 avio_rb32(pb); /* reserved */
5992 avio_rb32(pb); /* reserved */
5993
5994 avio_rb16(pb); /* layer */
5995 avio_rb16(pb); /* alternate group */
5996 avio_rb16(pb); /* volume */
5997 avio_rb16(pb); /* reserved */
5998
5999 //read in the display matrix (outlined in ISO 14496-12, Section 6.2.2)
6000 // they're kept in fixed point format through all calculations
6001 // save u,v,z to store the whole matrix in the AV_PKT_DATA_DISPLAYMATRIX
6002 // side data, but the scale factor is not needed to calculate aspect ratio
6003 for (i = 0; i < 3; i++) {
6004 display_matrix[i][0] = avio_rb32(pb); // 16.16 fixed point
6005 display_matrix[i][1] = avio_rb32(pb); // 16.16 fixed point
6006 display_matrix[i][2] = avio_rb32(pb); // 2.30 fixed point
6007 }
6008
6009 width = avio_rb32(pb); // 16.16 fixed point track width
6010 height = avio_rb32(pb); // 16.16 fixed point track height
6011 sc->width = width >> 16;
6012 sc->height = height >> 16;
6013
6014 // apply the moov display matrix (after the tkhd one)
6015 for (i = 0; i < 3; i++) {
6016 const int sh[3] = { 16, 16, 30 };
6017 for (j = 0; j < 3; j++) {
6018 for (e = 0; e < 3; e++) {
6019 res_display_matrix[i][j] +=
6020 ((int64_t) display_matrix[i][e] *
6021 c->movie_display_matrix[e][j]) >> sh[e];
6022 }
6023 }
6024 }
6025
6026 // save the matrix when it is not the default identity
6027 if (!IS_MATRIX_IDENT(res_display_matrix)) {
6029 sc->display_matrix = av_malloc(sizeof(int32_t) * 9);
6030 if (!sc->display_matrix)
6031 return AVERROR(ENOMEM);
6032
6033 for (i = 0; i < 3; i++)
6034 for (j = 0; j < 3; j++)
6035 sc->display_matrix[i * 3 + j] = res_display_matrix[i][j];
6036 }
6037
6038 // transform the display width/height according to the matrix
6039 // to keep the same scale, use [width height 1<<16]
6040 if (width && height && sc->display_matrix) {
6041 double disp_transform[2];
6042
6043 for (i = 0; i < 2; i++)
6044 disp_transform[i] = hypot(sc->display_matrix[0 + i],
6045 sc->display_matrix[3 + i]);
6046
6047 if (disp_transform[0] > 1 && disp_transform[1] > 1 &&
6048 disp_transform[0] < (1<<24) && disp_transform[1] < (1<<24) &&
6049 fabs((disp_transform[0] / disp_transform[1]) - 1.0) > 0.01)
6051 disp_transform[0] / disp_transform[1],
6052 INT_MAX);
6053 }
6054 return 0;
6055}
6056
6058{
6059 MOVFragment *frag = &c->fragment;
6060 MOVTrackExt *trex = NULL;
6061 int flags, track_id, i;
6062 MOVFragmentStreamInfo * frag_stream_info;
6063
6064 avio_r8(pb); /* version */
6065 flags = avio_rb24(pb);
6066
6067 track_id = avio_rb32(pb);
6068 if (!track_id)
6069 return AVERROR_INVALIDDATA;
6070 for (i = 0; i < c->trex_count; i++)
6071 if (c->trex_data[i].track_id == track_id) {
6072 trex = &c->trex_data[i];
6073 break;
6074 }
6075 if (!trex) {
6076 av_log(c->fc, AV_LOG_WARNING, "could not find corresponding trex (id %u)\n", track_id);
6077 return 0;
6078 }
6079 c->fragment.found_tfhd = 1;
6080 frag->track_id = track_id;
6081 set_frag_stream(&c->frag_index, track_id);
6082
6085 frag->moof_offset : frag->implicit_offset;
6086 frag->stsd_id = flags & MOV_TFHD_STSD_ID ? avio_rb32(pb) : trex->stsd_id;
6087
6089 avio_rb32(pb) : trex->duration;
6090 frag->size = flags & MOV_TFHD_DEFAULT_SIZE ?
6091 avio_rb32(pb) : trex->size;
6093 avio_rb32(pb) : trex->flags;
6094 av_log(c->fc, AV_LOG_TRACE, "frag flags 0x%x\n", frag->flags);
6095
6096 frag_stream_info = get_current_frag_stream_info(&c->frag_index);
6097 if (frag_stream_info) {
6098 frag_stream_info->next_trun_dts = AV_NOPTS_VALUE;
6099 frag_stream_info->stsd_id = frag->stsd_id;
6100 }
6101 return 0;
6102}
6103
6105{
6106 unsigned i, num;
6107 void *new_tracks;
6108
6109 num = atom.size / 4;
6110 if (!(new_tracks = av_malloc_array(num, sizeof(int))))
6111 return AVERROR(ENOMEM);
6112
6113 av_free(c->chapter_tracks);
6114 c->chapter_tracks = new_tracks;
6115 c->nb_chapter_tracks = num;
6116
6117 for (i = 0; i < num && !pb->eof_reached; i++)
6118 c->chapter_tracks[i] = avio_rb32(pb);
6119
6120 c->nb_chapter_tracks = i;
6121
6122 return 0;
6123}
6124
6126{
6127 MOVTrackExt *trex;
6128 int err;
6129
6130 if ((uint64_t)c->trex_count+1 >= UINT_MAX / sizeof(*c->trex_data))
6131 return AVERROR_INVALIDDATA;
6132 if ((err = av_reallocp_array(&c->trex_data, c->trex_count + 1,
6133 sizeof(*c->trex_data))) < 0) {
6134 c->trex_count = 0;
6135 return err;
6136 }
6137
6138 c->fc->duration = AV_NOPTS_VALUE; // the duration from mvhd is not representing the whole file when fragments are used.
6139
6140 trex = &c->trex_data[c->trex_count++];
6141 avio_r8(pb); /* version */
6142 avio_rb24(pb); /* flags */
6143 trex->track_id = avio_rb32(pb);
6144 trex->stsd_id = avio_rb32(pb);
6145 trex->duration = avio_rb32(pb);
6146 trex->size = avio_rb32(pb);
6147 trex->flags = avio_rb32(pb);
6148 return 0;
6149}
6150
6152{
6153 MOVFragment *frag = &c->fragment;
6154 AVStream *st = NULL;
6155 MOVStreamContext *sc;
6156 int version, i;
6157 MOVFragmentStreamInfo * frag_stream_info;
6158 int64_t base_media_decode_time;
6159
6160 for (i = 0; i < c->fc->nb_streams; i++) {
6161 sc = c->fc->streams[i]->priv_data;
6162 if (sc->id == frag->track_id) {
6163 st = c->fc->streams[i];
6164 break;
6165 }
6166 }
6167 if (!st) {
6168 av_log(c->fc, AV_LOG_WARNING, "could not find corresponding track id %u\n", frag->track_id);
6169 return 0;
6170 }
6171 sc = st->priv_data;
6172 if (sc->pseudo_stream_id + 1 != frag->stsd_id && sc->pseudo_stream_id != -1)
6173 return 0;
6174 version = avio_r8(pb);
6175 avio_rb24(pb); /* flags */
6176 if (version) {
6177 base_media_decode_time = avio_rb64(pb);
6178 } else {
6179 base_media_decode_time = avio_rb32(pb);
6180 }
6181
6182 frag_stream_info = get_current_frag_stream_info(&c->frag_index);
6183 if (frag_stream_info)
6184 frag_stream_info->tfdt_dts = base_media_decode_time;
6185 sc->track_end = base_media_decode_time;
6186
6187 return 0;
6188}
6189
6191{
6192 MOVFragment *frag = &c->fragment;
6193 AVStream *st = NULL;
6194 FFStream *sti = NULL;
6195 MOVStreamContext *sc;
6196 MOVTimeToSample *tts_data;
6197 uint64_t offset;
6198 int64_t dts, pts = AV_NOPTS_VALUE;
6199 int data_offset = 0;
6200 unsigned entries, first_sample_flags = frag->flags;
6201 int flags, distance, i;
6202 int64_t prev_dts = AV_NOPTS_VALUE;
6203 int next_frag_index = -1, index_entry_pos;
6204 size_t requested_size;
6205 size_t old_allocated_size;
6206 AVIndexEntry *new_entries;
6207 MOVFragmentStreamInfo * frag_stream_info;
6208
6209 if (!frag->found_tfhd) {
6210 av_log(c->fc, AV_LOG_ERROR, "trun track id unknown, no tfhd was found\n");
6211 return AVERROR_INVALIDDATA;
6212 }
6213
6214 for (i = 0; i < c->fc->nb_streams; i++) {
6215 sc = c->fc->streams[i]->priv_data;
6216 if (sc->id == frag->track_id) {
6217 st = c->fc->streams[i];
6218 sti = ffstream(st);
6219 break;
6220 }
6221 }
6222 if (!st) {
6223 av_log(c->fc, AV_LOG_WARNING, "could not find corresponding track id %u\n", frag->track_id);
6224 return 0;
6225 }
6226 sc = st->priv_data;
6227 if (sc->pseudo_stream_id+1 != frag->stsd_id && sc->pseudo_stream_id != -1)
6228 return 0;
6229
6230 // Find the next frag_index index that has a valid index_entry for
6231 // the current track_id.
6232 //
6233 // A valid index_entry means the trun for the fragment was read
6234 // and it's samples are in index_entries at the given position.
6235 // New index entries will be inserted before the index_entry found.
6236 index_entry_pos = sti->nb_index_entries;
6237 for (i = c->frag_index.current + 1; i < c->frag_index.nb_items; i++) {
6238 frag_stream_info = get_frag_stream_info(&c->frag_index, i, frag->track_id);
6239 if (frag_stream_info && frag_stream_info->index_entry >= 0) {
6240 next_frag_index = i;
6241 index_entry_pos = frag_stream_info->index_entry;
6242 break;
6243 }
6244 }
6245 av_assert0(index_entry_pos <= sti->nb_index_entries);
6246
6247 avio_r8(pb); /* version */
6248 flags = avio_rb24(pb);
6249 entries = avio_rb32(pb);
6250 av_log(c->fc, AV_LOG_TRACE, "flags 0x%x entries %u\n", flags, entries);
6251
6252 if ((uint64_t)entries+sc->tts_count >= UINT_MAX/sizeof(*sc->tts_data))
6253 return AVERROR_INVALIDDATA;
6254 if (flags & MOV_TRUN_DATA_OFFSET) data_offset = avio_rb32(pb);
6255 if (flags & MOV_TRUN_FIRST_SAMPLE_FLAGS) first_sample_flags = avio_rb32(pb);
6256
6257 int entry_size = !!(flags & MOV_TRUN_SAMPLE_DURATION) * 4
6258 + !!(flags & MOV_TRUN_SAMPLE_SIZE) * 4
6259 + !!(flags & MOV_TRUN_SAMPLE_FLAGS) * 4
6260 + !!(flags & MOV_TRUN_SAMPLE_CTS) * 4;
6261 int64_t sample_data_size = avio_size(sc->pb);
6262 int64_t max_entries = INT64_MAX;
6263
6264 if (sample_data_size > 0)
6265 max_entries = sample_data_size - sti->nb_index_entries;
6266 if (entry_size) {
6267 int64_t size = sc->pb == pb ? sample_data_size : avio_size(pb);
6268 int64_t pos = avio_tell(pb);
6269 int64_t left = atom.size - 8 - !!(flags & MOV_TRUN_DATA_OFFSET) * 4
6271
6272 if (pos >= 0 && size >= pos)
6273 left = FFMIN(left, size - pos);
6274 max_entries = FFMIN(max_entries, left / entry_size);
6275 }
6276 if (entries > max_entries) {
6277 av_log(c->fc, AV_LOG_ERROR, "trun sample count %u exceeds the %"PRId64" "
6278 "samples the input can hold\n", entries, max_entries);
6279 return AVERROR_INVALIDDATA;
6280 }
6281
6282 frag_stream_info = get_current_frag_stream_info(&c->frag_index);
6283 if (frag_stream_info) {
6284 if (frag_stream_info->next_trun_dts != AV_NOPTS_VALUE) {
6285 dts = frag_stream_info->next_trun_dts - sc->time_offset;
6286 } else if (frag_stream_info->first_tfra_pts != AV_NOPTS_VALUE &&
6287 c->use_mfra_for == FF_MOV_FLAG_MFRA_PTS) {
6288 pts = frag_stream_info->first_tfra_pts;
6289 av_log(c->fc, AV_LOG_DEBUG, "found mfra time %"PRId64
6290 ", using it for pts\n", pts);
6291 } else if (frag_stream_info->first_tfra_pts != AV_NOPTS_VALUE &&
6292 c->use_mfra_for == FF_MOV_FLAG_MFRA_DTS) {
6293 dts = frag_stream_info->first_tfra_pts;
6294 av_log(c->fc, AV_LOG_DEBUG, "found mfra time %"PRId64
6295 ", using it for dts\n", pts);
6296 } else {
6297 int has_tfdt = frag_stream_info->tfdt_dts != AV_NOPTS_VALUE;
6298 int has_sidx = frag_stream_info->sidx_pts != AV_NOPTS_VALUE;
6299 int fallback_tfdt = !c->use_tfdt && !has_sidx && has_tfdt;
6300 int fallback_sidx = c->use_tfdt && !has_tfdt && has_sidx;
6301
6302 if (fallback_sidx) {
6303 av_log(c->fc, AV_LOG_DEBUG, "use_tfdt set but no tfdt found, using sidx instead\n");
6304 }
6305 if (fallback_tfdt) {
6306 av_log(c->fc, AV_LOG_DEBUG, "use_tfdt not set but no sidx found, using tfdt instead\n");
6307 }
6308
6309 if (has_tfdt && c->use_tfdt || fallback_tfdt) {
6310 dts = frag_stream_info->tfdt_dts - sc->time_offset;
6311 av_log(c->fc, AV_LOG_DEBUG, "found tfdt time %"PRId64
6312 ", using it for dts\n", dts);
6313 } else if (has_sidx && !c->use_tfdt || fallback_sidx) {
6314 // FIXME: sidx earliest_presentation_time is *PTS*, s.b.
6315 // pts = frag_stream_info->sidx_pts;
6316 dts = frag_stream_info->sidx_pts;
6317 av_log(c->fc, AV_LOG_DEBUG, "found sidx time %"PRId64
6318 ", using it for dts\n", frag_stream_info->sidx_pts);
6319 } else {
6320 dts = sc->track_end - sc->time_offset;
6321 av_log(c->fc, AV_LOG_DEBUG, "found track end time %"PRId64
6322 ", using it for dts\n", dts);
6323 }
6324 }
6325 } else {
6326 dts = sc->track_end - sc->time_offset;
6327 av_log(c->fc, AV_LOG_DEBUG, "found track end time %"PRId64
6328 ", using it for dts\n", dts);
6329 }
6330 offset = frag->base_data_offset + data_offset;
6331 distance = 0;
6332 av_log(c->fc, AV_LOG_TRACE, "first sample flags 0x%x\n", first_sample_flags);
6333
6334 // realloc space for new index entries
6335 if ((uint64_t)sti->nb_index_entries + entries >= UINT_MAX / sizeof(AVIndexEntry)) {
6336 entries = UINT_MAX / sizeof(AVIndexEntry) - sti->nb_index_entries;
6337 av_log(c->fc, AV_LOG_ERROR, "Failed to add index entry\n");
6338 }
6339 if (entries == 0)
6340 return 0;
6341
6342 requested_size = (sti->nb_index_entries + entries) * sizeof(AVIndexEntry);
6343 new_entries = av_fast_realloc(sti->index_entries,
6345 requested_size);
6346 if (!new_entries)
6347 return AVERROR(ENOMEM);
6348 sti->index_entries= new_entries;
6349
6350 requested_size = (sti->nb_index_entries + entries) * sizeof(*sc->tts_data);
6351 old_allocated_size = sc->tts_allocated_size;
6352 tts_data = av_fast_realloc(sc->tts_data, &sc->tts_allocated_size,
6353 requested_size);
6354 if (!tts_data)
6355 return AVERROR(ENOMEM);
6356 sc->tts_data = tts_data;
6357
6358 // In case there were samples without time to sample entries, ensure they get
6359 // zero valued entries. This ensures clips which mix boxes with and
6360 // without time to sample entries don't pickup uninitialized data.
6361 memset((uint8_t*)(sc->tts_data) + old_allocated_size, 0,
6362 sc->tts_allocated_size - old_allocated_size);
6363
6364 if (index_entry_pos < sti->nb_index_entries) {
6365 // Make hole in index_entries and tts_data for new samples
6366 memmove(sti->index_entries + index_entry_pos + entries,
6367 sti->index_entries + index_entry_pos,
6368 sizeof(*sti->index_entries) *
6369 (sti->nb_index_entries - index_entry_pos));
6370 memmove(sc->tts_data + index_entry_pos + entries,
6371 sc->tts_data + index_entry_pos,
6372 sizeof(*sc->tts_data) * (sc->tts_count - index_entry_pos));
6373 if (index_entry_pos < sc->current_sample) {
6374 sc->current_sample += entries;
6375 }
6376 }
6377
6378 sti->nb_index_entries += entries;
6379 sc->tts_count = sti->nb_index_entries;
6380 sc->stts_count = sti->nb_index_entries;
6382 sc->ctts_count = sti->nb_index_entries;
6383
6384 // Record the index_entry position in frag_index of this fragment
6385 if (frag_stream_info) {
6386 frag_stream_info->index_entry = index_entry_pos;
6387 if (frag_stream_info->index_base < 0)
6388 frag_stream_info->index_base = index_entry_pos;
6389 }
6390
6391 if (index_entry_pos > 0)
6392 prev_dts = sti->index_entries[index_entry_pos-1].timestamp;
6393
6394 for (i = 0; i < entries && !pb->eof_reached; i++) {
6395 unsigned sample_size = frag->size;
6396 int sample_flags = i ? frag->flags : first_sample_flags;
6397 unsigned sample_duration = frag->duration;
6398 unsigned ctts_duration = 0;
6399 int keyframe = 0;
6400 int index_entry_flags = 0;
6401
6402 if (flags & MOV_TRUN_SAMPLE_DURATION) sample_duration = avio_rb32(pb);
6403 if (flags & MOV_TRUN_SAMPLE_SIZE) sample_size = avio_rb32(pb);
6404 if (flags & MOV_TRUN_SAMPLE_FLAGS) sample_flags = avio_rb32(pb);
6405 if (flags & MOV_TRUN_SAMPLE_CTS) ctts_duration = avio_rb32(pb);
6406
6407 mov_update_dts_shift(sc, ctts_duration, c->fc);
6408 if (pts != AV_NOPTS_VALUE) {
6409 dts = pts - sc->dts_shift;
6410 if (flags & MOV_TRUN_SAMPLE_CTS) {
6411 dts -= ctts_duration;
6412 } else {
6413 dts -= sc->time_offset;
6414 }
6415 av_log(c->fc, AV_LOG_DEBUG,
6416 "pts %"PRId64" calculated dts %"PRId64
6417 " sc->dts_shift %d ctts.duration %d"
6418 " sc->time_offset %"PRId64
6419 " flags & MOV_TRUN_SAMPLE_CTS %d\n",
6420 pts, dts,
6421 sc->dts_shift, ctts_duration,
6424 }
6425
6426 keyframe =
6427 !(sample_flags & (MOV_FRAG_SAMPLE_FLAG_IS_NON_SYNC |
6429 if (keyframe) {
6430 distance = 0;
6431 index_entry_flags |= AVINDEX_KEYFRAME;
6432 }
6433 // Fragments can overlap in time. Discard overlapping frames after
6434 // decoding.
6435 if (prev_dts >= dts)
6436 index_entry_flags |= AVINDEX_DISCARD_FRAME;
6437
6438 sti->index_entries[index_entry_pos].pos = offset;
6439 sti->index_entries[index_entry_pos].timestamp = dts;
6440 sti->index_entries[index_entry_pos].size = sample_size;
6441 sti->index_entries[index_entry_pos].min_distance = distance;
6442 sti->index_entries[index_entry_pos].flags = index_entry_flags;
6443
6444 sc->tts_data[index_entry_pos].count = 1;
6445 sc->tts_data[index_entry_pos].offset = ctts_duration;
6446 sc->tts_data[index_entry_pos].duration = sample_duration;
6447 index_entry_pos++;
6448
6449 av_log(c->fc, AV_LOG_TRACE, "AVIndex stream %d, sample %d, offset %"PRIx64", dts %"PRId64", "
6450 "size %u, distance %d, keyframe %d\n", st->index,
6451 index_entry_pos, offset, dts, sample_size, distance, keyframe);
6452 distance++;
6453 if (av_sat_add64(dts, sample_duration) != dts + (uint64_t)sample_duration)
6454 return AVERROR_INVALIDDATA;
6455 if (!sample_size)
6456 return AVERROR_INVALIDDATA;
6457 dts += sample_duration;
6458 offset += sample_size;
6459 sc->data_size += sample_size;
6460
6461 if (sample_duration <= INT64_MAX - sc->duration_for_fps &&
6462 1 <= INT_MAX - sc->nb_frames_for_fps
6463 ) {
6464 sc->duration_for_fps += sample_duration;
6465 sc->nb_frames_for_fps ++;
6466 }
6467 }
6468 if (frag_stream_info)
6469 frag_stream_info->next_trun_dts = dts + sc->time_offset;
6470 if (i < entries) {
6471 // EOF found before reading all entries. Fix the hole this would
6472 // leave in index_entries and tts_data
6473 int gap = entries - i;
6474 memmove(sti->index_entries + index_entry_pos,
6475 sti->index_entries + index_entry_pos + gap,
6476 sizeof(*sti->index_entries) *
6477 (sti->nb_index_entries - (index_entry_pos + gap)));
6478 memmove(sc->tts_data + index_entry_pos,
6479 sc->tts_data + index_entry_pos + gap,
6480 sizeof(*sc->tts_data) *
6481 (sc->tts_count - (index_entry_pos + gap)));
6482
6483 sti->nb_index_entries -= gap;
6484 sc->tts_count -= gap;
6485 if (index_entry_pos < sc->current_sample) {
6486 sc->current_sample -= gap;
6487 }
6488 entries = i;
6489 }
6490
6491 // The end of this new fragment may overlap in time with the start
6492 // of the next fragment in index_entries. Mark the samples in the next
6493 // fragment that overlap with AVINDEX_DISCARD_FRAME
6494 prev_dts = AV_NOPTS_VALUE;
6495 if (index_entry_pos > 0)
6496 prev_dts = sti->index_entries[index_entry_pos-1].timestamp;
6497 for (int i = index_entry_pos; i < sti->nb_index_entries; i++) {
6498 if (prev_dts < sti->index_entries[i].timestamp)
6499 break;
6501 }
6502
6503 // If a hole was created to insert the new index_entries into,
6504 // the index_entry recorded for all subsequent moof must
6505 // be incremented by the number of entries inserted.
6506 fix_frag_index_entries(&c->frag_index, next_frag_index,
6507 frag->track_id, entries);
6508
6509 if (pb->eof_reached) {
6510 av_log(c->fc, AV_LOG_WARNING, "reached eof, corrupted TRUN atom\n");
6511 return AVERROR_EOF;
6512 }
6513
6514 frag->implicit_offset = offset;
6515
6516 sc->track_end = dts + sc->time_offset;
6517 if (st->duration < sc->track_end)
6518 st->duration = sc->track_end;
6519
6520 return 0;
6521}
6522
6524{
6525 int64_t stream_size = avio_size(pb);
6526 int64_t offset = av_sat_add64(avio_tell(pb), atom.size), pts, timestamp;
6527 uint8_t version, is_complete;
6528 int64_t offadd;
6529 unsigned i, j, track_id, item_count;
6530 AVStream *st = NULL;
6531 AVStream *ref_st = NULL;
6532 MOVStreamContext *sc, *ref_sc = NULL;
6533 AVRational timescale;
6534
6535 version = avio_r8(pb);
6536 if (version > 1) {
6537 avpriv_request_sample(c->fc, "sidx version %u", version);
6538 return 0;
6539 }
6540
6541 avio_rb24(pb); // flags
6542
6543 track_id = avio_rb32(pb); // Reference ID
6544 for (i = 0; i < c->fc->nb_streams; i++) {
6545 sc = c->fc->streams[i]->priv_data;
6546 if (sc->id == track_id) {
6547 st = c->fc->streams[i];
6548 break;
6549 }
6550 }
6551 if (!st) {
6552 av_log(c->fc, AV_LOG_WARNING, "could not find corresponding track id %d\n", track_id);
6553 return 0;
6554 }
6555
6556 sc = st->priv_data;
6557
6558 timescale = av_make_q(1, avio_rb32(pb));
6559
6560 if (timescale.den <= 0) {
6561 av_log(c->fc, AV_LOG_ERROR, "Invalid sidx timescale 1/%d\n", timescale.den);
6562 return AVERROR_INVALIDDATA;
6563 }
6564
6565 if (version == 0) {
6566 pts = avio_rb32(pb);
6567 offadd= avio_rb32(pb);
6568 } else {
6569 pts = avio_rb64(pb);
6570 offadd= avio_rb64(pb);
6571 }
6572 if (av_sat_add64(offset, offadd) != offset + (uint64_t)offadd)
6573 return AVERROR_INVALIDDATA;
6574
6575 offset += (uint64_t)offadd;
6576
6577 avio_rb16(pb); // reserved
6578
6579 item_count = avio_rb16(pb);
6580 if (item_count == 0)
6581 return AVERROR_INVALIDDATA;
6582
6583 for (i = 0; i < item_count; i++) {
6584 int index;
6585 MOVFragmentStreamInfo * frag_stream_info;
6586 uint32_t size = avio_rb32(pb);
6587 uint32_t duration = avio_rb32(pb);
6588 if (size & 0x80000000) {
6589 avpriv_request_sample(c->fc, "sidx reference_type 1");
6590 return AVERROR_PATCHWELCOME;
6591 }
6592 avio_rb32(pb); // sap_flags
6593 timestamp = av_rescale_q(pts, timescale, st->time_base);
6594
6596 frag_stream_info = get_frag_stream_info(&c->frag_index, index, track_id);
6597 if (frag_stream_info)
6598 frag_stream_info->sidx_pts = timestamp;
6599
6600 if (av_sat_add64(offset, size) != offset + (uint64_t)size ||
6601 av_sat_add64(pts, duration) != pts + (uint64_t)duration
6602 )
6603 return AVERROR_INVALIDDATA;
6604 offset += size;
6605 pts += duration;
6606 }
6607
6608 st->duration = sc->track_end = pts;
6609
6610 sc->has_sidx = 1;
6611
6612 // See if the remaining bytes are just an mfra which we can ignore.
6613 is_complete = offset == stream_size;
6614 if (!is_complete && (pb->seekable & AVIO_SEEKABLE_NORMAL) && stream_size > 0 ) {
6615 int64_t ret;
6616 int64_t original_pos = avio_tell(pb);
6617 if (!c->have_read_mfra_size) {
6618 if ((ret = avio_seek(pb, stream_size - 4, SEEK_SET)) < 0)
6619 return ret;
6620 c->mfra_size = avio_rb32(pb);
6621 c->have_read_mfra_size = 1;
6622 if ((ret = avio_seek(pb, original_pos, SEEK_SET)) < 0)
6623 return ret;
6624 }
6625 if (offset == stream_size - c->mfra_size)
6626 is_complete = 1;
6627 }
6628
6629 if (is_complete) {
6630 // Find first entry in fragment index that came from an sidx.
6631 // This will pretty much always be the first entry.
6632 for (i = 0; i < c->frag_index.nb_items; i++) {
6633 MOVFragmentIndexItem * item = &c->frag_index.item[i];
6634 for (j = 0; ref_st == NULL && j < item->nb_stream_info; j++) {
6636 si = &item->stream_info[j];
6637 if (si->sidx_pts != AV_NOPTS_VALUE) {
6638 ref_st = c->fc->streams[j];
6639 ref_sc = ref_st->priv_data;
6640 break;
6641 }
6642 }
6643 }
6644 if (ref_st) for (i = 0; i < c->fc->nb_streams; i++) {
6645 st = c->fc->streams[i];
6646 sc = st->priv_data;
6647 if (!sc->has_sidx) {
6648 st->duration = sc->track_end = av_rescale(ref_st->duration, sc->time_scale, ref_sc->time_scale);
6649 }
6650 }
6651
6652 if (offadd == 0)
6653 c->frag_index.complete = 1;
6654 }
6655
6656 return 0;
6657}
6658
6659/* this atom should be null (from specs), but some buggy files put the 'moov' atom inside it... */
6660/* like the files created with Adobe Premiere 5.0, for samples see */
6661/* http://graphics.tudelft.nl/~wouter/publications/soundtests/ */
6663{
6664 int err;
6665
6666 if (atom.size < 8)
6667 return 0; /* continue */
6668 if (avio_rb32(pb) != 0) { /* 0 sized mdat atom... use the 'wide' atom size */
6669 avio_skip(pb, atom.size - 4);
6670 return 0;
6671 }
6672 atom.type = avio_rl32(pb);
6673 atom.size -= 8;
6674 if (atom.type != MKTAG('m','d','a','t')) {
6675 avio_skip(pb, atom.size);
6676 return 0;
6677 }
6678 err = mov_read_mdat(c, pb, atom);
6679 return err;
6680}
6681
6683{
6684#if CONFIG_ZLIB
6686 uint8_t *cmov_data;
6687 uint8_t *moov_data; /* uncompressed data */
6688 long cmov_len, moov_len;
6689 int ret = -1;
6690
6691 avio_rb32(pb); /* dcom atom */
6692 if (avio_rl32(pb) != MKTAG('d','c','o','m'))
6693 return AVERROR_INVALIDDATA;
6694 if (avio_rl32(pb) != MKTAG('z','l','i','b')) {
6695 av_log(c->fc, AV_LOG_ERROR, "unknown compression for cmov atom !\n");
6696 return AVERROR_INVALIDDATA;
6697 }
6698 avio_rb32(pb); /* cmvd atom */
6699 if (avio_rl32(pb) != MKTAG('c','m','v','d'))
6700 return AVERROR_INVALIDDATA;
6701 moov_len = avio_rb32(pb); /* uncompressed size */
6702 cmov_len = atom.size - 6 * 4;
6703
6704 cmov_data = av_malloc(cmov_len);
6705 if (!cmov_data)
6706 return AVERROR(ENOMEM);
6707 moov_data = av_malloc(moov_len);
6708 if (!moov_data) {
6709 av_free(cmov_data);
6710 return AVERROR(ENOMEM);
6711 }
6712 ret = ffio_read_size(pb, cmov_data, cmov_len);
6713 if (ret < 0)
6714 goto free_and_return;
6715
6716 ret = AVERROR_INVALIDDATA;
6717 if (uncompress (moov_data, (uLongf *) &moov_len, (const Bytef *)cmov_data, cmov_len) != Z_OK)
6718 goto free_and_return;
6719 ffio_init_read_context(&ctx, moov_data, moov_len);
6720 ctx.pub.seekable = AVIO_SEEKABLE_NORMAL;
6721 atom.type = MKTAG('m','o','o','v');
6722 atom.size = moov_len;
6723 ret = mov_read_default(c, &ctx.pub, atom);
6724free_and_return:
6725 av_free(moov_data);
6726 av_free(cmov_data);
6727 return ret;
6728#else
6729 av_log(c->fc, AV_LOG_ERROR, "this file requires zlib support compiled in\n");
6730 return AVERROR(ENOSYS);
6731#endif
6732}
6733
6734/* edit list atom */
6736{
6737 MOVStreamContext *sc;
6738 int i, edit_count, version;
6739 int64_t elst_entry_size;
6740
6741 if (c->fc->nb_streams < 1 || c->ignore_editlist)
6742 return 0;
6743 sc = c->fc->streams[c->fc->nb_streams-1]->priv_data;
6744
6745 version = avio_r8(pb); /* version */
6746 avio_rb24(pb); /* flags */
6747 edit_count = avio_rb32(pb); /* entries */
6748 atom.size -= 8;
6749
6750 elst_entry_size = version == 1 ? 20 : 12;
6751 if (atom.size != edit_count * elst_entry_size) {
6752 if (c->fc->strict_std_compliance >= FF_COMPLIANCE_STRICT) {
6753 av_log(c->fc, AV_LOG_ERROR, "Invalid edit list entry_count: %d for elst atom of size: %"PRId64" bytes.\n",
6754 edit_count, atom.size + 8);
6755 return AVERROR_INVALIDDATA;
6756 } else {
6757 edit_count = atom.size / elst_entry_size;
6758 if (edit_count * elst_entry_size != atom.size) {
6759 av_log(c->fc, AV_LOG_WARNING, "ELST atom of %"PRId64" bytes, bigger than %d entries.\n", atom.size, edit_count);
6760 }
6761 }
6762 }
6763
6764 if (!edit_count)
6765 return 0;
6766 if (sc->elst_data)
6767 av_log(c->fc, AV_LOG_WARNING, "Duplicated ELST atom\n");
6768 av_free(sc->elst_data);
6769 sc->elst_count = 0;
6770 sc->elst_data = av_malloc_array(edit_count, sizeof(*sc->elst_data));
6771 if (!sc->elst_data)
6772 return AVERROR(ENOMEM);
6773
6774 av_log(c->fc, AV_LOG_TRACE, "track[%u].edit_count = %i\n", c->fc->nb_streams - 1, edit_count);
6775 for (i = 0; i < edit_count && atom.size > 0 && !pb->eof_reached; i++) {
6776 MOVElst *e = &sc->elst_data[i];
6777
6778 if (version == 1) {
6779 e->duration = avio_rb64(pb);
6780 e->time = avio_rb64(pb);
6781 atom.size -= 16;
6782 } else {
6783 e->duration = avio_rb32(pb); /* segment duration */
6784 e->time = (int32_t)avio_rb32(pb); /* media time */
6785 atom.size -= 8;
6786 }
6787 e->rate = avio_rb32(pb) / 65536.0;
6788 atom.size -= 4;
6789 av_log(c->fc, AV_LOG_TRACE, "duration=%"PRId64" time=%"PRId64" rate=%f\n",
6790 e->duration, e->time, e->rate);
6791
6792 if (e->time < 0 && e->time != -1 &&
6793 c->fc->strict_std_compliance >= FF_COMPLIANCE_STRICT) {
6794 av_log(c->fc, AV_LOG_ERROR, "Track %d, edit %d: Invalid edit list media time=%"PRId64"\n",
6795 c->fc->nb_streams-1, i, e->time);
6796 return AVERROR_INVALIDDATA;
6797 }
6798 if (e->duration < 0) {
6799 av_log(c->fc, AV_LOG_ERROR, "Track %d, edit %d: Invalid edit list duration=%"PRId64"\n",
6800 c->fc->nb_streams-1, i, e->duration);
6801 return AVERROR_INVALIDDATA;
6802 }
6803 }
6804 sc->elst_count = i;
6805
6806 return 0;
6807}
6808
6810{
6811 MOVStreamContext *sc;
6812 int err;
6813
6814 if (c->fc->nb_streams < 1)
6815 return AVERROR_INVALIDDATA;
6816 sc = c->fc->streams[c->fc->nb_streams - 1]->priv_data;
6817
6818 if (atom.size % sizeof(uint32_t))
6819 return AVERROR_INVALIDDATA;
6820
6821 MovTref *tag = mov_add_tref_tag(sc, atom.type);
6822 if (!tag)
6823 return AVERROR(ENOMEM);
6824
6825 int nb_timecode_track = atom.size >> 2;
6826 for (int i = 0; i < nb_timecode_track; i++) {
6827 if (avio_feof(pb))
6828 return AVERROR_INVALIDDATA;
6829 err = mov_add_tref_id(tag, avio_rb32(pb));
6830 if (err < 0)
6831 return err;
6832 }
6833
6834 return 0;
6835}
6836
6838{
6839 AVStream *st;
6840 int version, color_range, color_primaries, color_trc, color_space;
6841
6842 if (c->fc->nb_streams < 1)
6843 return 0;
6844 st = c->fc->streams[c->fc->nb_streams - 1];
6845
6846 if (atom.size < 5) {
6847 av_log(c->fc, AV_LOG_ERROR, "Empty VP Codec Configuration box\n");
6848 return AVERROR_INVALIDDATA;
6849 }
6850
6851 version = avio_r8(pb);
6852 if (version != 1) {
6853 av_log(c->fc, AV_LOG_WARNING, "Unsupported VP Codec Configuration box version %d\n", version);
6854 return 0;
6855 }
6856 avio_skip(pb, 3); /* flags */
6857
6858 avio_skip(pb, 2); /* profile + level */
6859 color_range = avio_r8(pb); /* bitDepth, chromaSubsampling, videoFullRangeFlag */
6861 color_trc = avio_r8(pb);
6862 color_space = avio_r8(pb);
6863 if (avio_rb16(pb)) /* codecIntializationDataSize */
6864 return AVERROR_INVALIDDATA;
6865
6868 if (!av_color_transfer_name(color_trc))
6869 color_trc = AVCOL_TRC_UNSPECIFIED;
6870 if (!av_color_space_name(color_space))
6871 color_space = AVCOL_SPC_UNSPECIFIED;
6872
6875 st->codecpar->color_trc = color_trc;
6876 st->codecpar->color_space = color_space;
6877
6878 return 0;
6879}
6880
6882{
6883 MOVStreamContext *sc;
6884 int i, version;
6885
6886 if (c->fc->nb_streams < 1)
6887 return AVERROR_INVALIDDATA;
6888
6889 sc = c->fc->streams[c->fc->nb_streams - 1]->priv_data;
6890
6891 if (atom.size < 5) {
6892 av_log(c->fc, AV_LOG_ERROR, "Empty Mastering Display Metadata box\n");
6893 return AVERROR_INVALIDDATA;
6894 }
6895
6896 version = avio_r8(pb);
6897 if (version) {
6898 av_log(c->fc, AV_LOG_WARNING, "Unsupported Mastering Display Metadata box version %d\n", version);
6899 return 0;
6900 }
6901 if (sc->mastering) {
6902 av_log(c->fc, AV_LOG_WARNING, "Ignoring duplicate Mastering Display Metadata\n");
6903 return 0;
6904 }
6905
6906 avio_skip(pb, 3); /* flags */
6907
6909 if (!sc->mastering)
6910 return AVERROR(ENOMEM);
6911
6912 for (i = 0; i < 3; i++) {
6913 sc->mastering->display_primaries[i][0] = av_make_q(avio_rb16(pb), 1 << 16);
6914 sc->mastering->display_primaries[i][1] = av_make_q(avio_rb16(pb), 1 << 16);
6915 }
6916 sc->mastering->white_point[0] = av_make_q(avio_rb16(pb), 1 << 16);
6917 sc->mastering->white_point[1] = av_make_q(avio_rb16(pb), 1 << 16);
6918
6919 sc->mastering->max_luminance = av_make_q(avio_rb32(pb), 1 << 8);
6920 sc->mastering->min_luminance = av_make_q(avio_rb32(pb), 1 << 14);
6921
6922 sc->mastering->has_primaries = 1;
6923 sc->mastering->has_luminance = 1;
6924
6925 return 0;
6926}
6927
6929{
6930 MOVStreamContext *sc;
6931 const int mapping[3] = {1, 2, 0};
6932 const int chroma_den = 50000;
6933 const int luma_den = 10000;
6934 int i;
6935
6936 if (c->fc->nb_streams < 1)
6937 return AVERROR_INVALIDDATA;
6938
6939 sc = c->fc->streams[c->fc->nb_streams - 1]->priv_data;
6940
6941 if (atom.size < 24) {
6942 av_log(c->fc, AV_LOG_ERROR, "Invalid Mastering Display Color Volume box\n");
6943 return AVERROR_INVALIDDATA;
6944 }
6945
6946 if (sc->mastering) {
6947 av_log(c->fc, AV_LOG_WARNING, "Ignoring duplicate Mastering Display Color Volume\n");
6948 return 0;
6949 }
6950
6952 if (!sc->mastering)
6953 return AVERROR(ENOMEM);
6954
6955 for (i = 0; i < 3; i++) {
6956 const int j = mapping[i];
6957 sc->mastering->display_primaries[j][0] = av_make_q(avio_rb16(pb), chroma_den);
6958 sc->mastering->display_primaries[j][1] = av_make_q(avio_rb16(pb), chroma_den);
6959 }
6960 sc->mastering->white_point[0] = av_make_q(avio_rb16(pb), chroma_den);
6961 sc->mastering->white_point[1] = av_make_q(avio_rb16(pb), chroma_den);
6962
6963 sc->mastering->max_luminance = av_make_q(avio_rb32(pb), luma_den);
6964 sc->mastering->min_luminance = av_make_q(avio_rb32(pb), luma_den);
6965
6966 sc->mastering->has_luminance = 1;
6967 sc->mastering->has_primaries = 1;
6968
6969 return 0;
6970}
6971
6973{
6974 MOVStreamContext *sc;
6975 int version;
6976
6977 if (c->fc->nb_streams < 1)
6978 return AVERROR_INVALIDDATA;
6979
6980 sc = c->fc->streams[c->fc->nb_streams - 1]->priv_data;
6981
6982 if (atom.size < 5) {
6983 av_log(c->fc, AV_LOG_ERROR, "Empty Content Light Level box\n");
6984 return AVERROR_INVALIDDATA;
6985 }
6986
6987 version = avio_r8(pb);
6988 if (version) {
6989 av_log(c->fc, AV_LOG_WARNING, "Unsupported Content Light Level box version %d\n", version);
6990 return 0;
6991 }
6992 avio_skip(pb, 3); /* flags */
6993
6994 if (sc->coll){
6995 av_log(c->fc, AV_LOG_WARNING, "Ignoring duplicate COLL\n");
6996 return 0;
6997 }
6998
7000 if (!sc->coll)
7001 return AVERROR(ENOMEM);
7002
7003 sc->coll->MaxCLL = avio_rb16(pb);
7004 sc->coll->MaxFALL = avio_rb16(pb);
7005
7006 return 0;
7007}
7008
7010{
7011 MOVStreamContext *sc;
7012
7013 if (c->fc->nb_streams < 1)
7014 return AVERROR_INVALIDDATA;
7015
7016 sc = c->fc->streams[c->fc->nb_streams - 1]->priv_data;
7017
7018 if (atom.size < 4) {
7019 av_log(c->fc, AV_LOG_ERROR, "Empty Content Light Level Info box\n");
7020 return AVERROR_INVALIDDATA;
7021 }
7022
7023 if (sc->coll){
7024 av_log(c->fc, AV_LOG_WARNING, "Ignoring duplicate CLLI/COLL\n");
7025 return 0;
7026 }
7027
7029 if (!sc->coll)
7030 return AVERROR(ENOMEM);
7031
7032 sc->coll->MaxCLL = avio_rb16(pb);
7033 sc->coll->MaxFALL = avio_rb16(pb);
7034
7035 return 0;
7036}
7037
7039{
7040 MOVStreamContext *sc;
7041 const int illuminance_den = 10000;
7042 const int ambient_den = 50000;
7043 if (c->fc->nb_streams < 1)
7044 return AVERROR_INVALIDDATA;
7045 sc = c->fc->streams[c->fc->nb_streams - 1]->priv_data;
7046 if (atom.size < 6) {
7047 av_log(c->fc, AV_LOG_ERROR, "Empty Ambient Viewing Environment Info box\n");
7048 return AVERROR_INVALIDDATA;
7049 }
7050 if (sc->ambient){
7051 av_log(c->fc, AV_LOG_WARNING, "Ignoring duplicate AMVE\n");
7052 return 0;
7053 }
7055 if (!sc->ambient)
7056 return AVERROR(ENOMEM);
7057 sc->ambient->ambient_illuminance = av_make_q(avio_rb32(pb), illuminance_den);
7058 sc->ambient->ambient_light_x = av_make_q(avio_rb16(pb), ambient_den);
7059 sc->ambient->ambient_light_y = av_make_q(avio_rb16(pb), ambient_den);
7060 return 0;
7061}
7062
7064{
7065 AVStream *st;
7066 MOVStreamContext *sc;
7067 enum AVStereo3DType type;
7068 int mode;
7069
7070 if (c->fc->nb_streams < 1)
7071 return 0;
7072
7073 st = c->fc->streams[c->fc->nb_streams - 1];
7074 sc = st->priv_data;
7075
7076 if (atom.size < 5) {
7077 av_log(c->fc, AV_LOG_ERROR, "Empty stereoscopic video box\n");
7078 return AVERROR_INVALIDDATA;
7079 }
7080
7081 if (sc->stereo3d)
7082 return AVERROR_INVALIDDATA;
7083
7084 avio_skip(pb, 4); /* version + flags */
7085
7086 mode = avio_r8(pb);
7087 switch (mode) {
7088 case 0:
7090 break;
7091 case 1:
7093 break;
7094 case 2:
7096 break;
7097 default:
7098 av_log(c->fc, AV_LOG_WARNING, "Unknown st3d mode value %d\n", mode);
7099 return 0;
7100 }
7101
7103 if (!sc->stereo3d)
7104 return AVERROR(ENOMEM);
7105
7106 sc->stereo3d->type = type;
7107 return 0;
7108}
7109
7111{
7112 AVStream *st;
7113 MOVStreamContext *sc;
7114 int size = 0;
7115 int64_t remaining;
7116 uint32_t tag = 0;
7118
7119 if (c->fc->nb_streams < 1)
7120 return 0;
7121
7122 st = c->fc->streams[c->fc->nb_streams - 1];
7123 sc = st->priv_data;
7124
7125 remaining = atom.size;
7126 while (remaining > 0) {
7127 size = avio_rb32(pb);
7128 if (size < 8 || size > remaining ) {
7129 av_log(c->fc, AV_LOG_ERROR, "Invalid child size in pack box\n");
7130 return AVERROR_INVALIDDATA;
7131 }
7132
7133 tag = avio_rl32(pb);
7134 switch (tag) {
7135 case MKTAG('p','k','i','n'): {
7136 if (size != 16) {
7137 av_log(c->fc, AV_LOG_ERROR, "Invalid size of pkin box: %d\n", size);
7138 return AVERROR_INVALIDDATA;
7139 }
7140 avio_skip(pb, 1); // version
7141 avio_skip(pb, 3); // flags
7142
7143 tag = avio_rl32(pb);
7144 switch (tag) {
7145 case MKTAG('s','i','d','e'):
7147 break;
7148 case MKTAG('o','v','e','r'):
7150 break;
7151 case 0:
7152 // This means value will be set in another layer
7153 break;
7154 default:
7155 av_log(c->fc, AV_LOG_WARNING, "Unknown tag in pkin: %s\n",
7157 avio_skip(pb, size - 8);
7158 break;
7159 }
7160
7161 break;
7162 }
7163 default:
7164 av_log(c->fc, AV_LOG_WARNING, "Unknown tag in pack: %s\n",
7166 avio_skip(pb, size - 8);
7167 break;
7168 }
7169 remaining -= size;
7170 }
7171
7172 if (remaining != 0) {
7173 av_log(c->fc, AV_LOG_ERROR, "Broken pack box\n");
7174 return AVERROR_INVALIDDATA;
7175 }
7176
7177 if (type == AV_STEREO3D_2D)
7178 return 0;
7179
7180 if (!sc->stereo3d) {
7182 if (!sc->stereo3d)
7183 return AVERROR(ENOMEM);
7184 }
7185
7186 sc->stereo3d->type = type;
7187
7188 return 0;
7189}
7190
7192{
7193 AVStream *st;
7194 MOVStreamContext *sc;
7195 int size, version, layout;
7196 int32_t yaw, pitch, roll;
7197 uint32_t l = 0, t = 0, r = 0, b = 0;
7198 uint32_t tag, padding = 0;
7199 enum AVSphericalProjection projection;
7200
7201 if (c->fc->nb_streams < 1)
7202 return 0;
7203
7204 st = c->fc->streams[c->fc->nb_streams - 1];
7205 sc = st->priv_data;
7206
7207 if (atom.size < 8) {
7208 av_log(c->fc, AV_LOG_ERROR, "Empty spherical video box\n");
7209 return AVERROR_INVALIDDATA;
7210 }
7211
7212 size = avio_rb32(pb);
7213 if (size <= 12 || size > atom.size)
7214 return AVERROR_INVALIDDATA;
7215
7216 tag = avio_rl32(pb);
7217 if (tag != MKTAG('s','v','h','d')) {
7218 av_log(c->fc, AV_LOG_ERROR, "Missing spherical video header\n");
7219 return 0;
7220 }
7221 version = avio_r8(pb);
7222 if (version != 0) {
7223 av_log(c->fc, AV_LOG_WARNING, "Unknown spherical version %d\n",
7224 version);
7225 return 0;
7226 }
7227 avio_skip(pb, 3); /* flags */
7228 avio_skip(pb, size - 12); /* metadata_source */
7229
7230 size = avio_rb32(pb);
7231 if (size > atom.size)
7232 return AVERROR_INVALIDDATA;
7233
7234 tag = avio_rl32(pb);
7235 if (tag != MKTAG('p','r','o','j')) {
7236 av_log(c->fc, AV_LOG_ERROR, "Missing projection box\n");
7237 return 0;
7238 }
7239
7240 size = avio_rb32(pb);
7241 if (size > atom.size)
7242 return AVERROR_INVALIDDATA;
7243
7244 tag = avio_rl32(pb);
7245 if (tag != MKTAG('p','r','h','d')) {
7246 av_log(c->fc, AV_LOG_ERROR, "Missing projection header box\n");
7247 return 0;
7248 }
7249 version = avio_r8(pb);
7250 if (version != 0) {
7251 av_log(c->fc, AV_LOG_WARNING, "Unknown spherical version %d\n",
7252 version);
7253 return 0;
7254 }
7255 avio_skip(pb, 3); /* flags */
7256
7257 /* 16.16 fixed point */
7258 yaw = avio_rb32(pb);
7259 pitch = avio_rb32(pb);
7260 roll = avio_rb32(pb);
7261
7262 size = avio_rb32(pb);
7263 if (size > atom.size)
7264 return AVERROR_INVALIDDATA;
7265
7266 tag = avio_rl32(pb);
7267 version = avio_r8(pb);
7268 if (version != 0) {
7269 av_log(c->fc, AV_LOG_WARNING, "Unknown spherical version %d\n",
7270 version);
7271 return 0;
7272 }
7273 avio_skip(pb, 3); /* flags */
7274 switch (tag) {
7275 case MKTAG('c','b','m','p'):
7276 layout = avio_rb32(pb);
7277 if (layout) {
7278 av_log(c->fc, AV_LOG_WARNING,
7279 "Unsupported cubemap layout %d\n", layout);
7280 return 0;
7281 }
7282 projection = AV_SPHERICAL_CUBEMAP;
7283 padding = avio_rb32(pb);
7284 break;
7285 case MKTAG('e','q','u','i'):
7286 t = avio_rb32(pb);
7287 b = avio_rb32(pb);
7288 l = avio_rb32(pb);
7289 r = avio_rb32(pb);
7290
7291 if (b >= UINT_MAX - t || r >= UINT_MAX - l) {
7292 av_log(c->fc, AV_LOG_ERROR,
7293 "Invalid bounding rectangle coordinates "
7294 "%"PRIu32",%"PRIu32",%"PRIu32",%"PRIu32"\n", l, t, r, b);
7295 return AVERROR_INVALIDDATA;
7296 }
7297
7298 if (l || t || r || b)
7300 else
7301 projection = AV_SPHERICAL_EQUIRECTANGULAR;
7302 break;
7303 default:
7304 av_log(c->fc, AV_LOG_ERROR, "Unknown projection type: %s\n", av_fourcc2str(tag));
7305 return 0;
7306 }
7307
7309 if (!sc->spherical)
7310 return AVERROR(ENOMEM);
7311
7312 sc->spherical->projection = projection;
7313
7314 sc->spherical->yaw = yaw;
7315 sc->spherical->pitch = pitch;
7316 sc->spherical->roll = roll;
7317
7318 sc->spherical->padding = padding;
7319
7320 sc->spherical->bound_left = l;
7321 sc->spherical->bound_top = t;
7322 sc->spherical->bound_right = r;
7323 sc->spherical->bound_bottom = b;
7324
7325 return 0;
7326}
7327
7329{
7330 AVStream *st;
7331 MOVStreamContext *sc;
7332 int size;
7333 uint32_t tag;
7334 enum AVSphericalProjection projection;
7335
7336 if (c->fc->nb_streams < 1)
7337 return 0;
7338
7339 st = c->fc->streams[c->fc->nb_streams - 1];
7340 sc = st->priv_data;
7341
7342 if (atom.size < 16) {
7343 av_log(c->fc, AV_LOG_ERROR, "Invalid size for proj box: %"PRIu64"\n", atom.size);
7344 return AVERROR_INVALIDDATA;
7345 }
7346
7347 size = avio_rb32(pb);
7348 if (size < 16) {
7349 av_log(c->fc, AV_LOG_ERROR, "Invalid size for prji box: %d\n", size);
7350 return AVERROR_INVALIDDATA;
7351 } else if (size > 16) {
7352 av_log(c->fc, AV_LOG_WARNING, "Box has more bytes (%d) than prji box required (16) \n", size);
7353 }
7354
7355 tag = avio_rl32(pb);
7356 if (tag != MKTAG('p','r','j','i')) {
7357 av_log(c->fc, AV_LOG_ERROR, "Invalid child box of proj box: %s\n",
7359 return AVERROR_INVALIDDATA;
7360 }
7361
7362 // version and flags, only support (0, 0)
7363 unsigned n = avio_rl32(pb);
7364 if (n != 0) {
7365 av_log(c->fc, AV_LOG_ERROR, "prji version %u, flag %u are not supported\n",
7366 n & 0xFF, n >> 8);
7367 return AVERROR_PATCHWELCOME;
7368 }
7369
7370 tag = avio_rl32(pb);
7371 switch (tag) {
7372 case MKTAG('r','e','c','t'):
7373 projection = AV_SPHERICAL_RECTILINEAR;
7374 break;
7375 case MKTAG('e','q','u','i'):
7376 projection = AV_SPHERICAL_EQUIRECTANGULAR;
7377 break;
7378 case MKTAG('h','e','q','u'):
7380 break;
7381 case MKTAG('f','i','s','h'):
7382 projection = AV_SPHERICAL_FISHEYE;
7383 break;
7384 case MKTAG('p','r','i','m'):
7386 break;
7387 default:
7388 av_log(c->fc, AV_LOG_ERROR, "Invalid projection type in prji box: %s\n", av_fourcc2str(tag));
7389 return AVERROR_INVALIDDATA;
7390 }
7391
7393 if (!sc->spherical)
7394 return AVERROR(ENOMEM);
7395
7396 sc->spherical->projection = projection;
7397
7398 return 0;
7399}
7400
7402{
7403 AVStream *st;
7404 MOVStreamContext *sc;
7405 int size, flags = 0;
7406 int64_t remaining;
7407 uint32_t tag, baseline = 0;
7410 enum AVStereo3DPrimaryEye primary_eye = AV_PRIMARY_EYE_NONE;
7411 AVRational horizontal_disparity_adjustment = { 0, 1 };
7412
7413 if (c->fc->nb_streams < 1)
7414 return 0;
7415
7416 st = c->fc->streams[c->fc->nb_streams - 1];
7417 sc = st->priv_data;
7418
7419 remaining = atom.size;
7420 while (remaining > 0) {
7421 size = avio_rb32(pb);
7422 if (size < 8 || size > remaining ) {
7423 av_log(c->fc, AV_LOG_ERROR, "Invalid child size in eyes box\n");
7424 return AVERROR_INVALIDDATA;
7425 }
7426
7427 tag = avio_rl32(pb);
7428 switch (tag) {
7429 case MKTAG('s','t','r','i'): {
7430 int has_right, has_left;
7431 uint8_t tmp;
7432 if (size != 13) {
7433 av_log(c->fc, AV_LOG_ERROR, "Invalid size of stri box: %d\n", size);
7434 return AVERROR_INVALIDDATA;
7435 }
7436 avio_skip(pb, 1); // version
7437 avio_skip(pb, 3); // flags
7438
7439 tmp = avio_r8(pb);
7440
7441 // eye_views_reversed
7442 if (tmp & 8) {
7444 }
7445 // has_additional_views
7446 if (tmp & 4) {
7447 // skip...
7448 }
7449
7450 has_right = tmp & 2; // has_right_eye_view
7451 has_left = tmp & 1; // has_left_eye_view
7452
7453 if (has_left && has_right)
7455 else if (has_left)
7456 view = AV_STEREO3D_VIEW_LEFT;
7457 else if (has_right)
7459 if (has_left || has_right)
7461
7462 break;
7463 }
7464 case MKTAG('h','e','r','o'): {
7465 int tmp;
7466 if (size != 13) {
7467 av_log(c->fc, AV_LOG_ERROR, "Invalid size of hero box: %d\n", size);
7468 return AVERROR_INVALIDDATA;
7469 }
7470 avio_skip(pb, 1); // version
7471 avio_skip(pb, 3); // flags
7472
7473 tmp = avio_r8(pb);
7474 if (tmp == 0)
7475 primary_eye = AV_PRIMARY_EYE_NONE;
7476 else if (tmp == 1)
7477 primary_eye = AV_PRIMARY_EYE_LEFT;
7478 else if (tmp == 2)
7479 primary_eye = AV_PRIMARY_EYE_RIGHT;
7480 else
7481 av_log(c->fc, AV_LOG_WARNING, "Unknown hero eye type: %d\n", tmp);
7482
7483 break;
7484 }
7485 case MKTAG('c','a','m','s'): {
7486 uint32_t subtag;
7487 int subsize;
7488 if (size != 24) {
7489 av_log(c->fc, AV_LOG_ERROR, "Invalid size of cams box: %d\n", size);
7490 return AVERROR_INVALIDDATA;
7491 }
7492
7493 subsize = avio_rb32(pb);
7494 if (subsize != 16) {
7495 av_log(c->fc, AV_LOG_ERROR, "Invalid size of blin box: %d\n", size);
7496 return AVERROR_INVALIDDATA;
7497 }
7498
7499 subtag = avio_rl32(pb);
7500 if (subtag != MKTAG('b','l','i','n')) {
7501 av_log(c->fc, AV_LOG_ERROR, "Expected blin box, got %s\n",
7502 av_fourcc2str(subtag));
7503 return AVERROR_INVALIDDATA;
7504 }
7505
7506 avio_skip(pb, 1); // version
7507 avio_skip(pb, 3); // flags
7508
7509 baseline = avio_rb32(pb);
7510
7511 break;
7512 }
7513 case MKTAG('c','m','f','y'): {
7514 uint32_t subtag;
7515 int subsize;
7516 int32_t adjustment;
7517 if (size != 24) {
7518 av_log(c->fc, AV_LOG_ERROR, "Invalid size of cmfy box: %d\n", size);
7519 return AVERROR_INVALIDDATA;
7520 }
7521
7522 subsize = avio_rb32(pb);
7523 if (subsize != 16) {
7524 av_log(c->fc, AV_LOG_ERROR, "Invalid size of dadj box: %d\n", size);
7525 return AVERROR_INVALIDDATA;
7526 }
7527
7528 subtag = avio_rl32(pb);
7529 if (subtag != MKTAG('d','a','d','j')) {
7530 av_log(c->fc, AV_LOG_ERROR, "Expected dadj box, got %s\n",
7531 av_fourcc2str(subtag));
7532 return AVERROR_INVALIDDATA;
7533 }
7534
7535 avio_skip(pb, 1); // version
7536 avio_skip(pb, 3); // flags
7537
7538 adjustment = (int32_t) avio_rb32(pb);
7539
7540 horizontal_disparity_adjustment.num = (int) adjustment;
7541 horizontal_disparity_adjustment.den = 10000;
7542
7543 break;
7544 }
7545 default:
7546 av_log(c->fc, AV_LOG_WARNING, "Unknown tag in eyes: %s\n",
7548 avio_skip(pb, size - 8);
7549 break;
7550 }
7551 remaining -= size;
7552 }
7553
7554 if (remaining != 0) {
7555 av_log(c->fc, AV_LOG_ERROR, "Broken eyes box\n");
7556 return AVERROR_INVALIDDATA;
7557 }
7558
7559 if (type == AV_STEREO3D_2D)
7560 return 0;
7561
7562 if (!sc->stereo3d) {
7564 if (!sc->stereo3d)
7565 return AVERROR(ENOMEM);
7566 }
7567
7568 sc->stereo3d->flags = flags;
7569 sc->stereo3d->type = type;
7570 sc->stereo3d->view = view;
7571 sc->stereo3d->primary_eye = primary_eye;
7572 sc->stereo3d->baseline = baseline;
7573 sc->stereo3d->horizontal_disparity_adjustment = horizontal_disparity_adjustment;
7574
7575 return 0;
7576}
7577
7579{
7580 int size;
7581 int64_t remaining;
7582 uint32_t tag;
7583
7584 if (c->fc->nb_streams < 1)
7585 return 0;
7586
7587 if (atom.size < 8) {
7588 av_log(c->fc, AV_LOG_ERROR, "Empty video extension usage box\n");
7589 return AVERROR_INVALIDDATA;
7590 }
7591
7592 remaining = atom.size;
7593 while (remaining > 0) {
7594 size = avio_rb32(pb);
7595 if (size < 8 || size > remaining ) {
7596 av_log(c->fc, AV_LOG_ERROR, "Invalid child size in vexu box\n");
7597 return AVERROR_INVALIDDATA;
7598 }
7599
7600 tag = avio_rl32(pb);
7601 switch (tag) {
7602 case MKTAG('p','r','o','j'): {
7603 MOVAtom proj = { tag, size - 8 };
7604 int ret = mov_read_vexu_proj(c, pb, proj);
7605 if (ret < 0)
7606 return ret;
7607 break;
7608 }
7609 case MKTAG('e','y','e','s'): {
7610 MOVAtom eyes = { tag, size - 8 };
7611 int ret = mov_read_eyes(c, pb, eyes);
7612 if (ret < 0)
7613 return ret;
7614 break;
7615 }
7616 case MKTAG('p','a','c','k'): {
7617 MOVAtom pack = { tag, size - 8 };
7618 int ret = mov_read_pack(c, pb, pack);
7619 if (ret < 0)
7620 return ret;
7621 break;
7622 }
7623 default:
7624 av_log(c->fc, AV_LOG_WARNING, "Unknown tag in vexu: %s\n",
7626 avio_skip(pb, size - 8);
7627 break;
7628 }
7629 remaining -= size;
7630 }
7631
7632 if (remaining != 0) {
7633 av_log(c->fc, AV_LOG_ERROR, "Broken vexu box\n");
7634 return AVERROR_INVALIDDATA;
7635 }
7636
7637 return 0;
7638}
7639
7641{
7642 AVStream *st;
7643 MOVStreamContext *sc;
7644
7645 if (c->fc->nb_streams < 1)
7646 return 0;
7647
7648 st = c->fc->streams[c->fc->nb_streams - 1];
7649 sc = st->priv_data;
7650
7651 if (atom.size != 4) {
7652 av_log(c->fc, AV_LOG_ERROR, "Invalid size of hfov box: %"PRIu64"\n", atom.size);
7653 return AVERROR_INVALIDDATA;
7654 }
7655
7656
7657 if (!sc->stereo3d) {
7659 if (!sc->stereo3d)
7660 return AVERROR(ENOMEM);
7661 }
7662
7664 sc->stereo3d->horizontal_field_of_view.den = 1000; // thousands of a degree
7665
7666 return 0;
7667}
7668
7670{
7671 int ret = 0;
7672 uint8_t *buffer = av_malloc(len + 1);
7673 const char *val;
7674
7675 if (!buffer)
7676 return AVERROR(ENOMEM);
7677 buffer[len] = '\0';
7678
7679 ret = ffio_read_size(pb, buffer, len);
7680 if (ret < 0)
7681 goto out;
7682
7683 /* Check for mandatory keys and values, try to support XML as best-effort */
7684 if (!sc->spherical &&
7685 av_stristr(buffer, "<GSpherical:StitchingSoftware>") &&
7686 (val = av_stristr(buffer, "<GSpherical:Spherical>")) &&
7687 av_stristr(val, "true") &&
7688 (val = av_stristr(buffer, "<GSpherical:Stitched>")) &&
7689 av_stristr(val, "true") &&
7690 (val = av_stristr(buffer, "<GSpherical:ProjectionType>")) &&
7691 av_stristr(val, "equirectangular")) {
7693 if (!sc->spherical)
7694 goto out;
7695
7697
7698 if (av_stristr(buffer, "<GSpherical:StereoMode>") && !sc->stereo3d) {
7699 enum AVStereo3DType mode;
7700
7701 if (av_stristr(buffer, "left-right"))
7703 else if (av_stristr(buffer, "top-bottom"))
7705 else
7707
7709 if (!sc->stereo3d)
7710 goto out;
7711
7712 sc->stereo3d->type = mode;
7713 }
7714
7715 /* orientation */
7716 val = av_stristr(buffer, "<GSpherical:InitialViewHeadingDegrees>");
7717 if (val)
7718 sc->spherical->yaw = strtol(val, NULL, 10) * (1 << 16);
7719 val = av_stristr(buffer, "<GSpherical:InitialViewPitchDegrees>");
7720 if (val)
7721 sc->spherical->pitch = strtol(val, NULL, 10) * (1 << 16);
7722 val = av_stristr(buffer, "<GSpherical:InitialViewRollDegrees>");
7723 if (val)
7724 sc->spherical->roll = strtol(val, NULL, 10) * (1 << 16);
7725 }
7726
7727out:
7728 av_free(buffer);
7729 return ret;
7730}
7731
7733{
7734 AVStream *st;
7735 MOVStreamContext *sc;
7736 int64_t ret;
7737 AVUUID uuid;
7738 static const AVUUID uuid_isml_manifest = {
7739 0xa5, 0xd4, 0x0b, 0x30, 0xe8, 0x14, 0x11, 0xdd,
7740 0xba, 0x2f, 0x08, 0x00, 0x20, 0x0c, 0x9a, 0x66
7741 };
7742 static const AVUUID uuid_xmp = {
7743 0xbe, 0x7a, 0xcf, 0xcb, 0x97, 0xa9, 0x42, 0xe8,
7744 0x9c, 0x71, 0x99, 0x94, 0x91, 0xe3, 0xaf, 0xac
7745 };
7746 static const AVUUID uuid_spherical = {
7747 0xff, 0xcc, 0x82, 0x63, 0xf8, 0x55, 0x4a, 0x93,
7748 0x88, 0x14, 0x58, 0x7a, 0x02, 0x52, 0x1f, 0xdd,
7749 };
7750
7751 if (atom.size < AV_UUID_LEN || atom.size >= FFMIN(INT_MAX, SIZE_MAX))
7752 return AVERROR_INVALIDDATA;
7753
7754 if (c->fc->nb_streams < 1)
7755 return 0;
7756 st = c->fc->streams[c->fc->nb_streams - 1];
7757 sc = st->priv_data;
7758
7759 ret = ffio_read_size(pb, uuid, AV_UUID_LEN);
7760 if (ret < 0)
7761 return ret;
7762 if (av_uuid_equal(uuid, uuid_isml_manifest)) {
7763 uint8_t *buffer, *ptr;
7764 char *endptr;
7765 size_t len = atom.size - AV_UUID_LEN;
7766
7767 if (len < 4) {
7768 return AVERROR_INVALIDDATA;
7769 }
7770 ret = avio_skip(pb, 4); // zeroes
7771 len -= 4;
7772
7773 buffer = av_mallocz(len + 1);
7774 if (!buffer) {
7775 return AVERROR(ENOMEM);
7776 }
7777 ret = ffio_read_size(pb, buffer, len);
7778 if (ret < 0) {
7779 av_free(buffer);
7780 return ret;
7781 }
7782
7783 ptr = buffer;
7784 while ((ptr = av_stristr(ptr, "systemBitrate=\""))) {
7785 ptr += sizeof("systemBitrate=\"") - 1;
7786 c->bitrates_count++;
7787 c->bitrates = av_realloc_f(c->bitrates, c->bitrates_count, sizeof(*c->bitrates));
7788 if (!c->bitrates) {
7789 c->bitrates_count = 0;
7790 av_free(buffer);
7791 return AVERROR(ENOMEM);
7792 }
7793 errno = 0;
7794 ret = strtol(ptr, &endptr, 10);
7795 if (ret < 0 || errno || *endptr != '"') {
7796 c->bitrates[c->bitrates_count - 1] = 0;
7797 } else {
7798 c->bitrates[c->bitrates_count - 1] = ret;
7799 }
7800 }
7801
7802 av_free(buffer);
7803 } else if (av_uuid_equal(uuid, uuid_xmp)) {
7804 uint8_t *buffer;
7805 size_t len = atom.size - AV_UUID_LEN;
7806 if (c->export_xmp) {
7807 buffer = av_mallocz(len + 1);
7808 if (!buffer) {
7809 return AVERROR(ENOMEM);
7810 }
7811 ret = ffio_read_size(pb, buffer, len);
7812 if (ret < 0) {
7813 av_free(buffer);
7814 return ret;
7815 }
7816 buffer[len] = '\0';
7817 av_dict_set(&c->fc->metadata, "xmp",
7819 } else {
7820 // skip all uuid atom, which makes it fast for long uuid-xmp file
7821 ret = avio_skip(pb, len);
7822 if (ret < 0)
7823 return ret;
7824 }
7825 } else if (av_uuid_equal(uuid, uuid_spherical)) {
7826 size_t len = atom.size - AV_UUID_LEN;
7827 ret = mov_parse_uuid_spherical(sc, pb, len);
7828 if (ret < 0)
7829 return ret;
7830 if (!sc->spherical)
7831 av_log(c->fc, AV_LOG_WARNING, "Invalid spherical metadata found\n");
7832 }
7833
7834 return 0;
7835}
7836
7838{
7839 int ret;
7840 uint8_t content[16];
7841
7842 if (atom.size < 8)
7843 return 0;
7844
7845 ret = ffio_read_size(pb, content, FFMIN(sizeof(content), atom.size));
7846 if (ret < 0)
7847 return ret;
7848
7849 if ( !c->found_moov
7850 && !c->found_mdat
7851 && !memcmp(content, "Anevia\x1A\x1A", 8)
7852 && c->use_mfra_for == FF_MOV_FLAG_MFRA_AUTO) {
7853 c->use_mfra_for = FF_MOV_FLAG_MFRA_PTS;
7854 }
7855
7856 return 0;
7857}
7858
7860{
7861 uint32_t format = avio_rl32(pb);
7862 MOVStreamContext *sc;
7863 enum AVCodecID id;
7864 AVStream *st;
7865
7866 if (c->fc->nb_streams < 1)
7867 return 0;
7868 st = c->fc->streams[c->fc->nb_streams - 1];
7869 sc = st->priv_data;
7870
7871 switch (sc->format)
7872 {
7873 case MKTAG('e','n','c','v'): // encrypted video
7874 case MKTAG('e','n','c','a'): // encrypted audio
7875 id = mov_codec_id(st, format);
7876 if (st->codecpar->codec_id != AV_CODEC_ID_NONE &&
7877 st->codecpar->codec_id != id) {
7878 av_log(c->fc, AV_LOG_WARNING,
7879 "ignoring 'frma' atom of '%.4s', stream has codec id %d\n",
7880 (char*)&format, st->codecpar->codec_id);
7881 break;
7882 }
7883
7884 st->codecpar->codec_id = id;
7885 sc->format = format;
7886 break;
7887
7888 default:
7889 if (format != sc->format) {
7890 av_log(c->fc, AV_LOG_WARNING,
7891 "ignoring 'frma' atom of '%.4s', stream format is '%.4s'\n",
7892 (char*)&format, (char*)&sc->format);
7893 }
7894 break;
7895 }
7896
7897 return 0;
7898}
7899
7900/**
7901 * Gets the current encryption info and associated current stream context. If
7902 * we are parsing a track fragment, this will return the specific encryption
7903 * info for this fragment; otherwise this will return the global encryption
7904 * info for the current stream.
7905 */
7907{
7908 MOVFragmentStreamInfo *frag_stream_info;
7909 AVStream *st;
7910 int i;
7911
7912 frag_stream_info = get_current_frag_stream_info(&c->frag_index);
7913 if (frag_stream_info) {
7914 for (i = 0; i < c->fc->nb_streams; i++) {
7915 *sc = c->fc->streams[i]->priv_data;
7916 if ((*sc)->id == frag_stream_info->id) {
7917 st = c->fc->streams[i];
7918 break;
7919 }
7920 }
7921 if (i == c->fc->nb_streams)
7922 return 0;
7923 *sc = st->priv_data;
7924
7925 if (!frag_stream_info->encryption_index) {
7926 // If this stream isn't encrypted, don't create the index.
7927 if (!(*sc)->cenc.default_encrypted_sample)
7928 return 0;
7929 frag_stream_info->encryption_index = av_mallocz(sizeof(*frag_stream_info->encryption_index));
7930 if (!frag_stream_info->encryption_index)
7931 return AVERROR(ENOMEM);
7932 }
7933 *encryption_index = frag_stream_info->encryption_index;
7934 return 1;
7935 } else {
7936 // No current track fragment, using stream level encryption info.
7937
7938 if (c->fc->nb_streams < 1)
7939 return 0;
7940 st = c->fc->streams[c->fc->nb_streams - 1];
7941 *sc = st->priv_data;
7942
7943 if (!(*sc)->cenc.encryption_index) {
7944 // If this stream isn't encrypted, don't create the index.
7945 if (!(*sc)->cenc.default_encrypted_sample)
7946 return 0;
7947 (*sc)->cenc.encryption_index = av_mallocz(sizeof(*frag_stream_info->encryption_index));
7948 if (!(*sc)->cenc.encryption_index)
7949 return AVERROR(ENOMEM);
7950 }
7951
7952 *encryption_index = (*sc)->cenc.encryption_index;
7953 return 1;
7954 }
7955}
7956
7958{
7959 int i, ret;
7960 unsigned int subsample_count;
7961 AVSubsampleEncryptionInfo *subsamples;
7962
7963 if (!sc->cenc.default_encrypted_sample) {
7964 av_log(c->fc, AV_LOG_ERROR, "Missing schm or tenc\n");
7965 return AVERROR_INVALIDDATA;
7966 }
7967
7968 if (sc->cenc.per_sample_iv_size || use_subsamples) {
7970 if (!*sample)
7971 return AVERROR(ENOMEM);
7972 } else
7973 *sample = NULL;
7974
7975 if (sc->cenc.per_sample_iv_size != 0) {
7976 if ((ret = ffio_read_size(pb, (*sample)->iv, sc->cenc.per_sample_iv_size)) < 0) {
7977 av_log(c->fc, AV_LOG_ERROR, "failed to read the initialization vector\n");
7979 *sample = NULL;
7980 return ret;
7981 }
7982 }
7983
7984 if (use_subsamples) {
7985 subsample_count = avio_rb16(pb);
7986 av_free((*sample)->subsamples);
7987 (*sample)->subsamples = av_calloc(subsample_count, sizeof(*subsamples));
7988 if (!(*sample)->subsamples) {
7990 *sample = NULL;
7991 return AVERROR(ENOMEM);
7992 }
7993
7994 for (i = 0; i < subsample_count && !pb->eof_reached; i++) {
7995 (*sample)->subsamples[i].bytes_of_clear_data = avio_rb16(pb);
7996 (*sample)->subsamples[i].bytes_of_protected_data = avio_rb32(pb);
7997 }
7998
7999 if (pb->eof_reached) {
8000 av_log(c->fc, AV_LOG_ERROR, "hit EOF while reading sub-sample encryption info\n");
8002 *sample = NULL;
8003 return AVERROR_INVALIDDATA;
8004 }
8005 (*sample)->subsample_count = subsample_count;
8006 }
8007
8008 return 0;
8009}
8010
8012{
8013 AVEncryptionInfo **encrypted_samples;
8014 MOVEncryptionIndex *encryption_index;
8015 MOVStreamContext *sc;
8016 int use_subsamples, ret;
8017 unsigned int sample_count, i, alloc_size = 0;
8018
8019 ret = get_current_encryption_info(c, &encryption_index, &sc);
8020 if (ret != 1)
8021 return ret;
8022
8023 if (encryption_index->nb_encrypted_samples) {
8024 // This can happen if we have both saio/saiz and senc atoms.
8025 av_log(c->fc, AV_LOG_DEBUG, "Ignoring duplicate encryption info in senc\n");
8026 return 0;
8027 }
8028
8029 avio_r8(pb); /* version */
8030 use_subsamples = avio_rb24(pb) & 0x02; /* flags */
8031
8032 sample_count = avio_rb32(pb);
8033 if (sample_count >= INT_MAX / sizeof(*encrypted_samples))
8034 return AVERROR(ENOMEM);
8035
8036 for (i = 0; i < sample_count; i++) {
8037 unsigned int min_samples = FFMIN(FFMAX(i + 1, 1024 * 1024), sample_count);
8038 encrypted_samples = av_fast_realloc(encryption_index->encrypted_samples, &alloc_size,
8039 min_samples * sizeof(*encrypted_samples));
8040 if (encrypted_samples) {
8041 encryption_index->encrypted_samples = encrypted_samples;
8042
8044 c, pb, sc, &encryption_index->encrypted_samples[i], use_subsamples);
8045 } else {
8046 ret = AVERROR(ENOMEM);
8047 }
8048 if (pb->eof_reached) {
8049 av_log(c->fc, AV_LOG_ERROR, "Hit EOF while reading senc\n");
8050 if (ret >= 0)
8051 av_encryption_info_free(encryption_index->encrypted_samples[i]);
8052 ret = AVERROR_INVALIDDATA;
8053 }
8054
8055 if (ret < 0) {
8056 for (; i > 0; i--)
8057 av_encryption_info_free(encryption_index->encrypted_samples[i - 1]);
8058 av_freep(&encryption_index->encrypted_samples);
8059 return ret;
8060 }
8061 }
8062 encryption_index->nb_encrypted_samples = sample_count;
8063
8064 return 0;
8065}
8066
8068{
8069 AVEncryptionInfo **sample, **encrypted_samples;
8070 int64_t prev_pos;
8071 size_t sample_count, sample_info_size, i;
8072 int ret = 0;
8073 unsigned int alloc_size = 0;
8074
8075 if (encryption_index->nb_encrypted_samples)
8076 return 0;
8077 sample_count = encryption_index->auxiliary_info_sample_count;
8078 if (encryption_index->auxiliary_offsets_count != 1) {
8079 av_log(c->fc, AV_LOG_ERROR, "Multiple auxiliary info chunks are not supported\n");
8080 return AVERROR_PATCHWELCOME;
8081 }
8082 if (sample_count >= INT_MAX / sizeof(*encrypted_samples))
8083 return AVERROR(ENOMEM);
8084
8085 prev_pos = avio_tell(pb);
8086 if (!(pb->seekable & AVIO_SEEKABLE_NORMAL) ||
8087 avio_seek(pb, encryption_index->auxiliary_offsets[0], SEEK_SET) != encryption_index->auxiliary_offsets[0]) {
8088 av_log(c->fc, AV_LOG_INFO, "Failed to seek for auxiliary info, will only parse senc atoms for encryption info\n");
8089 goto finish;
8090 }
8091
8092 for (i = 0; i < sample_count && !pb->eof_reached; i++) {
8093 unsigned int min_samples = FFMIN(FFMAX(i + 1, 1024 * 1024), sample_count);
8094 encrypted_samples = av_fast_realloc(encryption_index->encrypted_samples, &alloc_size,
8095 min_samples * sizeof(*encrypted_samples));
8096 if (!encrypted_samples) {
8097 ret = AVERROR(ENOMEM);
8098 goto finish;
8099 }
8100 encryption_index->encrypted_samples = encrypted_samples;
8101
8102 sample = &encryption_index->encrypted_samples[i];
8103 sample_info_size = encryption_index->auxiliary_info_default_size
8104 ? encryption_index->auxiliary_info_default_size
8105 : encryption_index->auxiliary_info_sizes[i];
8106
8107 ret = mov_read_sample_encryption_info(c, pb, sc, sample, sample_info_size > sc->cenc.per_sample_iv_size);
8108 if (ret < 0)
8109 goto finish;
8110 }
8111 if (pb->eof_reached) {
8112 av_log(c->fc, AV_LOG_ERROR, "Hit EOF while reading auxiliary info\n");
8113 ret = AVERROR_INVALIDDATA;
8114 } else {
8115 encryption_index->nb_encrypted_samples = sample_count;
8116 }
8117
8118finish:
8119 avio_seek(pb, prev_pos, SEEK_SET);
8120 if (ret < 0) {
8121 for (; i > 0; i--) {
8122 av_encryption_info_free(encryption_index->encrypted_samples[i - 1]);
8123 }
8124 av_freep(&encryption_index->encrypted_samples);
8125 }
8126 return ret;
8127}
8128
8130{
8131 MOVEncryptionIndex *encryption_index;
8132 MOVStreamContext *sc;
8133 int ret;
8134 unsigned int sample_count, aux_info_type, aux_info_param;
8135
8136 ret = get_current_encryption_info(c, &encryption_index, &sc);
8137 if (ret != 1)
8138 return ret;
8139
8140 if (encryption_index->nb_encrypted_samples) {
8141 // This can happen if we have both saio/saiz and senc atoms.
8142 av_log(c->fc, AV_LOG_DEBUG, "Ignoring duplicate encryption info in saiz\n");
8143 return 0;
8144 }
8145
8146 if (encryption_index->auxiliary_info_sample_count) {
8147 av_log(c->fc, AV_LOG_ERROR, "Duplicate saiz atom\n");
8148 return AVERROR_INVALIDDATA;
8149 }
8150
8151 avio_r8(pb); /* version */
8152 if (avio_rb24(pb) & 0x01) { /* flags */
8153 aux_info_type = avio_rb32(pb);
8154 aux_info_param = avio_rb32(pb);
8156 if (aux_info_type != sc->cenc.default_encrypted_sample->scheme) {
8157 av_log(c->fc, AV_LOG_DEBUG, "Ignoring saiz box with non-zero aux_info_type\n");
8158 return 0;
8159 }
8160 if (aux_info_param != 0) {
8161 av_log(c->fc, AV_LOG_DEBUG, "Ignoring saiz box with non-zero aux_info_type_parameter\n");
8162 return 0;
8163 }
8164 } else {
8165 // Didn't see 'schm' or 'tenc', so this isn't encrypted.
8166 if ((aux_info_type == MKBETAG('c','e','n','c') ||
8167 aux_info_type == MKBETAG('c','e','n','s') ||
8168 aux_info_type == MKBETAG('c','b','c','1') ||
8169 aux_info_type == MKBETAG('c','b','c','s')) &&
8170 aux_info_param == 0) {
8171 av_log(c->fc, AV_LOG_ERROR, "Saw encrypted saiz without schm/tenc\n");
8172 return AVERROR_INVALIDDATA;
8173 } else {
8174 return 0;
8175 }
8176 }
8177 } else if (!sc->cenc.default_encrypted_sample) {
8178 // Didn't see 'schm' or 'tenc', so this isn't encrypted.
8179 return 0;
8180 }
8181
8182 encryption_index->auxiliary_info_default_size = avio_r8(pb);
8183 sample_count = avio_rb32(pb);
8184
8185 if (encryption_index->auxiliary_info_default_size == 0) {
8186 if (sample_count == 0)
8187 return AVERROR_INVALIDDATA;
8188
8189 encryption_index->auxiliary_info_sizes = av_malloc(sample_count);
8190 if (!encryption_index->auxiliary_info_sizes)
8191 return AVERROR(ENOMEM);
8192
8193 ret = avio_read(pb, encryption_index->auxiliary_info_sizes, sample_count);
8194 if (ret != sample_count) {
8195 av_freep(&encryption_index->auxiliary_info_sizes);
8196
8197 if (ret >= 0)
8198 ret = AVERROR_INVALIDDATA;
8199 av_log(c->fc, AV_LOG_ERROR, "Failed to read the auxiliary info, %s\n",
8200 av_err2str(ret));
8201 return ret;
8202 }
8203 }
8204 encryption_index->auxiliary_info_sample_count = sample_count;
8205
8206 if (encryption_index->auxiliary_offsets_count) {
8207 return mov_parse_auxiliary_info(c, sc, pb, encryption_index);
8208 }
8209
8210 return 0;
8211}
8212
8214{
8215 uint64_t *auxiliary_offsets;
8216 MOVEncryptionIndex *encryption_index;
8217 MOVStreamContext *sc;
8218 int i, ret;
8219 unsigned int version, entry_count, aux_info_type, aux_info_param;
8220 unsigned int alloc_size = 0;
8221
8222 ret = get_current_encryption_info(c, &encryption_index, &sc);
8223 if (ret != 1)
8224 return ret;
8225
8226 if (encryption_index->nb_encrypted_samples) {
8227 // This can happen if we have both saio/saiz and senc atoms.
8228 av_log(c->fc, AV_LOG_DEBUG, "Ignoring duplicate encryption info in saio\n");
8229 return 0;
8230 }
8231
8232 if (encryption_index->auxiliary_offsets_count) {
8233 av_log(c->fc, AV_LOG_ERROR, "Duplicate saio atom\n");
8234 return AVERROR_INVALIDDATA;
8235 }
8236
8237 version = avio_r8(pb); /* version */
8238 if (avio_rb24(pb) & 0x01) { /* flags */
8239 aux_info_type = avio_rb32(pb);
8240 aux_info_param = avio_rb32(pb);
8242 if (aux_info_type != sc->cenc.default_encrypted_sample->scheme) {
8243 av_log(c->fc, AV_LOG_DEBUG, "Ignoring saio box with non-zero aux_info_type\n");
8244 return 0;
8245 }
8246 if (aux_info_param != 0) {
8247 av_log(c->fc, AV_LOG_DEBUG, "Ignoring saio box with non-zero aux_info_type_parameter\n");
8248 return 0;
8249 }
8250 } else {
8251 // Didn't see 'schm' or 'tenc', so this isn't encrypted.
8252 if ((aux_info_type == MKBETAG('c','e','n','c') ||
8253 aux_info_type == MKBETAG('c','e','n','s') ||
8254 aux_info_type == MKBETAG('c','b','c','1') ||
8255 aux_info_type == MKBETAG('c','b','c','s')) &&
8256 aux_info_param == 0) {
8257 av_log(c->fc, AV_LOG_ERROR, "Saw encrypted saio without schm/tenc\n");
8258 return AVERROR_INVALIDDATA;
8259 } else {
8260 return 0;
8261 }
8262 }
8263 } else if (!sc->cenc.default_encrypted_sample) {
8264 // Didn't see 'schm' or 'tenc', so this isn't encrypted.
8265 return 0;
8266 }
8267
8268 entry_count = avio_rb32(pb);
8269 if (entry_count >= INT_MAX / sizeof(*auxiliary_offsets))
8270 return AVERROR(ENOMEM);
8271
8272 for (i = 0; i < entry_count && !pb->eof_reached; i++) {
8273 unsigned int min_offsets = FFMIN(FFMAX(i + 1, 1024), entry_count);
8274 auxiliary_offsets = av_fast_realloc(
8275 encryption_index->auxiliary_offsets, &alloc_size,
8276 min_offsets * sizeof(*auxiliary_offsets));
8277 if (!auxiliary_offsets) {
8278 av_freep(&encryption_index->auxiliary_offsets);
8279 return AVERROR(ENOMEM);
8280 }
8281 encryption_index->auxiliary_offsets = auxiliary_offsets;
8282
8283 if (version == 0) {
8284 encryption_index->auxiliary_offsets[i] = avio_rb32(pb);
8285 } else {
8286 encryption_index->auxiliary_offsets[i] = avio_rb64(pb);
8287 }
8288 if (c->frag_index.current >= 0) {
8289 encryption_index->auxiliary_offsets[i] += c->fragment.base_data_offset;
8290 }
8291 }
8292
8293 if (pb->eof_reached) {
8294 av_log(c->fc, AV_LOG_ERROR, "Hit EOF while reading saio\n");
8295 av_freep(&encryption_index->auxiliary_offsets);
8296 return AVERROR_INVALIDDATA;
8297 }
8298
8299 encryption_index->auxiliary_offsets_count = entry_count;
8300
8301 if (encryption_index->auxiliary_info_sample_count) {
8302 return mov_parse_auxiliary_info(c, sc, pb, encryption_index);
8303 }
8304
8305 return 0;
8306}
8307
8309{
8310 AVEncryptionInitInfo *info, *old_init_info;
8311 uint8_t **key_ids;
8312 AVStream *st;
8313 const AVPacketSideData *old_side_data;
8314 uint8_t *side_data, *extra_data;
8315 size_t side_data_size;
8316 int ret = 0;
8317 unsigned int version, kid_count, extra_data_size, alloc_size = 0;
8318
8319 if (c->fc->nb_streams < 1)
8320 return 0;
8321 st = c->fc->streams[c->fc->nb_streams-1];
8322
8323 version = avio_r8(pb); /* version */
8324 avio_rb24(pb); /* flags */
8325
8326 info = av_encryption_init_info_alloc(/* system_id_size */ 16, /* num_key_ids */ 0,
8327 /* key_id_size */ 16, /* data_size */ 0);
8328 if (!info)
8329 return AVERROR(ENOMEM);
8330
8331 if ((ret = ffio_read_size(pb, info->system_id, 16)) < 0) {
8332 av_log(c->fc, AV_LOG_ERROR, "Failed to read the system id\n");
8333 goto finish;
8334 }
8335
8336 if (version > 0) {
8337 kid_count = avio_rb32(pb);
8338 if (kid_count >= INT_MAX / sizeof(*key_ids)) {
8339 ret = AVERROR(ENOMEM);
8340 goto finish;
8341 }
8342
8343 for (unsigned int i = 0; i < kid_count && !pb->eof_reached; i++) {
8344 unsigned int min_kid_count = FFMIN(FFMAX(i + 1, 1024), kid_count);
8345 key_ids = av_fast_realloc(info->key_ids, &alloc_size,
8346 min_kid_count * sizeof(*key_ids));
8347 if (!key_ids) {
8348 ret = AVERROR(ENOMEM);
8349 goto finish;
8350 }
8351 info->key_ids = key_ids;
8352
8353 info->key_ids[i] = av_mallocz(16);
8354 if (!info->key_ids[i]) {
8355 ret = AVERROR(ENOMEM);
8356 goto finish;
8357 }
8358 info->num_key_ids = i + 1;
8359
8360 if ((ret = ffio_read_size(pb, info->key_ids[i], 16)) < 0) {
8361 av_log(c->fc, AV_LOG_ERROR, "Failed to read the key id\n");
8362 goto finish;
8363 }
8364 }
8365
8366 if (pb->eof_reached) {
8367 av_log(c->fc, AV_LOG_ERROR, "Hit EOF while reading pssh\n");
8368 ret = AVERROR_INVALIDDATA;
8369 goto finish;
8370 }
8371 }
8372
8373 extra_data_size = avio_rb32(pb);
8374 extra_data = av_malloc(extra_data_size);
8375 if (!extra_data) {
8376 ret = AVERROR(ENOMEM);
8377 goto finish;
8378 }
8379 ret = avio_read(pb, extra_data, extra_data_size);
8380 if (ret != extra_data_size) {
8381 av_free(extra_data);
8382
8383 if (ret >= 0)
8384 ret = AVERROR_INVALIDDATA;
8385 goto finish;
8386 }
8387
8388 av_freep(&info->data); // malloc(0) may still allocate something.
8389 info->data = extra_data;
8390 info->data_size = extra_data_size;
8391
8392 // If there is existing initialization data, append to the list.
8395 if (old_side_data) {
8396 old_init_info = av_encryption_init_info_get_side_data(old_side_data->data, old_side_data->size);
8397 if (old_init_info) {
8398 // Append to the end of the list.
8399 for (AVEncryptionInitInfo *cur = old_init_info;; cur = cur->next) {
8400 if (!cur->next) {
8401 cur->next = info;
8402 break;
8403 }
8404 }
8405 info = old_init_info;
8406 } else {
8407 // Assume existing side-data will be valid, so the only error we could get is OOM.
8408 ret = AVERROR(ENOMEM);
8409 goto finish;
8410 }
8411 }
8412
8413 side_data = av_encryption_init_info_add_side_data(info, &side_data_size);
8414 if (!side_data) {
8415 ret = AVERROR(ENOMEM);
8416 goto finish;
8417 }
8421 side_data, side_data_size, 0))
8422 av_free(side_data);
8423
8424finish:
8426 return ret;
8427}
8428
8430{
8431 AVStream *st;
8432 MOVStreamContext *sc;
8433
8434 if (c->fc->nb_streams < 1)
8435 return 0;
8436 st = c->fc->streams[c->fc->nb_streams-1];
8437 sc = st->priv_data;
8438
8439 if (sc->pseudo_stream_id != 0) {
8440 av_log(c->fc, AV_LOG_ERROR, "schm boxes are only supported in first sample descriptor\n");
8441 return AVERROR_PATCHWELCOME;
8442 }
8443
8444 if (atom.size < 8)
8445 return AVERROR_INVALIDDATA;
8446
8447 avio_rb32(pb); /* version and flags */
8448
8449 if (!sc->cenc.default_encrypted_sample) {
8451 if (!sc->cenc.default_encrypted_sample) {
8452 return AVERROR(ENOMEM);
8453 }
8454 }
8455
8457 return 0;
8458}
8459
8461{
8462 AVStream *st;
8463 MOVStreamContext *sc;
8464 unsigned int version, pattern, is_protected, iv_size;
8465
8466 if (c->fc->nb_streams < 1)
8467 return 0;
8468 st = c->fc->streams[c->fc->nb_streams-1];
8469 sc = st->priv_data;
8470
8471 if (sc->pseudo_stream_id != 0) {
8472 av_log(c->fc, AV_LOG_ERROR, "tenc atom are only supported in first sample descriptor\n");
8473 return AVERROR_PATCHWELCOME;
8474 }
8475
8476 if (!sc->cenc.default_encrypted_sample) {
8478 if (!sc->cenc.default_encrypted_sample) {
8479 return AVERROR(ENOMEM);
8480 }
8481 }
8482
8483 if (atom.size < 20)
8484 return AVERROR_INVALIDDATA;
8485
8486 version = avio_r8(pb); /* version */
8487 avio_rb24(pb); /* flags */
8488
8489 avio_r8(pb); /* reserved */
8490 pattern = avio_r8(pb);
8491
8492 if (version > 0) {
8494 sc->cenc.default_encrypted_sample->skip_byte_block = pattern & 0xf;
8495 }
8496
8497 is_protected = avio_r8(pb);
8498 if (is_protected && !sc->cenc.encryption_index) {
8499 // The whole stream should be by-default encrypted.
8501 if (!sc->cenc.encryption_index)
8502 return AVERROR(ENOMEM);
8503 }
8505 if (sc->cenc.per_sample_iv_size != 0 && sc->cenc.per_sample_iv_size != 8 &&
8506 sc->cenc.per_sample_iv_size != 16) {
8507 av_log(c->fc, AV_LOG_ERROR, "invalid per-sample IV size value\n");
8508 return AVERROR_INVALIDDATA;
8509 }
8510 if (avio_read(pb, sc->cenc.default_encrypted_sample->key_id, 16) != 16) {
8511 av_log(c->fc, AV_LOG_ERROR, "failed to read the default key ID\n");
8512 return AVERROR_INVALIDDATA;
8513 }
8514
8515 if (is_protected && !sc->cenc.per_sample_iv_size) {
8516 iv_size = avio_r8(pb);
8517 if (iv_size != 8 && iv_size != 16) {
8518 av_log(c->fc, AV_LOG_ERROR, "invalid default_constant_IV_size in tenc atom\n");
8519 return AVERROR_INVALIDDATA;
8520 }
8521
8522 if (avio_read(pb, sc->cenc.default_encrypted_sample->iv, iv_size) != iv_size) {
8523 av_log(c->fc, AV_LOG_ERROR, "failed to read the default IV\n");
8524 return AVERROR_INVALIDDATA;
8525 }
8526 }
8527
8528 return 0;
8529}
8530
8532{
8533 AVStream *st;
8534 int last, type, size, ret;
8535 uint8_t buf[4];
8536
8537 if (c->fc->nb_streams < 1)
8538 return 0;
8539 st = c->fc->streams[c->fc->nb_streams-1];
8540
8541 if ((uint64_t)atom.size > (1<<30) || atom.size < 42)
8542 return AVERROR_INVALIDDATA;
8543
8544 /* Check FlacSpecificBox version. */
8545 if (avio_r8(pb) != 0)
8546 return AVERROR_INVALIDDATA;
8547
8548 avio_rb24(pb); /* Flags */
8549
8550 if (avio_read(pb, buf, sizeof(buf)) != sizeof(buf)) {
8551 av_log(c->fc, AV_LOG_ERROR, "failed to read FLAC metadata block header\n");
8552 return pb->error < 0 ? pb->error : AVERROR_INVALIDDATA;
8553 }
8554 flac_parse_block_header(buf, &last, &type, &size);
8555
8557 av_log(c->fc, AV_LOG_ERROR, "STREAMINFO must be first FLACMetadataBlock\n");
8558 return AVERROR_INVALIDDATA;
8559 }
8560
8561 ret = ff_get_extradata(c->fc, st->codecpar, pb, size);
8562 if (ret < 0)
8563 return ret;
8564
8565 if (!last)
8566 av_log(c->fc, AV_LOG_WARNING, "non-STREAMINFO FLACMetadataBlock(s) ignored\n");
8567
8568 return 0;
8569}
8570
8572 AVDictionaryEntry *key_entry_hex;
8573 char kid_hex[16*2+1];
8574
8575 if (c->decryption_default_key && c->decryption_default_key_len != len) {
8576 av_log(c->fc, AV_LOG_ERROR, "invalid default decryption key length: got %d, expected %d\n", c->decryption_default_key_len, len);
8577 return -1;
8578 }
8579
8580 if (!c->decryption_keys) {
8581 av_assert0(c->decryption_default_key);
8582 memcpy(out, c->decryption_default_key, len);
8583 return 0;
8584 }
8585
8586 if (sample->key_id_size != 16) {
8587 av_log(c->fc, AV_LOG_ERROR, "invalid key ID size: got %u, expected 16\n", sample->key_id_size);
8588 return -1;
8589 }
8590
8591 ff_data_to_hex(kid_hex, sample->key_id, 16, 1);
8592 key_entry_hex = av_dict_get(c->decryption_keys, kid_hex, NULL, AV_DICT_DONT_STRDUP_KEY|AV_DICT_DONT_STRDUP_VAL);
8593 if (!key_entry_hex) {
8594 if (!c->decryption_default_key) {
8595 av_log(c->fc, AV_LOG_ERROR, "unable to find KID %s\n", kid_hex);
8596 return -1;
8597 }
8598 memcpy(out, c->decryption_default_key, len);
8599 return 0;
8600 }
8601 if (strlen(key_entry_hex->value) != len*2) {
8602 return -1;
8603 }
8604 ff_hex_to_data(out, key_entry_hex->value);
8605 return 0;
8606}
8607
8609{
8610 int i, ret;
8611 int bytes_of_protected_data;
8612 uint8_t decryption_key[AES_CTR_KEY_SIZE];
8613
8614 if (!sc->cenc.aes_ctr) {
8615 ret = get_key_from_kid(decryption_key, sizeof(decryption_key), c, sample);
8616 if (ret < 0) {
8617 return ret;
8618 }
8619
8620 /* initialize the cipher */
8622 if (!sc->cenc.aes_ctr) {
8623 return AVERROR(ENOMEM);
8624 }
8625
8626 ret = av_aes_ctr_init(sc->cenc.aes_ctr, decryption_key);
8627 if (ret < 0) {
8628 return ret;
8629 }
8630 }
8631
8633
8634 if (!sample->subsample_count) {
8635 /* decrypt the whole packet */
8636 av_aes_ctr_crypt(sc->cenc.aes_ctr, input, input, size);
8637 return 0;
8638 }
8639
8640 for (i = 0; i < sample->subsample_count; i++) {
8641 if (sample->subsamples[i].bytes_of_clear_data + (int64_t)sample->subsamples[i].bytes_of_protected_data > size) {
8642 av_log(c->fc, AV_LOG_ERROR, "subsample size exceeds the packet size left\n");
8643 return AVERROR_INVALIDDATA;
8644 }
8645
8646 /* skip the clear bytes */
8647 input += sample->subsamples[i].bytes_of_clear_data;
8648 size -= sample->subsamples[i].bytes_of_clear_data;
8649
8650 /* decrypt the encrypted bytes */
8651
8652 bytes_of_protected_data = sample->subsamples[i].bytes_of_protected_data;
8653 av_aes_ctr_crypt(sc->cenc.aes_ctr, input, input, bytes_of_protected_data);
8654
8655 input += bytes_of_protected_data;
8656 size -= bytes_of_protected_data;
8657 }
8658
8659 if (size > 0) {
8660 av_log(c->fc, AV_LOG_ERROR, "leftover packet bytes after subsample processing\n");
8661 return AVERROR_INVALIDDATA;
8662 }
8663
8664 return 0;
8665}
8666
8668{
8669 int i, ret;
8670 int num_of_encrypted_blocks;
8671 uint8_t iv[16];
8672 uint8_t decryption_key[16];
8673
8674 if (!sc->cenc.aes_ctx) {
8675 ret = get_key_from_kid(decryption_key, sizeof(decryption_key), c, sample);
8676 if (ret < 0) {
8677 return ret;
8678 }
8679
8680 /* initialize the cipher */
8681 sc->cenc.aes_ctx = av_aes_alloc();
8682 if (!sc->cenc.aes_ctx) {
8683 return AVERROR(ENOMEM);
8684 }
8685
8686 ret = av_aes_init(sc->cenc.aes_ctx, decryption_key, 16 * 8, 1);
8687 if (ret < 0) {
8688 return ret;
8689 }
8690 }
8691
8692 memcpy(iv, sample->iv, 16);
8693
8694 /* whole-block full sample encryption */
8695 if (!sample->subsample_count) {
8696 /* decrypt the whole packet */
8697 av_aes_crypt(sc->cenc.aes_ctx, input, input, size/16, iv, 1);
8698 return 0;
8699 }
8700
8701 for (i = 0; i < sample->subsample_count; i++) {
8702 if (sample->subsamples[i].bytes_of_clear_data + (int64_t)sample->subsamples[i].bytes_of_protected_data > size) {
8703 av_log(c->fc, AV_LOG_ERROR, "subsample size exceeds the packet size left\n");
8704 return AVERROR_INVALIDDATA;
8705 }
8706
8707 if (sample->subsamples[i].bytes_of_protected_data % 16) {
8708 av_log(c->fc, AV_LOG_ERROR, "subsample BytesOfProtectedData is not a multiple of 16\n");
8709 return AVERROR_INVALIDDATA;
8710 }
8711
8712 /* skip the clear bytes */
8713 input += sample->subsamples[i].bytes_of_clear_data;
8714 size -= sample->subsamples[i].bytes_of_clear_data;
8715
8716 /* decrypt the encrypted bytes */
8717 num_of_encrypted_blocks = sample->subsamples[i].bytes_of_protected_data/16;
8718 if (num_of_encrypted_blocks > 0) {
8719 av_aes_crypt(sc->cenc.aes_ctx, input, input, num_of_encrypted_blocks, iv, 1);
8720 }
8721 input += sample->subsamples[i].bytes_of_protected_data;
8722 size -= sample->subsamples[i].bytes_of_protected_data;
8723 }
8724
8725 if (size > 0) {
8726 av_log(c->fc, AV_LOG_ERROR, "leftover packet bytes after subsample processing\n");
8727 return AVERROR_INVALIDDATA;
8728 }
8729
8730 return 0;
8731}
8732
8734{
8735 int i, ret, rem_bytes;
8736 uint8_t *data;
8737 uint8_t decryption_key[AES_CTR_KEY_SIZE];
8738
8739 if (!sc->cenc.aes_ctr) {
8740 ret = get_key_from_kid(decryption_key, sizeof(decryption_key), c, sample);
8741 if (ret < 0) {
8742 return ret;
8743 }
8744
8745 /* initialize the cipher */
8747 if (!sc->cenc.aes_ctr) {
8748 return AVERROR(ENOMEM);
8749 }
8750
8751 ret = av_aes_ctr_init(sc->cenc.aes_ctr, decryption_key);
8752 if (ret < 0) {
8753 return ret;
8754 }
8755 }
8756
8758
8759 /* whole-block full sample encryption */
8760 if (!sample->subsample_count) {
8761 /* decrypt the whole packet */
8762 av_aes_ctr_crypt(sc->cenc.aes_ctr, input, input, size);
8763 return 0;
8764 } else if (!sample->crypt_byte_block && !sample->skip_byte_block) {
8765 av_log(c->fc, AV_LOG_ERROR, "pattern encryption is not present in 'cens' scheme\n");
8766 return AVERROR_INVALIDDATA;
8767 }
8768
8769 for (i = 0; i < sample->subsample_count; i++) {
8770 if (sample->subsamples[i].bytes_of_clear_data + (int64_t)sample->subsamples[i].bytes_of_protected_data > size) {
8771 av_log(c->fc, AV_LOG_ERROR, "subsample size exceeds the packet size left\n");
8772 return AVERROR_INVALIDDATA;
8773 }
8774
8775 /* skip the clear bytes */
8776 input += sample->subsamples[i].bytes_of_clear_data;
8777 size -= sample->subsamples[i].bytes_of_clear_data;
8778
8779 /* decrypt the encrypted bytes */
8780 data = input;
8781 rem_bytes = sample->subsamples[i].bytes_of_protected_data;
8782 while (rem_bytes > 0) {
8783 if (rem_bytes < 16*sample->crypt_byte_block) {
8784 break;
8785 }
8786 av_aes_ctr_crypt(sc->cenc.aes_ctr, data, data, 16*sample->crypt_byte_block);
8787 data += 16*sample->crypt_byte_block;
8788 rem_bytes -= 16*sample->crypt_byte_block;
8789 data += FFMIN(16*sample->skip_byte_block, rem_bytes);
8790 rem_bytes -= FFMIN(16*sample->skip_byte_block, rem_bytes);
8791 }
8792 input += sample->subsamples[i].bytes_of_protected_data;
8793 size -= sample->subsamples[i].bytes_of_protected_data;
8794 }
8795
8796 if (size > 0) {
8797 av_log(c->fc, AV_LOG_ERROR, "leftover packet bytes after subsample processing\n");
8798 return AVERROR_INVALIDDATA;
8799 }
8800
8801 return 0;
8802}
8803
8805{
8806 int i, ret, rem_bytes;
8807 uint8_t iv[16];
8808 uint8_t *data;
8809 uint8_t decryption_key[16];
8810
8811 if (!sc->cenc.aes_ctx) {
8812 ret = get_key_from_kid(decryption_key, sizeof(decryption_key), c, sample);
8813 if (ret < 0) {
8814 return ret;
8815 }
8816
8817 /* initialize the cipher */
8818 sc->cenc.aes_ctx = av_aes_alloc();
8819 if (!sc->cenc.aes_ctx) {
8820 return AVERROR(ENOMEM);
8821 }
8822
8823 ret = av_aes_init(sc->cenc.aes_ctx, decryption_key, 16 * 8, 1);
8824 if (ret < 0) {
8825 return ret;
8826 }
8827 }
8828
8829 /* whole-block full sample encryption */
8830 if (!sample->subsample_count) {
8831 /* decrypt the whole packet */
8832 memcpy(iv, sample->iv, 16);
8833 av_aes_crypt(sc->cenc.aes_ctx, input, input, size/16, iv, 1);
8834 return 0;
8835 } else if (!sample->crypt_byte_block && !sample->skip_byte_block) {
8836 av_log(c->fc, AV_LOG_ERROR, "pattern encryption is not present in 'cbcs' scheme\n");
8837 return AVERROR_INVALIDDATA;
8838 }
8839
8840 for (i = 0; i < sample->subsample_count; i++) {
8841 if (sample->subsamples[i].bytes_of_clear_data + (int64_t)sample->subsamples[i].bytes_of_protected_data > size) {
8842 av_log(c->fc, AV_LOG_ERROR, "subsample size exceeds the packet size left\n");
8843 return AVERROR_INVALIDDATA;
8844 }
8845
8846 /* skip the clear bytes */
8847 input += sample->subsamples[i].bytes_of_clear_data;
8848 size -= sample->subsamples[i].bytes_of_clear_data;
8849
8850 /* decrypt the encrypted bytes */
8851 memcpy(iv, sample->iv, 16);
8852 data = input;
8853 rem_bytes = sample->subsamples[i].bytes_of_protected_data;
8854 while (rem_bytes > 0) {
8855 if (rem_bytes < 16*sample->crypt_byte_block) {
8856 break;
8857 }
8858 av_aes_crypt(sc->cenc.aes_ctx, data, data, sample->crypt_byte_block, iv, 1);
8859 data += 16*sample->crypt_byte_block;
8860 rem_bytes -= 16*sample->crypt_byte_block;
8861 data += FFMIN(16*sample->skip_byte_block, rem_bytes);
8862 rem_bytes -= FFMIN(16*sample->skip_byte_block, rem_bytes);
8863 }
8864 input += sample->subsamples[i].bytes_of_protected_data;
8865 size -= sample->subsamples[i].bytes_of_protected_data;
8866 }
8867
8868 if (size > 0) {
8869 av_log(c->fc, AV_LOG_ERROR, "leftover packet bytes after subsample processing\n");
8870 return AVERROR_INVALIDDATA;
8871 }
8872
8873 return 0;
8874}
8875
8876static int cenc_decrypt(MOVContext *c, MOVStreamContext *sc, AVEncryptionInfo *sample, uint8_t *input, int size)
8877{
8878 if (sample->scheme == MKBETAG('c','e','n','c') && !sample->crypt_byte_block && !sample->skip_byte_block) {
8879 return cenc_scheme_decrypt(c, sc, sample, input, size);
8880 } else if (sample->scheme == MKBETAG('c','b','c','1') && !sample->crypt_byte_block && !sample->skip_byte_block) {
8881 return cbc1_scheme_decrypt(c, sc, sample, input, size);
8882 } else if (sample->scheme == MKBETAG('c','e','n','s')) {
8883 return cens_scheme_decrypt(c, sc, sample, input, size);
8884 } else if (sample->scheme == MKBETAG('c','b','c','s')) {
8885 return cbcs_scheme_decrypt(c, sc, sample, input, size);
8886 } else {
8887 av_log(c->fc, AV_LOG_ERROR, "invalid encryption scheme\n");
8888 return AVERROR_INVALIDDATA;
8889 }
8890}
8891
8893{
8894 int current = frag_index->current;
8895
8896 if (!frag_index->nb_items)
8897 return NULL;
8898
8899 // Check frag_index->current is the right one for pkt. It can out of sync.
8900 if (current >= 0 && current < frag_index->nb_items) {
8901 if (frag_index->item[current].moof_offset < pkt->pos &&
8902 (current + 1 == frag_index->nb_items ||
8903 frag_index->item[current + 1].moof_offset > pkt->pos))
8904 return get_frag_stream_info(frag_index, current, id);
8905 }
8906
8907
8908 for (int i = 0; i < frag_index->nb_items; i++) {
8909 if (frag_index->item[i].moof_offset > pkt->pos)
8910 break;
8911 current = i;
8912 }
8913 frag_index->current = current;
8914 return get_frag_stream_info(frag_index, current, id);
8915}
8916
8917static int cenc_filter(MOVContext *mov, AVStream* st, MOVStreamContext *sc, AVPacket *pkt, int current_index)
8918{
8919 MOVFragmentStreamInfo *frag_stream_info;
8920 MOVEncryptionIndex *encryption_index;
8921 AVEncryptionInfo *encrypted_sample;
8922 int encrypted_index, ret;
8923
8924 frag_stream_info = get_frag_stream_info_from_pkt(&mov->frag_index, pkt, sc->id);
8925 encrypted_index = current_index;
8926 encryption_index = NULL;
8927 if (frag_stream_info) {
8928 // Note this only supports encryption info in the first sample descriptor.
8929 if (frag_stream_info->stsd_id == 1) {
8930 if (frag_stream_info->encryption_index) {
8931 encrypted_index = current_index - frag_stream_info->index_base;
8932 encryption_index = frag_stream_info->encryption_index;
8933 } else {
8934 encryption_index = sc->cenc.encryption_index;
8935 }
8936 }
8937 } else {
8938 encryption_index = sc->cenc.encryption_index;
8939 }
8940
8941 if (encryption_index) {
8942 if (encryption_index->auxiliary_info_sample_count &&
8943 !encryption_index->nb_encrypted_samples) {
8944 av_log(mov->fc, AV_LOG_ERROR, "saiz atom found without saio\n");
8945 return AVERROR_INVALIDDATA;
8946 }
8947 if (encryption_index->auxiliary_offsets_count &&
8948 !encryption_index->nb_encrypted_samples) {
8949 av_log(mov->fc, AV_LOG_ERROR, "saio atom found without saiz\n");
8950 return AVERROR_INVALIDDATA;
8951 }
8952
8953 encrypted_sample = NULL;
8954 if (!encryption_index->nb_encrypted_samples) {
8955 // Full-sample encryption with default settings.
8956 encrypted_sample = sc->cenc.default_encrypted_sample;
8957 } else if (encrypted_index >= 0 && encrypted_index < encryption_index->nb_encrypted_samples) {
8958 // Per-sample setting override.
8959 encrypted_sample = encryption_index->encrypted_samples[encrypted_index];
8960 if (!encrypted_sample) {
8961 encrypted_sample = sc->cenc.default_encrypted_sample;
8962 }
8963 }
8964
8965 if (!encrypted_sample) {
8966 av_log(mov->fc, AV_LOG_ERROR, "Incorrect number of samples in encryption info\n");
8967 return AVERROR_INVALIDDATA;
8968 }
8969
8970 if (mov->decryption_keys || mov->decryption_default_key) {
8971 return cenc_decrypt(mov, sc, encrypted_sample, pkt->data, pkt->size);
8972 } else {
8973 size_t size;
8974 uint8_t *side_data = av_encryption_info_add_side_data(encrypted_sample, &size);
8975 if (!side_data)
8976 return AVERROR(ENOMEM);
8978 if (ret < 0)
8979 av_free(side_data);
8980 return ret;
8981 }
8982 }
8983
8984 return 0;
8985}
8986
8988{
8989 const int OPUS_SEEK_PREROLL_MS = 80;
8990 int ret;
8991 AVStream *st;
8992 size_t size;
8993 uint16_t pre_skip;
8994
8995 if (c->fc->nb_streams < 1)
8996 return 0;
8997 st = c->fc->streams[c->fc->nb_streams-1];
8998
8999 if ((uint64_t)atom.size > (1<<30) || atom.size < 11 || st->codecpar->extradata)
9000 return AVERROR_INVALIDDATA;
9001
9002 /* Check OpusSpecificBox version. */
9003 if (avio_r8(pb) != 0) {
9004 av_log(c->fc, AV_LOG_ERROR, "unsupported OpusSpecificBox version\n");
9005 return AVERROR_INVALIDDATA;
9006 }
9007
9008 /* OpusSpecificBox size plus magic for Ogg OpusHead header. */
9009 size = atom.size + 8;
9010
9011 if ((ret = ff_alloc_extradata(st->codecpar, size)) < 0)
9012 return ret;
9013
9014 AV_WL32A(st->codecpar->extradata, MKTAG('O','p','u','s'));
9015 AV_WL32A(st->codecpar->extradata + 4, MKTAG('H','e','a','d'));
9016 AV_WB8(st->codecpar->extradata + 8, 1); /* OpusHead version */
9017 if ((ret = ffio_read_size(pb, st->codecpar->extradata + 9, size - 9)) < 0) {
9019 st->codecpar->extradata_size = 0;
9020 return ret;
9021 }
9022
9023 /* OpusSpecificBox is stored in big-endian, but OpusHead is
9024 little-endian; aside from the preceding magic and version they're
9025 otherwise currently identical. Data after output gain at offset 16
9026 doesn't need to be bytewapped. */
9027 pre_skip = AV_RB16A(st->codecpar->extradata + 10);
9028 AV_WL16A(st->codecpar->extradata + 10, pre_skip);
9029 AV_WL32A(st->codecpar->extradata + 12, AV_RB32A(st->codecpar->extradata + 12));
9030 AV_WL16A(st->codecpar->extradata + 16, AV_RB16A(st->codecpar->extradata + 16));
9031
9032 st->codecpar->initial_padding = pre_skip;
9034 (AVRational){1, 1000},
9035 (AVRational){1, 48000});
9036
9037 return 0;
9038}
9039
9041{
9042 AVStream *st;
9043 unsigned format_info;
9044 int channel_assignment, channel_assignment1, channel_assignment2;
9045 int ratebits;
9046 uint64_t chmask;
9047
9048 if (c->fc->nb_streams < 1)
9049 return 0;
9050 st = c->fc->streams[c->fc->nb_streams-1];
9051
9052 if (atom.size < 10)
9053 return AVERROR_INVALIDDATA;
9054
9055 format_info = avio_rb32(pb);
9056
9057 ratebits = (format_info >> 28) & 0xF;
9058 channel_assignment1 = (format_info >> 15) & 0x1F;
9059 channel_assignment2 = format_info & 0x1FFF;
9060 if (channel_assignment2)
9061 channel_assignment = channel_assignment2;
9062 else
9063 channel_assignment = channel_assignment1;
9064
9065 st->codecpar->frame_size = 40 << (ratebits & 0x7);
9066 st->codecpar->sample_rate = mlp_samplerate(ratebits);
9067
9069 chmask = truehd_layout(channel_assignment);
9071
9072 return 0;
9073}
9074
9076{
9077 AVStream *st;
9078 uint8_t buf[ISOM_DVCC_DVVC_SIZE];
9079 int ret;
9080 int64_t read_size = atom.size;
9081
9082 if (c->fc->nb_streams < 1)
9083 return 0;
9084 st = c->fc->streams[c->fc->nb_streams-1];
9085
9086 // At most 24 bytes
9087 read_size = FFMIN(read_size, ISOM_DVCC_DVVC_SIZE);
9088
9089 if ((ret = ffio_read_size(pb, buf, read_size)) < 0)
9090 return ret;
9091
9092 return ff_isom_parse_dvcc_dvvc(c->fc, st, buf, read_size);
9093}
9094
9096{
9097 AVStream *st;
9098 AVPacketSideData *sd;
9099 int ret;
9100
9101 if (c->fc->nb_streams < 1)
9102 return 0;
9103 st = c->fc->streams[c->fc->nb_streams - 1];
9104
9105 if (atom.size < 23 || atom.size > INT_MAX - AV_INPUT_BUFFER_PADDING_SIZE)
9106 return AVERROR_INVALIDDATA;
9107
9111 atom.size, 0);
9112 if (!sd)
9113 return AVERROR(ENOMEM);
9114
9115 ret = ffio_read_size(pb, sd->data, atom.size);
9116 if (ret < 0)
9117 return ret;
9118
9119 return 0;
9120}
9121
9123{
9124 AVStream *st;
9125 uint8_t *buf;
9126 int ret, old_size, num_arrays;
9127
9128 if (c->fc->nb_streams < 1)
9129 return 0;
9130 st = c->fc->streams[c->fc->nb_streams-1];
9131
9132 if (!st->codecpar->extradata_size)
9133 // TODO: handle lhvC when present before hvcC
9134 return 0;
9135
9136 if (atom.size < 6 || st->codecpar->extradata_size < 23 ||
9137 atom.size > INT_MAX - AV_INPUT_BUFFER_PADDING_SIZE) {
9138 return AVERROR_INVALIDDATA;
9139 }
9140
9142 if (!buf)
9143 return AVERROR(ENOMEM);
9144 memset(buf + atom.size, 0, AV_INPUT_BUFFER_PADDING_SIZE);
9145
9146 ret = ffio_read_size(pb, buf, atom.size);
9147 if (ret < 0) {
9148 av_free(buf);
9149 av_log(c->fc, AV_LOG_WARNING, "lhvC atom truncated\n");
9150 return 0;
9151 }
9152
9153 num_arrays = buf[5];
9154 old_size = st->codecpar->extradata_size;
9155 atom.size -= 8 /* account for mov_realloc_extradata offsetting */
9156 + 6 /* lhvC bytes before the arrays*/;
9157
9158 ret = mov_realloc_extradata(st->codecpar, atom);
9159 if (ret < 0) {
9160 av_free(buf);
9161 return ret;
9162 }
9163
9164 st->codecpar->extradata[22] += num_arrays;
9165 memcpy(st->codecpar->extradata + old_size, buf + 6, atom.size + 8);
9166
9168
9169 av_free(buf);
9170 return 0;
9171}
9172
9174{
9175 AVFormatContext *ctx = c->fc;
9176 AVStream *st = NULL;
9177 AVBPrint scheme_buf, value_buf;
9178 int64_t scheme_str_len = 0, value_str_len = 0;
9179 int version, flags, ret = AVERROR_BUG;
9180 int64_t size = atom.size;
9181
9182 if (atom.size < 6)
9183 // 4 bytes for version + flags, 2x 1 byte for null
9184 return AVERROR_INVALIDDATA;
9185
9186 if (c->fc->nb_streams < 1)
9187 return 0;
9188 st = c->fc->streams[c->fc->nb_streams-1];
9189
9190 version = avio_r8(pb);
9191 flags = avio_rb24(pb);
9192 size -= 4;
9193
9194 if (version != 0 || flags != 0) {
9196 "Unsupported 'kind' box with version %d, flags: %x",
9197 version, flags);
9198 return AVERROR_INVALIDDATA;
9199 }
9200
9203
9204 if ((scheme_str_len = ff_read_string_to_bprint_overwrite(pb, &scheme_buf,
9205 size)) < 0) {
9206 ret = scheme_str_len;
9207 goto cleanup;
9208 }
9209
9210 if (scheme_str_len + 1 >= size) {
9211 // we need to have another string, even if nullptr.
9212 // we check with + 1 since we expect that if size was not hit,
9213 // an additional null was read.
9214 ret = AVERROR_INVALIDDATA;
9215 goto cleanup;
9216 }
9217
9218 size -= scheme_str_len + 1;
9219
9220 if ((value_str_len = ff_read_string_to_bprint_overwrite(pb, &value_buf,
9221 size)) < 0) {
9222 ret = value_str_len;
9223 goto cleanup;
9224 }
9225
9226 if (value_str_len == size) {
9227 // in case of no trailing null, box is not valid.
9228 ret = AVERROR_INVALIDDATA;
9229 goto cleanup;
9230 }
9231
9233 "%s stream %d KindBox(scheme: %s, value: %s)\n",
9235 st->index,
9236 scheme_buf.str, value_buf.str);
9237
9238 for (int i = 0; ff_mov_track_kind_table[i].scheme_uri; i++) {
9240 if (!av_strstart(scheme_buf.str, map.scheme_uri, NULL))
9241 continue;
9242
9243 for (int j = 0; map.value_maps[j].disposition; j++) {
9244 const struct MP4TrackKindValueMapping value_map = map.value_maps[j];
9245 if (!av_strstart(value_buf.str, value_map.value, NULL))
9246 continue;
9247
9248 st->disposition |= value_map.disposition;
9249 }
9250 }
9251
9252 ret = 0;
9253
9254cleanup:
9255
9256 av_bprint_finalize(&scheme_buf, NULL);
9257 av_bprint_finalize(&value_buf, NULL);
9258
9259 return ret;
9260}
9261
9263{
9264 AVStream *st;
9265 AVChannelLayout ch_layout = { 0 };
9266 int ret, i, version, type;
9267 int ambisonic_order, channel_order, normalization, channel_count;
9268 int ambi_channels, non_diegetic_channels;
9269
9270 if (c->fc->nb_streams < 1)
9271 return 0;
9272
9273 st = c->fc->streams[c->fc->nb_streams - 1];
9274
9275 if (atom.size < 16) {
9276 av_log(c->fc, AV_LOG_ERROR, "SA3D audio box too small\n");
9277 return AVERROR_INVALIDDATA;
9278 }
9279
9280 version = avio_r8(pb);
9281 if (version) {
9282 av_log(c->fc, AV_LOG_WARNING, "Unsupported SA3D box version %d\n", version);
9283 return 0;
9284 }
9285
9286 type = avio_r8(pb);
9287 if (type & 0x7f) {
9288 av_log(c->fc, AV_LOG_WARNING,
9289 "Unsupported ambisonic type %d\n", type & 0x7f);
9290 return 0;
9291 }
9292 non_diegetic_channels = (type >> 7) * 2; // head_locked_stereo
9293
9294 ambisonic_order = avio_rb32(pb);
9295
9296 channel_order = avio_r8(pb);
9297 if (channel_order) {
9298 av_log(c->fc, AV_LOG_WARNING,
9299 "Unsupported channel_order %d\n", channel_order);
9300 return 0;
9301 }
9302
9303 normalization = avio_r8(pb);
9304 if (normalization) {
9305 av_log(c->fc, AV_LOG_WARNING,
9306 "Unsupported normalization %d\n", normalization);
9307 return 0;
9308 }
9309
9310 channel_count = avio_rb32(pb);
9311 if (ambisonic_order < 0 || ambisonic_order > 31 ||
9312 channel_count != ((ambisonic_order + 1LL) * (ambisonic_order + 1LL) +
9313 non_diegetic_channels)) {
9314 av_log(c->fc, AV_LOG_ERROR,
9315 "Invalid number of channels (%d / %d)\n",
9316 channel_count, ambisonic_order);
9317 return 0;
9318 }
9319 ambi_channels = channel_count - non_diegetic_channels;
9320
9321 ret = av_channel_layout_custom_init(&ch_layout, channel_count);
9322 if (ret < 0)
9323 return 0;
9324
9325 for (i = 0; i < channel_count; i++) {
9326 unsigned channel = avio_rb32(pb);
9327
9328 if (channel >= channel_count) {
9329 av_log(c->fc, AV_LOG_ERROR, "Invalid channel index (%d / %d)\n",
9330 channel, ambisonic_order);
9331 av_channel_layout_uninit(&ch_layout);
9332 return 0;
9333 }
9334 if (channel >= ambi_channels)
9335 ch_layout.u.map[i].id = channel - ambi_channels;
9336 else
9337 ch_layout.u.map[i].id = AV_CHAN_AMBISONIC_BASE + channel;
9338 }
9339
9341 if (ret < 0) {
9342 av_channel_layout_uninit(&ch_layout);
9343 return 0;
9344 }
9345
9347 st->codecpar->ch_layout = ch_layout;
9348
9349 return 0;
9350}
9351
9353{
9354 AVStream *st;
9355 int version;
9356
9357 if (c->fc->nb_streams < 1)
9358 return 0;
9359
9360 st = c->fc->streams[c->fc->nb_streams - 1];
9361
9362 if (atom.size < 5) {
9363 av_log(c->fc, AV_LOG_ERROR, "Empty SAND audio box\n");
9364 return AVERROR_INVALIDDATA;
9365 }
9366
9367 version = avio_r8(pb);
9368 if (version) {
9369 av_log(c->fc, AV_LOG_WARNING, "Unsupported SAND box version %d\n", version);
9370 return 0;
9371 }
9372
9374
9375 return 0;
9376}
9377
9378static int rb_size(AVIOContext *pb, int64_t *value, int size)
9379{
9380 if (size == 0)
9381 *value = 0;
9382 else if (size == 1)
9383 *value = avio_r8(pb);
9384 else if (size == 2)
9385 *value = avio_rb16(pb);
9386 else if (size == 4)
9387 *value = avio_rb32(pb);
9388 else if (size == 8) {
9389 *value = avio_rb64(pb);
9390 if (*value < 0)
9391 return -1;
9392 } else
9393 return -1;
9394 return size;
9395}
9396
9398{
9399 avio_rb32(pb); // version & flags.
9400 c->primary_item_id = avio_rb16(pb);
9401 av_log(c->fc, AV_LOG_TRACE, "pitm: primary_item_id %d\n", c->primary_item_id);
9402 return atom.size;
9403}
9404
9406{
9407 c->idat_offset = avio_tell(pb);
9408 return 0;
9409}
9410
9412{
9413 HEIFItem **heif_item;
9414 int version, offset_size, length_size, base_offset_size, index_size;
9415 int item_count, extent_count;
9416 int64_t base_offset, extent_offset, extent_length;
9417 uint8_t value;
9418
9419 if (c->found_iloc) {
9420 av_log(c->fc, AV_LOG_INFO, "Duplicate iloc box found\n");
9421 return 0;
9422 }
9423
9424 version = avio_r8(pb);
9425 avio_rb24(pb); // flags.
9426
9427 value = avio_r8(pb);
9428 offset_size = (value >> 4) & 0xF;
9429 length_size = value & 0xF;
9430 value = avio_r8(pb);
9431 base_offset_size = (value >> 4) & 0xF;
9432 index_size = !version ? 0 : (value & 0xF);
9433 if (index_size) {
9434 avpriv_report_missing_feature(c->fc, "iloc: index_size != 0");
9435 return AVERROR_PATCHWELCOME;
9436 }
9437 item_count = (version < 2) ? avio_rb16(pb) : avio_rb32(pb);
9438
9439 if (item_count > atom.size)
9440 return AVERROR_INVALIDDATA;
9441
9442 heif_item = av_realloc_array(c->heif_item, FFMAX(item_count, c->nb_heif_item), sizeof(*c->heif_item));
9443 if (!heif_item)
9444 return AVERROR(ENOMEM);
9445 c->heif_item = heif_item;
9446 if (item_count > c->nb_heif_item)
9447 memset(&c->heif_item[c->nb_heif_item], 0,
9448 sizeof(*c->heif_item) * (item_count - c->nb_heif_item));
9449 c->nb_heif_item = FFMAX(c->nb_heif_item, item_count);
9450
9451 av_log(c->fc, AV_LOG_TRACE, "iloc: item_count %d\n", item_count);
9452 for (int i = 0; i < item_count; i++) {
9453 HEIFItem *item = NULL;
9454 int item_id = (version < 2) ? avio_rb16(pb) : avio_rb32(pb);
9455 int offset_type = (version > 0) ? avio_rb16(pb) & 0xf : 0;
9456 int j;
9457
9458 if (avio_feof(pb))
9459 return AVERROR_INVALIDDATA;
9460 if (offset_type > 1) {
9461 avpriv_report_missing_feature(c->fc, "iloc offset type %d", offset_type);
9462 return AVERROR_PATCHWELCOME;
9463 }
9464
9465 avio_rb16(pb); // data_reference_index.
9466 if (rb_size(pb, &base_offset, base_offset_size) < 0)
9467 return AVERROR_INVALIDDATA;
9468 extent_count = avio_rb16(pb);
9469 if (extent_count > 1) {
9470 // For still AVIF images, we only support one extent item.
9471 avpriv_report_missing_feature(c->fc, "iloc: extent_count > 1");
9472 return AVERROR_PATCHWELCOME;
9473 }
9474
9475 if (rb_size(pb, &extent_offset, offset_size) < 0 ||
9476 rb_size(pb, &extent_length, length_size) < 0 ||
9477 base_offset > INT64_MAX - extent_offset)
9478 return AVERROR_INVALIDDATA;
9479
9480 for (j = 0; j < c->nb_heif_item; j++) {
9481 item = c->heif_item[j];
9482 if (!item)
9483 item = c->heif_item[j] = av_mallocz(sizeof(*item));
9484 else if (item->item_id != item_id)
9485 continue;
9486 break;
9487 }
9488 if (!item)
9489 return AVERROR(ENOMEM);
9490 if (j == c->nb_heif_item)
9491 return AVERROR_INVALIDDATA;
9492
9493 item->item_id = item_id;
9494
9495 if (offset_type == 1)
9496 item->is_idat_relative = 1;
9497 item->extent_length = extent_length;
9498 item->extent_offset = base_offset + extent_offset;
9499 av_log(c->fc, AV_LOG_TRACE, "iloc: item_idx %d, item->item_id %d, offset_type %d, "
9500 "extent_offset %"PRId64", extent_length %"PRId64"\n",
9501 i, item->item_id, offset_type, item->extent_offset, item->extent_length);
9502 }
9503
9504 c->found_iloc = 1;
9505 return atom.size;
9506}
9507
9509{
9510 HEIFItem *item = NULL;
9511 AVBPrint item_name;
9512 int64_t size = atom.size;
9513 uint32_t item_type;
9514 int item_id;
9515 int i, version, ret;
9516
9517 version = avio_r8(pb);
9518 avio_rb24(pb); // flags.
9519 size -= 4;
9520 if (size < 0)
9521 return AVERROR_INVALIDDATA;
9522
9523 if (version < 2) {
9524 avpriv_report_missing_feature(c->fc, "infe version < 2");
9525 avio_skip(pb, size);
9526 return 1;
9527 }
9528
9529 item_id = version > 2 ? avio_rb32(pb) : avio_rb16(pb);
9530 avio_rb16(pb); // item_protection_index
9531 item_type = avio_rl32(pb);
9532 size -= 8;
9533 if (size < 1)
9534 return AVERROR_INVALIDDATA;
9535
9538 if (ret < 0) {
9540 return ret;
9541 }
9542
9543 av_log(c->fc, AV_LOG_TRACE, "infe: item_id %d, item_type %s, item_name %s\n",
9544 item_id, av_fourcc2str(item_type), item_name.str);
9545
9546 size -= ret + 1;
9547 if (size > 0)
9548 avio_skip(pb, size);
9549
9550 for (i = 0; i < c->nb_heif_item; i++) {
9551 item = c->heif_item[i];
9552 if (!item)
9553 item = c->heif_item[i] = av_mallocz(sizeof(*item));
9554 else if (item->item_id != item_id)
9555 continue;
9556 break;
9557 }
9558 if (!item) {
9560 return AVERROR(ENOMEM);
9561 }
9562 if (i == c->nb_heif_item) {
9564 return AVERROR_INVALIDDATA;
9565 }
9566
9567 av_freep(&item->name);
9568 av_bprint_finalize(&item_name, ret ? &item->name : NULL);
9569 item->item_id = item_id;
9570 item->type = item_type;
9571
9572 switch (item_type) {
9573 case MKTAG('a','v','0','1'):
9574 case MKTAG('j','p','e','g'):
9575 case MKTAG('h','v','c','1'):
9576 ret = heif_add_stream(c, item);
9577 if (ret < 0)
9578 return ret;
9579 break;
9580 }
9581
9582 return 0;
9583}
9584
9586{
9587 HEIFItem **heif_item;
9588 int entry_count;
9589 int version, got_stream = 0, ret, i;
9590
9591 if (c->found_iinf) {
9592 av_log(c->fc, AV_LOG_WARNING, "Duplicate iinf box found\n");
9593 return 0;
9594 }
9595
9596 version = avio_r8(pb);
9597 avio_rb24(pb); // flags.
9598 entry_count = version ? avio_rb32(pb) : avio_rb16(pb);
9599
9600 if (entry_count > atom.size)
9601 return AVERROR_INVALIDDATA;
9602
9603 heif_item = av_realloc_array(c->heif_item, FFMAX(entry_count, c->nb_heif_item), sizeof(*c->heif_item));
9604 if (!heif_item)
9605 return AVERROR(ENOMEM);
9606 c->heif_item = heif_item;
9607 if (entry_count > c->nb_heif_item)
9608 memset(&c->heif_item[c->nb_heif_item], 0,
9609 sizeof(*c->heif_item) * (entry_count - c->nb_heif_item));
9610 c->nb_heif_item = FFMAX(c->nb_heif_item, entry_count);
9611
9612 for (i = 0; i < entry_count; i++) {
9613 MOVAtom infe;
9614
9615 infe.size = avio_rb32(pb) - 8;
9616 infe.type = avio_rl32(pb);
9617 if (avio_feof(pb)) {
9618 ret = AVERROR_INVALIDDATA;
9619 goto fail;
9620 }
9621 ret = mov_read_infe(c, pb, infe);
9622 if (ret < 0)
9623 goto fail;
9624 if (!ret)
9625 got_stream = 1;
9626 }
9627
9628 c->found_iinf = got_stream;
9629 return 0;
9630fail:
9631 for (; i >= 0; i--) {
9632 HEIFItem *item = c->heif_item[i];
9633
9634 if (!item)
9635 continue;
9636
9637 av_freep(&item->name);
9638 }
9639 return ret;
9640}
9641
9643{
9644 HEIFItem *item = NULL;
9645 HEIFGrid *grid;
9646 int entries, i;
9647 int from_item_id = version ? avio_rb32(pb) : avio_rb16(pb);
9648 int ret = 0;
9649
9650 for (int i = 0; i < c->nb_heif_grid; i++) {
9651 if (c->heif_grid[i].item->item_id == from_item_id) {
9652 av_log(c->fc, AV_LOG_ERROR, "More than one 'dimg' box "
9653 "referencing the same Derived Image item\n");
9654 return AVERROR_INVALIDDATA;
9655 }
9656 }
9657 for (int i = 0; i < c->nb_heif_item; i++) {
9658 if (!c->heif_item[i] || c->heif_item[i]->item_id != from_item_id)
9659 continue;
9660 item = c->heif_item[i];
9661
9662 switch (item->type) {
9663 case MKTAG('g','r','i','d'):
9664 case MKTAG('i','o','v','l'):
9665 break;
9666 default:
9667 avpriv_report_missing_feature(c->fc, "Derived Image item of type %s",
9668 av_fourcc2str(item->type));
9669 return 0;
9670 }
9671 break;
9672 }
9673 if (!item) {
9674 av_log(c->fc, AV_LOG_ERROR, "Missing grid information\n");
9675 return AVERROR_INVALIDDATA;
9676 }
9677
9678 entries = avio_rb16(pb);
9679 if (!entries) {
9680 av_log(c->fc, AV_LOG_ERROR,
9681 "Derived image item references no input images\n");
9682 return AVERROR_INVALIDDATA;
9683 }
9684
9685 grid = av_realloc_array(c->heif_grid, c->nb_heif_grid + 1U,
9686 sizeof(*c->heif_grid));
9687 if (!grid)
9688 return AVERROR(ENOMEM);
9689 c->heif_grid = grid;
9690 grid = &grid[c->nb_heif_grid];
9691
9692 grid->tile_id_list = av_malloc_array(entries, sizeof(*grid->tile_id_list));
9693 grid->tile_idx_list = av_calloc(entries, sizeof(*grid->tile_idx_list));
9694 grid->tile_item_list = av_calloc(entries, sizeof(*grid->tile_item_list));
9695 if (!grid->tile_id_list || !grid->tile_item_list || !grid->tile_idx_list) {
9696 ret = AVERROR(ENOMEM);
9697 goto fail;
9698 }
9699 /* 'to' item ids */
9700 for (i = 0; i < entries; i++) {
9701 grid->tile_id_list[i] = version ? avio_rb32(pb) : avio_rb16(pb);
9702
9703 if (avio_feof(pb)) {
9704 ret = AVERROR_INVALIDDATA;
9705 goto fail;
9706 }
9707 }
9708
9709 grid->nb_tiles = entries;
9710 grid->item = item;
9711 ++c->nb_heif_grid;
9712
9713 av_log(c->fc, AV_LOG_TRACE, "dimg: from_item_id %d, entries %d\n",
9714 from_item_id, entries);
9715
9716 return 0;
9717fail:
9718 av_freep(&grid->tile_id_list);
9719 av_freep(&grid->tile_idx_list);
9720 av_freep(&grid->tile_item_list);
9721
9722 return ret;
9723}
9724
9725static int mov_read_iref_cdsc(MOVContext *c, AVIOContext *pb, uint32_t type, int version, uint32_t size)
9726{
9727 HEIFItem *from_item = NULL;
9728 int entries;
9729 int item_id_size = version ? 4 : 2;
9730 int from_item_id = version ? avio_rb32(pb) : avio_rb16(pb);
9731 const HEIFItemRef ref = { type, from_item_id };
9732
9733 from_item = get_heif_item(c, from_item_id);
9734 if (!from_item) {
9735 av_log(c->fc, AV_LOG_ERROR, "Missing stream referenced by thmb item\n");
9736 return AVERROR_INVALIDDATA;
9737 }
9738
9739 entries = avio_rb16(pb);
9740 if ((int64_t)entries * item_id_size > (int64_t)size - item_id_size - 2) {
9741 av_log(c->fc, AV_LOG_ERROR, "iref %s entry count %d exceeds the sub-box size\n",
9742 av_fourcc2str(type), entries);
9743 return AVERROR_INVALIDDATA;
9744 }
9745 /* 'to' item ids */
9746 for (int i = 0; i < entries; i++) {
9747 HEIFItem *item = get_heif_item(c, version ? avio_rb32(pb) : avio_rb16(pb));
9748
9749 if (avio_feof(pb))
9750 return AVERROR_INVALIDDATA;
9751
9752 if (!item) {
9753 av_log(c->fc, AV_LOG_WARNING, "Missing stream referenced by %s item\n",
9755 continue;
9756 }
9757
9758 if (!av_dynarray2_add((void **)&item->iref_list, &item->nb_iref_list,
9759 sizeof(*item->iref_list), (const uint8_t *)&ref))
9760 return AVERROR(ENOMEM);
9761 }
9762
9763 av_log(c->fc, AV_LOG_TRACE, "%s: from_item_id %d, entries %d\n",
9764 av_fourcc2str(type), from_item_id, entries);
9765
9766 return 0;
9767}
9768
9770{
9771 int version = avio_r8(pb);
9772 int ret;
9773
9774 avio_rb24(pb); // flags
9775 atom.size -= 4;
9776
9777 if (version > 1) {
9778 av_log(c->fc, AV_LOG_WARNING, "Unknown iref box version %d\n", version);
9779 return 0;
9780 }
9781
9782 while (atom.size) {
9783 int64_t next = avio_tell(pb);
9784 uint32_t type, size = avio_rb32(pb);
9785
9786 if (size < 14 || size > atom.size || next > INT64_MAX - size)
9787 return AVERROR_INVALIDDATA;
9788
9789 next += size;
9790 type = avio_rl32(pb);
9791 switch (type) {
9792 case MKTAG('d','i','m','g'):
9793 ret = mov_read_iref_dimg(c, pb, version);
9794 if (ret < 0)
9795 return ret;
9796 break;
9797 case MKTAG('c','d','s','c'):
9798 case MKTAG('t','h','m','b'):
9799 ret = mov_read_iref_cdsc(c, pb, type, version, size - 8);
9800 if (ret < 0)
9801 return ret;
9802 break;
9803 default:
9804 av_log(c->fc, AV_LOG_DEBUG, "Unknown iref type %s size %"PRIu32"\n",
9806 }
9807
9808 atom.size -= size;
9809 avio_seek(pb, next, SEEK_SET);
9810 }
9811 return 0;
9812}
9813
9815{
9816 HEIFItem *item;
9817 uint32_t width, height;
9818
9819 avio_r8(pb); /* version */
9820 avio_rb24(pb); /* flags */
9821 width = avio_rb32(pb);
9822 height = avio_rb32(pb);
9823
9824 av_log(c->fc, AV_LOG_TRACE, "ispe: item_id %d, width %"PRIu32", height %"PRIu32"\n",
9825 c->cur_item_id, width, height);
9826
9827 if (!width || !height || width > INT_MAX || height > INT_MAX) {
9828 av_log(c->fc, AV_LOG_ERROR, "Invalid ispe dimensions %"PRIu32"x%"PRIu32"\n",
9829 width, height);
9830 return AVERROR_INVALIDDATA;
9831 }
9832
9833 item = get_heif_item(c, c->cur_item_id);
9834 if (item) {
9835 item->width = width;
9836 item->height = height;
9837 }
9838
9839 return 0;
9840}
9841
9843{
9844 HEIFItem *item;
9845 int angle;
9846
9847 angle = avio_r8(pb) & 0x3;
9848
9849 av_log(c->fc, AV_LOG_TRACE, "irot: item_id %d, angle %u\n",
9850 c->cur_item_id, angle);
9851
9852 item = get_heif_item(c, c->cur_item_id);
9853 if (item) {
9854 // angle * 90 specifies the angle (in anti-clockwise direction)
9855 // in units of degrees.
9856 item->rotation = angle * 90;
9857 }
9858
9859 return 0;
9860}
9861
9863{
9864 HEIFItem *item;
9865 int axis;
9866
9867 axis = avio_r8(pb) & 0x1;
9868
9869 av_log(c->fc, AV_LOG_TRACE, "imir: item_id %d, axis %u\n",
9870 c->cur_item_id, axis);
9871
9872 item = get_heif_item(c, c->cur_item_id);
9873 if (item) {
9874 item->hflip = axis;
9875 item->vflip = !axis;
9876 }
9877
9878 return 0;
9879}
9880
9882{
9883 typedef struct MOVAtoms {
9884 FFIOContext b;
9885 uint32_t type;
9886 int64_t size;
9887 uint8_t *data;
9888 } MOVAtoms;
9889 MOVAtoms *atoms = NULL;
9890 MOVAtom a;
9891 unsigned count;
9892 int nb_atoms = 0;
9893 int version, flags;
9894 int ret;
9895
9896 a.size = avio_rb32(pb);
9897 a.type = avio_rl32(pb);
9898
9899 if (a.size < 8 || a.type != MKTAG('i','p','c','o'))
9900 return AVERROR_INVALIDDATA;
9901
9902 a.size -= 8;
9903 while (a.size >= 8) {
9904 MOVAtoms *ref = av_dynarray2_add((void**)&atoms, &nb_atoms, sizeof(MOVAtoms), NULL);
9905 if (!ref) {
9906 ret = AVERROR(ENOMEM);
9907 goto fail;
9908 }
9909 ref->data = NULL;
9910 ref->size = avio_rb32(pb);
9911 ref->type = avio_rl32(pb);
9912 if (ref->size > a.size || ref->size < 8)
9913 break;
9914 ref->data = av_malloc(ref->size);
9915 if (!ref->data) {
9916 ret = AVERROR_INVALIDDATA;
9917 goto fail;
9918 }
9919 av_log(c->fc, AV_LOG_TRACE, "ipco: index %d, box type %s\n", nb_atoms, av_fourcc2str(ref->type));
9920 avio_seek(pb, -8, SEEK_CUR);
9921 if (avio_read(pb, ref->data, ref->size) != ref->size) {
9922 ret = AVERROR_INVALIDDATA;
9923 goto fail;
9924 }
9925 ffio_init_read_context(&ref->b, ref->data, ref->size);
9926 a.size -= ref->size;
9927 }
9928
9929 if (a.size) {
9930 ret = AVERROR_INVALIDDATA;
9931 goto fail;
9932 }
9933
9934 a.size = avio_rb32(pb);
9935 a.type = avio_rl32(pb);
9936
9937 if (a.size < 8 || a.type != MKTAG('i','p','m','a')) {
9938 ret = AVERROR_INVALIDDATA;
9939 goto fail;
9940 }
9941
9942 version = avio_r8(pb);
9943 flags = avio_rb24(pb);
9944 count = avio_rb32(pb);
9945
9946 for (int i = 0; i < count; i++) {
9947 int item_id = version ? avio_rb32(pb) : avio_rb16(pb);
9948 int assoc_count = avio_r8(pb);
9949
9950 if (avio_feof(pb)) {
9951 ret = AVERROR_INVALIDDATA;
9952 goto fail;
9953 }
9954
9955 for (int j = 0; j < assoc_count; j++) {
9956 MOVAtoms *ref;
9957 int index = avio_r8(pb) & 0x7f;
9958 if (flags & 1) {
9959 index <<= 8;
9960 index |= avio_r8(pb);
9961 }
9962 if (index > nb_atoms || index <= 0) {
9963 ret = AVERROR_INVALIDDATA;
9964 goto fail;
9965 }
9966 ref = &atoms[--index];
9967
9968 av_log(c->fc, AV_LOG_TRACE, "ipma: property_index %d, item_id %d, item_type %s\n",
9969 index + 1, item_id, av_fourcc2str(ref->type));
9970
9971 c->cur_item_id = item_id;
9972
9973 ret = mov_read_default(c, &ref->b.pub,
9974 (MOVAtom) { .size = ref->size,
9975 .type = MKTAG('i','p','c','o') });
9976 if (ret < 0)
9977 goto fail;
9978 ffio_init_read_context(&ref->b, ref->data, ref->size);
9979 }
9980 }
9981
9982 ret = 0;
9983fail:
9984 c->cur_item_id = -1;
9985 for (int i = 0; i < nb_atoms; i++)
9986 av_free(atoms[i].data);
9987 av_free(atoms);
9988
9989 return ret;
9990}
9991
9993{ MKTAG('A','C','L','R'), mov_read_aclr },
9994{ MKTAG('A','P','R','G'), mov_read_avid },
9995{ MKTAG('A','A','L','P'), mov_read_avid },
9996{ MKTAG('A','R','E','S'), mov_read_ares },
9997{ MKTAG('a','v','s','s'), mov_read_avss },
9998{ MKTAG('a','v','1','C'), mov_read_glbl },
9999{ MKTAG('c','h','p','l'), mov_read_chpl },
10000{ MKTAG('c','o','6','4'), mov_read_stco },
10001{ MKTAG('c','o','l','r'), mov_read_colr },
10002{ MKTAG('c','t','t','s'), mov_read_ctts }, /* composition time to sample */
10003{ MKTAG('d','i','n','f'), mov_read_default },
10004{ MKTAG('D','p','x','E'), mov_read_dpxe },
10005{ MKTAG('d','r','e','f'), mov_read_dref },
10006{ MKTAG('e','d','t','s'), mov_read_default },
10007{ MKTAG('e','l','s','t'), mov_read_elst },
10008{ MKTAG('e','n','d','a'), mov_read_enda },
10009{ MKTAG('f','i','e','l'), mov_read_fiel },
10010{ MKTAG('a','d','r','m'), mov_read_adrm },
10011{ MKTAG('f','t','y','p'), mov_read_ftyp },
10012{ MKTAG('g','l','b','l'), mov_read_glbl },
10013{ MKTAG('h','d','l','r'), mov_read_hdlr },
10014{ MKTAG('i','l','s','t'), mov_read_ilst },
10015{ MKTAG('j','p','2','h'), mov_read_jp2h },
10016{ MKTAG('m','d','a','t'), mov_read_mdat },
10017{ MKTAG('m','d','h','d'), mov_read_mdhd },
10018{ MKTAG('m','d','i','a'), mov_read_default },
10019{ MKTAG('m','e','t','a'), mov_read_meta },
10020{ MKTAG('m','i','n','f'), mov_read_default },
10021{ MKTAG('m','o','o','f'), mov_read_moof },
10022{ MKTAG('m','o','o','v'), mov_read_moov },
10023{ MKTAG('m','v','e','x'), mov_read_default },
10024{ MKTAG('m','v','h','d'), mov_read_mvhd },
10025{ MKTAG('S','M','I',' '), mov_read_svq3 },
10026{ MKTAG('a','l','a','c'), mov_read_alac }, /* alac specific atom */
10027{ MKTAG('a','v','c','C'), mov_read_glbl },
10028{ MKTAG('p','a','s','p'), mov_read_pasp },
10029{ MKTAG('c','l','a','p'), mov_read_clap },
10030{ MKTAG('c','d','s','c'), mov_read_cdsc_rndr },
10031{ MKTAG('r','n','d','r'), mov_read_cdsc_rndr },
10032{ MKTAG('s','b','a','s'), mov_read_sbas },
10033{ MKTAG('v','d','e','p'), mov_read_vdep },
10034{ MKTAG('s','i','d','x'), mov_read_sidx },
10035{ MKTAG('s','t','b','l'), mov_read_default },
10036{ MKTAG('s','t','c','o'), mov_read_stco },
10037{ MKTAG('s','t','p','s'), mov_read_stps },
10038{ MKTAG('s','t','r','f'), mov_read_strf },
10039{ MKTAG('s','t','s','c'), mov_read_stsc },
10040{ MKTAG('s','t','s','d'), mov_read_stsd }, /* sample description */
10041{ MKTAG('s','t','s','s'), mov_read_stss }, /* sync sample */
10042{ MKTAG('s','t','s','z'), mov_read_stsz }, /* sample size */
10043{ MKTAG('s','t','t','s'), mov_read_stts },
10044{ MKTAG('s','t','z','2'), mov_read_stsz }, /* compact sample size */
10045{ MKTAG('s','d','t','p'), mov_read_sdtp }, /* independent and disposable samples */
10046{ MKTAG('t','k','h','d'), mov_read_tkhd }, /* track header */
10047{ MKTAG('t','f','d','t'), mov_read_tfdt },
10048{ MKTAG('t','f','h','d'), mov_read_tfhd }, /* track fragment header */
10049{ MKTAG('t','r','a','k'), mov_read_trak },
10050{ MKTAG('t','r','a','f'), mov_read_default },
10051{ MKTAG('t','r','e','f'), mov_read_default },
10052{ MKTAG('t','m','c','d'), mov_read_tmcd },
10053{ MKTAG('c','h','a','p'), mov_read_chap },
10054{ MKTAG('t','r','e','x'), mov_read_trex },
10055{ MKTAG('t','r','u','n'), mov_read_trun },
10056{ MKTAG('u','d','t','a'), mov_read_default },
10057{ MKTAG('w','a','v','e'), mov_read_wave },
10058{ MKTAG('e','s','d','s'), mov_read_esds },
10059{ MKTAG('d','a','c','3'), mov_read_dac3 }, /* AC-3 info */
10060{ MKTAG('d','e','c','3'), mov_read_dec3 }, /* EAC-3 info */
10061{ MKTAG('d','d','t','s'), mov_read_ddts }, /* DTS audio descriptor */
10062{ MKTAG('w','i','d','e'), mov_read_wide }, /* place holder */
10063{ MKTAG('w','f','e','x'), mov_read_wfex },
10064{ MKTAG('c','m','o','v'), mov_read_cmov },
10065{ MKTAG('c','h','a','n'), mov_read_chan }, /* channel layout from quicktime */
10066{ MKTAG('c','h','n','l'), mov_read_chnl }, /* channel layout from ISO-14496-12 */
10067{ MKTAG('d','v','c','1'), mov_read_dvc1 },
10068{ MKTAG('s','g','p','d'), mov_read_sgpd },
10069{ MKTAG('s','b','g','p'), mov_read_sbgp },
10070{ MKTAG('h','v','c','C'), mov_read_glbl },
10071{ MKTAG('v','v','c','C'), mov_read_glbl },
10072{ MKTAG('u','u','i','d'), mov_read_uuid },
10073{ MKTAG('C','i','n', 0x8e), mov_read_targa_y216 },
10074{ MKTAG('f','r','e','e'), mov_read_free },
10075{ MKTAG('-','-','-','-'), mov_read_custom },
10076{ MKTAG('s','i','n','f'), mov_read_default },
10077{ MKTAG('f','r','m','a'), mov_read_frma },
10078{ MKTAG('s','e','n','c'), mov_read_senc },
10079{ MKTAG('s','a','i','z'), mov_read_saiz },
10080{ MKTAG('s','a','i','o'), mov_read_saio },
10081{ MKTAG('p','s','s','h'), mov_read_pssh },
10082{ MKTAG('s','c','h','m'), mov_read_schm },
10083{ MKTAG('s','c','h','i'), mov_read_default },
10084{ MKTAG('t','e','n','c'), mov_read_tenc },
10085{ MKTAG('d','f','L','a'), mov_read_dfla },
10086{ MKTAG('s','t','3','d'), mov_read_st3d }, /* stereoscopic 3D video box */
10087{ MKTAG('s','v','3','d'), mov_read_sv3d }, /* spherical video box */
10088{ MKTAG('v','e','x','u'), mov_read_vexu }, /* video extension usage */
10089{ MKTAG('h','f','o','v'), mov_read_hfov },
10090{ MKTAG('d','O','p','s'), mov_read_dops },
10091{ MKTAG('d','m','l','p'), mov_read_dmlp },
10092{ MKTAG('S','m','D','m'), mov_read_smdm },
10093{ MKTAG('C','o','L','L'), mov_read_coll },
10094{ MKTAG('v','p','c','C'), mov_read_vpcc },
10095{ MKTAG('m','d','c','v'), mov_read_mdcv },
10096{ MKTAG('c','l','l','i'), mov_read_clli },
10097{ MKTAG('d','v','c','C'), mov_read_dvcc_dvvc },
10098{ MKTAG('d','v','v','C'), mov_read_dvcc_dvvc },
10099{ MKTAG('d','v','w','C'), mov_read_dvcc_dvvc },
10100{ MKTAG('h','v','c','E'), mov_read_hvce },
10101{ MKTAG('k','i','n','d'), mov_read_kind },
10102{ MKTAG('S','A','3','D'), mov_read_SA3D }, /* ambisonic audio box */
10103{ MKTAG('S','A','N','D'), mov_read_SAND }, /* non diegetic audio box */
10104{ MKTAG('i','l','o','c'), mov_read_iloc },
10105{ MKTAG('p','c','m','C'), mov_read_pcmc }, /* PCM configuration box */
10106{ MKTAG('p','i','t','m'), mov_read_pitm },
10107{ MKTAG('e','v','c','C'), mov_read_glbl },
10108{ MKTAG('i','d','a','t'), mov_read_idat },
10109{ MKTAG('i','m','i','r'), mov_read_imir },
10110{ MKTAG('i','r','e','f'), mov_read_iref },
10111{ MKTAG('i','s','p','e'), mov_read_ispe },
10112{ MKTAG('i','r','o','t'), mov_read_irot },
10113{ MKTAG('i','p','r','p'), mov_read_iprp },
10114{ MKTAG('i','i','n','f'), mov_read_iinf },
10115{ MKTAG('a','m','v','e'), mov_read_amve }, /* ambient viewing environment box */
10116{ MKTAG('l','h','v','C'), mov_read_lhvc },
10117{ MKTAG('l','v','c','C'), mov_read_glbl },
10118{ MKTAG('a','p','v','C'), mov_read_glbl },
10119#if CONFIG_IAMFDEC
10120{ MKTAG('i','a','c','b'), mov_read_iacb },
10121#endif
10122{ MKTAG('s','r','a','t'), mov_read_srat },
10123{ 0, NULL }
10124};
10125
10127{
10128 int64_t total_size = 0;
10129 MOVAtom a;
10130 int i;
10131
10132 if (c->atom_depth > 10) {
10133 av_log(c->fc, AV_LOG_ERROR, "Atoms too deeply nested\n");
10134 return AVERROR_INVALIDDATA;
10135 }
10136 c->atom_depth ++;
10137
10138 if (atom.size < 0)
10139 atom.size = INT64_MAX;
10140 while (total_size <= atom.size - 8) {
10141 int (*parse)(MOVContext*, AVIOContext*, MOVAtom) = NULL;
10142 a.size = avio_rb32(pb);
10143 a.type = avio_rl32(pb);
10144 if (avio_feof(pb))
10145 break;
10146 if (((a.type == MKTAG('f','r','e','e') && c->moov_retry) ||
10147 a.type == MKTAG('h','o','o','v')) &&
10148 a.size >= 8 &&
10149 c->fc->strict_std_compliance < FF_COMPLIANCE_STRICT) {
10150 uint32_t type;
10151 avio_skip(pb, 4);
10152 type = avio_rl32(pb);
10153 if (avio_feof(pb))
10154 break;
10155 avio_seek(pb, -8, SEEK_CUR);
10156 if (type == MKTAG('m','v','h','d') ||
10157 type == MKTAG('c','m','o','v')) {
10158 av_log(c->fc, AV_LOG_ERROR, "Detected moov in a free or hoov atom.\n");
10159 a.type = MKTAG('m','o','o','v');
10160 }
10161 }
10162 if (atom.type != MKTAG('r','o','o','t') &&
10163 atom.type != MKTAG('m','o','o','v')) {
10164 if (a.type == MKTAG('t','r','a','k') ||
10165 a.type == MKTAG('m','d','a','t')) {
10166 av_log(c->fc, AV_LOG_ERROR, "Broken file, trak/mdat not at top-level\n");
10167 avio_skip(pb, -8);
10168 c->atom_depth --;
10169 return 0;
10170 }
10171 }
10172 total_size += 8;
10173 if (a.size == 1 && total_size + 8 <= atom.size) { /* 64 bit extended size */
10174 a.size = avio_rb64(pb) - 8;
10175 total_size += 8;
10176 }
10177 av_log(c->fc, AV_LOG_TRACE, "type:'%s' parent:'%s' sz: %"PRId64" %"PRId64" %"PRId64"\n",
10178 av_fourcc2str(a.type), av_fourcc2str(atom.type), a.size, total_size, atom.size);
10179 if (a.size == 0) {
10180 a.size = atom.size - total_size + 8;
10181 }
10182 if (a.size < 0)
10183 break;
10184 a.size -= 8;
10185 if (a.size < 0)
10186 break;
10187 a.size = FFMIN(a.size, atom.size - total_size);
10188
10189 for (i = 0; mov_default_parse_table[i].type; i++)
10190 if (mov_default_parse_table[i].type == a.type) {
10192 break;
10193 }
10194
10195 // container is user data
10196 if (!parse && (atom.type == MKTAG('u','d','t','a') ||
10197 atom.type == MKTAG('i','l','s','t')))
10199
10200 // Supports parsing the QuickTime Metadata Keys.
10201 // https://developer.apple.com/library/mac/documentation/QuickTime/QTFF/Metadata/Metadata.html
10202 if (!parse && c->found_hdlr_mdta &&
10203 atom.type == MKTAG('m','e','t','a') &&
10204 a.type == MKTAG('k','e','y','s') &&
10205 c->meta_keys_count == 0) {
10207 }
10208
10209 if (!parse) { /* skip leaf atoms data */
10210 avio_skip(pb, a.size);
10211 } else {
10212 int64_t start_pos = avio_tell(pb);
10213 int64_t left;
10214 int err = parse(c, pb, a);
10215 if (err < 0) {
10216 c->atom_depth --;
10217 return err;
10218 }
10219 if (c->found_moov && c->found_mdat && a.size <= INT64_MAX - start_pos &&
10220 ((!(pb->seekable & AVIO_SEEKABLE_NORMAL) || c->fc->flags & AVFMT_FLAG_IGNIDX || c->frag_index.complete) ||
10221 start_pos + a.size == avio_size(pb))) {
10222 if (!(pb->seekable & AVIO_SEEKABLE_NORMAL) || c->fc->flags & AVFMT_FLAG_IGNIDX || c->frag_index.complete)
10223 c->next_root_atom = start_pos + a.size;
10224 c->atom_depth --;
10225 return 0;
10226 }
10227 left = a.size - avio_tell(pb) + start_pos;
10228 if (left > 0) /* skip garbage at atom end */
10229 avio_skip(pb, left);
10230 else if (left < 0) {
10231 av_log(c->fc, AV_LOG_WARNING,
10232 "overread end of atom '%s' by %"PRId64" bytes\n",
10233 av_fourcc2str(a.type), -left);
10234 avio_seek(pb, left, SEEK_CUR);
10235 }
10236 }
10237
10238 total_size += a.size;
10239 }
10240
10241 if (total_size < atom.size && atom.size < 0x7ffff)
10242 avio_skip(pb, atom.size - total_size);
10243
10244 c->atom_depth --;
10245 return 0;
10246}
10247
10248static int mov_probe(const AVProbeData *p)
10249{
10251 uint32_t tag;
10252 int score = 0;
10253 int moov_offset = -1;
10254
10255 /* check file header */
10256 offset = 0;
10257 for (;;) {
10258 int64_t size;
10259 int minsize = 8;
10260 /* ignore invalid offset */
10261 if ((offset + 8ULL) > (unsigned int)p->buf_size)
10262 break;
10263 size = AV_RB32(p->buf + offset);
10264 if (size == 1 && offset + 16 <= (unsigned int)p->buf_size) {
10265 size = AV_RB64(p->buf+offset + 8);
10266 minsize = 16;
10267 } else if (size == 0) {
10268 size = p->buf_size - offset;
10269 }
10270 if (size < minsize) {
10271 offset += 4;
10272 continue;
10273 }
10274 tag = AV_RL32(p->buf + offset + 4);
10275 switch(tag) {
10276 /* check for obvious tags */
10277 case MKTAG('m','o','o','v'):
10278 moov_offset = offset + 4;
10280 case MKTAG('m','d','a','t'):
10281 case MKTAG('p','n','o','t'): /* detect movs with preview pics like ew.mov and april.mov */
10282 case MKTAG('u','d','t','a'): /* Packet Video PVAuthor adds this and a lot of more junk */
10283 case MKTAG('f','t','y','p'):
10284 if (tag == MKTAG('f','t','y','p') &&
10285 ( AV_RL32(p->buf + offset + 8) == MKTAG('j','p','2',' ')
10286 || AV_RL32(p->buf + offset + 8) == MKTAG('j','p','x',' ')
10287 || AV_RL32(p->buf + offset + 8) == MKTAG('j','x','l',' ')
10288 )) {
10289 score = FFMAX(score, 5);
10290 } else {
10291 score = AVPROBE_SCORE_MAX;
10292 }
10293 break;
10294 /* those are more common words, so rate then a bit less */
10295 case MKTAG('e','d','i','w'): /* xdcam files have reverted first tags */
10296 case MKTAG('w','i','d','e'):
10297 case MKTAG('f','r','e','e'):
10298 case MKTAG('j','u','n','k'):
10299 case MKTAG('p','i','c','t'):
10300 score = FFMAX(score, AVPROBE_SCORE_MAX - 5);
10301 break;
10302 case MKTAG(0x82,0x82,0x7f,0x7d):
10303 score = FFMAX(score, AVPROBE_SCORE_EXTENSION - 5);
10304 break;
10305 case MKTAG('s','k','i','p'):
10306 case MKTAG('u','u','i','d'):
10307 case MKTAG('p','r','f','l'):
10308 /* if we only find those cause probedata is too small at least rate them */
10309 score = FFMAX(score, AVPROBE_SCORE_EXTENSION);
10310 break;
10311 }
10312 if (size > INT64_MAX - offset)
10313 break;
10314 offset += size;
10315 }
10316 if (score > AVPROBE_SCORE_MAX - 50 && moov_offset != -1) {
10317 /* moov atom in the header - we should make sure that this is not a
10318 * MOV-packed MPEG-PS */
10319 offset = moov_offset;
10320
10321 while (offset < (p->buf_size - 16)) { /* Sufficient space */
10322 /* We found an actual hdlr atom */
10323 if (AV_RL32(p->buf + offset ) == MKTAG('h','d','l','r') &&
10324 AV_RL32(p->buf + offset + 8) == MKTAG('m','h','l','r') &&
10325 AV_RL32(p->buf + offset + 12) == MKTAG('M','P','E','G')) {
10326 av_log(NULL, AV_LOG_WARNING, "Found media data tag MPEG indicating this is a MOV-packed MPEG-PS.\n");
10327 /* We found a media handler reference atom describing an
10328 * MPEG-PS-in-MOV, return a
10329 * low score to force expanding the probe window until
10330 * mpegps_probe finds what it needs */
10331 return 5;
10332 } else {
10333 /* Keep looking */
10334 offset += 2;
10335 }
10336 }
10337 }
10338
10339 return score;
10340}
10341
10342// must be done after parsing all trak because there's no order requirement
10344{
10345 MOVContext *mov = s->priv_data;
10346 MOVStreamContext *sc;
10347 int64_t cur_pos;
10348 int i, j;
10349 int chapter_track;
10350
10351 for (j = 0; j < mov->nb_chapter_tracks; j++) {
10352 AVStream *st = NULL;
10353 FFStream *sti = NULL;
10354 chapter_track = mov->chapter_tracks[j];
10355 for (i = 0; i < s->nb_streams; i++) {
10356 sc = mov->fc->streams[i]->priv_data;
10357 if (sc->id == chapter_track) {
10358 st = s->streams[i];
10359 break;
10360 }
10361 }
10362 if (!st) {
10363 av_log(s, AV_LOG_ERROR, "Referenced QT chapter track not found\n");
10364 continue;
10365 }
10366 sti = ffstream(st);
10367
10368 sc = st->priv_data;
10369 cur_pos = avio_tell(sc->pb);
10370
10373 if (!st->attached_pic.data && sti->nb_index_entries) {
10374 // Retrieve the first frame, if possible
10375 AVIndexEntry *sample = &sti->index_entries[0];
10376 if (avio_seek(sc->pb, sample->pos, SEEK_SET) != sample->pos) {
10377 av_log(s, AV_LOG_ERROR, "Failed to retrieve first frame\n");
10378 goto finish;
10379 }
10380
10381 if (ff_add_attached_pic(s, st, sc->pb, NULL, sample->size) < 0)
10382 goto finish;
10383 }
10384 } else {
10387 st->discard = AVDISCARD_ALL;
10388 for (int i = 0; i < sti->nb_index_entries; i++) {
10390 int64_t end = i+1 < sti->nb_index_entries ? sti->index_entries[i+1].timestamp : st->duration;
10391 uint8_t *title;
10392 uint16_t ch;
10393 int len, title_len;
10394
10395 if (end < sample->timestamp) {
10396 av_log(s, AV_LOG_WARNING, "ignoring stream duration which is shorter than chapters\n");
10397 end = AV_NOPTS_VALUE;
10398 }
10399
10400 if (avio_seek(sc->pb, sample->pos, SEEK_SET) != sample->pos) {
10401 av_log(s, AV_LOG_ERROR, "Chapter %d not found in file\n", i);
10402 goto finish;
10403 }
10404
10405 // the first two bytes are the length of the title
10406 len = avio_rb16(sc->pb);
10407 if (len > sample->size-2)
10408 continue;
10409 title_len = 2*len + 1;
10410 if (!(title = av_mallocz(title_len)))
10411 goto finish;
10412
10413 // The samples could theoretically be in any encoding if there's an encd
10414 // atom following, but in practice are only utf-8 or utf-16, distinguished
10415 // instead by the presence of a BOM
10416 if (!len) {
10417 title[0] = 0;
10418 } else {
10419 ch = avio_rb16(sc->pb);
10420 if (ch == 0xfeff)
10421 avio_get_str16be(sc->pb, len, title, title_len);
10422 else if (ch == 0xfffe)
10423 avio_get_str16le(sc->pb, len, title, title_len);
10424 else {
10425 AV_WB16(title, ch);
10426 if (len == 1 || len == 2)
10427 title[len] = 0;
10428 else
10429 avio_get_str(sc->pb, INT_MAX, title + 2, len - 1);
10430 }
10431 }
10432
10433 avpriv_new_chapter(s, i, st->time_base, sample->timestamp, end, title);
10434 av_freep(&title);
10435 }
10436 }
10437finish:
10438 avio_seek(sc->pb, cur_pos, SEEK_SET);
10439 }
10440}
10441
10443 int64_t value, int flags)
10444{
10445 AVTimecode tc;
10446 char buf[AV_TIMECODE_STR_SIZE];
10447 AVRational rate = st->avg_frame_rate;
10448 int ret = av_timecode_init(&tc, rate, flags, 0, s);
10449 if (ret < 0)
10450 return ret;
10451 av_dict_set(&st->metadata, "timecode",
10452 av_timecode_make_string(&tc, buf, value), 0);
10453 return 0;
10454}
10455
10457{
10458 MOVStreamContext *sc = st->priv_data;
10459 FFStream *const sti = ffstream(st);
10460 char buf[AV_TIMECODE_STR_SIZE];
10461 int64_t cur_pos = avio_tell(sc->pb);
10462 int hh, mm, ss, ff, drop;
10463
10464 if (!sti->nb_index_entries)
10465 return -1;
10466
10467 avio_seek(sc->pb, sti->index_entries->pos, SEEK_SET);
10468 avio_skip(s->pb, 13);
10469 hh = avio_r8(s->pb);
10470 mm = avio_r8(s->pb);
10471 ss = avio_r8(s->pb);
10472 drop = avio_r8(s->pb);
10473 ff = avio_r8(s->pb);
10474 snprintf(buf, AV_TIMECODE_STR_SIZE, "%02d:%02d:%02d%c%02d",
10475 hh, mm, ss, drop ? ';' : ':', ff);
10476 av_dict_set(&st->metadata, "timecode", buf, 0);
10477
10478 avio_seek(sc->pb, cur_pos, SEEK_SET);
10479 return 0;
10480}
10481
10483{
10484 MOVStreamContext *sc = st->priv_data;
10485 FFStream *const sti = ffstream(st);
10486 int flags = 0;
10487 int64_t cur_pos = avio_tell(sc->pb);
10488 int64_t value;
10489 AVRational tc_rate = st->avg_frame_rate;
10490 int tmcd_nb_frames = sc->tmcd_nb_frames;
10491 int rounded_tc_rate;
10492
10493 if (!sti->nb_index_entries)
10494 return -1;
10495
10496 if (!tc_rate.num || !tc_rate.den || !tmcd_nb_frames)
10497 return -1;
10498
10499 avio_seek(sc->pb, sti->index_entries->pos, SEEK_SET);
10500 value = avio_rb32(s->pb);
10501
10502 if (sc->tmcd_flags & 0x0001) flags |= AV_TIMECODE_FLAG_DROPFRAME;
10503 if (sc->tmcd_flags & 0x0002) flags |= AV_TIMECODE_FLAG_24HOURSMAX;
10504 if (sc->tmcd_flags & 0x0004) flags |= AV_TIMECODE_FLAG_ALLOWNEGATIVE;
10505
10506 /* Assume Counter flag is set to 1 in tmcd track (even though it is likely
10507 * not the case) and thus assume "frame number format" instead of QT one.
10508 * No sample with tmcd track can be found with a QT timecode at the moment,
10509 * despite what the tmcd track "suggests" (Counter flag set to 0 means QT
10510 * format). */
10511
10512 /* 60 fps content have tmcd_nb_frames set to 30 but tc_rate set to 60, so
10513 * we multiply the frame number with the quotient.
10514 * See tickets #9492, #9710. */
10515 rounded_tc_rate = (tc_rate.num + tc_rate.den / 2LL) / tc_rate.den;
10516 /* Work around files where tmcd_nb_frames is rounded down from frame rate
10517 * instead of up. See ticket #5978. */
10518 if (tmcd_nb_frames == tc_rate.num / tc_rate.den &&
10519 s->strict_std_compliance < FF_COMPLIANCE_STRICT)
10520 tmcd_nb_frames = rounded_tc_rate;
10521 value = av_rescale(value, rounded_tc_rate, tmcd_nb_frames);
10522
10524
10525 avio_seek(sc->pb, cur_pos, SEEK_SET);
10526 return 0;
10527}
10528
10530 int i;
10531 if (!index || !*index) return;
10532 for (i = 0; i < (*index)->nb_encrypted_samples; i++) {
10533 av_encryption_info_free((*index)->encrypted_samples[i]);
10534 }
10535 av_freep(&(*index)->encrypted_samples);
10536 av_freep(&(*index)->auxiliary_info_sizes);
10537 av_freep(&(*index)->auxiliary_offsets);
10538 av_freep(index);
10539}
10540
10542{
10543 MOVStreamContext *sc = st->priv_data;
10544
10545 if (!sc || --sc->refcount) {
10546 st->priv_data = NULL;
10547 return;
10548 }
10549
10550 av_freep(&sc->tts_data);
10551 for (int i = 0; i < sc->drefs_count; i++) {
10552 av_freep(&sc->drefs[i].path);
10553 av_freep(&sc->drefs[i].dir);
10554 }
10555 av_freep(&sc->drefs);
10556
10557 sc->drefs_count = 0;
10558
10559 if (!sc->pb_is_copied)
10560 ff_format_io_close(s, &sc->pb);
10561
10562 sc->pb = NULL;
10563 av_freep(&sc->chunk_offsets);
10564 av_freep(&sc->stsc_data);
10565 av_freep(&sc->sample_sizes);
10566 av_freep(&sc->keyframes);
10567 av_freep(&sc->ctts_data);
10568 av_freep(&sc->stts_data);
10569 av_freep(&sc->sdtp_data);
10570 av_freep(&sc->stps_data);
10571 av_freep(&sc->elst_data);
10572 av_freep(&sc->rap_group);
10573 av_freep(&sc->sync_group);
10574 av_freep(&sc->sgpd_sync);
10578 av_freep(&sc->index_ranges);
10579 for (int i = 0; i < sc->nb_tref_tags; i++)
10580 av_freep(&sc->tref_tags[i].id);
10581 av_freep(&sc->tref_tags);
10582
10583 if (sc->extradata)
10584 for (int i = 0; i < sc->stsd_count; i++)
10585 av_free(sc->extradata[i]);
10586 av_freep(&sc->extradata);
10588
10592
10593 av_freep(&sc->stereo3d);
10594 av_freep(&sc->spherical);
10595 av_freep(&sc->mastering);
10596 av_freep(&sc->coll);
10597 av_freep(&sc->ambient);
10598
10599#if CONFIG_IAMFDEC
10600 if (sc->iamf)
10602#endif
10603 av_freep(&sc->iamf);
10604}
10605
10607{
10608 MOVContext *mov = s->priv_data;
10609 int i, j;
10610
10611 for (i = 0; i < s->nb_streams; i++) {
10612 AVStream *st = s->streams[i];
10613
10615 }
10616
10617 av_freep(&mov->dv_demux);
10619 mov->dv_fctx = NULL;
10620
10621 if (mov->meta_keys) {
10622 for (i = 1; i < mov->meta_keys_count; i++) {
10623 av_freep(&mov->meta_keys[i]);
10624 }
10625 av_freep(&mov->meta_keys);
10626 }
10627
10628 av_freep(&mov->trex_data);
10629 av_freep(&mov->bitrates);
10630
10631 for (i = 0; i < mov->frag_index.nb_items; i++) {
10633 for (j = 0; j < mov->frag_index.item[i].nb_stream_info; j++) {
10634 mov_free_encryption_index(&frag[j].encryption_index);
10635 }
10637 }
10638 av_freep(&mov->frag_index.item);
10639
10640 av_freep(&mov->aes_decrypt);
10641 av_freep(&mov->chapter_tracks);
10642 for (i = 0; i < mov->nb_heif_item; i++) {
10643 if (!mov->heif_item[i])
10644 continue;
10645 av_freep(&mov->heif_item[i]->name);
10646 av_freep(&mov->heif_item[i]->iref_list);
10648 av_freep(&mov->heif_item[i]);
10649 }
10650 av_freep(&mov->heif_item);
10651 for (i = 0; i < mov->nb_heif_grid; i++) {
10655 }
10656 av_freep(&mov->heif_grid);
10657
10658 return 0;
10659}
10660
10661static int tmcd_is_referenced(AVFormatContext *s, int tmcd_id)
10662{
10663 int i;
10664
10665 for (i = 0; i < s->nb_streams; i++) {
10666 AVStream *st = s->streams[i];
10667 MOVStreamContext *sc = st->priv_data;
10668 MovTref *tag = mov_find_tref_tag(sc, MKTAG('t','m','c','d'));
10669
10670 if (!tag)
10671 continue;
10672 if (mov_find_tref_id(tag, tmcd_id))
10673 return 1;
10674 }
10675 return 0;
10676}
10677
10678/* look for a tmcd track not referenced by any video track, and export it globally */
10680{
10681 int i;
10682
10683 for (i = 0; i < s->nb_streams; i++) {
10684 AVStream *st = s->streams[i];
10685
10686 if (st->codecpar->codec_tag == MKTAG('t','m','c','d') &&
10687 !tmcd_is_referenced(s, st->id)) {
10688 AVDictionaryEntry *tcr = av_dict_get(st->metadata, "timecode", NULL, 0);
10689 if (tcr) {
10690 av_dict_set(&s->metadata, "timecode", tcr->value, 0);
10691 break;
10692 }
10693 }
10694 }
10695}
10696
10698{
10699 int version, fieldlength, i, j;
10701 uint32_t size = avio_rb32(f);
10702 unsigned track_id, item_count;
10703
10704 if (avio_rb32(f) != MKBETAG('t', 'f', 'r', 'a')) {
10705 return 1;
10706 }
10707 av_log(mov->fc, AV_LOG_VERBOSE, "found tfra\n");
10708
10709 version = avio_r8(f);
10710 avio_rb24(f);
10711 track_id = avio_rb32(f);
10712 fieldlength = avio_rb32(f);
10713 item_count = avio_rb32(f);
10714 for (i = 0; i < item_count; i++) {
10715 int64_t time, offset;
10716 int index;
10717 MOVFragmentStreamInfo * frag_stream_info;
10718
10719 if (avio_feof(f)) {
10720 return AVERROR_INVALIDDATA;
10721 }
10722
10723 if (version == 1) {
10724 time = avio_rb64(f);
10725 offset = avio_rb64(f);
10726 } else {
10727 time = avio_rb32(f);
10728 offset = avio_rb32(f);
10729 }
10730
10731 // The first sample of each stream in a fragment is always a random
10732 // access sample. So it's entry in the tfra can be used as the
10733 // initial PTS of the fragment.
10735 frag_stream_info = get_frag_stream_info(&mov->frag_index, index, track_id);
10736 if (frag_stream_info &&
10737 frag_stream_info->first_tfra_pts == AV_NOPTS_VALUE)
10738 frag_stream_info->first_tfra_pts = time;
10739
10740 for (j = 0; j < ((fieldlength >> 4) & 3) + 1; j++)
10741 avio_r8(f);
10742 for (j = 0; j < ((fieldlength >> 2) & 3) + 1; j++)
10743 avio_r8(f);
10744 for (j = 0; j < ((fieldlength >> 0) & 3) + 1; j++)
10745 avio_r8(f);
10746 }
10747
10748 avio_seek(f, pos + size, SEEK_SET);
10749 return 0;
10750}
10751
10753{
10754 int64_t stream_size = avio_size(f);
10755 int64_t original_pos = avio_tell(f);
10756 int64_t seek_ret;
10757 int ret = -1;
10758 if ((seek_ret = avio_seek(f, stream_size - 4, SEEK_SET)) < 0) {
10759 ret = seek_ret;
10760 goto fail;
10761 }
10762 c->mfra_size = avio_rb32(f);
10763 c->have_read_mfra_size = 1;
10764 if (!c->mfra_size || c->mfra_size > stream_size) {
10765 av_log(c->fc, AV_LOG_DEBUG, "doesn't look like mfra (unreasonable size)\n");
10766 goto fail;
10767 }
10768 if ((seek_ret = avio_seek(f, -((int64_t) c->mfra_size), SEEK_CUR)) < 0) {
10769 ret = seek_ret;
10770 goto fail;
10771 }
10772 if (avio_rb32(f) != c->mfra_size) {
10773 av_log(c->fc, AV_LOG_DEBUG, "doesn't look like mfra (size mismatch)\n");
10774 goto fail;
10775 }
10776 if (avio_rb32(f) != MKBETAG('m', 'f', 'r', 'a')) {
10777 av_log(c->fc, AV_LOG_DEBUG, "doesn't look like mfra (tag mismatch)\n");
10778 goto fail;
10779 }
10780 av_log(c->fc, AV_LOG_VERBOSE, "stream has mfra\n");
10781 do {
10782 ret = read_tfra(c, f);
10783 if (ret < 0)
10784 goto fail;
10785 } while (!ret);
10786 ret = 0;
10787 c->frag_index.complete = 1;
10788fail:
10789 seek_ret = avio_seek(f, original_pos, SEEK_SET);
10790 if (seek_ret < 0) {
10791 av_log(c->fc, AV_LOG_ERROR,
10792 "failed to seek back after looking for mfra\n");
10793 ret = seek_ret;
10794 }
10795 return ret;
10796}
10797
10798static int set_icc_profile_from_item(AVPacketSideData **coded_side_data, int *nb_coded_side_data,
10799 const HEIFItem *item)
10800{
10801 AVPacketSideData *sd = av_packet_side_data_new(coded_side_data, nb_coded_side_data,
10803 item->icc_profile_size, 0);
10804 if (!sd)
10805 return AVERROR(ENOMEM);
10806
10807 memcpy(sd->data, item->icc_profile, item->icc_profile_size);
10808
10809 return 0;
10810}
10811
10812static int set_display_matrix_from_item(AVPacketSideData **coded_side_data, int *nb_coded_side_data,
10813 const HEIFItem *item)
10814{
10815 int32_t *matrix;
10816 AVPacketSideData *sd = av_packet_side_data_new(coded_side_data,
10817 nb_coded_side_data,
10819 9 * sizeof(*matrix), 0);
10820 if (!sd)
10821 return AVERROR(ENOMEM);
10822
10823 matrix = (int32_t*)sd->data;
10824 /* rotation is in the counter-clockwise direction whereas
10825 * av_display_rotation_set() expects its argument to be
10826 * oriented clockwise, so we need to negate it. */
10829
10830 return 0;
10831}
10832
10834 AVStreamGroupTileGrid *tile_grid)
10835{
10836 MOVContext *c = s->priv_data;
10837 const HEIFItem *item = grid->item;
10838 int64_t coded_width = 0, coded_height = 0;
10839 int64_t offset = 0, pos = avio_tell(s->pb);
10840 int64_t x = 0, y = 0;
10841 int i = 0;
10842 int tile_rows, tile_cols;
10843 int flags, size;
10844
10845 if (!(s->pb->seekable & AVIO_SEEKABLE_NORMAL)) {
10846 av_log(c->fc, AV_LOG_INFO, "grid box with non seekable input\n");
10847 return AVERROR_PATCHWELCOME;
10848 }
10849 if (item->is_idat_relative) {
10850 if (!c->idat_offset) {
10851 av_log(c->fc, AV_LOG_ERROR, "missing idat box required by the image grid\n");
10852 return AVERROR_INVALIDDATA;
10853 }
10854 offset = c->idat_offset;
10855 }
10856
10857 if (offset > INT64_MAX - item->extent_offset)
10858 return AVERROR_INVALIDDATA;
10859
10860 avio_seek(s->pb, item->extent_offset + offset, SEEK_SET);
10861
10862 avio_r8(s->pb); /* version */
10863 flags = avio_r8(s->pb);
10864
10865 tile_rows = avio_r8(s->pb) + 1;
10866 tile_cols = avio_r8(s->pb) + 1;
10867 /* actual width and height of output image */
10868 tile_grid->width = (flags & 1) ? avio_rb32(s->pb) : avio_rb16(s->pb);
10869 tile_grid->height = (flags & 1) ? avio_rb32(s->pb) : avio_rb16(s->pb);
10870
10871 av_log(c->fc, AV_LOG_TRACE, "grid: grid_rows %d grid_cols %d output_width %d output_height %d\n",
10872 tile_rows, tile_cols, tile_grid->width, tile_grid->height);
10873
10874 avio_seek(s->pb, pos, SEEK_SET);
10875
10877 tile_grid->nb_tiles = grid->nb_tiles;
10878
10879 if (tile_grid->nb_tiles != size)
10880 return AVERROR_INVALIDDATA;
10881
10882 for (int i = 0; i < tile_cols; i++)
10883 coded_width += grid->tile_item_list[i]->width;
10884 for (int i = 0; i < size; i += tile_cols)
10885 coded_height += grid->tile_item_list[i]->height;
10886
10887 if (coded_width > INT_MAX || coded_height > INT_MAX)
10888 return AVERROR_INVALIDDATA;
10889
10890 tile_grid->coded_width = coded_width;
10891 tile_grid->coded_height = coded_height;
10892
10893 tile_grid->offsets = av_calloc(tile_grid->nb_tiles, sizeof(*tile_grid->offsets));
10894 if (!tile_grid->offsets)
10895 return AVERROR(ENOMEM);
10896
10897 while (y < tile_grid->coded_height) {
10898 int left_col = i;
10899
10900 while (x < tile_grid->coded_width) {
10901 if (i == tile_grid->nb_tiles)
10902 return AVERROR_INVALIDDATA;
10903
10904 tile_grid->offsets[i].idx = grid->tile_idx_list[i];
10905 tile_grid->offsets[i].horizontal = x;
10906 tile_grid->offsets[i].vertical = y;
10907
10908 x += grid->tile_item_list[i++]->width;
10909 }
10910
10911 if (x > tile_grid->coded_width) {
10912 av_log(c->fc, AV_LOG_ERROR, "Non uniform HEIF tiles\n");
10913 return AVERROR_INVALIDDATA;
10914 }
10915
10916 x = 0;
10917 y += grid->tile_item_list[left_col]->height;
10918 }
10919
10920 if (y > tile_grid->coded_height || i != tile_grid->nb_tiles) {
10921 av_log(c->fc, AV_LOG_ERROR, "Non uniform HEIF tiles\n");
10922 return AVERROR_INVALIDDATA;
10923 }
10924
10925 return 0;
10926}
10927
10929 AVStreamGroupTileGrid *tile_grid)
10930{
10931 MOVContext *c = s->priv_data;
10932 const HEIFItem *item = grid->item;
10933 uint16_t canvas_fill_value[4];
10934 int64_t offset = 0, pos = avio_tell(s->pb);
10935 int ret = 0, flags;
10936
10937 if (!(s->pb->seekable & AVIO_SEEKABLE_NORMAL)) {
10938 av_log(c->fc, AV_LOG_INFO, "iovl box with non seekable input\n");
10939 return AVERROR_PATCHWELCOME;
10940 }
10941 if (item->is_idat_relative) {
10942 if (!c->idat_offset) {
10943 av_log(c->fc, AV_LOG_ERROR, "missing idat box required by the image overlay\n");
10944 return AVERROR_INVALIDDATA;
10945 }
10946 offset = c->idat_offset;
10947 }
10948
10949 if (offset > INT64_MAX - item->extent_offset)
10950 return AVERROR_INVALIDDATA;
10951
10952 avio_seek(s->pb, item->extent_offset + offset, SEEK_SET);
10953
10954 avio_r8(s->pb); /* version */
10955 flags = avio_r8(s->pb);
10956
10957 for (int i = 0; i < 4; i++)
10958 canvas_fill_value[i] = avio_rb16(s->pb);
10959 av_log(c->fc, AV_LOG_TRACE, "iovl: canvas_fill_value { %u, %u, %u, %u }\n",
10960 canvas_fill_value[0], canvas_fill_value[1],
10961 canvas_fill_value[2], canvas_fill_value[3]);
10962 for (int i = 0; i < 4; i++)
10963 tile_grid->background[i] = canvas_fill_value[i];
10964
10965 /* actual width and height of output image */
10966 tile_grid->width =
10967 tile_grid->coded_width = (flags & 1) ? avio_rb32(s->pb) : avio_rb16(s->pb);
10968 tile_grid->height =
10969 tile_grid->coded_height = (flags & 1) ? avio_rb32(s->pb) : avio_rb16(s->pb);
10970
10971 av_log(c->fc, AV_LOG_TRACE, "iovl: output_width %d, output_height %d\n",
10972 tile_grid->width, tile_grid->height);
10973
10974 tile_grid->nb_tiles = grid->nb_tiles;
10975 tile_grid->offsets = av_malloc_array(tile_grid->nb_tiles, sizeof(*tile_grid->offsets));
10976 if (!tile_grid->offsets) {
10977 ret = AVERROR(ENOMEM);
10978 goto fail;
10979 }
10980
10981 for (int i = 0; i < tile_grid->nb_tiles; i++) {
10982 tile_grid->offsets[i].idx = grid->tile_idx_list[i];
10983 tile_grid->offsets[i].horizontal = (flags & 1) ? avio_rb32(s->pb) : avio_rb16(s->pb);
10984 tile_grid->offsets[i].vertical = (flags & 1) ? avio_rb32(s->pb) : avio_rb16(s->pb);
10985 av_log(c->fc, AV_LOG_TRACE, "iovl: stream_idx[%d] %u, "
10986 "horizontal_offset[%d] %d, vertical_offset[%d] %d\n",
10987 i, tile_grid->offsets[i].idx,
10988 i, tile_grid->offsets[i].horizontal, i, tile_grid->offsets[i].vertical);
10989 }
10990
10991fail:
10992 avio_seek(s->pb, pos, SEEK_SET);
10993
10994 return ret;
10995}
10996
10998 AVPacketSideData **coded_side_data, int *nb_coded_side_data,
10999 const HEIFItem *ref)
11000{
11001 MOVContext *c = s->priv_data;
11002 AVPacketSideData *sd;
11003 AVExifMetadata ifd = { 0 };
11004 AVBufferRef *buf;
11005 int64_t offset = 0, pos = avio_tell(s->pb);
11006 unsigned orientation_id = av_exif_get_tag_id("Orientation");
11007 int err;
11008
11009 if (!(s->pb->seekable & AVIO_SEEKABLE_NORMAL)) {
11010 av_log(c->fc, AV_LOG_WARNING, "Exif metadata with non seekable input\n");
11011 return AVERROR_PATCHWELCOME;
11012 }
11013 if (ref->is_idat_relative) {
11014 if (!c->idat_offset) {
11015 av_log(c->fc, AV_LOG_ERROR, "missing idat box required by the Exif metadata\n");
11016 return AVERROR_INVALIDDATA;
11017 }
11018 offset = c->idat_offset;
11019 }
11020
11021 buf = av_buffer_alloc(ref->extent_length);
11022 if (!buf)
11023 return AVERROR(ENOMEM);
11024
11025 if (offset > INT64_MAX - ref->extent_offset) {
11026 err = AVERROR(ENOMEM);
11027 goto fail;
11028 }
11029
11030 avio_seek(s->pb, ref->extent_offset + offset, SEEK_SET);
11031 err = avio_read(s->pb, buf->data, ref->extent_length);
11032 if (err != ref->extent_length) {
11033 if (err > 0)
11034 err = AVERROR_INVALIDDATA;
11035 goto fail;
11036 }
11037
11038 // HEIF spec states that Exif metadata is informative. The irot item property is
11039 // the normative source of rotation information. So we remove any Orientation tag
11040 // present in the Exif buffer.
11041 err = av_exif_parse_buffer(s, buf->data, ref->extent_length, &ifd, AV_EXIF_T_OFF);
11042 if (err < 0) {
11043 av_log(s, AV_LOG_ERROR, "Unable to parse Exif metadata\n");
11044 goto fail;
11045 }
11046
11047 err = av_exif_remove_entry(s, &ifd, orientation_id, 0);
11048 if (err < 0)
11049 goto fail;
11050 else if (!err)
11051 goto finish;
11052
11053 av_buffer_unref(&buf);
11054 err = av_exif_write(s, &ifd, &buf, AV_EXIF_T_OFF);
11055 if (err < 0)
11056 goto fail;
11057
11058finish:
11059 offset = AV_RB32(buf->data) + 4;
11060 if (offset >= buf->size) {
11061 err = AVERROR_INVALIDDATA;
11062 goto fail;
11063 }
11064 sd = av_packet_side_data_new(coded_side_data, nb_coded_side_data,
11065 AV_PKT_DATA_EXIF, buf->size - offset, 0);
11066 if (!sd) {
11067 err = AVERROR(ENOMEM);
11068 goto fail;
11069 }
11070 memcpy(sd->data, buf->data + offset, buf->size - offset);
11071
11072 err = 0;
11073fail:
11074 av_buffer_unref(&buf);
11075 av_exif_free(&ifd);
11076 avio_seek(s->pb, pos, SEEK_SET);
11077
11078 return err;
11079}
11080
11082{
11083 MOVContext *mov = s->priv_data;
11084
11085 for (int i = 0; i < mov->nb_heif_grid; i++) {
11087 AVStreamGroupTileGrid *tile_grid;
11088 const HEIFGrid *grid = &mov->heif_grid[i];
11089 int err, loop = 1;
11090
11091 if (!stg)
11092 return AVERROR(ENOMEM);
11093
11094 stg->id = grid->item->item_id;
11095 tile_grid = stg->params.tile_grid;
11096
11097 for (int j = 0; j < grid->nb_tiles; j++) {
11098 int tile_id = grid->tile_id_list[j];
11099 int k;
11100
11101 for (k = 0; k < mov->nb_heif_item; k++) {
11102 HEIFItem *item = mov->heif_item[k];
11103 AVStream *st;
11104
11105 if (!item || item->item_id != tile_id)
11106 continue;
11107 st = item->st;
11108 if (!st) {
11109 av_log(s, AV_LOG_WARNING, "HEIF item id %d from grid id %d doesn't "
11110 "reference a stream\n",
11111 tile_id, grid->item->item_id);
11113 loop = 0;
11114 break;
11115 }
11116
11117 grid->tile_item_list[j] = item;
11118 grid->tile_idx_list[j] = stg->nb_streams;
11119
11120 err = avformat_stream_group_add_stream(stg, st);
11121 if (err < 0) {
11122 int l;
11123 if (err != AVERROR(EEXIST))
11124 return err;
11125
11126 for (l = 0; l < stg->nb_streams; l++)
11127 if (stg->streams[l]->index == st->index)
11128 break;
11129 av_assert0(l < stg->nb_streams);
11130 grid->tile_idx_list[j] = l;
11131 }
11132
11133 if (item->item_id != mov->primary_item_id)
11135 break;
11136 }
11137
11138 if (k == mov->nb_heif_item) {
11140 av_log(s, AV_LOG_WARNING, "HEIF item id %d referenced by grid id %d doesn't "
11141 "exist\n",
11142 tile_id, grid->item->item_id);
11144 loop = 0;
11145 }
11146 if (!loop)
11147 break;
11148 }
11149
11150 if (!loop)
11151 continue;
11152
11153 switch (grid->item->type) {
11154 case MKTAG('g','r','i','d'):
11155 err = read_image_grid(s, grid, tile_grid);
11156 break;
11157 case MKTAG('i','o','v','l'):
11158 err = read_image_iovl(s, grid, tile_grid);
11159 break;
11160 default:
11161 av_assert0(0);
11162 }
11163 if (err < 0)
11164 return err;
11165
11166 for (int j = 0; j < grid->item->nb_iref_list; j++) {
11167 HEIFItem *ref = get_heif_item(mov, grid->item->iref_list[j].item_id);
11168
11169 av_assert0(ref);
11170 switch(ref->type) {
11171 case MKTAG('E','x','i','f'):
11172 err = mov_parse_exif_item(s, &tile_grid->coded_side_data,
11173 &tile_grid->nb_coded_side_data, ref);
11174 if (err < 0 && (s->error_recognition & AV_EF_EXPLODE))
11175 return err;
11176 break;
11177 default:
11178 break;
11179 }
11180 }
11181
11182 /* rotation */
11183 if (grid->item->rotation || grid->item->hflip || grid->item->vflip) {
11185 &tile_grid->nb_coded_side_data, grid->item);
11186 if (err < 0)
11187 return err;
11188 }
11189
11190 /* ICC profile */
11191 if (grid->item->icc_profile_size) {
11193 &tile_grid->nb_coded_side_data, grid->item);
11194 if (err < 0)
11195 return err;
11196 }
11197
11198 if (grid->item->name)
11199 av_dict_set(&stg->metadata, "title", grid->item->name, 0);
11200 if (grid->item->item_id == mov->primary_item_id)
11202 }
11203
11204 return 0;
11205}
11206
11208{
11209 MOVContext *mov = s->priv_data;
11210 int err;
11211
11212 for (int i = 0; i < mov->nb_heif_item; i++) {
11213 HEIFItem *item = mov->heif_item[i];
11214 MOVStreamContext *sc;
11215 AVStream *st;
11216 int64_t offset = 0;
11217
11218 if (!item)
11219 continue;
11220 if (!item->st) {
11221 continue;
11222 }
11223 if (item->is_idat_relative) {
11224 if (!mov->idat_offset) {
11225 av_log(s, AV_LOG_ERROR, "Missing idat box for item %d\n", item->item_id);
11226 return AVERROR_INVALIDDATA;
11227 }
11228 offset = mov->idat_offset;
11229 }
11230
11231 st = item->st;
11232 sc = st->priv_data;
11233 st->codecpar->width = item->width;
11234 st->codecpar->height = item->height;
11235
11236 sc->sample_size = sc->stsz_sample_size = item->extent_length;
11237 sc->sample_count = 1;
11238
11239 err = sanity_checks(s, sc, st->index);
11240 if (err)
11241 return AVERROR_INVALIDDATA;
11242
11243 if (offset > INT64_MAX - item->extent_offset)
11244 return AVERROR_INVALIDDATA;
11245
11246 sc->chunk_offsets[0] = item->extent_offset + offset;
11247
11248 if (item->item_id == mov->primary_item_id)
11250
11251 for (int j = 0; j < item->nb_iref_list; j++) {
11252 HEIFItem *ref = get_heif_item(mov, item->iref_list[j].item_id);
11253
11254 av_assert0(ref);
11255 switch(ref->type) {
11256 case MKTAG('E','x','i','f'):
11259 if (err < 0 && (s->error_recognition & AV_EF_EXPLODE))
11260 return err;
11261 break;
11262 default:
11263 break;
11264 }
11265 }
11266
11267 if (item->rotation || item->hflip || item->vflip) {
11269 &st->codecpar->nb_coded_side_data, item);
11270 if (err < 0)
11271 return err;
11272 }
11273
11274 mov_build_index(mov, st);
11275 }
11276
11277 if (mov->nb_heif_grid) {
11278 err = mov_parse_tiles(s);
11279 if (err < 0)
11280 return err;
11281 }
11282
11283 return 0;
11284}
11285
11287{
11288 int err;
11289
11290 for (int i = 0; i < s->nb_streams; i++) {
11291 AVStreamGroup *stg;
11292 const AVDictionaryEntry *tcr;
11293 AVStream *st = s->streams[i];
11294
11295 if (st->codecpar->codec_tag != MKTAG('t','m','c','d'))
11296 continue;
11297
11299 if (!stg)
11300 return AVERROR(ENOMEM);
11301
11302 stg->id = st->id;
11303 tcr = av_dict_get(st->metadata, "timecode", NULL, 0);
11304
11305 for (int j = 0; j < s->nb_streams; j++) {
11306 AVStream *st2 = s->streams[j];
11307 MOVStreamContext *sc2 = st2->priv_data;
11308 MovTref *tag = mov_find_tref_tag(sc2, MKTAG('t','m','c','d'));
11309
11310 if (!tag)
11311 continue;
11312
11313 for (int k = 0; k < tag->nb_id; k++) {
11314 if (tag->id[k] != st->id)
11315 continue;
11316
11317 err = avformat_stream_group_add_stream(stg, st2);
11318 if (err < 0)
11319 return err;
11320
11321 if (tcr)
11322 av_dict_set(&st2->metadata, "timecode", tcr->value, AV_DICT_DONT_OVERWRITE);
11323 }
11324 }
11325
11326 if (!stg->nb_streams) {
11328 continue;
11329 }
11330
11331 err = avformat_stream_group_add_stream(stg, st);
11332 if (err < 0)
11333 return err;
11334
11335 stg->params.tref->metadata_index = stg->nb_streams - 1;
11336 }
11338
11339 return 0;
11340}
11341
11343 uint32_t *tref_id, int nb_tref_id, int first_index)
11344{
11345 if (!nb_tref_id)
11346 return NULL;
11347
11348 for (int i = first_index; i < s->nb_streams; i++)
11349 for (int j = 0; j < nb_tref_id; j++)
11350 if (s->streams[i]->index != st->index &&
11351 s->streams[i]->id == tref_id[j])
11352 return s->streams[i];
11353
11354 return NULL;
11355}
11356
11358{
11359 static const uint32_t tref_tags[] = {
11360 MKTAG('c','d','s','c'),
11361 MKTAG('r','n','d','r'),
11362 };
11363
11364 int err;
11365
11366 // Don't try to add a group if there's only one track
11367 if (s->nb_streams <= 1)
11368 return 0;
11369
11370 for (int i = 0; i < s->nb_streams; i++) {
11371 AVStream *st = s->streams[i];
11372 MOVStreamContext *sc = st->priv_data;
11373
11374 for (int c = 0; c < FF_ARRAY_ELEMS(tref_tags); c++) {
11375 AVStreamGroup *stg;
11376 AVStream *st_ref;
11377 MovTref *tag = mov_find_tref_tag(sc, tref_tags[c]);
11378
11379 if (!tag)
11380 continue;
11381
11382 st_ref = mov_find_reference_track(s, st, tag->id, tag->nb_id, 0);
11383 if (!st_ref) {
11384 int loglevel = (s->error_recognition & AV_EF_EXPLODE) ? AV_LOG_ERROR : AV_LOG_WARNING;
11385 av_log(s, loglevel, "Failed to find referenced stream\n");
11386 if (s->error_recognition & AV_EF_EXPLODE)
11387 return AVERROR_INVALIDDATA;
11388 continue;
11389 }
11390
11392 if (!stg)
11393 return AVERROR(ENOMEM);
11394
11395 stg->id = st_ref->id;
11396
11397 err = avformat_stream_group_add_stream(stg, st_ref);
11398 if (err < 0)
11399 return err;
11400
11401 err = avformat_stream_group_add_stream(stg, st);
11402 if (err < 0)
11403 return err;
11404
11405 stg->params.tref->metadata_index = stg->nb_streams - 1;
11406 }
11407 }
11408
11409 return 0;
11410}
11411
11413{
11414 int err;
11415
11416 // Don't try to add a group if there's only one track
11417 if (s->nb_streams <= 1)
11418 return 0;
11419
11420 for (int i = 0; i < s->nb_streams; i++) {
11421 AVStreamGroup *stg;
11422 AVStream *st = s->streams[i];
11423 AVStream *st_base;
11424 MOVStreamContext *sc = st->priv_data;
11425 MovTref *tag = mov_find_tref_tag(sc, MKTAG('s','b','a','s'));
11426 int j = 0;
11427
11428 /* Find an enhancement stream. */
11429 if (st->codecpar->codec_id != AV_CODEC_ID_LCEVC || !tag)
11430 continue;
11431
11433 if (!stg)
11434 return AVERROR(ENOMEM);
11435
11436 stg->id = st->id;
11439
11440 while (st_base = mov_find_reference_track(s, st, tag->id, tag->nb_id, j)) {
11441 err = avformat_stream_group_add_stream(stg, st_base);
11442 if (err < 0)
11443 return err;
11444
11445 j = st_base->index + 1;
11446 }
11447 if (!j) {
11448 int loglevel = (s->error_recognition & AV_EF_EXPLODE) ? AV_LOG_ERROR : AV_LOG_WARNING;
11449 av_log(s, loglevel, "Failed to find base stream for LCEVC stream\n");
11451 if (s->error_recognition & AV_EF_EXPLODE)
11452 return AVERROR_INVALIDDATA;
11453 continue;
11454 }
11455
11456 err = avformat_stream_group_add_stream(stg, st);
11457 if (err < 0)
11458 return err;
11459
11460 stg->params.layered_video->el_index = stg->nb_streams - 1;
11461 }
11462
11463 return 0;
11464}
11465
11467{
11468 int err;
11469
11470 if (s->nb_streams <= 1)
11471 return 0;
11472
11473 /* Identify legacy dual-track Dolby Vision profile 7 carriage per Annex
11474 * C of "Dolby Vision Streams Within the ISO Base Media File Format",
11475 * v2.7.1. The 'vdep' track reference type is shared with depth video
11476 * and multi-view dependencies. The spec-mandated DV-specific sample
11477 * entry combined with the dvcC configuration record disambiguates
11478 * those uses. */
11479 for (int i = 0; i < s->nb_streams; i++) {
11480 AVStreamGroup *stg;
11481 AVStream *st = s->streams[i];
11482 AVStream *st_base;
11483 MOVStreamContext *sc = st->priv_data;
11484 MovTref *tag = mov_find_tref_tag(sc, MKTAG('v','d','e','p'));
11485 const AVPacketSideData *sd;
11487
11488 if (st->codecpar->codec_id != AV_CODEC_ID_HEVC || !tag)
11489 continue;
11490
11491 if (st->codecpar->codec_tag != MKTAG('d','v','h','e') &&
11492 st->codecpar->codec_tag != MKTAG('d','v','h','1'))
11493 continue;
11494
11498 if (!sd)
11499 continue;
11500 dovi = (const AVDOVIDecoderConfigurationRecord *)sd->data;
11501
11502 /* EL track of a dual-track stream: rpu_present_flag = 1,
11503 * el_present_flag = 1, bl_present_flag = 0, dv_profile = 7. */
11504 if (dovi->dv_profile != 7 || !dovi->rpu_present_flag ||
11505 !dovi->el_present_flag || dovi->bl_present_flag)
11506 continue;
11507
11508 st_base = mov_find_reference_track(s, st, tag->id, tag->nb_id, 0);
11509 if (!st_base) {
11510 int loglevel = (s->error_recognition & AV_EF_EXPLODE) ? AV_LOG_ERROR : AV_LOG_WARNING;
11511 av_log(s, loglevel, "Failed to find base layer for Dolby Vision EL stream\n");
11512 if (s->error_recognition & AV_EF_EXPLODE)
11513 return AVERROR_INVALIDDATA;
11514 continue;
11515 }
11516
11518 if (!stg)
11519 return AVERROR(ENOMEM);
11520
11521 stg->id = st->id;
11522
11523 err = avformat_stream_group_add_stream(stg, st_base);
11524 if (err < 0)
11525 return err;
11526
11527 err = avformat_stream_group_add_stream(stg, st);
11528 if (err < 0)
11529 return err;
11530
11531 stg->params.layered_video->el_index = stg->nb_streams - 1;
11532 stg->params.layered_video->width = st_base->codecpar->width;
11533 stg->params.layered_video->height = st_base->codecpar->height;
11534 }
11535
11536 return 0;
11537}
11538
11540{
11541 int highest_id = 0, lowest_iamf_id = INT_MAX;
11542
11543 for (int i = 0; i < s->nb_streams; i++) {
11544 const AVStream *st = s->streams[i];
11545 const MOVStreamContext *sc = st->priv_data;
11546 if (!sc->iamf)
11547 highest_id = FFMAX(highest_id, st->id);
11548 }
11549
11550 for (int i = 0; i < s->nb_stream_groups; i++) {
11551 AVStreamGroup *stg = s->stream_groups[i];
11553 continue;
11554 for (int j = 0; j < stg->nb_streams; j++) {
11555 AVStream *st = stg->streams[j];
11556 lowest_iamf_id = FFMIN(lowest_iamf_id, st->id);
11557 }
11558 }
11559
11560 if (highest_id < lowest_iamf_id)
11561 return;
11562
11563 highest_id += !lowest_iamf_id;
11564 for (int i = 0; highest_id > 1 && i < s->nb_stream_groups; i++) {
11565 AVStreamGroup *stg = s->stream_groups[i];
11567 continue;
11568 for (int j = 0; j < stg->nb_streams; j++) {
11569 AVStream *st = stg->streams[j];
11570 MOVStreamContext *sc = st->priv_data;
11571 st->id += highest_id;
11572 sc->iamf_stream_offset = highest_id;
11573 }
11574 }
11575}
11576
11578{
11579 MOVContext *mov = s->priv_data;
11580 AVIOContext *pb = s->pb;
11581 int j, err;
11582 MOVAtom atom = { AV_RL32("root") };
11583 int i;
11584
11585 mov->fc = s;
11586 mov->trak_index = -1;
11587 mov->primary_item_id = -1;
11588 mov->cur_item_id = -1;
11589 /* .mov and .mp4 aren't streamable anyway (only progressive download if moov is before mdat) */
11591 atom.size = avio_size(pb);
11592 else
11593 atom.size = INT64_MAX;
11594
11595 /* check MOV header */
11596 do {
11597 if (mov->moov_retry)
11598 avio_seek(pb, 0, SEEK_SET);
11599 if ((err = mov_read_default(mov, pb, atom)) < 0) {
11600 av_log(s, AV_LOG_ERROR, "error reading header\n");
11601 return err;
11602 }
11603 } while ((pb->seekable & AVIO_SEEKABLE_NORMAL) &&
11604 !mov->found_moov && (!mov->found_iloc || !mov->found_iinf) && !mov->moov_retry++);
11605 if (!mov->found_moov && !mov->found_iloc && !mov->found_iinf) {
11606 av_log(s, AV_LOG_ERROR, "moov atom not found\n");
11607 return AVERROR_INVALIDDATA;
11608 }
11609 av_log(mov->fc, AV_LOG_TRACE, "on_parse_exit_offset=%"PRId64"\n", avio_tell(pb));
11610
11611 if (mov->found_iloc && mov->found_iinf) {
11612 err = mov_parse_heif_items(s);
11613 if (err < 0)
11614 return err;
11615 }
11616 // prevent iloc and iinf boxes from being parsed while reading packets.
11617 // this is needed because an iinf box may have been parsed but ignored
11618 // for having old infe boxes which create no streams.
11619 mov->found_iloc = mov->found_iinf = 1;
11620
11621 if (pb->seekable & AVIO_SEEKABLE_NORMAL) {
11622 if (mov->nb_chapter_tracks > 0 && !mov->ignore_chapters)
11624 for (i = 0; i < s->nb_streams; i++)
11625 if (s->streams[i]->codecpar->codec_tag == AV_RL32("tmcd")) {
11626 mov_read_timecode_track(s, s->streams[i]);
11627 } else if (s->streams[i]->codecpar->codec_tag == AV_RL32("rtmd")) {
11628 mov_read_rtmd_track(s, s->streams[i]);
11629 }
11630 }
11631
11632 /* Create metadata stream groups. */
11634 if (err < 0)
11635 return err;
11636
11637 /* copy timecode metadata from tmcd tracks to the related video streams */
11639 if (err < 0)
11640 return err;
11641
11642 /* Create LCEVC stream groups. */
11644 if (err < 0)
11645 return err;
11646
11647 /* Create Dolby Vision Profile 7 stream groups. */
11649 if (err < 0)
11650 return err;
11651
11652 for (i = 0; i < s->nb_streams; i++) {
11653 AVStream *st = s->streams[i];
11654 FFStream *const sti = ffstream(st);
11655 MOVStreamContext *sc = st->priv_data;
11656 uint32_t dvdsub_clut[FF_DVDCLUT_CLUT_LEN] = {0};
11657 fix_timescale(mov, sc);
11658
11659 /* Set the primary extradata based on the first Sample if it doesn't reference the first stsd entry. */
11660 if (sc->stsc_count && sc->extradata_size && !sc->iamf &&
11661 sc->stsc_data[0].id > 1 && sc->stsc_data[0].id <= sc->stsd_count) {
11662 sc->last_stsd_index = sc->stsc_data[0].id - 1;
11665 if (sc->extradata_size[sc->last_stsd_index]) {
11667 if (!st->codecpar->extradata)
11668 return AVERROR(ENOMEM);
11670 }
11671 }
11672
11676 }
11679 sc->time_scale*(int64_t)sc->nb_frames_for_fps, sc->duration_for_fps, INT_MAX);
11681 if (st->codecpar->width <= 0 || st->codecpar->height <= 0) {
11682 st->codecpar->width = sc->width;
11683 st->codecpar->height = sc->height;
11684 }
11687
11688 for (j = 0; j < FF_DVDCLUT_CLUT_LEN; j++)
11689 dvdsub_clut[j] = AV_RB32(st->codecpar->extradata + j * 4);
11690
11691 err = ff_dvdclut_yuv_to_rgb(dvdsub_clut, FF_DVDCLUT_CLUT_SIZE);
11692 if (err < 0)
11693 return err;
11694
11696 st->codecpar->extradata_size = 0;
11697
11699 st->codecpar);
11700 if (err < 0)
11701 return err;
11702 }
11703 }
11704 if (mov->handbrake_version &&
11705 mov->handbrake_version <= 1000000*0 + 1000*10 + 2 && // 0.10.2
11707 av_log(s, AV_LOG_VERBOSE, "Forcing full parsing for mp3 stream\n");
11709 }
11710 }
11711
11712 if (mov->trex_data || mov->use_mfra_for > 0) {
11713 for (i = 0; i < s->nb_streams; i++) {
11714 AVStream *st = s->streams[i];
11715 MOVStreamContext *sc = st->priv_data;
11716 if (sc->duration_for_fps > 0) {
11717 /* Akin to sc->data_size * 8 * sc->time_scale / sc->duration_for_fps but accounting for overflows. */
11719 if (st->codecpar->bit_rate == INT64_MIN) {
11720 av_log(s, AV_LOG_WARNING, "Overflow during bit rate calculation %"PRId64" * 8 * %d\n",
11721 sc->data_size, sc->time_scale);
11722 st->codecpar->bit_rate = 0;
11723 if (s->error_recognition & AV_EF_EXPLODE)
11724 return AVERROR_INVALIDDATA;
11725 }
11726 }
11727 }
11728 }
11729
11730 for (i = 0; i < mov->bitrates_count && i < s->nb_streams; i++) {
11731 if (mov->bitrates[i]) {
11732 s->streams[i]->codecpar->bit_rate = mov->bitrates[i];
11733 }
11734 }
11735
11737
11738 for (i = 0; i < s->nb_streams; i++) {
11739 AVStream *st = s->streams[i];
11740 MOVStreamContext *sc = st->priv_data;
11741
11742 switch (st->codecpar->codec_type) {
11743 case AVMEDIA_TYPE_AUDIO:
11744 err = ff_replaygain_export(st, s->metadata);
11745 if (err < 0)
11746 return err;
11747 break;
11748 case AVMEDIA_TYPE_VIDEO:
11749 if (sc->display_matrix) {
11752 (uint8_t*)sc->display_matrix, sizeof(int32_t) * 9, 0))
11753 return AVERROR(ENOMEM);
11754
11755 sc->display_matrix = NULL;
11756 }
11757 if (sc->stereo3d) {
11760 (uint8_t *)sc->stereo3d, sc->stereo3d_size, 0))
11761 return AVERROR(ENOMEM);
11762
11763 sc->stereo3d = NULL;
11764 }
11765 if (sc->spherical) {
11768 (uint8_t *)sc->spherical, sc->spherical_size, 0))
11769 return AVERROR(ENOMEM);
11770
11771 sc->spherical = NULL;
11772 }
11773 if (sc->mastering) {
11776 (uint8_t *)sc->mastering, sc->mastering_size, 0))
11777 return AVERROR(ENOMEM);
11778
11779 sc->mastering = NULL;
11780 }
11781 if (sc->coll) {
11784 (uint8_t *)sc->coll, sc->coll_size, 0))
11785 return AVERROR(ENOMEM);
11786
11787 sc->coll = NULL;
11788 }
11789 if (sc->ambient) {
11792 (uint8_t *) sc->ambient, sc->ambient_size, 0))
11793 return AVERROR(ENOMEM);
11794
11795 sc->ambient = NULL;
11796 }
11797 break;
11798 }
11799 }
11800
11802
11804
11805 for (i = 0; i < mov->frag_index.nb_items; i++)
11806 if (mov->frag_index.item[i].moof_offset <= mov->fragment.moof_offset)
11807 mov->frag_index.item[i].headers_read = 1;
11808
11809 return 0;
11810}
11811
11813{
11815 int64_t best_dts = INT64_MAX;
11816 int i;
11817 MOVContext *mov = s->priv_data;
11818 int no_interleave = !mov->interleaved_read || !(s->pb->seekable & AVIO_SEEKABLE_NORMAL);
11819 for (i = 0; i < s->nb_streams; i++) {
11820 AVStream *avst = s->streams[i];
11821 FFStream *const avsti = ffstream(avst);
11822 MOVStreamContext *msc = avst->priv_data;
11823 if (msc->pb && msc->current_sample < avsti->nb_index_entries) {
11824 AVIndexEntry *current_sample = &avsti->index_entries[msc->current_sample];
11825 int64_t dts = av_rescale(current_sample->timestamp, AV_TIME_BASE, msc->time_scale);
11826 uint64_t dtsdiff = best_dts > dts ? best_dts - (uint64_t)dts : ((uint64_t)dts - best_dts);
11827 av_log(s, AV_LOG_TRACE, "stream %d, sample %d, dts %"PRId64"\n", i, msc->current_sample, dts);
11828 if (!sample || (no_interleave && current_sample->pos < sample->pos) ||
11829 ((s->pb->seekable & AVIO_SEEKABLE_NORMAL) &&
11830 ((msc->pb != s->pb && dts < best_dts) || (msc->pb == s->pb && dts != AV_NOPTS_VALUE &&
11831 ((dtsdiff <= AV_TIME_BASE && current_sample->pos < sample->pos) ||
11832 (dtsdiff > AV_TIME_BASE && dts < best_dts && mov->interleaved_read)))))) {
11833 sample = current_sample;
11834 best_dts = dts;
11835 *st = avst;
11836 }
11837 }
11838 }
11839 return sample;
11840}
11841
11842static int should_retry(AVIOContext *pb, int error_code) {
11843 if (error_code == AVERROR_EOF || avio_feof(pb))
11844 return 0;
11845
11846 return 1;
11847}
11848
11850{
11851 int ret;
11852 MOVContext *mov = s->priv_data;
11853
11854 if (index >= 0 && index < mov->frag_index.nb_items)
11855 target = mov->frag_index.item[index].moof_offset;
11856 if (target >= 0 && avio_seek(s->pb, target, SEEK_SET) != target) {
11857 av_log(mov->fc, AV_LOG_ERROR, "root atom offset 0x%"PRIx64": partial file\n", target);
11858 return AVERROR_INVALIDDATA;
11859 }
11860
11861 mov->next_root_atom = 0;
11862 if ((index < 0 && target >= 0) || index >= mov->frag_index.nb_items)
11863 index = search_frag_moof_offset(&mov->frag_index, target);
11864 if (index >= 0 && index < mov->frag_index.nb_items &&
11865 mov->frag_index.item[index].moof_offset == target) {
11866 if (index + 1 < mov->frag_index.nb_items)
11869 return 0;
11871 }
11872
11873 mov->found_mdat = 0;
11874
11875 ret = mov_read_default(mov, s->pb, (MOVAtom){ AV_RL32("root"), INT64_MAX });
11876 if (ret < 0)
11877 return ret;
11878 if (avio_feof(s->pb))
11879 return AVERROR_EOF;
11880 av_log(s, AV_LOG_TRACE, "read fragments, offset 0x%"PRIx64"\n", avio_tell(s->pb));
11881
11882 return 1;
11883}
11884
11886{
11887 MOVStreamContext *sc = st->priv_data;
11888 uint8_t *side, *extradata;
11889 int extradata_size;
11890
11891 /* Save the current index. */
11892 sc->last_stsd_index = sc->stsc_data[sc->stsc_index].id - 1;
11893
11894 /* Notify the decoder that extradata changed. */
11895 extradata_size = sc->extradata_size[sc->last_stsd_index];
11896 extradata = sc->extradata[sc->last_stsd_index];
11897 if (st->discard != AVDISCARD_ALL && extradata_size > 0 && extradata) {
11900 extradata_size);
11901 if (!side)
11902 return AVERROR(ENOMEM);
11903 memcpy(side, extradata, extradata_size);
11904 }
11905
11906 return 0;
11907}
11908
11909static int get_eia608_packet(AVIOContext *pb, AVPacket *pkt, int src_size)
11910{
11911 /* We can't make assumptions about the structure of the payload,
11912 because it may include multiple cdat and cdt2 samples. */
11913 const uint32_t cdat = AV_RB32("cdat");
11914 const uint32_t cdt2 = AV_RB32("cdt2");
11915 int ret, out_size = 0;
11916
11917 /* a valid payload must have size, 4cc, and at least 1 byte pair: */
11918 if (src_size < 10)
11919 return AVERROR_INVALIDDATA;
11920
11921 /* avoid an int overflow: */
11922 if ((src_size - 8) / 2 >= INT_MAX / 3)
11923 return AVERROR_INVALIDDATA;
11924
11925 ret = av_new_packet(pkt, ((src_size - 8) / 2) * 3);
11926 if (ret < 0)
11927 return ret;
11928
11929 /* parse and re-format the c608 payload in one pass. */
11930 while (src_size >= 10) {
11931 const uint32_t atom_size = avio_rb32(pb);
11932 const uint32_t atom_type = avio_rb32(pb);
11933 const uint32_t data_size = atom_size - 8;
11934 const uint8_t cc_field =
11935 atom_type == cdat ? 1 :
11936 atom_type == cdt2 ? 2 :
11937 0;
11938
11939 /* account for bytes consumed for atom size and type. */
11940 src_size -= 8;
11941
11942 /* make sure the data size stays within the buffer boundaries. */
11943 if (data_size < 2 || data_size > src_size) {
11944 ret = AVERROR_INVALIDDATA;
11945 break;
11946 }
11947
11948 /* make sure the data size is consistent with N byte pairs. */
11949 if (data_size % 2 != 0) {
11950 ret = AVERROR_INVALIDDATA;
11951 break;
11952 }
11953
11954 if (!cc_field) {
11955 /* neither cdat or cdt2 ... skip it */
11956 avio_skip(pb, data_size);
11957 src_size -= data_size;
11958 continue;
11959 }
11960
11961 for (uint32_t i = 0; i < data_size; i += 2) {
11962 pkt->data[out_size] = (0x1F << 3) | (1 << 2) | (cc_field - 1);
11963 pkt->data[out_size + 1] = avio_r8(pb);
11964 pkt->data[out_size + 2] = avio_r8(pb);
11965 out_size += 3;
11966 src_size -= 2;
11967 }
11968 }
11969
11970 if (src_size > 0)
11971 /* skip any remaining unread portion of the input payload */
11972 avio_skip(pb, src_size);
11973
11975 return ret;
11976}
11977
11979 int64_t current_index, AVPacket *pkt)
11980{
11981 MOVContext *mov = s->priv_data;
11982 MOVStreamContext *sc = st->priv_data;
11983
11984 pkt->stream_index = sc->ffindex;
11985 pkt->dts = sample->timestamp;
11986 if (sample->flags & AVINDEX_DISCARD_FRAME) {
11987 pkt->flags |= AV_PKT_FLAG_DISCARD;
11988 }
11989 if (sc->stts_count && sc->tts_index < sc->tts_count)
11990 pkt->duration = sc->tts_data[sc->tts_index].duration;
11991 if (sc->ctts_count && sc->tts_index < sc->tts_count) {
11992 pkt->pts = av_sat_add64(pkt->dts, av_sat_add64(sc->dts_shift, sc->tts_data[sc->tts_index].offset));
11993 } else {
11994 if (pkt->duration == 0) {
11995 int64_t next_dts = (sc->current_sample < ffstream(st)->nb_index_entries) ?
11997 if (next_dts >= pkt->dts)
11998 pkt->duration = next_dts - pkt->dts;
11999 }
12000 pkt->pts = pkt->dts;
12001 }
12002
12004 sc->current_sample >= ffstream(st)->nb_index_entries) {
12005 int64_t pts = av_rescale_q(pkt->pts, st->time_base, (AVRational){ 1, st->codecpar->sample_rate });
12006 int64_t total = av_rescale_q(st->duration, st->time_base, (AVRational){ 1, st->codecpar->sample_rate });
12007 int64_t duration = pkt->duration;
12008
12009 if (st->duration < pkt->pts) {
12010 duration = 0;
12011 } else
12012 duration = FFMIN(duration, (uint64_t)st->duration - pkt->pts);
12013
12014 duration = av_rescale_q(duration, st->time_base, (AVRational){ 1, st->codecpar->sample_rate });
12015
12016 if (!ffstream(st)->first_discard_sample)
12018 if (!ffstream(st)->last_discard_sample)
12019 ffstream(st)->last_discard_sample = total;
12020 }
12021
12022 if (sc->tts_data && sc->tts_index < sc->tts_count) {
12023 /* update tts context */
12024 sc->tts_sample++;
12025 if (sc->tts_index < sc->tts_count &&
12026 sc->tts_data[sc->tts_index].count == sc->tts_sample) {
12027 sc->tts_index++;
12028 sc->tts_sample = 0;
12029 }
12030 }
12031
12032 if (sc->sdtp_data && sc->current_sample <= sc->sdtp_count) {
12033 uint8_t sample_flags = sc->sdtp_data[sc->current_sample - 1];
12034 uint8_t sample_is_depended_on = (sample_flags >> 2) & 0x3;
12035 pkt->flags |= sample_is_depended_on == MOV_SAMPLE_DEPENDENCY_NO ? AV_PKT_FLAG_DISPOSABLE : 0;
12036 }
12037 pkt->flags |= sample->flags & AVINDEX_KEYFRAME ? AV_PKT_FLAG_KEY : 0;
12038 pkt->pos = sample->pos;
12039
12040 /* Multiple stsd handling. */
12041 if (sc->stsc_data) {
12042 if (sc->stsc_data[sc->stsc_index].id > 0 &&
12043 sc->stsc_data[sc->stsc_index].id - 1 < sc->stsd_count &&
12044 sc->stsc_data[sc->stsc_index].id - 1 != sc->last_stsd_index) {
12045 int ret = mov_change_extradata(st, pkt);
12046 if (ret < 0)
12047 return ret;
12048 }
12049
12050 /* Update the stsc index for the next sample */
12051 sc->stsc_sample++;
12054 sc->stsc_index++;
12055 sc->stsc_sample = 0;
12056 }
12057 }
12058
12059 return 0;
12060}
12061
12063{
12064 MOVContext *mov = s->priv_data;
12065 MOVStreamContext *sc;
12067 AVStream *st = NULL;
12068 FFStream *avsti = NULL;
12069 int64_t current_index;
12070 int ret;
12071 int i;
12072 mov->fc = s;
12073 retry:
12074 if (s->pb->pos == 0) {
12075
12076 // Discard current fragment index
12077 if (mov->frag_index.allocated_size > 0) {
12078 for(int i = 0; i < mov->frag_index.nb_items; i++) {
12080 }
12081 av_freep(&mov->frag_index.item);
12082 mov->frag_index.nb_items = 0;
12083 mov->frag_index.allocated_size = 0;
12084 mov->frag_index.current = -1;
12085 mov->frag_index.complete = 0;
12086 }
12087
12088 for (i = 0; i < s->nb_streams; i++) {
12089 AVStream *avst = s->streams[i];
12090 MOVStreamContext *msc = avst->priv_data;
12091
12092 // Clear current sample
12093 mov_current_sample_set(msc, 0);
12094 msc->tts_index = 0;
12095
12096 // Discard current index entries
12097 avsti = ffstream(avst);
12098 if (avsti->index_entries_allocated_size > 0) {
12099 av_freep(&avsti->index_entries);
12101 avsti->nb_index_entries = 0;
12102 }
12103 }
12104
12105 if ((ret = mov_switch_root(s, -1, -1)) < 0)
12106 return ret;
12107 }
12109 if (!sample || (mov->next_root_atom && sample->pos > mov->next_root_atom)) {
12110 if (!mov->next_root_atom)
12111 return AVERROR_EOF;
12112 if ((ret = mov_switch_root(s, mov->next_root_atom, -1)) < 0)
12113 return ret;
12114 goto retry;
12115 }
12116 sc = st->priv_data;
12117 /* must be done just before reading, to avoid infinite loop on sample */
12118 current_index = sc->current_index;
12120
12121 if (mov->next_root_atom) {
12122 sample->pos = FFMIN(sample->pos, mov->next_root_atom);
12123 sample->size = FFMIN(sample->size, (mov->next_root_atom - sample->pos));
12124 }
12125
12126 if (st->discard != AVDISCARD_ALL || sc->iamf) {
12127 int64_t ret64 = avio_seek(sc->pb, sample->pos, SEEK_SET);
12128 if (ret64 != sample->pos) {
12129 av_log(mov->fc, AV_LOG_ERROR, "stream %d, offset 0x%"PRIx64": partial file\n",
12130 sc->ffindex, sample->pos);
12131 if (should_retry(sc->pb, ret64)) {
12133 } else if (ret64 < 0) {
12134 return (int)ret64;
12135 }
12136 return AVERROR_INVALIDDATA;
12137 }
12138
12139 if (st->discard == AVDISCARD_NONKEY && !(sample->flags & AVINDEX_KEYFRAME)) {
12140 av_log(mov->fc, AV_LOG_DEBUG, "Nonkey frame from stream %d discarded due to AVDISCARD_NONKEY\n", sc->ffindex);
12141 goto retry;
12142 }
12143
12144 if (st->codecpar->codec_id == AV_CODEC_ID_EIA_608 && sample->size > 8)
12145 ret = get_eia608_packet(sc->pb, pkt, sample->size);
12146#if CONFIG_IAMFDEC
12147 else if (sc->iamf) {
12148 int64_t pts, dts, pos, duration;
12149 int flags, size = sample->size;
12150 ret = mov_finalize_packet(s, st, sample, current_index, pkt);
12151 pts = pkt->pts; dts = pkt->dts;
12152 pos = pkt->pos; flags = pkt->flags;
12153 duration = pkt->duration;
12154 while (!ret && size > 0) {
12155 ret = ff_iamf_read_packet(s, sc->iamf, sc->pb, size, sc->iamf_stream_offset, pkt);
12156 if (ret < 0) {
12157 if (should_retry(sc->pb, ret))
12159 return ret;
12160 }
12161 size -= ret;
12162
12163 if (pkt->flags & AV_PKT_FLAG_DISCARD) {
12165 ret = 0;
12166 continue;
12167 }
12168 pkt->pts = pts; pkt->dts = dts;
12169 pkt->pos = pos; pkt->flags |= flags;
12170 pkt->duration = duration;
12171 ret = ff_buffer_packet(s, pkt);
12172 }
12173 if (!ret)
12174 return FFERROR_REDO;
12175 }
12176#endif
12177 else if (st->codecpar->codec_id == AV_CODEC_ID_APV && sample->size > 4) {
12178 uint32_t au_size = avio_rb32(sc->pb);
12179 int explode = !!(mov->fc->error_recognition & AV_EF_EXPLODE);
12180 if (au_size > sample->size - 4) {
12181 av_log(s, explode ? AV_LOG_ERROR : AV_LOG_WARNING,
12182 "APV au_size %u exceeds sample body %d\n",
12183 au_size, sample->size - 4);
12184 if (explode)
12185 return AVERROR_INVALIDDATA;
12186 au_size = sample->size - 4;
12187 }
12188 ret = av_get_packet(sc->pb, pkt, au_size);
12189 } else
12190 ret = av_get_packet(sc->pb, pkt, sample->size);
12191 if (ret < 0) {
12192 if (should_retry(sc->pb, ret)) {
12194 }
12195 return ret;
12196 }
12197#if CONFIG_DV_DEMUXER
12198 if (mov->dv_demux && sc->dv_audio_container) {
12199 ret = avpriv_dv_produce_packet(mov->dv_demux, NULL, pkt->data, pkt->size, pkt->pos);
12201 if (ret < 0)
12202 return ret;
12203 ret = avpriv_dv_get_packet(mov->dv_demux, pkt);
12204 if (ret < 0)
12205 return ret;
12206 }
12207#endif
12208 if (sc->has_palette) {
12209 uint8_t *pal;
12210
12212 if (!pal) {
12213 av_log(mov->fc, AV_LOG_ERROR, "Cannot append palette to packet\n");
12214 } else {
12215 memcpy(pal, sc->palette, AVPALETTE_SIZE);
12216 sc->has_palette = 0;
12217 }
12218 }
12219 if (st->codecpar->codec_id == AV_CODEC_ID_MP3 && !ffstream(st)->need_parsing && pkt->size > 4) {
12220 if (ff_mpa_check_header(AV_RB32(pkt->data)) < 0)
12222 }
12223 }
12224
12225 ret = mov_finalize_packet(s, st, sample, current_index, pkt);
12226 if (ret < 0)
12227 return ret;
12228
12229 if (st->discard == AVDISCARD_ALL)
12230 goto retry;
12231
12232 if (mov->aax_mode)
12233 aax_filter(pkt->data, pkt->size, mov);
12234
12235 ret = cenc_filter(mov, st, sc, pkt, current_index);
12236 if (ret < 0) {
12237 return ret;
12238 }
12239
12240 return 0;
12241}
12242
12244{
12245 MOVContext *mov = s->priv_data;
12246 int index;
12247
12248 if (!mov->frag_index.complete)
12249 return 0;
12250
12251 index = search_frag_timestamp(s, &mov->frag_index, st, timestamp);
12252 if (index < 0)
12253 index = 0;
12254 if (!mov->frag_index.item[index].headers_read)
12255 return mov_switch_root(s, -1, index);
12256 if (index + 1 < mov->frag_index.nb_items)
12258
12259 return 0;
12260}
12261
12263{
12264 // TODO: a bisect search would scale much better
12265 for (int i = 0; i < sc->open_key_samples_count; i++) {
12266 const int oks = sc->open_key_samples[i];
12267 if (oks == sample)
12268 return 1;
12269 if (oks > sample) /* list is monotically increasing so we can stop early */
12270 break;
12271 }
12272 return 0;
12273}
12274
12275/*
12276 * Some key sample may be key frames but not IDR frames, so a random access to
12277 * them may not be allowed.
12278 */
12279static int can_seek_to_key_sample(AVStream *st, int sample, int64_t requested_pts)
12280{
12281 MOVStreamContext *sc = st->priv_data;
12282 FFStream *const sti = ffstream(st);
12283 int64_t key_sample_dts, key_sample_pts;
12284
12286 return 1;
12287
12288 if (sample >= sc->sample_offsets_count)
12289 return 1;
12290
12291 av_assert0(sample >= 0);
12292 key_sample_dts = sti->index_entries[sample].timestamp;
12293 key_sample_pts = key_sample_dts + sc->sample_offsets[sample] + sc->dts_shift;
12294
12295 /*
12296 * If the sample needs to be presented before an open key sample, they may
12297 * not be decodable properly, even though they come after in decoding
12298 * order.
12299 */
12300 if (is_open_key_sample(sc, sample) && key_sample_pts > requested_pts)
12301 return 0;
12302
12303 return 1;
12304}
12305
12306static int mov_seek_stream(AVFormatContext *s, AVStream *st, int64_t timestamp, int flags)
12307{
12308 MOVStreamContext *sc = st->priv_data;
12309 FFStream *const sti = ffstream(st);
12310 int sample, time_sample, ret, requested_sample;
12311 int64_t next_ts;
12312 unsigned int i;
12313
12314 // Here we consider timestamp to be PTS, hence try to offset it so that we
12315 // can search over the DTS timeline.
12316 timestamp -= (sc->min_corrected_pts + sc->dts_shift);
12317
12318 ret = mov_seek_fragment(s, st, timestamp);
12319 if (ret < 0)
12320 return ret;
12321
12322 for (;;) {
12323 sample = av_index_search_timestamp(st, timestamp, flags);
12324 av_log(s, AV_LOG_TRACE, "stream %d, timestamp %"PRId64", sample %d\n", st->index, timestamp, sample);
12325 if (sample < 0 && sti->nb_index_entries && timestamp < sti->index_entries[0].timestamp)
12326 sample = 0;
12327 if (sample < 0) /* not sure what to do */
12328 return AVERROR_INVALIDDATA;
12329
12330 if (!sample || can_seek_to_key_sample(st, sample, timestamp))
12331 break;
12332
12333 next_ts = timestamp - FFMAX(sc->min_sample_duration, 1);
12334 requested_sample = av_index_search_timestamp(st, next_ts, flags);
12335 if (requested_sample < 0)
12336 return AVERROR_INVALIDDATA;
12337
12338 // If we've reached a different sample trying to find a good pts to
12339 // seek to, give up searching because we'll end up seeking back to
12340 // sample 0 on every seek.
12341 if (sample != requested_sample && !can_seek_to_key_sample(st, requested_sample, next_ts))
12342 break;
12343
12344 timestamp = next_ts;
12345 }
12346
12348 av_log(s, AV_LOG_TRACE, "stream %d, found sample %d\n", st->index, sc->current_sample);
12349 /* adjust time to sample index */
12350 if (sc->tts_data) {
12351 time_sample = 0;
12352 for (i = 0; i < sc->tts_count; i++) {
12353 int next = time_sample + sc->tts_data[i].count;
12354 if (next > sc->current_sample) {
12355 sc->tts_index = i;
12356 sc->tts_sample = sc->current_sample - time_sample;
12357 break;
12358 }
12359 time_sample = next;
12360 }
12361 }
12362
12363 /* adjust stsd index */
12364 if (sc->chunk_count) {
12365 time_sample = 0;
12366 for (i = 0; i < sc->stsc_count; i++) {
12367 int64_t next = time_sample + mov_get_stsc_samples(sc, i);
12368 if (next > sc->current_sample) {
12369 sc->stsc_index = i;
12370 sc->stsc_sample = sc->current_sample - time_sample;
12371 break;
12372 }
12373 av_assert0(next == (int)next);
12374 time_sample = next;
12375 }
12376 }
12377
12378 return sample;
12379}
12380
12382{
12383 FFStream *const sti = ffstream(st);
12384 int64_t first_ts = sti->index_entries[0].timestamp;
12386 int64_t off;
12387
12389 return 0;
12390
12391 /* compute skip samples according to stream initial_padding, seek ts and first ts */
12392 off = av_rescale_q(ts - first_ts, st->time_base,
12393 (AVRational){1, st->codecpar->sample_rate});
12394 return FFMAX(st->codecpar->initial_padding - off, 0);
12395}
12396
12397static int mov_read_seek(AVFormatContext *s, int stream_index, int64_t sample_time, int flags)
12398{
12399 MOVContext *mc = s->priv_data;
12400 AVStream *st;
12401 FFStream *sti;
12402 int sample;
12403 int i;
12404
12405 if (stream_index >= s->nb_streams)
12406 return AVERROR_INVALIDDATA;
12407
12408 st = s->streams[stream_index];
12409 sti = ffstream(st);
12410 sample = mov_seek_stream(s, st, sample_time, flags);
12411 if (sample < 0)
12412 return sample;
12413
12414 if (mc->seek_individually) {
12415 /* adjust seek timestamp to found sample timestamp */
12416 int64_t seek_timestamp = sti->index_entries[sample].timestamp;
12418
12419 for (i = 0; i < s->nb_streams; i++) {
12420 AVStream *const st = s->streams[i];
12421 FFStream *const sti = ffstream(st);
12422 int64_t timestamp;
12423
12424 if (stream_index == i)
12425 continue;
12426
12427 timestamp = av_rescale_q(seek_timestamp, s->streams[stream_index]->time_base, st->time_base);
12428 sample = mov_seek_stream(s, st, timestamp, flags);
12429 if (sample >= 0)
12431 }
12432 } else {
12433 for (i = 0; i < s->nb_streams; i++) {
12434 MOVStreamContext *sc;
12435 st = s->streams[i];
12436 sc = st->priv_data;
12438 }
12439 while (1) {
12440 MOVStreamContext *sc;
12442 if (!entry)
12443 return AVERROR_INVALIDDATA;
12444 sc = st->priv_data;
12445 if (sc->ffindex == stream_index && sc->current_sample == sample)
12446 break;
12448 }
12449 }
12450 return 0;
12451}
12452
12453#define OFFSET(x) offsetof(MOVContext, x)
12454#define FLAGS AV_OPT_FLAG_VIDEO_PARAM | AV_OPT_FLAG_DECODING_PARAM
12455static const AVOption mov_options[] = {
12456 {"use_absolute_path",
12457 "allow using absolute path when opening alias, this is a possible security issue",
12458 OFFSET(use_absolute_path), AV_OPT_TYPE_BOOL, {.i64 = 0},
12459 0, 1, FLAGS},
12460 {"seek_streams_individually",
12461 "Seek each stream individually to the closest point",
12462 OFFSET(seek_individually), AV_OPT_TYPE_BOOL, { .i64 = 1 },
12463 0, 1, FLAGS},
12464 {"ignore_editlist", "Ignore the edit list atom.", OFFSET(ignore_editlist), AV_OPT_TYPE_BOOL, {.i64 = 0},
12465 0, 1, FLAGS},
12466 {"advanced_editlist",
12467 "Modify the AVIndex according to the editlists. Use this option to decode in the order specified by the edits.",
12468 OFFSET(advanced_editlist), AV_OPT_TYPE_BOOL, {.i64 = 1},
12469 0, 1, FLAGS},
12470 {"ignore_chapters", "", OFFSET(ignore_chapters), AV_OPT_TYPE_BOOL, {.i64 = 0},
12471 0, 1, FLAGS},
12472 {"use_mfra_for",
12473 "use mfra for fragment timestamps",
12474 OFFSET(use_mfra_for), AV_OPT_TYPE_INT, {.i64 = FF_MOV_FLAG_MFRA_AUTO},
12476 .unit = "use_mfra_for"},
12477 {"auto", "auto", 0, AV_OPT_TYPE_CONST, {.i64 = FF_MOV_FLAG_MFRA_AUTO}, 0, 0,
12478 FLAGS, .unit = "use_mfra_for" },
12479 {"dts", "dts", 0, AV_OPT_TYPE_CONST, {.i64 = FF_MOV_FLAG_MFRA_DTS}, 0, 0,
12480 FLAGS, .unit = "use_mfra_for" },
12481 {"pts", "pts", 0, AV_OPT_TYPE_CONST, {.i64 = FF_MOV_FLAG_MFRA_PTS}, 0, 0,
12482 FLAGS, .unit = "use_mfra_for" },
12483 {"use_tfdt", "use tfdt for fragment timestamps", OFFSET(use_tfdt), AV_OPT_TYPE_BOOL, {.i64 = 1},
12484 0, 1, FLAGS},
12485 { "export_all", "Export unrecognized metadata entries", OFFSET(export_all),
12486 AV_OPT_TYPE_BOOL, { .i64 = 0 }, 0, 1, .flags = FLAGS },
12487 { "export_xmp", "Export full XMP metadata", OFFSET(export_xmp),
12488 AV_OPT_TYPE_BOOL, { .i64 = 0 }, 0, 1, .flags = FLAGS },
12489 { "activation_bytes", "Secret bytes for Audible AAX files", OFFSET(activation_bytes),
12491 { "audible_key", "AES-128 Key for Audible AAXC files", OFFSET(audible_key),
12493 { "audible_iv", "AES-128 IV for Audible AAXC files", OFFSET(audible_iv),
12495 { "audible_fixed_key", // extracted from libAAX_SDK.so and AAXSDKWin.dll files!
12496 "Fixed key used for handling Audible AAX files", OFFSET(audible_fixed_key),
12497 AV_OPT_TYPE_BINARY, {.str="77214d4b196a87cd520045fd20a51d67"},
12498 .flags = AV_OPT_FLAG_DECODING_PARAM },
12499 { "decryption_key", "The default media decryption key (hex)", OFFSET(decryption_default_key), AV_OPT_TYPE_BINARY, .flags = AV_OPT_FLAG_DECODING_PARAM },
12500 { "decryption_keys", "The media decryption keys by KID (hex)", OFFSET(decryption_keys), AV_OPT_TYPE_DICT, .flags = AV_OPT_FLAG_DECODING_PARAM },
12501 { "enable_drefs", "Enable external track support.", OFFSET(enable_drefs), AV_OPT_TYPE_BOOL,
12502 {.i64 = 0}, 0, 1, FLAGS },
12503 { "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 },
12504 { "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 },
12505
12506 { NULL },
12507};
12508
12509static const AVClass mov_class = {
12510 .class_name = "mov,mp4,m4a,3gp,3g2,mj2",
12511 .item_name = av_default_item_name,
12512 .option = mov_options,
12513 .version = LIBAVUTIL_VERSION_INT,
12514};
12515
12517 .p.name = "mov,mp4,m4a,3gp,3g2,mj2",
12518 .p.long_name = NULL_IF_CONFIG_SMALL("QuickTime / MOV"),
12519 .p.priv_class = &mov_class,
12520 .p.extensions = "mov,mp4,m4a,3gp,3g2,mj2,psp,m4v,m4b,ism,ismv,isma,f4v,avif,heic,heif",
12522 .priv_data_size = sizeof(MOVContext),
12523 .flags_internal = FF_INFMT_FLAG_INIT_CLEANUP,
12529};
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:12516
AVAmbientViewingEnvironment * av_ambient_viewing_environment_alloc(size_t *size)
Allocate an AVAmbientViewingEnvironment structure.
#define entry
static FILE * out
static int out_size
static AVFormatContext * ctx
static void finish(void)
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:46
#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
int ff_itunes_parse_smpb(const char *value, int64_t *priming, int64_t *remainder, int64_t *samples)
Parse the gapless playback information Apple encoders store in an iTunSMPB tag.
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:12381
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:11909
static int mov_read_iloc(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition mov.c:9411
static int mov_read_pack(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition mov.c:7110
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:12397
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:10541
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:5867
static int mov_read_dops(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition mov.c:8987
static int set_display_matrix_from_item(AVPacketSideData **coded_side_data, int *nb_coded_side_data, const HEIFItem *item)
Definition mov.c:10812
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:11849
static int mov_read_vexu_proj(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition mov.c:7328
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:8571
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:9405
static int mov_parse_tmcd_streams(AVFormatContext *s)
Definition mov.c:11286
static int mov_read_lhvc(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition mov.c:9122
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:9397
static int mov_seek_stream(AVFormatContext *s, AVStream *st, int64_t timestamp, int flags)
Definition mov.c:12306
static int mov_read_packet(AVFormatContext *s, AVPacket *pkt)
Definition mov.c:12062
static int mov_parse_lcevc_streams(AVFormatContext *s)
Definition mov.c:11412
static int mov_read_hvce(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition mov.c:9095
static int cbcs_scheme_decrypt(MOVContext *c, MOVStreamContext *sc, AVEncryptionInfo *sample, uint8_t *input, int size)
Definition mov.c:8804
static int mov_read_default(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition mov.c:10126
static int mov_finalize_packet(AVFormatContext *s, AVStream *st, AVIndexEntry *sample, int64_t current_index, AVPacket *pkt)
Definition mov.c:11978
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:8213
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:6809
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:7401
static int cenc_scheme_decrypt(MOVContext *c, MOVStreamContext *sc, AVEncryptionInfo *sample, uint8_t *input, int size)
Definition mov.c:8608
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:10928
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:9642
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 rb_size(AVIOContext *pb, int64_t *value, int size)
Definition mov.c:9378
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:11577
static int mov_read_dfla(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition mov.c:8531
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:7063
static int mov_read_elst(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition mov.c:6735
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:7191
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:8917
static const AVClass mov_class
Definition mov.c:12509
static int mov_read_sample_encryption_info(MOVContext *c, AVIOContext *pb, MOVStreamContext *sc, AVEncryptionInfo **sample, int use_subsamples)
Definition mov.c:7957
static int mov_read_meta(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition mov.c:5926
static int mov_read_smdm(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition mov.c:6881
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:6523
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:10456
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:9040
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:8429
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:10697
static int mov_seek_fragment(AVFormatContext *s, AVStream *st, int64_t timestamp)
Definition mov.c:12243
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:11466
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:10997
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:9075
static int should_retry(AVIOContext *pb, int error_code)
Definition mov.c:11842
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:6151
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:7009
static int mov_read_trun(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition mov.c:6190
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:9173
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:8308
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:5952
static int mov_read_iprp(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition mov.c:9881
static int mov_read_cdsc_rndr(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition mov.c:2703
static int cens_scheme_decrypt(MOVContext *c, MOVStreamContext *sc, AVEncryptionInfo *sample, uint8_t *input, int size)
Definition mov.c:8733
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:10752
#define MIN_DATA_ENTRY_BOX_SIZE
Definition mov.c:653
static int mov_change_extradata(AVStream *st, AVPacket *pkt)
Definition mov.c:11885
static int mov_read_mdcv(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition mov.c:6928
static int mov_read_timecode_track(AVFormatContext *s, AVStream *st)
Definition mov.c:10482
static int mov_read_imir(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition mov.c:9862
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 int mov_parse_cdsc_and_rndr_streams(AVFormatContext *s)
Definition mov.c:11357
static const MOVParseTableEntry mov_default_parse_table[]
Definition mov.c:9992
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:9769
static int mov_read_trex(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition mov.c:6125
static int mov_read_saiz(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition mov.c:8129
static int mov_read_hfov(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition mov.c:7640
static int mov_read_free(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition mov.c:7837
static int set_icc_profile_from_item(AVPacketSideData **coded_side_data, int *nb_coded_side_data, const HEIFItem *item)
Definition mov.c:10798
static int mov_read_infe(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition mov.c:9508
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:8667
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:7906
static int mov_read_close(AVFormatContext *s)
Definition mov.c:10606
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:8892
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:8460
static int mov_read_uuid(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition mov.c:7732
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:7038
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:5944
static int can_seek_to_key_sample(AVStream *st, int sample, int64_t requested_pts)
Definition mov.c:12279
static int mov_parse_auxiliary_info(MOVContext *c, MOVStreamContext *sc, AVIOContext *pb, MOVEncryptionIndex *encryption_index)
Definition mov.c:8067
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:6837
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:11081
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:9725
static int cenc_decrypt(MOVContext *c, MOVStreamContext *sc, AVEncryptionInfo *sample, uint8_t *input, int size)
Definition mov.c:8876
static int mov_read_senc(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition mov.c:8011
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:11342
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:9352
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:10529
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:11539
#define OFFSET(x)
Definition mov.c:12453
static AVIndexEntry * mov_find_next_sample(AVFormatContext *s, AVStream **st)
Definition mov.c:11812
static int mov_read_chap(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition mov.c:6104
#define MOV_MERGE_CTTS
Definition mov.c:4890
static int is_open_key_sample(const MOVStreamContext *sc, int sample)
Definition mov.c:12262
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:9262
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:6972
static int mov_read_frma(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition mov.c:7859
static int mov_read_ispe(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition mov.c:9814
static int mov_codec_id(AVStream *st, uint32_t format)
Definition mov.c:2885
static void export_orphan_timecode(AVFormatContext *s)
Definition mov.c:10679
static int mov_parse_heif_items(AVFormatContext *s)
Definition mov.c:11207
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:6057
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:9842
static int read_image_grid(AVFormatContext *s, const HEIFGrid *grid, AVStreamGroupTileGrid *tile_grid)
Definition mov.c:10833
static int mov_probe(const AVProbeData *p)
Definition mov.c:10248
static int parse_timecode_in_framenum_format(AVFormatContext *s, AVStream *st, int64_t value, int flags)
Definition mov.c:10442
static int mov_parse_uuid_spherical(MOVStreamContext *sc, AVIOContext *pb, size_t len)
Definition mov.c:7669
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:6662
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:9585
static int tmcd_is_referenced(AVFormatContext *s, int tmcd_id)
Definition mov.c:10661
static void mov_read_chapters(AVFormatContext *s)
Definition mov.c:10343
static int mov_read_cmov(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition mov.c:6682
static void set_frag_stream(MOVFragmentIndex *frag_index, int id)
Definition mov.c:1733
static const AVOption mov_options[]
Definition mov.c:12455
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:7578
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:2087
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 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]