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"
62#include "avformat.h"
63#include "internal.h"
64#include "avio_internal.h"
65#include "demux.h"
66#include "dvdclut.h"
67#include "iamf_parse.h"
68#include "iamf_reader.h"
69#include "dovi_isom.h"
70#include "riff.h"
71#include "isom.h"
72#include "libavcodec/get_bits.h"
73#include "id3v1.h"
74#include "mov_chan.h"
75#include "replaygain.h"
76
77#if CONFIG_ZLIB
78#include <zlib.h>
79#endif
80
81#include "qtpalette.h"
82
83/* those functions parse an atom */
84/* links atom IDs to parse functions */
85typedef struct MOVParseTableEntry {
86 uint32_t type;
87 int (*parse)(MOVContext *ctx, AVIOContext *pb, MOVAtom atom);
89
90static int mov_read_default(MOVContext *c, AVIOContext *pb, MOVAtom atom);
93
95 unsigned len, const char *key)
96{
97 char buf[16];
98
99 short current, total = 0;
100 avio_rb16(pb); // unknown
101 current = avio_rb16(pb);
102 if (len >= 6)
103 total = avio_rb16(pb);
104 if (!total)
105 snprintf(buf, sizeof(buf), "%d", current);
106 else
107 snprintf(buf, sizeof(buf), "%d/%d", current, total);
108 c->fc->event_flags |= AVFMT_EVENT_FLAG_METADATA_UPDATED;
109 av_dict_set(&c->fc->metadata, key, buf, 0);
110
111 return 0;
112}
113
115 unsigned len, const char *key)
116{
117 /* bypass padding bytes */
118 avio_r8(pb);
119 avio_r8(pb);
120 avio_r8(pb);
121
122 c->fc->event_flags |= AVFMT_EVENT_FLAG_METADATA_UPDATED;
123 av_dict_set_int(&c->fc->metadata, key, avio_r8(pb), 0);
124
125 return 0;
126}
127
129 unsigned len, const char *key)
130{
131 c->fc->event_flags |= AVFMT_EVENT_FLAG_METADATA_UPDATED;
132 av_dict_set_int(&c->fc->metadata, key, avio_r8(pb), 0);
133
134 return 0;
135}
136
138 unsigned len, const char *key)
139{
140 short genre;
141
142 avio_r8(pb); // unknown
143
144 genre = avio_r8(pb);
145 if (genre < 1 || genre > ID3v1_GENRE_MAX)
146 return 0;
147 c->fc->event_flags |= AVFMT_EVENT_FLAG_METADATA_UPDATED;
148 av_dict_set(&c->fc->metadata, key, ff_id3v1_genre_str[genre-1], 0);
149
150 return 0;
151}
152
153static const uint32_t mac_to_unicode[128] = {
154 0x00C4,0x00C5,0x00C7,0x00C9,0x00D1,0x00D6,0x00DC,0x00E1,
155 0x00E0,0x00E2,0x00E4,0x00E3,0x00E5,0x00E7,0x00E9,0x00E8,
156 0x00EA,0x00EB,0x00ED,0x00EC,0x00EE,0x00EF,0x00F1,0x00F3,
157 0x00F2,0x00F4,0x00F6,0x00F5,0x00FA,0x00F9,0x00FB,0x00FC,
158 0x2020,0x00B0,0x00A2,0x00A3,0x00A7,0x2022,0x00B6,0x00DF,
159 0x00AE,0x00A9,0x2122,0x00B4,0x00A8,0x2260,0x00C6,0x00D8,
160 0x221E,0x00B1,0x2264,0x2265,0x00A5,0x00B5,0x2202,0x2211,
161 0x220F,0x03C0,0x222B,0x00AA,0x00BA,0x03A9,0x00E6,0x00F8,
162 0x00BF,0x00A1,0x00AC,0x221A,0x0192,0x2248,0x2206,0x00AB,
163 0x00BB,0x2026,0x00A0,0x00C0,0x00C3,0x00D5,0x0152,0x0153,
164 0x2013,0x2014,0x201C,0x201D,0x2018,0x2019,0x00F7,0x25CA,
165 0x00FF,0x0178,0x2044,0x20AC,0x2039,0x203A,0xFB01,0xFB02,
166 0x2021,0x00B7,0x201A,0x201E,0x2030,0x00C2,0x00CA,0x00C1,
167 0x00CB,0x00C8,0x00CD,0x00CE,0x00CF,0x00CC,0x00D3,0x00D4,
168 0xF8FF,0x00D2,0x00DA,0x00DB,0x00D9,0x0131,0x02C6,0x02DC,
169 0x00AF,0x02D8,0x02D9,0x02DA,0x00B8,0x02DD,0x02DB,0x02C7,
170};
171
173 char *dst, int dstlen)
174{
175 char *p = dst;
176 char *end = dst+dstlen-1;
177 int i;
178
179 for (i = 0; i < len; i++) {
180 uint8_t t, c = avio_r8(pb);
181
182 if (p >= end)
183 continue;
184
185 if (c < 0x80)
186 *p++ = c;
187 else if (p < end)
188 PUT_UTF8(mac_to_unicode[c-0x80], t, if (p < end) *p++ = t;);
189 }
190 *p = 0;
191 return p - dst;
192}
193
194/**
195 * Get the requested item.
196 */
197static HEIFItem *get_heif_item(MOVContext *c, unsigned id)
198{
199 HEIFItem *item = NULL;
200
201 for (int i = 0; i < c->nb_heif_item; i++) {
202 if (!c->heif_item[i] || c->heif_item[i]->item_id != id)
203 continue;
204
205 item = c->heif_item[i];
206 break;
207 }
208
209 return item;
210}
211
212/**
213 * Get the current stream in the parsing process. This can either be the
214 * latest stream added to the context, or the stream referenced by an item.
215 */
217{
218 AVStream *st = NULL;
219 HEIFItem *item;
220
221 if (c->fc->nb_streams < 1)
222 return NULL;
223
224 if (c->cur_item_id == -1)
225 return c->fc->streams[c->fc->nb_streams-1];
226
227 item = get_heif_item(c, c->cur_item_id);
228 if (item)
229 st = item->st;
230
231 return st;
232}
233
234static int mov_read_covr(MOVContext *c, AVIOContext *pb, int type, int len)
235{
236 AVStream *st;
238 enum AVCodecID id;
239 int ret;
240
241 switch (type) {
242 case 0xd: id = AV_CODEC_ID_MJPEG; break;
243 case 0xe: id = AV_CODEC_ID_PNG; break;
244 case 0x1b: id = AV_CODEC_ID_BMP; break;
245 default:
246 av_log(c->fc, AV_LOG_WARNING, "Unknown cover type: 0x%x.\n", type);
247 avio_skip(pb, len);
248 return 0;
249 }
250
251 sc = av_mallocz(sizeof(*sc));
252 if (!sc)
253 return AVERROR(ENOMEM);
254 ret = ff_add_attached_pic(c->fc, NULL, pb, NULL, len);
255 if (ret < 0) {
256 av_free(sc);
257 return ret;
258 }
259 st = c->fc->streams[c->fc->nb_streams - 1];
260 st->priv_data = sc;
261 sc->id = st->id;
262 sc->refcount = 1;
263
264 if (st->attached_pic.size >= 8 && id != AV_CODEC_ID_BMP) {
265 if (AV_RB64(st->attached_pic.data) == 0x89504e470d0a1a0a) {
266 id = AV_CODEC_ID_PNG;
267 } else {
269 }
270 }
271 st->codecpar->codec_id = id;
272
273 return 0;
274}
275
276// 3GPP TS 26.244
277static int mov_metadata_loci(MOVContext *c, AVIOContext *pb, unsigned len)
278{
279 char language[4] = { 0 };
280 char buf[200], place[100];
281 uint16_t langcode = 0;
282 double longitude, latitude, altitude;
283 const char *key = "location";
284
285 if (len < 4 + 2 + 1 + 1 + 4 + 4 + 4) {
286 av_log(c->fc, AV_LOG_ERROR, "loci too short\n");
287 return AVERROR_INVALIDDATA;
288 }
289
290 avio_skip(pb, 4); // version+flags
291 langcode = avio_rb16(pb);
292 ff_mov_lang_to_iso639(langcode, language);
293 len -= 6;
294
295 len -= avio_get_str(pb, len, place, sizeof(place));
296 if (len < 1) {
297 av_log(c->fc, AV_LOG_ERROR, "place name too long\n");
298 return AVERROR_INVALIDDATA;
299 }
300 avio_skip(pb, 1); // role
301 len -= 1;
302
303 if (len < 12) {
304 av_log(c->fc, AV_LOG_ERROR,
305 "loci too short (%u bytes left, need at least %d)\n", len, 12);
306 return AVERROR_INVALIDDATA;
307 }
308 longitude = ((int32_t) avio_rb32(pb)) / (float) (1 << 16);
309 latitude = ((int32_t) avio_rb32(pb)) / (float) (1 << 16);
310 altitude = ((int32_t) avio_rb32(pb)) / (float) (1 << 16);
311
312 // Try to output in the same format as the ?xyz field
313 snprintf(buf, sizeof(buf), "%+08.4f%+09.4f", latitude, longitude);
314 if (altitude)
315 av_strlcatf(buf, sizeof(buf), "%+f", altitude);
316 av_strlcatf(buf, sizeof(buf), "/%s", place);
317
318 if (*language && strcmp(language, "und")) {
319 char key2[16];
320 snprintf(key2, sizeof(key2), "%s-%s", key, language);
321 av_dict_set(&c->fc->metadata, key2, buf, 0);
322 }
323 c->fc->event_flags |= AVFMT_EVENT_FLAG_METADATA_UPDATED;
324 return av_dict_set(&c->fc->metadata, key, buf, 0);
325}
326
327static int mov_metadata_hmmt(MOVContext *c, AVIOContext *pb, unsigned len)
328{
329 int i, n_hmmt;
330
331 if (len < 2)
332 return 0;
333 if (c->ignore_chapters)
334 return 0;
335
336 n_hmmt = avio_rb32(pb);
337 if (n_hmmt > len / 4)
338 return AVERROR_INVALIDDATA;
339 for (i = 0; i < n_hmmt && !pb->eof_reached; i++) {
340 int moment_time = avio_rb32(pb);
341 avpriv_new_chapter(c->fc, i, av_make_q(1, 1000), moment_time, AV_NOPTS_VALUE, NULL);
342 }
343 if (avio_feof(pb))
344 return AVERROR_INVALIDDATA;
345 return 0;
346}
347
349{
350 char tmp_key[AV_FOURCC_MAX_STRING_SIZE] = {0};
351 char key2[32], language[4] = {0};
352 char *str = NULL;
353 const char *key = NULL;
354 uint16_t langcode = 0;
355 uint32_t data_type = 0, str_size_alloc;
356 uint64_t str_size;
357 int (*parse)(MOVContext*, AVIOContext*, unsigned, const char*) = NULL;
358 int raw = 0;
359 int num = 0;
361
362 if (c->trak_index >= 0 && c->trak_index < c->fc->nb_streams)
363 metadata = &c->fc->streams[c->trak_index]->metadata;
364 else
365 metadata = &c->fc->metadata;
366
367 switch (atom.type) {
368 case MKTAG( '@','P','R','M'): key = "premiere_version"; raw = 1; break;
369 case MKTAG( '@','P','R','Q'): key = "quicktime_version"; raw = 1; break;
370 case MKTAG( 'X','M','P','_'):
371 if (c->export_xmp) { key = "xmp"; raw = 1; } break;
372 case MKTAG( 'a','A','R','T'): key = "album_artist"; break;
373 case MKTAG( 'a','k','I','D'): key = "account_type";
375 case MKTAG( 'a','p','I','D'): key = "account_id"; break;
376 case MKTAG( 'c','a','t','g'): key = "category"; break;
377 case MKTAG( 'c','p','i','l'): key = "compilation";
379 case MKTAG( 'c','p','r','t'): key = "copyright"; break;
380 case MKTAG( 'd','e','s','c'): key = "description"; break;
381 case MKTAG( 'd','i','s','k'): key = "disc";
383 case MKTAG( 'e','g','i','d'): key = "episode_uid";
385 case MKTAG( 'F','I','R','M'): key = "firmware"; raw = 1; break;
386 case MKTAG( 'g','n','r','e'): key = "genre";
387 parse = mov_metadata_gnre; break;
388 case MKTAG( 'h','d','v','d'): key = "hd_video";
390 case MKTAG( 'H','M','M','T'):
391 return mov_metadata_hmmt(c, pb, atom.size);
392 case MKTAG( 'k','e','y','w'): key = "keywords"; break;
393 case MKTAG( 'l','d','e','s'): key = "synopsis"; break;
394 case MKTAG( 'l','o','c','i'):
395 return mov_metadata_loci(c, pb, atom.size);
396 case MKTAG( 'm','a','n','u'): key = "make"; break;
397 case MKTAG( 'm','o','d','l'): key = "model"; break;
398 case MKTAG( 'n','a','m','e'): key = "name"; break;
399 case MKTAG( 'p','c','s','t'): key = "podcast";
401 case MKTAG( 'p','g','a','p'): key = "gapless_playback";
403 case MKTAG( 'p','u','r','d'): key = "purchase_date"; break;
404 case MKTAG( 'r','t','n','g'): key = "rating";
406 case MKTAG( 's','o','a','a'): key = "sort_album_artist"; break;
407 case MKTAG( 's','o','a','l'): key = "sort_album"; break;
408 case MKTAG( 's','o','a','r'): key = "sort_artist"; break;
409 case MKTAG( 's','o','c','o'): key = "sort_composer"; break;
410 case MKTAG( 's','o','n','m'): key = "sort_name"; break;
411 case MKTAG( 's','o','s','n'): key = "sort_show"; break;
412 case MKTAG( 's','t','i','k'): key = "media_type";
414 case MKTAG( 't','r','k','n'): key = "track";
416 case MKTAG( 't','v','e','n'): key = "episode_id"; break;
417 case MKTAG( 't','v','e','s'): key = "episode_sort";
419 case MKTAG( 't','v','n','n'): key = "network"; break;
420 case MKTAG( 't','v','s','h'): key = "show"; break;
421 case MKTAG( 't','v','s','n'): key = "season_number";
423 case MKTAG(0xa9,'A','R','T'): key = "artist"; break;
424 case MKTAG(0xa9,'P','R','D'): key = "producer"; break;
425 case MKTAG(0xa9,'a','l','b'): key = "album"; break;
426 case MKTAG(0xa9,'a','u','t'): key = "artist"; break;
427 case MKTAG(0xa9,'c','h','p'): key = "chapter"; break;
428 case MKTAG(0xa9,'c','m','t'): key = "comment"; break;
429 case MKTAG(0xa9,'c','o','m'): key = "composer"; break;
430 case MKTAG(0xa9,'c','p','y'): key = "copyright"; break;
431 case MKTAG(0xa9,'d','a','y'): key = "date"; break;
432 case MKTAG(0xa9,'d','i','r'): key = "director"; break;
433 case MKTAG(0xa9,'d','i','s'): key = "disclaimer"; break;
434 case MKTAG(0xa9,'e','d','1'): key = "edit_date"; break;
435 case MKTAG(0xa9,'e','n','c'): key = "encoder"; break;
436 case MKTAG(0xa9,'f','m','t'): key = "original_format"; break;
437 case MKTAG(0xa9,'g','e','n'): key = "genre"; break;
438 case MKTAG(0xa9,'g','r','p'): key = "grouping"; break;
439 case MKTAG(0xa9,'h','s','t'): key = "host_computer"; break;
440 case MKTAG(0xa9,'i','n','f'): key = "comment"; break;
441 case MKTAG(0xa9,'l','y','r'): key = "lyrics"; break;
442 case MKTAG(0xa9,'m','a','k'): key = "make"; break;
443 case MKTAG(0xa9,'m','o','d'): key = "model"; break;
444 case MKTAG(0xa9,'n','a','m'): key = "title"; break;
445 case MKTAG(0xa9,'o','p','e'): key = "original_artist"; break;
446 case MKTAG(0xa9,'p','r','d'): key = "producer"; break;
447 case MKTAG(0xa9,'p','r','f'): key = "performers"; break;
448 case MKTAG(0xa9,'r','e','q'): key = "playback_requirements"; break;
449 case MKTAG(0xa9,'s','r','c'): key = "original_source"; break;
450 case MKTAG(0xa9,'s','t','3'): key = "subtitle"; break;
451 case MKTAG(0xa9,'s','w','r'): key = "encoder"; break;
452 case MKTAG(0xa9,'t','o','o'): key = "encoder"; break;
453 case MKTAG(0xa9,'t','r','k'): key = "track"; break;
454 case MKTAG(0xa9,'u','r','l'): key = "URL"; break;
455 case MKTAG(0xa9,'w','r','n'): key = "warning"; break;
456 case MKTAG(0xa9,'w','r','t'): key = "composer"; break;
457 case MKTAG(0xa9,'x','y','z'): key = "location"; break;
458 }
459retry:
460 if (c->itunes_metadata && atom.size > 8) {
461 int data_size = avio_rb32(pb);
462 int tag = avio_rl32(pb);
463 if (tag == MKTAG('d','a','t','a') && data_size <= atom.size && data_size >= 16) {
464 data_type = avio_rb32(pb); // type
465 avio_rb32(pb); // unknown
466 str_size = data_size - 16;
467 atom.size -= 16;
468
469 if (!key && c->found_hdlr_mdta && c->meta_keys) {
470 uint32_t index = av_bswap32(atom.type); // BE number has been read as LE
471 if (index < c->meta_keys_count && index > 0) {
472 key = c->meta_keys[index];
473 } else if (atom.type != MKTAG('c', 'o', 'v', 'r')) {
475 "The index of 'data' is out of range: %"PRId32" < 1 or >= %d.\n",
476 index, c->meta_keys_count);
477 }
478 }
479 if (atom.type == MKTAG('c', 'o', 'v', 'r') ||
480 (key && !strcmp(key, "com.apple.quicktime.artwork"))) {
481 int ret = mov_read_covr(c, pb, data_type, str_size);
482 if (ret < 0) {
483 av_log(c->fc, AV_LOG_ERROR, "Error parsing cover art.\n");
484 return ret;
485 }
486 atom.size -= str_size;
487 if (atom.size > 8)
488 goto retry;
489 return ret;
490 }
491 } else return 0;
492 } else if (atom.size > 4 && (key || c->export_all) && !c->itunes_metadata && !raw) {
493 str_size = avio_rb16(pb); // string length
494 if (str_size > atom.size) {
495 raw = 1;
496 avio_seek(pb, -2, SEEK_CUR);
497 av_log(c->fc, AV_LOG_WARNING, "UDTA parsing failed retrying raw\n");
498 goto retry;
499 }
500 langcode = avio_rb16(pb);
501 ff_mov_lang_to_iso639(langcode, language);
502 atom.size -= 4;
503 } else
504 str_size = atom.size;
505
506 if (c->export_all && !key) {
507 key = av_fourcc_make_string(tmp_key, atom.type);
508 }
509
510 if (!key)
511 return 0;
512 if (atom.size < 0 || str_size >= INT_MAX/2)
513 return AVERROR_INVALIDDATA;
514
515 // Allocates enough space if data_type is a int32 or float32 number, otherwise
516 // worst-case requirement for output string in case of utf8 coded input
517 num = (data_type >= 21 && data_type <= 23);
518 str_size_alloc = (num ? 512 : (raw ? str_size : str_size * 2)) + 1;
519 str = av_mallocz(str_size_alloc);
520 if (!str)
521 return AVERROR(ENOMEM);
522
523 if (parse)
524 parse(c, pb, str_size, key);
525 else {
526 if (!raw && (data_type == 3 || (data_type == 0 && (langcode < 0x400 || langcode == 0x7fff)))) { // MAC Encoded
527 mov_read_mac_string(c, pb, str_size, str, str_size_alloc);
528 } else if (data_type == 21) { // BE signed integer, variable size
529 int val = 0;
530 if (str_size == 1)
531 val = (int8_t)avio_r8(pb);
532 else if (str_size == 2)
533 val = (int16_t)avio_rb16(pb);
534 else if (str_size == 3)
535 val = ((int32_t)(avio_rb24(pb)<<8))>>8;
536 else if (str_size == 4)
537 val = (int32_t)avio_rb32(pb);
538 if (snprintf(str, str_size_alloc, "%d", val) >= str_size_alloc) {
539 av_log(c->fc, AV_LOG_ERROR,
540 "Failed to store the number (%d) in string.\n", val);
541 av_free(str);
542 return AVERROR_INVALIDDATA;
543 }
544 } else if (data_type == 22) { // BE unsigned integer, variable size
545 unsigned int val = 0;
546 if (str_size == 1)
547 val = avio_r8(pb);
548 else if (str_size == 2)
549 val = avio_rb16(pb);
550 else if (str_size == 3)
551 val = avio_rb24(pb);
552 else if (str_size == 4)
553 val = avio_rb32(pb);
554 if (snprintf(str, str_size_alloc, "%u", val) >= str_size_alloc) {
555 av_log(c->fc, AV_LOG_ERROR,
556 "Failed to store the number (%u) in string.\n", val);
557 av_free(str);
558 return AVERROR_INVALIDDATA;
559 }
560 } else if (data_type == 23 && str_size >= 4) { // BE float32
561 float val = av_int2float(avio_rb32(pb));
562 if (snprintf(str, str_size_alloc, "%f", val) >= str_size_alloc) {
563 av_log(c->fc, AV_LOG_ERROR,
564 "Failed to store the float32 number (%f) in string.\n", val);
565 av_free(str);
566 return AVERROR_INVALIDDATA;
567 }
568 } else if (data_type > 1 && data_type != 4) {
569 // data_type can be 0 if not set at all above. data_type 1 means
570 // UTF8 and 4 means "UTF8 sort". For any other type (UTF16 or e.g.
571 // a picture), don't return it blindly in a string that is supposed
572 // to be UTF8 text.
573 av_log(c->fc, AV_LOG_WARNING, "Skipping unhandled metadata %s of type %"PRIu32"\n", key, data_type);
574 av_free(str);
575 return 0;
576 } else {
577 int ret = ffio_read_size(pb, str, str_size);
578 if (ret < 0) {
579 av_free(str);
580 return ret;
581 }
582 str[str_size] = 0;
583 }
584 c->fc->event_flags |= AVFMT_EVENT_FLAG_METADATA_UPDATED;
585 if (c->itunes_metadata && av_dict_get(*metadata, key, NULL, 0))
587 av_dict_set(metadata, key, str, c->itunes_metadata ? AV_DICT_APPEND : 0);
588 if (*language && strcmp(language, "und")) {
589 snprintf(key2, sizeof(key2), "%s-%s", key, language);
590 av_dict_set(metadata, key2, str, 0);
591 }
592 if (!strcmp(key, "encoder")) {
593 int major, minor, micro;
594 if (sscanf(str, "HandBrake %d.%d.%d", &major, &minor, &micro) == 3) {
595 c->handbrake_version = 1000000*major + 1000*minor + micro;
596 }
597 }
598
599 atom.size -= str_size;
600 av_freep(&str);
601
602 // Read remaining data atoms for multi-valued iTunes tags (e.g. multiple
603 // artists stored as multiple data atoms within one tag atom), consistent
604 // with the existing covr path.
605 // Note: multiple sibling tag atoms with the same key (e.g. three separate
606 // ©ART atoms under ilst) are handled by the AV_DICT_APPEND logic above,
607 // since mov_read_udta_string() is called once per tag atom.
608 if (c->itunes_metadata && atom.size > 8)
609 goto retry;
610 }
611
612 av_freep(&str);
613 return 0;
614}
615
617{
618 int64_t start;
619 int i, nb_chapters, str_len, version;
620 char str[256+1];
621 int ret;
622
623 if (c->ignore_chapters)
624 return 0;
625
626 if ((atom.size -= 5) < 0)
627 return 0;
628
629 version = avio_r8(pb);
630 avio_rb24(pb);
631 if (version)
632 avio_rb32(pb); // ???
633 nb_chapters = avio_r8(pb);
634
635 for (i = 0; i < nb_chapters; i++) {
636 if (atom.size < 9)
637 return 0;
638
639 start = avio_rb64(pb);
640 str_len = avio_r8(pb);
641
642 if ((atom.size -= 9+str_len) < 0)
643 return 0;
644
645 ret = ffio_read_size(pb, str, str_len);
646 if (ret < 0)
647 return ret;
648 str[str_len] = 0;
649 avpriv_new_chapter(c->fc, i, (AVRational){1,10000000}, start, AV_NOPTS_VALUE, str);
650 }
651 return 0;
652}
653
654#define MIN_DATA_ENTRY_BOX_SIZE 12
656{
657 AVStream *st;
659 int entries, i, j;
660
661 if (c->fc->nb_streams < 1)
662 return 0;
663 st = c->fc->streams[c->fc->nb_streams-1];
664 sc = st->priv_data;
665
666 avio_rb32(pb); // version + flags
667 entries = avio_rb32(pb);
668 if (!entries ||
669 entries > (atom.size - 1) / MIN_DATA_ENTRY_BOX_SIZE + 1 ||
670 entries >= UINT_MAX / sizeof(*sc->drefs))
671 return AVERROR_INVALIDDATA;
672
673 for (i = 0; i < sc->drefs_count; i++) {
674 MOVDref *dref = &sc->drefs[i];
675 av_freep(&dref->path);
676 av_freep(&dref->dir);
677 }
678 av_free(sc->drefs);
679 sc->drefs_count = 0;
680 sc->drefs = av_mallocz(entries * sizeof(*sc->drefs));
681 if (!sc->drefs)
682 return AVERROR(ENOMEM);
683 sc->drefs_count = entries;
684
685 for (i = 0; i < entries; i++) {
686 MOVDref *dref = &sc->drefs[i];
687 uint32_t size = avio_rb32(pb);
688 int64_t next = avio_tell(pb);
689
690 if (size < 12 || next < 0 || next > INT64_MAX - size)
691 return AVERROR_INVALIDDATA;
692
693 next += size - 4;
694
695 dref->type = avio_rl32(pb);
696 avio_rb32(pb); // version + flags
697
698 if (dref->type == MKTAG('a','l','i','s') && size > 150) {
699 /* macintosh alias record */
700 uint16_t volume_len, len;
701 int16_t type;
702 int ret;
703
704 avio_skip(pb, 10);
705
706 volume_len = avio_r8(pb);
707 volume_len = FFMIN(volume_len, 27);
708 ret = ffio_read_size(pb, dref->volume, 27);
709 if (ret < 0)
710 return ret;
711 dref->volume[volume_len] = 0;
712 av_log(c->fc, AV_LOG_DEBUG, "volume %s, len %d\n", dref->volume, volume_len);
713
714 avio_skip(pb, 12);
715
716 len = avio_r8(pb);
717 len = FFMIN(len, 63);
718 ret = ffio_read_size(pb, dref->filename, 63);
719 if (ret < 0)
720 return ret;
721 dref->filename[len] = 0;
722 av_log(c->fc, AV_LOG_DEBUG, "filename %s, len %d\n", dref->filename, len);
723
724 avio_skip(pb, 16);
725
726 /* read next level up_from_alias/down_to_target */
727 dref->nlvl_from = avio_rb16(pb);
728 dref->nlvl_to = avio_rb16(pb);
729 av_log(c->fc, AV_LOG_DEBUG, "nlvl from %d, nlvl to %d\n",
730 dref->nlvl_from, dref->nlvl_to);
731
732 avio_skip(pb, 16);
733
734 for (type = 0; type != -1 && avio_tell(pb) < next; ) {
735 if (avio_feof(pb))
736 return AVERROR_EOF;
737 type = avio_rb16(pb);
738 len = avio_rb16(pb);
739 av_log(c->fc, AV_LOG_DEBUG, "type %d, len %d\n", type, len);
740 if (len&1)
741 len += 1;
742 if (type == 2) { // absolute path
743 av_free(dref->path);
744 dref->path = av_mallocz(len+1);
745 if (!dref->path)
746 return AVERROR(ENOMEM);
747
748 ret = ffio_read_size(pb, dref->path, len);
749 if (ret < 0) {
750 av_freep(&dref->path);
751 return ret;
752 }
753 if (len > volume_len && !strncmp(dref->path, dref->volume, volume_len)) {
754 len -= volume_len;
755 memmove(dref->path, dref->path+volume_len, len);
756 dref->path[len] = 0;
757 }
758 // trim string of any ending zeros
759 for (j = len - 1; j >= 0; j--) {
760 if (dref->path[j] == 0)
761 len--;
762 else
763 break;
764 }
765 for (j = 0; j < len; j++)
766 if (dref->path[j] == ':' || dref->path[j] == 0)
767 dref->path[j] = '/';
768 av_log(c->fc, AV_LOG_DEBUG, "path %s\n", dref->path);
769 } else if (type == 0) { // directory name
770 av_free(dref->dir);
771 dref->dir = av_malloc(len+1);
772 if (!dref->dir)
773 return AVERROR(ENOMEM);
774
775 ret = ffio_read_size(pb, dref->dir, len);
776 if (ret < 0) {
777 av_freep(&dref->dir);
778 return ret;
779 }
780 dref->dir[len] = 0;
781 for (j = 0; j < len; j++)
782 if (dref->dir[j] == ':')
783 dref->dir[j] = '/';
784 av_log(c->fc, AV_LOG_DEBUG, "dir %s\n", dref->dir);
785 } else
786 avio_skip(pb, len);
787 }
788 } else {
789 av_log(c->fc, AV_LOG_DEBUG, "Unknown dref type 0x%08"PRIx32" size %"PRIu32"\n",
790 dref->type, size);
791 entries--;
792 i--;
793 }
794 avio_seek(pb, next, SEEK_SET);
795 }
796 return 0;
797}
798
800{
801 AVStream *st;
802 uint32_t type;
803 uint32_t ctype;
804 int64_t title_size;
805 char *title_str;
806 int ret;
807
808 avio_r8(pb); /* version */
809 avio_rb24(pb); /* flags */
810
811 /* component type */
812 ctype = avio_rl32(pb);
813 type = avio_rl32(pb); /* component subtype */
814
815 av_log(c->fc, AV_LOG_TRACE, "ctype=%s\n", av_fourcc2str(ctype));
816 av_log(c->fc, AV_LOG_TRACE, "stype=%s\n", av_fourcc2str(type));
817
818 if (c->trak_index < 0) { // meta not inside a trak
819 if (type == MKTAG('m','d','t','a')) {
820 c->found_hdlr_mdta = 1;
821 }
822 return 0;
823 }
824
825 st = c->fc->streams[c->fc->nb_streams-1];
826
827 if (type == MKTAG('v','i','d','e'))
829 else if (type == MKTAG('s','o','u','n'))
831 else if (type == MKTAG('m','1','a',' '))
833 else if ((type == MKTAG('s','u','b','p')) || (type == MKTAG('c','l','c','p')))
835
836 avio_rb32(pb); /* component manufacture */
837 avio_rb32(pb); /* component flags */
838 avio_rb32(pb); /* component flags mask */
839
840 title_size = atom.size - 24;
841 if (title_size > 0) {
842 if (title_size > FFMIN(INT_MAX, SIZE_MAX-1))
843 return AVERROR_INVALIDDATA;
844 title_str = av_malloc(title_size + 1); /* Add null terminator */
845 if (!title_str)
846 return AVERROR(ENOMEM);
847
848 ret = ffio_read_size(pb, title_str, title_size);
849 if (ret < 0) {
850 av_freep(&title_str);
851 return ret;
852 }
853 title_str[title_size] = 0;
854 if (title_str[0]) {
855 int off = (!c->isom && title_str[0] == title_size - 1);
856 // flag added so as to not set stream handler name if already set from mdia->hdlr
857 av_dict_set(&st->metadata, "handler_name", title_str + off, AV_DICT_DONT_OVERWRITE);
858 }
859 av_freep(&title_str);
860 }
861
862 return 0;
863}
864
866{
867 return ff_mov_read_esds(c->fc, pb);
868}
869
871{
872 AVStream *st;
874 enum AVAudioServiceType *ast;
875 int ac3info, acmod, lfeon, bsmod;
876 uint64_t mask;
877
878 if (c->fc->nb_streams < 1)
879 return 0;
880 st = c->fc->streams[c->fc->nb_streams-1];
881
885 sizeof(*ast), 0);
886 if (!sd)
887 return AVERROR(ENOMEM);
888
889 ast = (enum AVAudioServiceType*)sd->data;
890 ac3info = avio_rb24(pb);
891 bsmod = (ac3info >> 14) & 0x7;
892 acmod = (ac3info >> 11) & 0x7;
893 lfeon = (ac3info >> 10) & 0x1;
894
896 if (lfeon)
900
901 *ast = bsmod;
902 if (st->codecpar->ch_layout.nb_channels > 1 && bsmod == 0x7)
904
905 return 0;
906}
907
908#if CONFIG_IAMFDEC
909static int mov_read_iacb(MOVContext *c, AVIOContext *pb, MOVAtom atom)
910{
911 AVStream *st;
914 AVIOContext *descriptor_pb;
916 IAMFContext *iamf;
918 unsigned descriptors_size;
919 int nb_frames, disposition;
920 int version, ret;
921
922 if (atom.size < 5)
923 return AVERROR_INVALIDDATA;
924
925 if (c->fc->nb_streams < 1)
926 return 0;
927
928 version = avio_r8(pb);
929 if (version != 1) {
930 av_log(c->fc, AV_LOG_ERROR, "%s configurationVersion %d",
931 version < 1 ? "invalid" : "unsupported", version);
932 return AVERROR_INVALIDDATA;
933 }
934
935 descriptors_size = ffio_read_leb(pb);
936 if (!descriptors_size || descriptors_size > INT_MAX)
937 return AVERROR_INVALIDDATA;
938
939 st = c->fc->streams[c->fc->nb_streams - 1];
940 sc = st->priv_data;
941
942 if (st->codecpar->extradata) {
943 av_log(c->fc, AV_LOG_WARNING, "ignoring iacb\n");
944 return 0;
945 }
946
947 sc->iamf = av_mallocz(sizeof(*sc->iamf));
948 if (!sc->iamf)
949 return AVERROR(ENOMEM);
950 iamf = &sc->iamf->iamf;
951
952 ret = ff_alloc_extradata(st->codecpar, descriptors_size);
953 if (ret < 0)
954 return ret;
955
956 ret = avio_read(pb, st->codecpar->extradata, descriptors_size);
957 if (ret != descriptors_size)
958 return ret < 0 ? ret : AVERROR_INVALIDDATA;
959
960 ffio_init_read_context(&b, st->codecpar->extradata, descriptors_size);
961 descriptor_pb = &b.pub;
962
963 ret = ff_iamfdec_read_descriptors(iamf, descriptor_pb, descriptors_size, c->fc);
964 if (ret < 0)
965 return ret;
966
967 metadata = st->metadata;
968 st->metadata = NULL;
970 nb_frames = st->nb_frames;
971 duration = st->duration;
972 disposition = st->disposition;
973
974 for (int i = 0; i < iamf->nb_audio_elements; i++) {
975 IAMFAudioElement *audio_element = iamf->audio_elements[i];
976 const AVIAMFAudioElement *element;
977 AVStreamGroup *stg =
979
980 if (!stg) {
981 ret = AVERROR(ENOMEM);
982 goto fail;
983 }
984
986 stg->id = audio_element->audio_element_id;
987 /* Transfer ownership */
988 element = stg->params.iamf_audio_element = audio_element->element;
989 audio_element->element = NULL;
990
991 for (int j = 0; j < audio_element->nb_substreams; j++) {
992 IAMFSubStream *substream = &audio_element->substreams[j];
993 AVStream *stream;
994
995 if (!i && !j) {
996 if (audio_element->layers[0].substream_count != 1)
997 disposition &= ~AV_DISPOSITION_DEFAULT;
998 stream = st;
999 } else
1000 stream = avformat_new_stream(c->fc, NULL);
1001 if (!stream) {
1002 ret = AVERROR(ENOMEM);
1003 goto fail;
1004 }
1005
1006 stream->start_time = start_time;
1007 stream->nb_frames = nb_frames;
1008 stream->duration = duration;
1009 stream->disposition = disposition;
1010 if (stream != st) {
1011 stream->priv_data = sc;
1012 sc->refcount++;
1013 }
1014
1017 if (i || j) {
1019 if (audio_element->layers[0].substream_count == 1)
1021 }
1022
1023 ret = avcodec_parameters_copy(stream->codecpar, substream->codecpar);
1024 if (ret < 0)
1025 goto fail;
1026
1027 stream->id = substream->audio_substream_id;
1028
1029 avpriv_set_pts_info(st, 64, 1, sc->time_scale);
1030
1031 ret = avformat_stream_group_add_stream(stg, stream);
1032 if (ret < 0)
1033 goto fail;
1034 }
1035
1036 ret = av_dict_copy(&stg->metadata, metadata, 0);
1037 if (ret < 0)
1038 goto fail;
1039 }
1040
1041 for (int i = 0; i < iamf->nb_mix_presentations; i++) {
1042 IAMFMixPresentation *mix_presentation = iamf->mix_presentations[i];
1043 const AVIAMFMixPresentation *mix = mix_presentation->cmix;
1044 AVStreamGroup *stg =
1046
1047 if (!stg) {
1048 ret = AVERROR(ENOMEM);
1049 goto fail;
1050 }
1051
1053 stg->id = mix_presentation->mix_presentation_id;
1054 /* Transfer ownership */
1055 stg->params.iamf_mix_presentation = mix_presentation->mix;
1056 mix_presentation->mix = NULL;
1057
1058 for (int j = 0; j < mix->nb_submixes; j++) {
1059 const AVIAMFSubmix *submix = mix->submixes[j];
1060
1061 for (int k = 0; k < submix->nb_elements; k++) {
1062 const AVIAMFSubmixElement *submix_element = submix->elements[k];
1063 const AVStreamGroup *audio_element = NULL;
1064
1065 for (int l = 0; l < c->fc->nb_stream_groups; l++)
1066 if (c->fc->stream_groups[l]->type == AV_STREAM_GROUP_PARAMS_IAMF_AUDIO_ELEMENT &&
1067 c->fc->stream_groups[l]->id == submix_element->audio_element_id) {
1068 audio_element = c->fc->stream_groups[l];
1069 break;
1070 }
1071 av_assert0(audio_element);
1072
1073 for (int l = 0; l < audio_element->nb_streams; l++) {
1074 ret = avformat_stream_group_add_stream(stg, audio_element->streams[l]);
1075 if (ret < 0 && ret != AVERROR(EEXIST))
1076 goto fail;
1077 }
1078 }
1079 }
1080
1081 ret = av_dict_copy(&stg->metadata, metadata, 0);
1082 if (ret < 0)
1083 goto fail;
1084 }
1085
1086 ret = 0;
1087fail:
1089
1090 return ret;
1091}
1092#endif
1093
1095{
1096 AVStream *st;
1097 int32_t sample_rate;
1098
1099 if (atom.size < 8 || c->fc->nb_streams < 1)
1100 return 0;
1101
1102 st = c->fc->streams[c->fc->nb_streams-1];
1104 av_log(c->fc, AV_LOG_WARNING, "'srat' within non-audio sample entry, skip\n");
1105 return 0;
1106 }
1107
1108 if (!c->isom) {
1109 av_log(c->fc, AV_LOG_WARNING, "'srat' within non-isom, skip\n");
1110 return 0;
1111 }
1112
1113 avio_skip(pb, 4); // version+flags
1114 sample_rate = avio_rb32(pb);
1115 if (sample_rate > 0) {
1116 av_log(c->fc, AV_LOG_DEBUG,
1117 "overwrite sample rate from %d to %d by 'srat'\n",
1118 st->codecpar->sample_rate, sample_rate);
1119 st->codecpar->sample_rate = sample_rate;
1120 } else {
1121 av_log(c->fc, AV_LOG_WARNING,
1122 "ignore invalid sample rate %d in 'srat'\n", sample_rate);
1123 }
1124
1125 return 0;
1126}
1127
1129{
1130 AVStream *st;
1131 AVPacketSideData *sd;
1132 enum AVAudioServiceType *ast;
1133 int eac3info, acmod, lfeon, bsmod;
1134 uint64_t mask;
1135
1136 if (c->fc->nb_streams < 1)
1137 return 0;
1138 st = c->fc->streams[c->fc->nb_streams-1];
1139
1143 sizeof(*ast), 0);
1144 if (!sd)
1145 return AVERROR(ENOMEM);
1146
1147 ast = (enum AVAudioServiceType*)sd->data;
1148
1149 /* No need to parse fields for additional independent substreams and its
1150 * associated dependent substreams since libavcodec's E-AC-3 decoder
1151 * does not support them yet. */
1152 avio_rb16(pb); /* data_rate and num_ind_sub */
1153 eac3info = avio_rb24(pb);
1154 bsmod = (eac3info >> 12) & 0x1f;
1155 acmod = (eac3info >> 9) & 0x7;
1156 lfeon = (eac3info >> 8) & 0x1;
1157
1159 if (lfeon)
1163
1164 *ast = bsmod;
1165 if (st->codecpar->ch_layout.nb_channels > 1 && bsmod == 0x7)
1167
1168 return 0;
1169}
1170
1171/* Maps the DTS `StreamConstruction` field (ETSI TS 102 114 Table E-2) to the
1172 * coarse FFmpeg DTS profile enum. Extension-substream XLL maps to HD_MA;
1173 * extension-substream XXCH, X96, or XBR maps to HD_HRA; core-substream XCH or
1174 * XXCH maps to ES; core-substream X96 maps to 96/24; a core component alone
1175 * maps to DTS; and extension-substream LBR maps to Express. Value 0 (undefined)
1176 * and values outside 1..21 map to AV_PROFILE_UNKNOWN. */
1178{
1179 static const int profile[22] = {
1180 [ 1] = AV_PROFILE_DTS, /* core Core */
1181 [ 2] = AV_PROFILE_DTS_ES, /* core Core + core XCH */
1182 [ 3] = AV_PROFILE_DTS_ES, /* core Core + core XXCH */
1183 [ 4] = AV_PROFILE_DTS_96_24, /* core Core + core X96 */
1184 [ 5] = AV_PROFILE_DTS_HD_HRA, /* core Core + ext XXCH */
1185 [ 6] = AV_PROFILE_DTS_HD_HRA, /* core Core + ext XBR */
1186 [ 7] = AV_PROFILE_DTS_HD_HRA, /* core Core + core XCH + ext XBR */
1187 [ 8] = AV_PROFILE_DTS_HD_HRA, /* core Core + core XXCH + ext XBR */
1188 [ 9] = AV_PROFILE_DTS_HD_HRA, /* core Core + ext XXCH + ext XBR */
1189 [10] = AV_PROFILE_DTS_HD_HRA, /* core Core + ext X96 */
1190 [11] = AV_PROFILE_DTS_HD_HRA, /* core Core + core XCH + ext X96 */
1191 [12] = AV_PROFILE_DTS_HD_HRA, /* core Core + core XXCH + ext X96 */
1192 [13] = AV_PROFILE_DTS_HD_HRA, /* core Core + ext XXCH + ext X96 */
1193 [14] = AV_PROFILE_DTS_HD_MA, /* core Core + ext XLL */
1194 [15] = AV_PROFILE_DTS_HD_MA, /* core Core + core XCH + ext XLL */
1195 [16] = AV_PROFILE_DTS_HD_MA, /* core Core + core X96 + ext XLL */
1196 [17] = AV_PROFILE_DTS_HD_MA, /* ext XLL */
1197 [18] = AV_PROFILE_DTS_EXPRESS, /* ext LBR */
1198 [19] = AV_PROFILE_DTS, /* ext Core */
1199 [20] = AV_PROFILE_DTS_HD_HRA, /* ext Core + ext XXCH */
1200 [21] = AV_PROFILE_DTS_HD_MA, /* ext Core + ext XLL */
1201 };
1202 if (!sc || sc > 21)
1203 return AV_PROFILE_UNKNOWN;
1204 return profile[sc];
1205}
1206
1207/* Maps the 16-bit DTS `ChannelLayout` bitmask (ETSI TS 102 114 Table E-5) to an
1208 * ffmpeg channel mask. Pair bits follow Table 7-10 / DCA_SPEAKER_PAIR_*;
1209 * LwRw (0x0400) and LssRss (0x0800) must not collapse onto SIDE like LsRs. */
1210static uint64_t mov_dts_channel_layout_to_mask(unsigned int code)
1211{
1212 static const struct { unsigned int dts; uint64_t av; } map[] = {
1213 { 0x0001, AV_CH_FRONT_CENTER },
1214 { 0x0002, AV_CH_FRONT_LEFT | AV_CH_FRONT_RIGHT },
1215 { 0x0004, AV_CH_SIDE_LEFT | AV_CH_SIDE_RIGHT },
1216 { 0x0008, AV_CH_LOW_FREQUENCY },
1217 { 0x0010, AV_CH_BACK_CENTER },
1219 { 0x0040, AV_CH_BACK_LEFT | AV_CH_BACK_RIGHT },
1220 { 0x0080, AV_CH_TOP_FRONT_CENTER },
1221 { 0x0100, AV_CH_TOP_CENTER },
1223 { 0x0400, AV_CH_WIDE_LEFT | AV_CH_WIDE_RIGHT },
1225 { 0x1000, AV_CH_LOW_FREQUENCY_2 },
1227 { 0x4000, AV_CH_TOP_BACK_CENTER },
1229 };
1230 uint64_t mask = 0;
1231 int i;
1232 for (i = 0; i < FF_ARRAY_ELEMS(map); i++)
1233 if (code & map[i].dts)
1234 mask |= map[i].av;
1235 return mask;
1236}
1237
1239{
1240#define DDTS_SIZE 20
1242 AVStream *st = NULL;
1243 uint32_t frame_duration_code = 0;
1244 uint32_t channel_layout_code = 0;
1245 uint64_t channel_layout_mask;
1246 unsigned int stream_construction;
1247 unsigned int representation_type;
1248 GetBitContext gb;
1249 int ret;
1250
1251 if ((ret = ffio_read_size(pb, buf, DDTS_SIZE)) < 0)
1252 return ret;
1253
1254 init_get_bits(&gb, buf, 8 * DDTS_SIZE);
1255
1256 if (c->fc->nb_streams < 1) {
1257 return 0;
1258 }
1259 st = c->fc->streams[c->fc->nb_streams-1];
1260
1261 st->codecpar->sample_rate = get_bits_long(&gb, 32);
1262 if (st->codecpar->sample_rate <= 0) {
1263 av_log(c->fc, AV_LOG_ERROR, "Invalid sample rate %d\n", st->codecpar->sample_rate);
1264 return AVERROR_INVALIDDATA;
1265 }
1266 skip_bits_long(&gb, 32); /* max bitrate */
1267 st->codecpar->bit_rate = get_bits_long(&gb, 32);
1269 frame_duration_code = get_bits(&gb, 2);
1270 stream_construction = get_bits(&gb, 5); /* Table E-2 - profile source */
1271 skip_bits(&gb, 1); /* CoreLFEPresent */
1272 skip_bits(&gb, 6); /* CoreLayout */
1273 skip_bits(&gb, 14); /* CoreSize */
1274 skip_bits(&gb, 1); /* StereoDownmix */
1275 representation_type = get_bits(&gb, 3);
1276 channel_layout_code = get_bits(&gb, 16);
1277
1278 st->codecpar->frame_size =
1279 (frame_duration_code == 0) ? 512 :
1280 (frame_duration_code == 1) ? 1024 :
1281 (frame_duration_code == 2) ? 2048 :
1282 (frame_duration_code == 3) ? 4096 : 0;
1283
1284 /* Publish StreamConstruction as codecpar->profile, including for encrypted
1285 * tracks where frame headers cannot be inspected. */
1286 st->codecpar->profile = mov_dts_stream_construction_to_profile(stream_construction);
1287
1288 channel_layout_mask = mov_dts_channel_layout_to_mask(channel_layout_code);
1289 if (channel_layout_mask) {
1291 av_channel_layout_from_mask(&st->codecpar->ch_layout, channel_layout_mask);
1292 } else if (representation_type == 2 || representation_type == 3) {
1295 }
1296
1297 return 0;
1298}
1299
1301{
1302 AVStream *st;
1303
1304 if (c->fc->nb_streams < 1)
1305 return 0;
1306 st = c->fc->streams[c->fc->nb_streams-1];
1307
1308 if (atom.size < 16)
1309 return 0;
1310
1311 /* skip version and flags */
1312 avio_skip(pb, 4);
1313
1314 ff_mov_read_chan(c->fc, pb, st, atom.size - 4);
1315
1316 return 0;
1317}
1318
1320{
1321 int64_t end = av_sat_add64(avio_tell(pb), atom.size);
1322 int version, flags;
1323 int ret;
1324 AVStream *st;
1325
1326 if (c->fc->nb_streams < 1)
1327 return 0;
1328 st = c->fc->streams[c->fc->nb_streams-1];
1329
1330 version = avio_r8(pb);
1331 flags = avio_rb24(pb);
1332 if (version > 1 || flags != 0) {
1333 av_log(c->fc, AV_LOG_WARNING,
1334 "Unsupported 'chnl' box with version %d, flags: %#x\n",
1335 version, flags);
1336 return 0;
1337 }
1338
1339 ret = ff_mov_read_chnl(c->fc, pb, st, version);
1340 if (ret < 0) {
1341 avio_seek(pb, end, SEEK_SET);
1342 return 0;
1343 }
1344
1345 if (avio_tell(pb) != end) {
1346 av_log(c->fc, AV_LOG_WARNING, "skip %" PRId64 " bytes of unknown data inside chnl\n",
1347 end - avio_tell(pb));
1348 avio_seek(pb, end, SEEK_SET);
1349 }
1350 return ret;
1351}
1352
1354{
1355 AVStream *st;
1356 int ret;
1357
1358 if (c->fc->nb_streams < 1)
1359 return 0;
1360 st = c->fc->streams[c->fc->nb_streams-1];
1361
1362 if ((ret = ff_get_wav_header(c->fc, pb, st->codecpar, atom.size, 0)) < 0)
1363 av_log(c->fc, AV_LOG_WARNING, "get_wav_header failed\n");
1364
1365 return ret;
1366}
1367
1369{
1370 AVStream *st;
1371 HEIFItem *item;
1372 AVPacketSideData *sd;
1373 int width, height, err = 0;
1374 AVRational aperture_width, aperture_height, horiz_off, vert_off;
1375 AVRational pc_x, pc_y;
1376 uint64_t top, bottom, left, right;
1377
1378 item = get_heif_item(c, c->cur_item_id);
1379 st = get_curr_st(c);
1380 if (!st)
1381 return 0;
1382
1383 width = st->codecpar->width;
1384 height = st->codecpar->height;
1385 if ((!width || !height) && item) {
1386 width = item->width;
1387 height = item->height;
1388 }
1389 if (!width || !height) {
1390 err = AVERROR_INVALIDDATA;
1391 goto fail;
1392 }
1393
1394 aperture_width.num = avio_rb32(pb);
1395 aperture_width.den = avio_rb32(pb);
1396 aperture_height.num = avio_rb32(pb);
1397 aperture_height.den = avio_rb32(pb);
1398
1399 horiz_off.num = avio_rb32(pb);
1400 horiz_off.den = avio_rb32(pb);
1401 vert_off.num = avio_rb32(pb);
1402 vert_off.den = avio_rb32(pb);
1403
1404 if (aperture_width.num < 0 || aperture_width.den < 0 ||
1405 aperture_height.num < 0 || aperture_height.den < 0 ||
1406 horiz_off.den < 0 || vert_off.den < 0) {
1407 err = AVERROR_INVALIDDATA;
1408 goto fail;
1409 }
1410 if ((av_cmp_q((AVRational) { width, 1 }, aperture_width) < 0) ||
1411 (av_cmp_q((AVRational) { height, 1 }, aperture_height) < 0)) {
1412 err = AVERROR_INVALIDDATA;
1413 goto fail;
1414 }
1415 av_log(c->fc, AV_LOG_TRACE, "clap: apertureWidth %d/%d, apertureHeight %d/%d "
1416 "horizOff %d/%d vertOff %d/%d\n",
1417 aperture_width.num, aperture_width.den, aperture_height.num, aperture_height.den,
1418 horiz_off.num, horiz_off.den, vert_off.num, vert_off.den);
1419
1420 pc_x = av_mul_q((AVRational) { width - 1, 1 }, (AVRational) { 1, 2 });
1421 pc_x = av_add_q(pc_x, horiz_off);
1422 pc_y = av_mul_q((AVRational) { height - 1, 1 }, (AVRational) { 1, 2 });
1423 pc_y = av_add_q(pc_y, vert_off);
1424
1425 aperture_width = av_sub_q(aperture_width, (AVRational) { 1, 1 });
1426 aperture_width = av_mul_q(aperture_width, (AVRational) { 1, 2 });
1427 aperture_height = av_sub_q(aperture_height, (AVRational) { 1, 1 });
1428 aperture_height = av_mul_q(aperture_height, (AVRational) { 1, 2 });
1429
1430 left = av_q2d(av_sub_q(pc_x, aperture_width));
1431 right = av_q2d(av_add_q(pc_x, aperture_width));
1432 top = av_q2d(av_sub_q(pc_y, aperture_height));
1433 bottom = av_q2d(av_add_q(pc_y, aperture_height));
1434
1435 if (bottom > (height - 1) ||
1436 right > (width - 1)) {
1437 err = AVERROR_INVALIDDATA;
1438 goto fail;
1439 }
1440
1441 bottom = height - 1 - bottom;
1442 right = width - 1 - right;
1443
1444 if (!(left | right | top | bottom))
1445 return 0;
1446
1447 if ((left + right) >= width ||
1448 (top + bottom) >= height) {
1449 err = AVERROR_INVALIDDATA;
1450 goto fail;
1451 }
1452
1456 sizeof(uint32_t) * 4, 0);
1457 if (!sd)
1458 return AVERROR(ENOMEM);
1459
1460 AV_WL32A(sd->data, top);
1461 AV_WL32A(sd->data + 4, bottom);
1462 AV_WL32A(sd->data + 8, left);
1463 AV_WL32A(sd->data + 12, right);
1464
1465fail:
1466 if (err < 0) {
1467 int explode = !!(c->fc->error_recognition & AV_EF_EXPLODE);
1468 av_log(c->fc, explode ? AV_LOG_ERROR : AV_LOG_WARNING, "Invalid clap box\n");
1469 if (!explode)
1470 err = 0;
1471 }
1472
1473 return err;
1474}
1475
1476/* This atom overrides any previously set aspect ratio */
1478{
1479 const int num = avio_rb32(pb);
1480 const int den = avio_rb32(pb);
1481 AVStream *st;
1482 MOVStreamContext *sc;
1483
1484 if (c->fc->nb_streams < 1)
1485 return 0;
1486 st = c->fc->streams[c->fc->nb_streams-1];
1487 sc = st->priv_data;
1488
1489 av_log(c->fc, AV_LOG_TRACE, "pasp: hSpacing %d, vSpacing %d\n", num, den);
1490
1491 if (den != 0) {
1492 sc->h_spacing = num;
1493 sc->v_spacing = den;
1494 }
1495 return 0;
1496}
1497
1498/* this atom contains actual media data */
1500{
1501 if (atom.size == 0) /* wrong one (MP4) */
1502 return 0;
1503 c->found_mdat=1;
1504 return 0; /* now go for moov */
1505}
1506
1507#define DRM_BLOB_SIZE 56
1508
1510{
1511 uint8_t intermediate_key[20];
1512 uint8_t intermediate_iv[20];
1513 uint8_t input[64];
1514 uint8_t output[64];
1515 uint8_t file_checksum[20];
1516 uint8_t calculated_checksum[20];
1517 char checksum_string[2 * sizeof(file_checksum) + 1];
1518 struct AVSHA *sha;
1519 int i;
1520 int ret = 0;
1521 uint8_t *activation_bytes = c->activation_bytes;
1522 uint8_t *fixed_key = c->audible_fixed_key;
1523
1524 c->aax_mode = 1;
1525
1526 sha = av_sha_alloc();
1527 if (!sha)
1528 return AVERROR(ENOMEM);
1529 av_free(c->aes_decrypt);
1530 c->aes_decrypt = av_aes_alloc();
1531 if (!c->aes_decrypt) {
1532 ret = AVERROR(ENOMEM);
1533 goto fail;
1534 }
1535
1536 /* drm blob processing */
1537 avio_read(pb, output, 8); // go to offset 8, absolute position 0x251
1538 avio_read(pb, input, DRM_BLOB_SIZE);
1539 avio_read(pb, output, 4); // go to offset 4, absolute position 0x28d
1540 ret = ffio_read_size(pb, file_checksum, 20);
1541 if (ret < 0)
1542 goto fail;
1543
1544 // required by external tools
1545 ff_data_to_hex(checksum_string, file_checksum, sizeof(file_checksum), 1);
1546 av_log(c->fc, AV_LOG_INFO, "[aax] file checksum == %s\n", checksum_string);
1547
1548 /* verify activation data */
1549 if (!activation_bytes) {
1550 av_log(c->fc, AV_LOG_WARNING, "[aax] activation_bytes option is missing!\n");
1551 ret = 0; /* allow ffprobe to continue working on .aax files */
1552 goto fail;
1553 }
1554 if (c->activation_bytes_size != 4) {
1555 av_log(c->fc, AV_LOG_FATAL, "[aax] activation_bytes value needs to be 4 bytes!\n");
1556 ret = AVERROR(EINVAL);
1557 goto fail;
1558 }
1559
1560 /* verify fixed key */
1561 if (c->audible_fixed_key_size != 16) {
1562 av_log(c->fc, AV_LOG_FATAL, "[aax] audible_fixed_key value needs to be 16 bytes!\n");
1563 ret = AVERROR(EINVAL);
1564 goto fail;
1565 }
1566
1567 /* AAX (and AAX+) key derivation */
1568 av_sha_init(sha, 160);
1569 av_sha_update(sha, fixed_key, 16);
1570 av_sha_update(sha, activation_bytes, 4);
1571 av_sha_final(sha, intermediate_key);
1572 av_sha_init(sha, 160);
1573 av_sha_update(sha, fixed_key, 16);
1574 av_sha_update(sha, intermediate_key, 20);
1575 av_sha_update(sha, activation_bytes, 4);
1576 av_sha_final(sha, intermediate_iv);
1577 av_sha_init(sha, 160);
1578 av_sha_update(sha, intermediate_key, 16);
1579 av_sha_update(sha, intermediate_iv, 16);
1580 av_sha_final(sha, calculated_checksum);
1581 if (memcmp(calculated_checksum, file_checksum, 20)) { // critical error
1582 av_log(c->fc, AV_LOG_ERROR, "[aax] mismatch in checksums!\n");
1583 ret = AVERROR_INVALIDDATA;
1584 goto fail;
1585 }
1586 av_aes_init(c->aes_decrypt, intermediate_key, 128, 1);
1587 av_aes_crypt(c->aes_decrypt, output, input, DRM_BLOB_SIZE >> 4, intermediate_iv, 1);
1588 for (i = 0; i < 4; i++) {
1589 // file data (in output) is stored in big-endian mode
1590 if (activation_bytes[i] != output[3 - i]) { // critical error
1591 av_log(c->fc, AV_LOG_ERROR, "[aax] error in drm blob decryption!\n");
1592 ret = AVERROR_INVALIDDATA;
1593 goto fail;
1594 }
1595 }
1596 memcpy(c->file_key, output + 8, 16);
1597 memcpy(input, output + 26, 16);
1598 av_sha_init(sha, 160);
1599 av_sha_update(sha, input, 16);
1600 av_sha_update(sha, c->file_key, 16);
1601 av_sha_update(sha, fixed_key, 16);
1602 av_sha_final(sha, c->file_iv);
1603
1604fail:
1605 av_free(sha);
1606
1607 return ret;
1608}
1609
1611{
1612 if (c->audible_key_size != 16) {
1613 av_log(c->fc, AV_LOG_FATAL, "[aaxc] audible_key value needs to be 16 bytes!\n");
1614 return AVERROR(EINVAL);
1615 }
1616
1617 if (c->audible_iv_size != 16) {
1618 av_log(c->fc, AV_LOG_FATAL, "[aaxc] audible_iv value needs to be 16 bytes!\n");
1619 return AVERROR(EINVAL);
1620 }
1621
1622 c->aes_decrypt = av_aes_alloc();
1623 if (!c->aes_decrypt) {
1624 return AVERROR(ENOMEM);
1625 }
1626
1627 memcpy(c->file_key, c->audible_key, 16);
1628 memcpy(c->file_iv, c->audible_iv, 16);
1629 c->aax_mode = 1;
1630
1631 return 0;
1632}
1633
1634// Audible AAX (and AAX+) bytestream decryption
1635static int aax_filter(uint8_t *input, int size, MOVContext *c)
1636{
1637 int blocks = 0;
1638 unsigned char iv[16];
1639
1640 memcpy(iv, c->file_iv, 16); // iv is overwritten
1641 blocks = size >> 4; // trailing bytes are not encrypted!
1642 av_aes_init(c->aes_decrypt, c->file_key, 128, 1);
1643 av_aes_crypt(c->aes_decrypt, input, input, blocks, iv, 1);
1644
1645 return 0;
1646}
1647
1648/* read major brand, minor version and compatible brands and store them as metadata */
1650{
1651 uint32_t minor_ver;
1652 int comp_brand_size;
1653 char* comp_brands_str;
1654 uint8_t type[5] = {0};
1655 int ret = ffio_read_size(pb, type, 4);
1656 if (ret < 0)
1657 return ret;
1658 if (c->fc->nb_streams) {
1659 if (c->fc->strict_std_compliance >= FF_COMPLIANCE_STRICT)
1660 return AVERROR_INVALIDDATA;
1661 av_log(c->fc, AV_LOG_DEBUG, "Ignoring duplicate FTYP\n");
1662 return 0;
1663 }
1664
1665 if (strcmp(type, "qt "))
1666 c->isom = 1;
1667 av_log(c->fc, AV_LOG_DEBUG, "ISO: File Type Major Brand: %.4s\n",(char *)&type);
1668 av_dict_set(&c->fc->metadata, "major_brand", type, 0);
1669 minor_ver = avio_rb32(pb); /* minor version */
1670 av_dict_set_int(&c->fc->metadata, "minor_version", minor_ver, 0);
1671
1672 comp_brand_size = atom.size - 8;
1673 if (comp_brand_size < 0 || comp_brand_size == INT_MAX)
1674 return AVERROR_INVALIDDATA;
1675 comp_brands_str = av_malloc(comp_brand_size + 1); /* Add null terminator */
1676 if (!comp_brands_str)
1677 return AVERROR(ENOMEM);
1678
1679 ret = ffio_read_size(pb, comp_brands_str, comp_brand_size);
1680 if (ret < 0) {
1681 av_freep(&comp_brands_str);
1682 return ret;
1683 }
1684 comp_brands_str[comp_brand_size] = 0;
1685 av_dict_set(&c->fc->metadata, "compatible_brands",
1686 comp_brands_str, AV_DICT_DONT_STRDUP_VAL);
1687
1688 // Logic for handling Audible's .aaxc files
1689 if (!strcmp(type, "aaxc")) {
1691 }
1692
1693 return 0;
1694}
1695
1696/* this atom should contain all header atoms */
1698{
1699 int ret;
1700
1701 if (c->found_moov) {
1702 av_log(c->fc, AV_LOG_WARNING, "Found duplicated MOOV Atom. Skipped it\n");
1703 avio_skip(pb, atom.size);
1704 return 0;
1705 }
1706
1707 if ((ret = mov_read_default(c, pb, atom)) < 0)
1708 return ret;
1709 /* we parsed the 'moov' atom, we can terminate the parsing as soon as we find the 'mdat' */
1710 /* so we don't parse the whole file if over a network */
1711 c->found_moov=1;
1712 return 0; /* now go for mdat */
1713}
1714
1716 MOVFragmentIndex *frag_index,
1717 int index,
1718 int id)
1719{
1720 int i;
1721 MOVFragmentIndexItem * item;
1722
1723 if (index < 0 || index >= frag_index->nb_items)
1724 return NULL;
1725 item = &frag_index->item[index];
1726 for (i = 0; i < item->nb_stream_info; i++)
1727 if (item->stream_info[i].id == id)
1728 return &item->stream_info[i];
1729
1730 // This shouldn't happen
1731 return NULL;
1732}
1733
1734static void set_frag_stream(MOVFragmentIndex *frag_index, int id)
1735{
1736 int i;
1737 MOVFragmentIndexItem * item;
1738
1739 if (frag_index->current < 0 ||
1740 frag_index->current >= frag_index->nb_items)
1741 return;
1742
1743 item = &frag_index->item[frag_index->current];
1744 for (i = 0; i < item->nb_stream_info; i++)
1745 if (item->stream_info[i].id == id) {
1746 item->current = i;
1747 return;
1748 }
1749
1750 // id not found. This shouldn't happen.
1751 item->current = -1;
1752}
1753
1755 MOVFragmentIndex *frag_index)
1756{
1758 if (frag_index->current < 0 ||
1759 frag_index->current >= frag_index->nb_items)
1760 return NULL;
1761
1762 item = &frag_index->item[frag_index->current];
1763 if (item->current >= 0 && item->current < item->nb_stream_info)
1764 return &item->stream_info[item->current];
1765
1766 // This shouldn't happen
1767 return NULL;
1768}
1769
1771{
1772 int a, b, m;
1773 int64_t moof_offset;
1774
1775 // Optimize for appending new entries
1776 if (!frag_index->nb_items ||
1777 frag_index->item[frag_index->nb_items - 1].moof_offset < offset)
1778 return frag_index->nb_items;
1779
1780 a = -1;
1781 b = frag_index->nb_items;
1782
1783 while (b - a > 1) {
1784 m = (a + b) >> 1;
1785 moof_offset = frag_index->item[m].moof_offset;
1786 if (moof_offset >= offset)
1787 b = m;
1788 if (moof_offset <= offset)
1789 a = m;
1790 }
1791 return b;
1792}
1793
1795{
1796 av_assert0(frag_stream_info);
1797 if (frag_stream_info->sidx_pts != AV_NOPTS_VALUE)
1798 return frag_stream_info->sidx_pts;
1799 if (frag_stream_info->first_tfra_pts != AV_NOPTS_VALUE)
1800 return frag_stream_info->first_tfra_pts;
1801 return frag_stream_info->tfdt_dts;
1802}
1803
1805 MOVFragmentIndex *frag_index, int index)
1806{
1807 MOVFragmentStreamInfo * frag_stream_info;
1808 MOVStreamContext *sc = dst_st->priv_data;
1809 int64_t timestamp;
1810 int i, j;
1811
1812 // If the stream is referenced by any sidx, limit the search
1813 // to fragments that referenced this stream in the sidx
1814 if (sc->has_sidx) {
1815 frag_stream_info = get_frag_stream_info(frag_index, index, sc->id);
1816 if (!frag_stream_info)
1817 return AV_NOPTS_VALUE;
1818 if (frag_stream_info->sidx_pts != AV_NOPTS_VALUE)
1819 return frag_stream_info->sidx_pts;
1820 if (frag_stream_info->first_tfra_pts != AV_NOPTS_VALUE)
1821 return frag_stream_info->first_tfra_pts;
1822 return frag_stream_info->sidx_pts;
1823 }
1824
1825 for (i = 0; i < frag_index->item[index].nb_stream_info; i++) {
1826 if (dst_st->id != frag_index->item[index].stream_info[i].id)
1827 continue;
1828 AVStream *frag_stream = NULL;
1829 frag_stream_info = &frag_index->item[index].stream_info[i];
1830 for (j = 0; j < s->nb_streams; j++) {
1831 MOVStreamContext *sc2 = s->streams[j]->priv_data;
1832 if (sc2->id == frag_stream_info->id)
1833 frag_stream = s->streams[j];
1834 }
1835 if (!frag_stream) {
1836 av_log(s, AV_LOG_WARNING, "No stream matching sidx ID found.\n");
1837 continue;
1838 }
1839 timestamp = get_stream_info_time(frag_stream_info);
1840 if (timestamp != AV_NOPTS_VALUE)
1841 return av_rescale_q(timestamp, frag_stream->time_base, dst_st->time_base);
1842 }
1843 return AV_NOPTS_VALUE;
1844}
1845
1847 AVStream *st, int64_t timestamp)
1848{
1849 int a, b, m, m0;
1850 int64_t frag_time;
1851
1852 a = -1;
1853 b = frag_index->nb_items;
1854
1855 while (b - a > 1) {
1856 m0 = m = (a + b) >> 1;
1857
1858 while (m < b &&
1859 (frag_time = get_frag_time(s, st, frag_index, m)) == AV_NOPTS_VALUE)
1860 m++;
1861
1862 if (m < b && frag_time <= timestamp)
1863 a = m;
1864 else
1865 b = m0;
1866 }
1867
1868 return a;
1869}
1870
1872{
1873 int index, i;
1874 MOVFragmentIndexItem * item;
1875 MOVFragmentStreamInfo * frag_stream_info;
1876
1877 // If moof_offset already exists in frag_index, return index to it
1878 index = search_frag_moof_offset(&c->frag_index, offset);
1879 if (index < c->frag_index.nb_items &&
1880 c->frag_index.item[index].moof_offset == offset)
1881 return index;
1882
1883 // offset is not yet in frag index.
1884 // Insert new item at index (sorted by moof offset)
1885 item = av_fast_realloc(c->frag_index.item,
1886 &c->frag_index.allocated_size,
1887 (c->frag_index.nb_items + 1) *
1888 sizeof(*c->frag_index.item));
1889 if (!item)
1890 return -1;
1891 c->frag_index.item = item;
1892
1893 frag_stream_info = av_realloc_array(NULL, c->fc->nb_streams,
1894 sizeof(*item->stream_info));
1895 if (!frag_stream_info)
1896 return -1;
1897
1898 for (i = 0; i < c->fc->nb_streams; i++) {
1899 // Avoid building frag index if streams lack track id.
1900 MOVStreamContext *sc = c->fc->streams[i]->priv_data;
1901 if (sc->id < 0) {
1902 av_free(frag_stream_info);
1903 return AVERROR_INVALIDDATA;
1904 }
1905
1906 frag_stream_info[i].id = sc->id;
1907 frag_stream_info[i].sidx_pts = AV_NOPTS_VALUE;
1908 frag_stream_info[i].tfdt_dts = AV_NOPTS_VALUE;
1909 frag_stream_info[i].next_trun_dts = AV_NOPTS_VALUE;
1910 frag_stream_info[i].first_tfra_pts = AV_NOPTS_VALUE;
1911 frag_stream_info[i].index_base = -1;
1912 frag_stream_info[i].index_entry = -1;
1913 frag_stream_info[i].encryption_index = NULL;
1914 frag_stream_info[i].stsd_id = -1;
1915 }
1916
1917 if (index < c->frag_index.nb_items)
1918 memmove(c->frag_index.item + index + 1, c->frag_index.item + index,
1919 (c->frag_index.nb_items - index) * sizeof(*c->frag_index.item));
1920 if (index <= c->frag_index.current)
1921 c->frag_index.current++;
1922
1923 item = &c->frag_index.item[index];
1924 item->headers_read = 0;
1925 item->current = 0;
1926 item->nb_stream_info = c->fc->nb_streams;
1927 item->moof_offset = offset;
1928 item->stream_info = frag_stream_info;
1929 c->frag_index.nb_items++;
1930
1931 return index;
1932}
1933
1934static void fix_frag_index_entries(MOVFragmentIndex *frag_index, int index,
1935 int id, int entries)
1936{
1937 int i;
1938 MOVFragmentStreamInfo * frag_stream_info;
1939
1940 if (index < 0)
1941 return;
1942 for (i = index; i < frag_index->nb_items; i++) {
1943 frag_stream_info = get_frag_stream_info(frag_index, i, id);
1944 if (frag_stream_info && frag_stream_info->index_entry >= 0)
1945 frag_stream_info->index_entry += entries;
1946 }
1947}
1948
1950{
1951 // Set by mov_read_tfhd(). mov_read_trun() will reject files missing tfhd.
1952 c->fragment.found_tfhd = 0;
1953
1954 if (!c->has_looked_for_mfra && c->use_mfra_for > 0) {
1955 c->has_looked_for_mfra = 1;
1956 if (pb->seekable & AVIO_SEEKABLE_NORMAL) {
1957 int ret;
1958 av_log(c->fc, AV_LOG_VERBOSE, "stream has moof boxes, will look "
1959 "for a mfra\n");
1960 if ((ret = mov_read_mfra(c, pb)) < 0) {
1961 av_log(c->fc, AV_LOG_VERBOSE, "found a moof box but failed to "
1962 "read the mfra (may be a live ismv)\n");
1963 }
1964 } else {
1965 av_log(c->fc, AV_LOG_VERBOSE, "found a moof box but stream is not "
1966 "seekable, can not look for mfra\n");
1967 }
1968 }
1969 c->fragment.moof_offset = c->fragment.implicit_offset = avio_tell(pb) - 8;
1970 av_log(c->fc, AV_LOG_TRACE, "moof offset %"PRIx64"\n", c->fragment.moof_offset);
1971 c->frag_index.current = update_frag_index(c, c->fragment.moof_offset);
1972 return mov_read_default(c, pb, atom);
1973}
1974
1976{
1977 int64_t time;
1978 if (version == 1) {
1979 time = avio_rb64(pb);
1980 avio_rb64(pb);
1981 if (time < 0) {
1982 av_log(c->fc, AV_LOG_DEBUG, "creation_time is negative\n");
1983 return;
1984 }
1985 } else {
1986 time = avio_rb32(pb);
1987 avio_rb32(pb); /* modification time */
1988 if (time > 0 && time < 2082844800) {
1989 av_log(c->fc, AV_LOG_WARNING, "Detected creation time before 1970, parsing as unix timestamp.\n");
1990 time += 2082844800;
1991 }
1992 }
1993 if (time) {
1994 time -= 2082844800; /* seconds between 1904-01-01 and Epoch */
1995
1996 if ((int64_t)(time * 1000000ULL) / 1000000 != time) {
1997 av_log(c->fc, AV_LOG_DEBUG, "creation_time is not representable\n");
1998 return;
1999 }
2000
2001 ff_dict_set_timestamp(metadata, "creation_time", time * 1000000);
2002 }
2003}
2004
2006{
2007 AVStream *st;
2008 MOVStreamContext *sc;
2009 int version;
2010 char language[4] = {0};
2011 unsigned lang;
2012
2013 if (c->fc->nb_streams < 1)
2014 return 0;
2015 st = c->fc->streams[c->fc->nb_streams-1];
2016 sc = st->priv_data;
2017
2018 if (sc->time_scale) {
2019 av_log(c->fc, AV_LOG_ERROR, "Multiple mdhd?\n");
2020 return AVERROR_INVALIDDATA;
2021 }
2022
2023 version = avio_r8(pb);
2024 if (version > 1) {
2025 avpriv_request_sample(c->fc, "Version %d", version);
2026 return AVERROR_PATCHWELCOME;
2027 }
2028 avio_rb24(pb); /* flags */
2030
2031 sc->time_scale = avio_rb32(pb);
2032 if (sc->time_scale <= 0) {
2033 av_log(c->fc, AV_LOG_ERROR, "Invalid mdhd time scale %d, defaulting to 1\n", sc->time_scale);
2034 sc->time_scale = 1;
2035 }
2036 st->duration = (version == 1) ? avio_rb64(pb) : avio_rb32(pb); /* duration */
2037
2038 if ((version == 1 && st->duration == UINT64_MAX) ||
2039 (version != 1 && st->duration == UINT32_MAX)) {
2040 st->duration = 0;
2041 }
2042
2043 lang = avio_rb16(pb); /* language */
2044 if (ff_mov_lang_to_iso639(lang, language))
2045 av_dict_set(&st->metadata, "language", language, 0);
2046 avio_rb16(pb); /* quality */
2047
2048 return 0;
2049}
2050
2052{
2053 int i;
2054 int version = avio_r8(pb); /* version */
2055 avio_rb24(pb); /* flags */
2056
2057 mov_metadata_creation_time(c, pb, &c->fc->metadata, version);
2058 c->time_scale = avio_rb32(pb); /* time scale */
2059 if (c->time_scale <= 0) {
2060 av_log(c->fc, AV_LOG_ERROR, "Invalid mvhd time scale %d, defaulting to 1\n", c->time_scale);
2061 c->time_scale = 1;
2062 }
2063 av_log(c->fc, AV_LOG_TRACE, "time scale = %i\n", c->time_scale);
2064
2065 c->duration = (version == 1) ? avio_rb64(pb) : avio_rb32(pb); /* duration */
2066 avio_rb32(pb); /* preferred scale */
2067
2068 avio_rb16(pb); /* preferred volume */
2069
2070 avio_skip(pb, 10); /* reserved */
2071
2072 /* movie display matrix, store it in main context and use it later on */
2073 for (i = 0; i < 3; i++) {
2074 c->movie_display_matrix[i][0] = avio_rb32(pb); // 16.16 fixed point
2075 c->movie_display_matrix[i][1] = avio_rb32(pb); // 16.16 fixed point
2076 c->movie_display_matrix[i][2] = avio_rb32(pb); // 2.30 fixed point
2077 }
2078
2079 avio_rb32(pb); /* preview time */
2080 avio_rb32(pb); /* preview duration */
2081 avio_rb32(pb); /* poster time */
2082 avio_rb32(pb); /* selection time */
2083 avio_rb32(pb); /* selection duration */
2084 avio_rb32(pb); /* current time */
2085 avio_rb32(pb); /* next track ID */
2086
2087 return 0;
2088}
2089
2091{
2092 AVStream *st;
2093
2094 if (fc->nb_streams < 1)
2095 return;
2096 st = fc->streams[fc->nb_streams-1];
2097
2098 switch (st->codecpar->codec_id) {
2101 break;
2104 break;
2107 break;
2110 break;
2113 break;
2114 default:
2115 break;
2116 }
2117}
2118
2120{
2121 int little_endian = avio_rb16(pb) & 0xFF;
2122 av_log(c->fc, AV_LOG_TRACE, "enda %d\n", little_endian);
2123 if (little_endian == 1)
2125 return 0;
2126}
2127
2129{
2130 int format_flags;
2131 int version, flags;
2132 int pcm_sample_size;
2133 AVFormatContext *fc = c->fc;
2134 AVStream *st;
2135 MOVStreamContext *sc;
2136
2137 if (atom.size < 6) {
2138 av_log(c->fc, AV_LOG_ERROR, "Empty pcmC box\n");
2139 return AVERROR_INVALIDDATA;
2140 }
2141
2142 version = avio_r8(pb);
2143 flags = avio_rb24(pb);
2144
2145 if (version != 0 || flags != 0) {
2146 av_log(c->fc, AV_LOG_ERROR,
2147 "Unsupported 'pcmC' box with version %d, flags: %x",
2148 version, flags);
2149 return AVERROR_INVALIDDATA;
2150 }
2151
2152 format_flags = avio_r8(pb);
2153 pcm_sample_size = avio_r8(pb);
2154
2155 if (fc->nb_streams < 1)
2156 return AVERROR_INVALIDDATA;
2157
2158 st = fc->streams[fc->nb_streams - 1];
2159 sc = st->priv_data;
2160
2161 if (sc->format == MOV_MP4_FPCM_TAG) {
2162 switch (pcm_sample_size) {
2163 case 32:
2165 break;
2166 case 64:
2168 break;
2169 default:
2170 av_log(fc, AV_LOG_ERROR, "invalid pcm_sample_size %d for %s\n",
2171 pcm_sample_size,
2172 av_fourcc2str(sc->format));
2173 return AVERROR_INVALIDDATA;
2174 }
2175 } else if (sc->format == MOV_MP4_IPCM_TAG) {
2176 switch (pcm_sample_size) {
2177 case 16:
2179 break;
2180 case 24:
2182 break;
2183 case 32:
2185 break;
2186 default:
2187 av_log(fc, AV_LOG_ERROR, "invalid pcm_sample_size %d for %s\n",
2188 pcm_sample_size,
2189 av_fourcc2str(sc->format));
2190 return AVERROR_INVALIDDATA;
2191 }
2192 } else {
2193 av_log(fc, AV_LOG_ERROR, "'pcmC' with invalid sample entry '%s'\n",
2194 av_fourcc2str(sc->format));
2195 return AVERROR_INVALIDDATA;
2196 }
2197
2198 if (format_flags & 1) // indicates little-endian format. If not present, big-endian format is used
2201
2202 return 0;
2203}
2204
2206{
2207 AVStream *st;
2208 HEIFItem *item = NULL;
2209 char color_parameter_type[5] = { 0 };
2210 uint16_t color_primaries, color_trc, color_matrix;
2211 int ret;
2212
2213 st = get_curr_st(c);
2214 if (!st) {
2215 item = get_heif_item(c, c->cur_item_id);
2216 if (!item)
2217 return 0;
2218 }
2219
2220 ret = ffio_read_size(pb, color_parameter_type, 4);
2221 if (ret < 0)
2222 return ret;
2223 if (strncmp(color_parameter_type, "nclx", 4) &&
2224 strncmp(color_parameter_type, "nclc", 4) &&
2225 strncmp(color_parameter_type, "prof", 4)) {
2226 av_log(c->fc, AV_LOG_WARNING, "unsupported color_parameter_type %s\n",
2227 color_parameter_type);
2228 return 0;
2229 }
2230
2231 if (!strncmp(color_parameter_type, "prof", 4)) {
2232 AVPacketSideData *sd;
2233 uint8_t *icc_profile;
2234 if (st) {
2238 atom.size - 4, 0);
2239 if (!sd)
2240 return AVERROR(ENOMEM);
2241 icc_profile = sd->data;
2242 } else {
2243 if (c->heif_icc_profile_items >= c->fc->max_streams) {
2244 av_log(c->fc, AV_LOG_WARNING,
2245 "HEIF ICC profile copies exceed cap %d; ignoring further items\n",
2246 c->fc->max_streams);
2247 return 0;
2248 }
2249 av_freep(&item->icc_profile);
2250 icc_profile = item->icc_profile = av_malloc(atom.size - 4);
2251 if (!icc_profile) {
2252 item->icc_profile_size = 0;
2253 return AVERROR(ENOMEM);
2254 }
2255 item->icc_profile_size = atom.size - 4;
2256 c->heif_icc_profile_items++;
2257 }
2258 ret = ffio_read_size(pb, icc_profile, atom.size - 4);
2259 if (ret < 0)
2260 return ret;
2261 } else if (st) {
2263 color_trc = avio_rb16(pb);
2264 color_matrix = avio_rb16(pb);
2265
2266 av_log(c->fc, AV_LOG_TRACE,
2267 "%s: pri %d trc %d matrix %d",
2268 color_parameter_type, color_primaries, color_trc, color_matrix);
2269
2270 if (!strncmp(color_parameter_type, "nclx", 4)) {
2271 uint8_t color_range = avio_r8(pb) >> 7;
2272 av_log(c->fc, AV_LOG_TRACE, " full %"PRIu8"", color_range);
2273 if (color_range)
2275 else
2277 }
2278
2281 if (!av_color_transfer_name(color_trc))
2282 color_trc = AVCOL_TRC_UNSPECIFIED;
2283 if (!av_color_space_name(color_matrix))
2284 color_matrix = AVCOL_SPC_UNSPECIFIED;
2285
2287 st->codecpar->color_trc = color_trc;
2288 st->codecpar->color_space = color_matrix;
2289 av_log(c->fc, AV_LOG_TRACE, "\n");
2290 }
2291 return 0;
2292}
2293
2295{
2296 AVStream *st;
2297 unsigned mov_field_order;
2298 enum AVFieldOrder decoded_field_order = AV_FIELD_UNKNOWN;
2299
2300 if (c->fc->nb_streams < 1) // will happen with jp2 files
2301 return 0;
2302 st = c->fc->streams[c->fc->nb_streams-1];
2303 if (atom.size < 2)
2304 return AVERROR_INVALIDDATA;
2305 mov_field_order = avio_rb16(pb);
2306 if ((mov_field_order & 0xFF00) == 0x0100)
2307 decoded_field_order = AV_FIELD_PROGRESSIVE;
2308 else if ((mov_field_order & 0xFF00) == 0x0200) {
2309 switch (mov_field_order & 0xFF) {
2310 case 0x01: decoded_field_order = AV_FIELD_TT;
2311 break;
2312 case 0x06: decoded_field_order = AV_FIELD_BB;
2313 break;
2314 case 0x09: decoded_field_order = AV_FIELD_TB;
2315 break;
2316 case 0x0E: decoded_field_order = AV_FIELD_BT;
2317 break;
2318 }
2319 }
2320 if (decoded_field_order == AV_FIELD_UNKNOWN && mov_field_order) {
2321 av_log(c->fc, AV_LOG_ERROR, "Unknown MOV field order 0x%04x\n", mov_field_order);
2322 }
2323 st->codecpar->field_order = decoded_field_order;
2324
2325 return 0;
2326}
2327
2329{
2330 int err = 0;
2331 uint64_t size = (uint64_t)par->extradata_size + atom.size + 8 + AV_INPUT_BUFFER_PADDING_SIZE;
2332 if (size > INT_MAX || (uint64_t)atom.size > INT_MAX)
2333 return AVERROR_INVALIDDATA;
2334 if ((err = av_reallocp(&par->extradata, size)) < 0) {
2335 par->extradata_size = 0;
2336 return err;
2337 }
2339 return 0;
2340}
2341
2342/* Read a whole atom into the extradata return the size of the atom read, possibly truncated if != atom.size */
2344 AVCodecParameters *par, uint8_t *buf)
2345{
2346 int64_t result = atom.size;
2347 int err;
2348
2349 AV_WB32(buf , atom.size + 8);
2350 AV_WL32(buf + 4, atom.type);
2351 err = ffio_read_size(pb, buf + 8, atom.size);
2352 if (err < 0) {
2353 par->extradata_size -= atom.size;
2354 return err;
2355 } else if (err < atom.size) {
2356 av_log(c->fc, AV_LOG_WARNING, "truncated extradata\n");
2357 par->extradata_size -= atom.size - err;
2358 result = err;
2359 }
2360 memset(buf + 8 + err, 0, AV_INPUT_BUFFER_PADDING_SIZE);
2361 return result;
2362}
2363
2364/* FIXME modify QDM2/SVQ3/H.264 decoders to take full atom as extradata */
2366 enum AVCodecID codec_id)
2367{
2368 AVStream *st;
2369 uint64_t original_size;
2370 int err;
2371
2372 if (c->fc->nb_streams < 1) // will happen with jp2 files
2373 return 0;
2374 st = c->fc->streams[c->fc->nb_streams-1];
2375
2376 if (st->codecpar->codec_id != codec_id)
2377 return 0; /* unexpected codec_id - don't mess with extradata */
2378
2379 original_size = st->codecpar->extradata_size;
2380 err = mov_realloc_extradata(st->codecpar, atom);
2381 if (err)
2382 return err;
2383
2384 err = mov_read_atom_into_extradata(c, pb, atom, st->codecpar, st->codecpar->extradata + original_size);
2385 if (err < 0)
2386 return err;
2387 return 0; // Note: this is the original behavior to ignore truncation.
2388}
2389
2390/* wrapper functions for reading ALAC/AVS/MJPEG/MJPEG2000 extradata atoms only for those codecs */
2392{
2393 return mov_read_extradata(c, pb, atom, AV_CODEC_ID_ALAC);
2394}
2395
2397{
2398 return mov_read_extradata(c, pb, atom, AV_CODEC_ID_CAVS);
2399}
2400
2402{
2403 return mov_read_extradata(c, pb, atom, AV_CODEC_ID_JPEG2000);
2404}
2405
2407{
2408 return mov_read_extradata(c, pb, atom, AV_CODEC_ID_R10K);
2409}
2410
2412{
2413 int ret = mov_read_extradata(c, pb, atom, AV_CODEC_ID_AVUI);
2414 if (!ret)
2415 ret = mov_read_extradata(c, pb, atom, AV_CODEC_ID_DNXHD);
2416 return ret;
2417}
2418
2420{
2421 int ret = mov_read_extradata(c, pb, atom, AV_CODEC_ID_TARGA_Y216);
2422
2423 if (!ret && c->fc->nb_streams >= 1) {
2424 AVCodecParameters *par = c->fc->streams[c->fc->nb_streams-1]->codecpar;
2425 if (par->extradata_size >= 40) {
2426 par->height = AV_RB16(&par->extradata[36]);
2427 par->width = AV_RB16(&par->extradata[38]);
2428 }
2429 }
2430 return ret;
2431}
2432
2434{
2435 if (c->fc->nb_streams >= 1) {
2436 AVStream *const st = c->fc->streams[c->fc->nb_streams - 1];
2437 FFStream *const sti = ffstream(st);
2438 AVCodecParameters *par = st->codecpar;
2439
2440 if (par->codec_tag == MKTAG('A', 'V', 'i', 'n') &&
2441 par->codec_id == AV_CODEC_ID_H264 &&
2442 atom.size > 11) {
2443 int cid;
2444 avio_skip(pb, 10);
2445 cid = avio_rb16(pb);
2446 /* For AVID AVCI50, force width of 1440 to be able to select the correct SPS and PPS */
2447 if (cid == 0xd4d || cid == 0xd4e)
2448 par->width = 1440;
2449 return 0;
2450 } else if ((par->codec_tag == MKTAG('A', 'V', 'd', '1') ||
2451 par->codec_tag == MKTAG('A', 'V', 'j', '2') ||
2452 par->codec_tag == MKTAG('A', 'V', 'd', 'n')) &&
2453 atom.size >= 24) {
2454 int num, den;
2455 avio_skip(pb, 12);
2456 num = avio_rb32(pb);
2457 den = avio_rb32(pb);
2458 if (num <= 0 || den <= 0)
2459 return 0;
2460 switch (avio_rb32(pb)) {
2461 case 2:
2462 if (den >= INT_MAX / 2)
2463 return 0;
2464 den *= 2;
2466 case 1:
2467 sti->display_aspect_ratio = (AVRational){ num, den };
2469 default:
2470 return 0;
2471 }
2472 }
2473 }
2474
2475 return mov_read_avid(c, pb, atom);
2476}
2477
2479{
2480 int ret = 0;
2481 int length = 0;
2482 uint64_t original_size;
2483 if (c->fc->nb_streams >= 1) {
2484 AVCodecParameters *par = c->fc->streams[c->fc->nb_streams-1]->codecpar;
2485 if (par->codec_id == AV_CODEC_ID_H264)
2486 return 0;
2487 if (atom.size == 16) {
2488 original_size = par->extradata_size;
2489 ret = mov_realloc_extradata(par, atom);
2490 if (!ret) {
2491 length = mov_read_atom_into_extradata(c, pb, atom, par, par->extradata + original_size);
2492 if (length == atom.size) {
2493 const uint8_t range_value = par->extradata[original_size + 19];
2494 switch (range_value) {
2495 case 1:
2497 break;
2498 case 2:
2500 break;
2501 default:
2502 av_log(c->fc, AV_LOG_WARNING, "ignored unknown aclr value (%d)\n", range_value);
2503 break;
2504 }
2505 ff_dlog(c->fc, "color_range: %d\n", par->color_range);
2506 } else {
2507 /* For some reason the whole atom was not added to the extradata */
2508 av_log(c->fc, AV_LOG_ERROR, "aclr not decoded - incomplete atom\n");
2509 }
2510 } else {
2511 av_log(c->fc, AV_LOG_ERROR, "aclr not decoded - unable to add atom to extradata\n");
2512 }
2513 } else {
2514 av_log(c->fc, AV_LOG_WARNING, "aclr not decoded - unexpected size %"PRId64"\n", atom.size);
2515 }
2516 }
2517
2518 return ret;
2519}
2520
2522{
2523 return mov_read_extradata(c, pb, atom, AV_CODEC_ID_SVQ3);
2524}
2525
2527{
2528 AVStream *st;
2529 int ret;
2530
2531 if (c->fc->nb_streams < 1)
2532 return 0;
2533 st = c->fc->streams[c->fc->nb_streams-1];
2534
2535 if ((uint64_t)atom.size > (1<<30))
2536 return AVERROR_INVALIDDATA;
2537
2538 if (st->codecpar->codec_id == AV_CODEC_ID_QDM2 ||
2541 // pass all frma atom to codec, needed at least for QDMC and QDM2
2542 ret = ff_get_extradata(c->fc, st->codecpar, pb, atom.size);
2543 if (ret < 0)
2544 return ret;
2545 } else if (atom.size > 8) { /* to read frma, esds atoms */
2546 if (st->codecpar->codec_id == AV_CODEC_ID_ALAC && atom.size >= 24) {
2547 uint64_t buffer;
2548 ret = ffio_ensure_seekback(pb, 8);
2549 if (ret < 0)
2550 return ret;
2551 buffer = avio_rb64(pb);
2552 atom.size -= 8;
2553 if ( (buffer & 0xFFFFFFFF) == MKBETAG('f','r','m','a')
2554 && buffer >> 32 <= atom.size
2555 && buffer >> 32 >= 8) {
2556 avio_skip(pb, -8);
2557 atom.size += 8;
2558 } else if (!st->codecpar->extradata_size) {
2559#define ALAC_EXTRADATA_SIZE 36
2561 if (!st->codecpar->extradata)
2562 return AVERROR(ENOMEM);
2565 AV_WB32(st->codecpar->extradata + 4, MKTAG('a','l','a','c'));
2566 AV_WB64(st->codecpar->extradata + 12, buffer);
2567 avio_read(pb, st->codecpar->extradata + 20, 16);
2568 avio_skip(pb, atom.size - 24);
2569 return 0;
2570 }
2571 }
2572 if ((ret = mov_read_default(c, pb, atom)) < 0)
2573 return ret;
2574 } else
2575 avio_skip(pb, atom.size);
2576 return 0;
2577}
2578
2579/**
2580 * This function reads atom content and puts data in extradata without tag
2581 * nor size unlike mov_read_extradata.
2582 */
2584{
2585 AVStream *st;
2586 int ret;
2587
2588 st = get_curr_st(c);
2589 if (!st)
2590 return 0;
2591
2592 if ((uint64_t)atom.size > (1<<30))
2593 return AVERROR_INVALIDDATA;
2594
2595 if (atom.type == MKTAG('v','v','c','C')) {
2596 avio_skip(pb, 4);
2597 atom.size -= 4;
2598 }
2599
2600 if (atom.size >= 10) {
2601 // Broken files created by legacy versions of libavformat will
2602 // wrap a whole fiel atom inside of a glbl atom.
2603 unsigned size = avio_rb32(pb);
2604 unsigned type = avio_rl32(pb);
2605 if (avio_feof(pb))
2606 return AVERROR_INVALIDDATA;
2607 avio_seek(pb, -8, SEEK_CUR);
2608 if (type == MKTAG('f','i','e','l') && size == atom.size)
2609 return mov_read_default(c, pb, atom);
2610 }
2611 if (st->codecpar->extradata_size > 1 && st->codecpar->extradata) {
2612 av_log(c->fc, AV_LOG_WARNING, "ignoring multiple glbl\n");
2613 return 0;
2614 }
2615 ret = ff_get_extradata(c->fc, st->codecpar, pb, atom.size);
2616 if (ret < 0)
2617 return ret;
2618 if (atom.type == MKTAG('h','v','c','C') && st->codecpar->codec_tag == MKTAG('d','v','h','1'))
2619 /* HEVC-based Dolby Vision derived from hvc1.
2620 Happens to match with an identifier
2621 previously utilized for DV. Thus, if we have
2622 the hvcC extradata box available as specified,
2623 set codec to HEVC */
2625
2626 return 0;
2627}
2628
2630{
2631 AVStream *st;
2632 uint8_t profile_level;
2633 int ret;
2634
2635 if (c->fc->nb_streams < 1)
2636 return 0;
2637 st = c->fc->streams[c->fc->nb_streams-1];
2638
2639 if (atom.size >= (1<<28) || atom.size < 7)
2640 return AVERROR_INVALIDDATA;
2641
2642 profile_level = avio_r8(pb);
2643 if ((profile_level & 0xf0) != 0xc0)
2644 return 0;
2645
2646 avio_seek(pb, 6, SEEK_CUR);
2647 ret = ff_get_extradata(c->fc, st->codecpar, pb, atom.size - 7);
2648 if (ret < 0)
2649 return ret;
2650
2651 return 0;
2652}
2653
2654static int mov_find_tref_id(const MovTref *tag, uint32_t id)
2655{
2656 for (int i = 0; i < tag->nb_id; i++) {
2657 if (tag->id[i] == id)
2658 return 1;
2659 }
2660 return 0;
2661}
2662
2663static int mov_add_tref_id(MovTref *tag, uint32_t id)
2664{
2665 int ret = mov_find_tref_id(tag, id);
2666
2667 if (!ret) {
2668 uint32_t *tmp = av_realloc_array(tag->id, tag->nb_id + 1, sizeof(*tag->id));
2669 if (!tmp)
2670 return AVERROR(ENOMEM);
2671 tag->id = tmp;
2672 tag->id[tag->nb_id++] = id;
2673 }
2674
2675 return 0;
2676}
2677
2679{
2680 for (int i = 0; i < sc->nb_tref_tags; i++) {
2681 MovTref *entry = &sc->tref_tags[i];
2682
2683 if (entry->name == name)
2684 return entry;
2685 }
2686 return NULL;
2687}
2688
2690{
2692
2693 if (!tag) {
2695 sizeof(*sc->tref_tags));
2696 if (!tmp)
2697 return NULL;
2698 sc->tref_tags = tmp;
2699 tag = &sc->tref_tags[sc->nb_tref_tags++];
2700 *tag = (MovTref){ .name = name };
2701 }
2702
2703 return tag;
2704}
2705
2707{
2708 AVStream* st;
2709 MOVStreamContext* sc;
2710
2711 if (c->fc->nb_streams < 1)
2712 return 0;
2713
2714 if (atom.size > 4) {
2715 av_log(c->fc, AV_LOG_ERROR, "Only a single tref of type cdsc/rndr is supported\n");
2716 return AVERROR_PATCHWELCOME;
2717 }
2718 if (atom.size < 4)
2719 return AVERROR_INVALIDDATA;
2720
2721 st = get_curr_st(c);
2722 if (!st)
2723 return AVERROR_INVALIDDATA;
2724 sc = st->priv_data;
2725
2726 MovTref *tag = mov_add_tref_tag(sc, atom.type);
2727 if (!tag)
2728 return AVERROR(ENOMEM);
2729
2730 int ret = mov_add_tref_id(tag, avio_rb32(pb));
2731 if (ret < 0)
2732 return ret;
2733
2734 return 0;
2735}
2736
2738{
2739 AVStream* st;
2740 MOVStreamContext* sc;
2741
2742 if (c->fc->nb_streams < 1)
2743 return 0;
2744
2745 /* For SBAS this should be fine - though beware if someone implements a
2746 * tref atom processor that doesn't drop down to default then this may
2747 * be lost. */
2748 if (atom.size > 4) {
2749 av_log(c->fc, AV_LOG_ERROR, "Only a single tref of type sbas is supported\n");
2750 return AVERROR_PATCHWELCOME;
2751 }
2752 if (atom.size < 4)
2753 return AVERROR_INVALIDDATA;
2754
2755 st = c->fc->streams[c->fc->nb_streams - 1];
2756 sc = st->priv_data;
2757
2758 MovTref *tag = mov_add_tref_tag(sc, atom.type);
2759 if (!tag)
2760 return AVERROR(ENOMEM);
2761
2762 int ret = mov_add_tref_id(tag, avio_rb32(pb));
2763 if (ret < 0)
2764 return ret;
2765
2766 return 0;
2767}
2768
2770{
2771 AVStream* st;
2772 MOVStreamContext* sc;
2773
2774 if (c->fc->nb_streams < 1)
2775 return 0;
2776
2777 if (atom.size > 4)
2778 av_log(c->fc, AV_LOG_WARNING, "More than one vdep reference is not supported.\n");
2779 if (atom.size < 4)
2780 return AVERROR_INVALIDDATA;
2781
2782 st = c->fc->streams[c->fc->nb_streams - 1];
2783 sc = st->priv_data;
2784
2785 MovTref *tag = mov_add_tref_tag(sc, atom.type);
2786 if (!tag)
2787 return AVERROR(ENOMEM);
2788
2789 int ret = mov_add_tref_id(tag, avio_rb32(pb));
2790 if (ret < 0)
2791 return ret;
2792
2793 return 0;
2794}
2795
2796/**
2797 * An strf atom is a BITMAPINFOHEADER struct. This struct is 40 bytes itself,
2798 * but can have extradata appended at the end after the 40 bytes belonging
2799 * to the struct.
2800 */
2802{
2803 AVStream *st;
2804 int ret;
2805
2806 if (c->fc->nb_streams < 1)
2807 return 0;
2808 if (atom.size <= 40)
2809 return 0;
2810 st = c->fc->streams[c->fc->nb_streams-1];
2811
2812 if ((uint64_t)atom.size > (1<<30))
2813 return AVERROR_INVALIDDATA;
2814
2815 avio_skip(pb, 40);
2816 ret = ff_get_extradata(c->fc, st->codecpar, pb, atom.size - 40);
2817 if (ret < 0)
2818 return ret;
2819
2820 return 0;
2821}
2822
2824{
2825 AVStream *st;
2826 MOVStreamContext *sc;
2827 unsigned int i, entries;
2828
2829 if (c->trak_index < 0) {
2830 av_log(c->fc, AV_LOG_WARNING, "STCO outside TRAK\n");
2831 return 0;
2832 }
2833 if (c->fc->nb_streams < 1)
2834 return 0;
2835 st = c->fc->streams[c->fc->nb_streams-1];
2836 sc = st->priv_data;
2837
2838 avio_r8(pb); /* version */
2839 avio_rb24(pb); /* flags */
2840
2841 // Clamp allocation size for `chunk_offsets` -- don't throw an error for an
2842 // invalid count since the EOF path doesn't throw either.
2843 entries = avio_rb32(pb);
2844 entries =
2845 FFMIN(entries,
2846 FFMAX(0, (atom.size - 8) /
2847 (atom.type == MKTAG('s', 't', 'c', 'o') ? 4 : 8)));
2848
2849 if (!entries)
2850 return 0;
2851
2852 if (sc->chunk_offsets) {
2853 av_log(c->fc, AV_LOG_WARNING, "Ignoring duplicated STCO atom\n");
2854 return 0;
2855 }
2856
2858 sc->chunk_count = 0;
2859 sc->chunk_offsets = av_malloc_array(entries, sizeof(*sc->chunk_offsets));
2860 if (!sc->chunk_offsets)
2861 return AVERROR(ENOMEM);
2862 sc->chunk_count = entries;
2863
2864 if (atom.type == MKTAG('s','t','c','o'))
2865 for (i = 0; i < entries && !pb->eof_reached; i++)
2866 sc->chunk_offsets[i] = avio_rb32(pb);
2867 else if (atom.type == MKTAG('c','o','6','4'))
2868 for (i = 0; i < entries && !pb->eof_reached; i++) {
2869 sc->chunk_offsets[i] = avio_rb64(pb);
2870 if (sc->chunk_offsets[i] < 0) {
2871 av_log(c->fc, AV_LOG_WARNING, "Impossible chunk_offset\n");
2872 sc->chunk_offsets[i] = 0;
2873 }
2874 }
2875 else
2876 return AVERROR_INVALIDDATA;
2877
2878 sc->chunk_count = i;
2879
2880 if (pb->eof_reached) {
2881 av_log(c->fc, AV_LOG_WARNING, "reached eof, corrupted STCO atom\n");
2882 return AVERROR_EOF;
2883 }
2884
2885 return 0;
2886}
2887
2888static int mov_codec_id(AVStream *st, uint32_t format)
2889{
2891
2892 if (id <= 0 &&
2893 ((format & 0xFFFF) == 'm' + ('s' << 8) ||
2894 (format & 0xFFFF) == 'T' + ('S' << 8)))
2896
2897 if (st->codecpar->codec_type != AVMEDIA_TYPE_VIDEO && id > 0) {
2899 } else if (st->codecpar->codec_type != AVMEDIA_TYPE_AUDIO &&
2900 /* skip old ASF MPEG-4 tag */
2901 format && format != MKTAG('m','p','4','s')) {
2903 if (id <= 0)
2905 if (id > 0)
2907 else if (st->codecpar->codec_type == AVMEDIA_TYPE_DATA ||
2911 if (id <= 0) {
2914 }
2915
2916 if (id > 0)
2918 else
2920 }
2921 }
2922
2923 st->codecpar->codec_tag = format;
2924
2925 return id;
2926}
2927
2929 AVStream *st, MOVStreamContext *sc)
2930{
2931 uint8_t codec_name[32] = { 0 };
2932 int64_t stsd_start;
2933 unsigned int len;
2934 uint32_t id = 0;
2935
2936 /* The first 16 bytes of the video sample description are already
2937 * read in ff_mov_read_stsd_entries() */
2938 stsd_start = avio_tell(pb) - 16;
2939
2940 if (c->isom) {
2941 avio_skip(pb, 2); /* pre_defined */
2942 avio_skip(pb, 2); /* reserved */
2943 avio_skip(pb, 12); /* pre_defined */
2944 } else {
2945 avio_rb16(pb); /* version */
2946 avio_rb16(pb); /* revision level */
2947 id = avio_rl32(pb); /* vendor */
2948 av_dict_set(&st->metadata, "vendor_id", av_fourcc2str(id), 0);
2949 avio_rb32(pb); /* temporal quality */
2950 avio_rb32(pb); /* spatial quality */
2951 }
2952
2953 st->codecpar->width = avio_rb16(pb); /* width */
2954 st->codecpar->height = avio_rb16(pb); /* height */
2955
2956 avio_rb32(pb); /* horiz resolution */
2957 avio_rb32(pb); /* vert resolution */
2958 avio_rb32(pb); /* data size, always 0 */
2959 avio_rb16(pb); /* frames per samples */
2960
2961 len = avio_r8(pb); /* codec name, pascal string */
2962 if (len > 31)
2963 len = 31;
2964 mov_read_mac_string(c, pb, len, codec_name, sizeof(codec_name));
2965 if (len < 31)
2966 avio_skip(pb, 31 - len);
2967
2968 if (codec_name[0])
2969 av_dict_set(&st->metadata, "encoder", codec_name, 0);
2970
2971 /* codec_tag YV12 triggers an UV swap in rawdec.c */
2972 if (!strncmp(codec_name, "Planar Y'CbCr 8-bit 4:2:0", 25)) {
2973 st->codecpar->codec_tag = MKTAG('I', '4', '2', '0');
2974 st->codecpar->width &= ~1;
2975 st->codecpar->height &= ~1;
2976 }
2977 /* Flash Media Server uses tag H.263 with Sorenson Spark */
2978 if (st->codecpar->codec_tag == MKTAG('H','2','6','3') &&
2979 !strncmp(codec_name, "Sorenson H263", 13))
2981
2982 st->codecpar->bits_per_coded_sample = avio_rb16(pb); /* depth */
2983
2984 avio_seek(pb, stsd_start, SEEK_SET);
2985
2986 if (ff_get_qtpalette(st->codecpar->codec_id, pb, sc->palette)) {
2987 st->codecpar->bits_per_coded_sample &= 0x1F;
2988 sc->has_palette = 1;
2989 }
2990}
2991
2993 AVStream *st, MOVStreamContext *sc)
2994{
2995 int bits_per_sample, flags;
2996 uint16_t version = avio_rb16(pb);
2997 uint32_t id = 0;
2998 AVDictionaryEntry *compatible_brands = av_dict_get(c->fc->metadata, "compatible_brands", NULL, AV_DICT_MATCH_CASE);
2999 int channel_count;
3000
3001 if (c->isom)
3002 avio_skip(pb, 6); /* reserved */
3003 else {
3004 avio_rb16(pb); /* revision level */
3005 id = avio_rl32(pb); /* vendor */
3006 av_dict_set(&st->metadata, "vendor_id", av_fourcc2str(id), 0);
3007 }
3008
3009 channel_count = avio_rb16(pb);
3010
3012 st->codecpar->ch_layout.nb_channels = channel_count;
3013 st->codecpar->bits_per_coded_sample = avio_rb16(pb); /* sample size */
3014 av_log(c->fc, AV_LOG_TRACE, "audio channels %d\n", channel_count);
3015
3016 sc->audio_cid = avio_rb16(pb);
3017 avio_rb16(pb); /* packet size = 0 */
3018
3019 st->codecpar->sample_rate = ((avio_rb32(pb) >> 16));
3020
3021 // Read QT version 1 fields. In version 0 these do not exist.
3022 av_log(c->fc, AV_LOG_TRACE, "version =%d, isom =%d\n", version, c->isom);
3023 if (!c->isom ||
3024 (compatible_brands && strstr(compatible_brands->value, "qt ")) ||
3025 (sc->stsd_version == 0 && version > 0)) {
3026 if (version == 1) {
3027 sc->samples_per_frame = avio_rb32(pb);
3028 avio_rb32(pb); /* bytes per packet */
3029 sc->bytes_per_frame = avio_rb32(pb);
3030 avio_rb32(pb); /* bytes per sample */
3031 } else if (version == 2) {
3032 avio_rb32(pb); /* sizeof struct only */
3034 channel_count = avio_rb32(pb);
3036 st->codecpar->ch_layout.nb_channels = channel_count;
3037 avio_rb32(pb); /* always 0x7F000000 */
3039
3040 flags = avio_rb32(pb); /* lpcm format specific flag */
3041 sc->bytes_per_frame = avio_rb32(pb);
3042 sc->samples_per_frame = avio_rb32(pb);
3043 if (st->codecpar->codec_tag == MKTAG('l','p','c','m'))
3044 st->codecpar->codec_id =
3046 flags);
3047 }
3048 if (version == 0 || (version == 1 && sc->audio_cid != -2)) {
3049 /* can't correctly handle variable sized packet as audio unit */
3050 switch (st->codecpar->codec_id) {
3051 case AV_CODEC_ID_MP2:
3052 case AV_CODEC_ID_MP3:
3054 break;
3055 }
3056 }
3057 }
3058
3059 if (sc->format == 0) {
3060 if (st->codecpar->bits_per_coded_sample == 8)
3061 st->codecpar->codec_id = mov_codec_id(st, MKTAG('r','a','w',' '));
3062 else if (st->codecpar->bits_per_coded_sample == 16)
3063 st->codecpar->codec_id = mov_codec_id(st, MKTAG('t','w','o','s'));
3064 }
3065
3066 switch (st->codecpar->codec_id) {
3067 case AV_CODEC_ID_PCM_S8:
3068 case AV_CODEC_ID_PCM_U8:
3069 if (st->codecpar->bits_per_coded_sample == 16)
3071 break;
3074 if (st->codecpar->bits_per_coded_sample == 8)
3076 else if (st->codecpar->bits_per_coded_sample == 24)
3077 st->codecpar->codec_id =
3080 else if (st->codecpar->bits_per_coded_sample == 32)
3081 st->codecpar->codec_id =
3084 break;
3085 /* set values for old format before stsd version 1 appeared */
3086 case AV_CODEC_ID_MACE3:
3087 sc->samples_per_frame = 6;
3089 break;
3090 case AV_CODEC_ID_MACE6:
3091 sc->samples_per_frame = 6;
3093 break;
3095 sc->samples_per_frame = 64;
3097 break;
3098 case AV_CODEC_ID_GSM:
3099 sc->samples_per_frame = 160;
3100 sc->bytes_per_frame = 33;
3101 break;
3102 default:
3103 break;
3104 }
3105
3106 bits_per_sample = av_get_bits_per_sample(st->codecpar->codec_id);
3107 if (bits_per_sample && (bits_per_sample >> 3) * (uint64_t)st->codecpar->ch_layout.nb_channels <= INT_MAX) {
3108 st->codecpar->bits_per_coded_sample = bits_per_sample;
3109 sc->sample_size = (bits_per_sample >> 3) * st->codecpar->ch_layout.nb_channels;
3110 }
3111}
3112
3114 AVStream *st, MOVStreamContext *sc,
3115 int64_t size)
3116{
3117 // ttxt stsd contains display flags, justification, background
3118 // color, fonts, and default styles, so fake an atom to read it
3119 MOVAtom fake_atom = { .size = size };
3120 // mp4s contains a regular esds atom, dfxp ISMV TTML has no content
3121 // in extradata unlike stpp MP4 TTML.
3122 if (st->codecpar->codec_tag != AV_RL32("mp4s") &&
3124 mov_read_glbl(c, pb, fake_atom);
3125 st->codecpar->width = sc->width;
3126 st->codecpar->height = sc->height;
3127}
3128
3130 AVStream *st, MOVStreamContext *sc,
3131 int64_t size)
3132{
3133 int ret;
3134
3135 if (st->codecpar->codec_tag == MKTAG('t','m','c','d')) {
3136 if ((int)size != size)
3137 return AVERROR(ENOMEM);
3138
3139 ret = ff_get_extradata(c->fc, st->codecpar, pb, size);
3140 if (ret < 0)
3141 return ret;
3142 if (size > 16) {
3143 MOVStreamContext *tmcd_ctx = st->priv_data;
3144 int val;
3145 val = AV_RB32(st->codecpar->extradata + 4);
3146 tmcd_ctx->tmcd_flags = val;
3147 st->avg_frame_rate.num = AV_RB32(st->codecpar->extradata + 8); /* timescale */
3148 st->avg_frame_rate.den = AV_RB32(st->codecpar->extradata + 12); /* frameDuration */
3149 tmcd_ctx->tmcd_nb_frames = st->codecpar->extradata[16]; /* number of frames */
3150 if (size > 30) {
3151 uint32_t len = AV_RB32(st->codecpar->extradata + 18); /* name atom length */
3152 uint32_t format = AV_RB32(st->codecpar->extradata + 22);
3153 if (format == AV_RB32("name") && (int64_t)size >= (int64_t)len + 18) {
3154 uint16_t str_size = AV_RB16(st->codecpar->extradata + 26); /* string length */
3155 if (str_size > 0 && size >= (int)str_size + 30 &&
3156 st->codecpar->extradata[30] /* Don't add empty string */) {
3157 char *reel_name = av_malloc(str_size + 1);
3158 if (!reel_name)
3159 return AVERROR(ENOMEM);
3160 memcpy(reel_name, st->codecpar->extradata + 30, str_size);
3161 reel_name[str_size] = 0; /* Add null terminator */
3162 av_dict_set(&st->metadata, "reel_name", reel_name,
3164 }
3165 }
3166 }
3167 }
3168 } else if (st->codecpar->codec_id == AV_CODEC_ID_ITUT_T35) {
3169 int t35_identifier_length = avio_r8(pb);
3170
3171 if (t35_identifier_length <= 0 || t35_identifier_length >= size)
3172 return AVERROR_INVALIDDATA;
3173
3174 ret = ff_get_extradata(c->fc, st->codecpar, pb, t35_identifier_length);
3175 if (ret < 0)
3176 return ret;
3177
3178 int hrsd_len = size - t35_identifier_length - 1;
3179 if (hrsd_len > 0) {
3180 uint8_t *hrsd_str = av_malloc(hrsd_len + 1);
3181 if (!hrsd_str)
3182 return AVERROR(ENOMEM);
3183
3184 ret = ffio_read_size(pb, hrsd_str, hrsd_len);
3185 if (ret < 0) {
3186 av_free(hrsd_str);
3187 return ret;
3188 }
3189 if (hrsd_str[0]) {
3190 hrsd_str[hrsd_len] = 0;
3191 ret = av_dict_set(&st->metadata, "description", hrsd_str, AV_DICT_DONT_OVERWRITE);
3192 }
3193 av_free(hrsd_str);
3194 }
3195 } else {
3196 /* other codec type, just skip (rtp, mp4s ...) */
3197 avio_skip(pb, size);
3198 }
3199 return 0;
3200}
3201
3203 AVStream *st, MOVStreamContext *sc)
3204{
3205 FFStream *const sti = ffstream(st);
3206
3208 !st->codecpar->sample_rate && sc->time_scale > 1)
3209 st->codecpar->sample_rate = sc->time_scale;
3210
3211 /* special codec parameters handling */
3212 switch (st->codecpar->codec_id) {
3213#if CONFIG_DV_DEMUXER
3215 if (c->dv_fctx) {
3216 avpriv_request_sample(c->fc, "multiple DV audio streams");
3217 return AVERROR(ENOSYS);
3218 }
3219
3220 c->dv_fctx = avformat_alloc_context();
3221 if (!c->dv_fctx) {
3222 av_log(c->fc, AV_LOG_ERROR, "dv demux context alloc error\n");
3223 return AVERROR(ENOMEM);
3224 }
3225 c->dv_demux = avpriv_dv_init_demux(c->dv_fctx);
3226 if (!c->dv_demux) {
3227 av_log(c->fc, AV_LOG_ERROR, "dv demux context init error\n");
3228 return AVERROR(ENOMEM);
3229 }
3230 sc->dv_audio_container = 1;
3232 break;
3233#endif
3234 /* no ifdef since parameters are always those */
3235 case AV_CODEC_ID_QCELP:
3238 // force sample rate for qcelp when not stored in mov
3239 if (st->codecpar->codec_tag != MKTAG('Q','c','l','p'))
3240 st->codecpar->sample_rate = 8000;
3241 // FIXME: Why is the following needed for some files?
3242 sc->samples_per_frame = 160;
3243 if (!sc->bytes_per_frame)
3244 sc->bytes_per_frame = 35;
3245 break;
3246 case AV_CODEC_ID_AMR_NB:
3249 /* force sample rate for amr, stsd in 3gp does not store sample rate */
3250 st->codecpar->sample_rate = 8000;
3251 break;
3252 case AV_CODEC_ID_AMR_WB:
3255 st->codecpar->sample_rate = 16000;
3256 break;
3257 case AV_CODEC_ID_MP2:
3258 case AV_CODEC_ID_MP3:
3259 /* force type after stsd for m1a hdlr */
3261 break;
3262 case AV_CODEC_ID_GSM:
3265 case AV_CODEC_ID_ILBC:
3266 case AV_CODEC_ID_MACE3:
3267 case AV_CODEC_ID_MACE6:
3268 case AV_CODEC_ID_QDM2:
3270 break;
3271 case AV_CODEC_ID_ALAC:
3272 if (st->codecpar->extradata_size == 36) {
3273 int channel_count = AV_RB8(st->codecpar->extradata + 21);
3274 if (st->codecpar->ch_layout.nb_channels != channel_count) {
3277 st->codecpar->ch_layout.nb_channels = channel_count;
3278 }
3279 st->codecpar->sample_rate = AV_RB32(st->codecpar->extradata + 32);
3280 }
3281 break;
3282 case AV_CODEC_ID_AC3:
3283 case AV_CODEC_ID_EAC3:
3285 case AV_CODEC_ID_VC1:
3286 case AV_CODEC_ID_VP8:
3287 case AV_CODEC_ID_VP9:
3289 break;
3291 case AV_CODEC_ID_PRORES:
3292 case AV_CODEC_ID_APV:
3293 case AV_CODEC_ID_EVC:
3294 case AV_CODEC_ID_LCEVC:
3295 case AV_CODEC_ID_AV1:
3296 /* field_order detection of H264 requires parsing */
3297 case AV_CODEC_ID_H264:
3299 break;
3300 default:
3301 break;
3302 }
3303 return 0;
3304}
3305
3307 int codec_tag, int format,
3308 int64_t size)
3309{
3310 if (codec_tag &&
3311 (codec_tag != format &&
3312 // AVID 1:1 samples with differing data format and codec tag exist
3313 (codec_tag != AV_RL32("AV1x") || format != AV_RL32("AVup")) &&
3314 // prores is allowed to have differing data format and codec tag
3315 codec_tag != AV_RL32("apcn") && codec_tag != AV_RL32("apch") &&
3316 // so is dv (sigh)
3317 codec_tag != AV_RL32("dvpp") && codec_tag != AV_RL32("dvcp") &&
3318 (c->fc->video_codec_id ? ff_codec_get_id(ff_codec_movvideo_tags, format) != c->fc->video_codec_id
3319 : codec_tag != MKTAG('j','p','e','g')))) {
3320 /* Multiple fourcc, we skip JPEG. This is not correct, we should
3321 * export it as a separate AVStream but this needs a few changes
3322 * in the MOV demuxer, patch welcome. */
3323
3324 av_log(c->fc, AV_LOG_WARNING, "multiple fourcc not supported\n");
3325 avio_skip(pb, size);
3326 return 1;
3327 }
3328
3329 return 0;
3330}
3331
3333{
3334 int ret;
3335
3336 /* special codec parameters handling */
3337 switch (st->codecpar->codec_id) {
3338 case AV_CODEC_ID_H264:
3339 // done for ai5q, ai52, ai55, ai1q, ai12 and ai15.
3342 if (ret < 0)
3343 return ret;
3344 }
3345 break;
3346 default:
3347 break;
3348 }
3349
3350 return 0;
3351}
3352
3354{
3355 AVStream *st;
3356 MOVStreamContext *sc;
3357 int pseudo_stream_id;
3358
3359 av_assert0 (c->fc->nb_streams >= 1);
3360 st = c->fc->streams[c->fc->nb_streams-1];
3361 sc = st->priv_data;
3362
3363 for (pseudo_stream_id = 0;
3364 pseudo_stream_id < entries && !pb->eof_reached;
3365 pseudo_stream_id++) {
3366 //Parsing Sample description table
3367 enum AVCodecID id;
3368 int ret, dref_id = 1;
3369 MOVAtom a = { AV_RL32("stsd") };
3370 int64_t start_pos = avio_tell(pb);
3371 int64_t size = avio_rb32(pb); /* size */
3372 uint32_t format = avio_rl32(pb); /* data format */
3373
3374 if (size >= 16) {
3375 avio_rb32(pb); /* reserved */
3376 avio_rb16(pb); /* reserved */
3377 dref_id = avio_rb16(pb);
3378 } else if (size <= 7) {
3379 av_log(c->fc, AV_LOG_ERROR,
3380 "invalid size %"PRId64" in stsd\n", size);
3381 return AVERROR_INVALIDDATA;
3382 }
3383
3385 size - (avio_tell(pb) - start_pos))) {
3386 sc->stsd_count++;
3387 continue;
3388 }
3389
3390 sc->pseudo_stream_id = st->codecpar->codec_tag ? -1 : pseudo_stream_id;
3391 sc->dref_id= dref_id;
3392 sc->format = format;
3393
3394 id = mov_codec_id(st, format);
3395
3396 av_log(c->fc, AV_LOG_TRACE,
3397 "size=%"PRId64" 4CC=%s codec_type=%d\n", size,
3399
3400 st->codecpar->codec_id = id;
3402 mov_parse_stsd_video(c, pb, st, sc);
3403 } else if (st->codecpar->codec_type==AVMEDIA_TYPE_AUDIO) {
3404 mov_parse_stsd_audio(c, pb, st, sc);
3405 if (st->codecpar->sample_rate < 0) {
3406 av_log(c->fc, AV_LOG_ERROR, "Invalid sample rate %d\n", st->codecpar->sample_rate);
3407 return AVERROR_INVALIDDATA;
3408 }
3409 if (st->codecpar->ch_layout.nb_channels < 0) {
3410 av_log(c->fc, AV_LOG_ERROR, "Invalid channels %d\n", st->codecpar->ch_layout.nb_channels);
3411 return AVERROR_INVALIDDATA;
3412 }
3413 } else if (st->codecpar->codec_type==AVMEDIA_TYPE_SUBTITLE){
3414 mov_parse_stsd_subtitle(c, pb, st, sc,
3415 size - (avio_tell(pb) - start_pos));
3416 } else {
3417 ret = mov_parse_stsd_data(c, pb, st, sc,
3418 size - (avio_tell(pb) - start_pos));
3419 if (ret < 0)
3420 return ret;
3421 }
3422 /* this will read extra atoms at the end (wave, alac, damr, avcC, hvcC, SMI ...) */
3423 a.size = size - (avio_tell(pb) - start_pos);
3424 if (a.size > 8) {
3425 if ((ret = mov_read_default(c, pb, a)) < 0)
3426 return ret;
3427 } else if (a.size > 0)
3428 avio_skip(pb, a.size);
3429
3430 ret = mov_finalize_stsd_entry(c, st);
3431 if (ret < 0)
3432 return ret;
3433
3434 if (sc->extradata && st->codecpar->extradata) {
3435 int extra_size = st->codecpar->extradata_size;
3436
3437 /* Move the current stream extradata to the stream context one. */
3438 sc->extradata_size[pseudo_stream_id] = extra_size;
3439 sc->extradata[pseudo_stream_id] = st->codecpar->extradata;
3440 st->codecpar->extradata = NULL;
3441 st->codecpar->extradata_size = 0;
3442 }
3443 sc->stsd_count++;
3444 }
3445
3446 if (pb->eof_reached) {
3447 av_log(c->fc, AV_LOG_WARNING, "reached eof, corrupted STSD atom\n");
3448 return AVERROR_EOF;
3449 }
3450
3451 return 0;
3452}
3453
3455{
3456 AVStream *st;
3457 MOVStreamContext *sc;
3458 int ret, entries;
3459
3460 if (c->fc->nb_streams < 1)
3461 return 0;
3462 st = c->fc->streams[c->fc->nb_streams - 1];
3463 sc = st->priv_data;
3464
3465 if (sc->extradata) {
3466 av_log(c->fc, AV_LOG_ERROR,
3467 "Duplicate stsd found in this track.\n");
3468 return AVERROR_INVALIDDATA;
3469 }
3470
3471 sc->stsd_version = avio_r8(pb);
3472 avio_rb24(pb); /* flags */
3473 entries = avio_rb32(pb);
3474
3475 /* Each entry contains a size (4 bytes) and format (4 bytes). */
3476 if (entries <= 0 || entries > atom.size / 8 || entries > 1024) {
3477 av_log(c->fc, AV_LOG_ERROR, "invalid STSD entries %d\n", entries);
3478 return AVERROR_INVALIDDATA;
3479 }
3480
3481 /* Prepare space for hosting multiple extradata. */
3482 sc->extradata = av_calloc(entries, sizeof(*sc->extradata));
3483 if (!sc->extradata)
3484 return AVERROR(ENOMEM);
3485
3486 sc->extradata_size = av_calloc(entries, sizeof(*sc->extradata_size));
3487 if (!sc->extradata_size) {
3488 ret = AVERROR(ENOMEM);
3489 goto fail;
3490 }
3491
3492 ret = ff_mov_read_stsd_entries(c, pb, entries);
3493 if (ret < 0)
3494 goto fail;
3495
3496 /* Restore back the primary extradata. */
3499 if (sc->extradata_size[0]) {
3501 if (!st->codecpar->extradata)
3502 return AVERROR(ENOMEM);
3503 memcpy(st->codecpar->extradata, sc->extradata[0], sc->extradata_size[0]);
3504 }
3505
3506 return mov_finalize_stsd_codec(c, pb, st, sc);
3507fail:
3508 if (sc->extradata) {
3509 int j;
3510 for (j = 0; j < sc->stsd_count; j++)
3511 av_freep(&sc->extradata[j]);
3512 }
3513
3514 sc->stsd_count = 0;
3515 av_freep(&sc->extradata);
3517 return ret;
3518}
3519
3521{
3522 AVStream *st;
3523 MOVStreamContext *sc;
3524 unsigned int i, entries;
3525
3526 if (c->trak_index < 0) {
3527 av_log(c->fc, AV_LOG_WARNING, "STSC outside TRAK\n");
3528 return 0;
3529 }
3530
3531 if (c->fc->nb_streams < 1)
3532 return 0;
3533 st = c->fc->streams[c->fc->nb_streams-1];
3534 sc = st->priv_data;
3535
3536 avio_r8(pb); /* version */
3537 avio_rb24(pb); /* flags */
3538
3539 entries = avio_rb32(pb);
3540 if ((uint64_t)entries * 12 + 4 > atom.size)
3541 return AVERROR_INVALIDDATA;
3542
3543 av_log(c->fc, AV_LOG_TRACE, "track[%u].stsc.entries = %u\n", c->fc->nb_streams - 1, entries);
3544
3545 if (!entries)
3546 return 0;
3547 if (sc->stsc_data) {
3548 av_log(c->fc, AV_LOG_WARNING, "Ignoring duplicated STSC atom\n");
3549 return 0;
3550 }
3551 av_free(sc->stsc_data);
3552 sc->stsc_count = 0;
3553 sc->stsc_data = av_malloc_array(entries, sizeof(*sc->stsc_data));
3554 if (!sc->stsc_data)
3555 return AVERROR(ENOMEM);
3556
3557 for (i = 0; i < entries && !pb->eof_reached; i++) {
3558 sc->stsc_data[i].first = avio_rb32(pb);
3559 sc->stsc_data[i].count = avio_rb32(pb);
3560 sc->stsc_data[i].id = avio_rb32(pb);
3561 }
3562
3563 sc->stsc_count = i;
3564 for (i = sc->stsc_count - 1; i < UINT_MAX; i--) {
3565 int64_t first_min = i + 1;
3566 if ((i+1 < sc->stsc_count && sc->stsc_data[i].first >= sc->stsc_data[i+1].first) ||
3567 (i > 0 && sc->stsc_data[i].first <= sc->stsc_data[i-1].first) ||
3568 sc->stsc_data[i].first < first_min ||
3569 sc->stsc_data[i].count < 1 ||
3570 sc->stsc_data[i].id < 1) {
3571 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);
3572 if (i+1 >= sc->stsc_count) {
3573 if (sc->stsc_data[i].count == 0 && i > 0) {
3574 sc->stsc_count --;
3575 continue;
3576 }
3577 sc->stsc_data[i].first = FFMAX(sc->stsc_data[i].first, first_min);
3578 if (i > 0 && sc->stsc_data[i].first <= sc->stsc_data[i-1].first)
3579 sc->stsc_data[i].first = FFMIN(sc->stsc_data[i-1].first + 1LL, INT_MAX);
3580 sc->stsc_data[i].count = FFMAX(sc->stsc_data[i].count, 1);
3581 sc->stsc_data[i].id = FFMAX(sc->stsc_data[i].id, 1);
3582 continue;
3583 }
3584 av_assert0(sc->stsc_data[i+1].first >= 2);
3585 // We replace this entry by the next valid
3586 sc->stsc_data[i].first = sc->stsc_data[i+1].first - 1;
3587 sc->stsc_data[i].count = sc->stsc_data[i+1].count;
3588 sc->stsc_data[i].id = sc->stsc_data[i+1].id;
3589 }
3590 }
3591
3592 if (pb->eof_reached) {
3593 av_log(c->fc, AV_LOG_WARNING, "reached eof, corrupted STSC atom\n");
3594 return AVERROR_EOF;
3595 }
3596
3597 return 0;
3598}
3599
3600static inline int mov_stsc_index_valid(unsigned int index, unsigned int count)
3601{
3602 return index < count - 1;
3603}
3604
3605/* Compute the samples value for the stsc entry at the given index. */
3606static inline int64_t mov_get_stsc_samples(MOVStreamContext *sc, unsigned int index)
3607{
3608 int chunk_count;
3609
3611 chunk_count = sc->stsc_data[index + 1].first - sc->stsc_data[index].first;
3612 else {
3613 // Validation for stsc / stco happens earlier in mov_read_stsc + mov_read_trak.
3615 chunk_count = sc->chunk_count - (sc->stsc_data[index].first - 1);
3616 }
3617
3618 return sc->stsc_data[index].count * (int64_t)chunk_count;
3619}
3620
3622{
3623 AVStream *st;
3624 MOVStreamContext *sc;
3625 unsigned i, entries;
3626
3627 if (c->trak_index < 0) {
3628 av_log(c->fc, AV_LOG_WARNING, "STPS outside TRAK\n");
3629 return 0;
3630 }
3631
3632 if (c->fc->nb_streams < 1)
3633 return 0;
3634 st = c->fc->streams[c->fc->nb_streams-1];
3635 sc = st->priv_data;
3636
3637 avio_rb32(pb); // version + flags
3638
3639 entries = avio_rb32(pb);
3640 if (sc->stps_data)
3641 av_log(c->fc, AV_LOG_WARNING, "Duplicated STPS atom\n");
3642 av_free(sc->stps_data);
3643 sc->stps_count = 0;
3644 sc->stps_data = av_malloc_array(entries, sizeof(*sc->stps_data));
3645 if (!sc->stps_data)
3646 return AVERROR(ENOMEM);
3647
3648 for (i = 0; i < entries && !pb->eof_reached; i++) {
3649 sc->stps_data[i] = avio_rb32(pb);
3650 }
3651
3652 sc->stps_count = i;
3653
3654 if (pb->eof_reached) {
3655 av_log(c->fc, AV_LOG_WARNING, "reached eof, corrupted STPS atom\n");
3656 return AVERROR_EOF;
3657 }
3658
3659 return 0;
3660}
3661
3663{
3664 AVStream *st;
3665 FFStream *sti;
3666 MOVStreamContext *sc;
3667 unsigned int i, entries;
3668
3669 if (c->trak_index < 0) {
3670 av_log(c->fc, AV_LOG_WARNING, "STSS outside TRAK\n");
3671 return 0;
3672 }
3673
3674 if (c->fc->nb_streams < 1)
3675 return 0;
3676 st = c->fc->streams[c->fc->nb_streams-1];
3677 sti = ffstream(st);
3678 sc = st->priv_data;
3679
3680 avio_r8(pb); /* version */
3681 avio_rb24(pb); /* flags */
3682
3683 entries = avio_rb32(pb);
3684
3685 av_log(c->fc, AV_LOG_TRACE, "keyframe_count = %u\n", entries);
3686
3687 if (!entries) {
3688 sc->keyframe_absent = 1;
3691 return 0;
3692 }
3693 if (sc->keyframes)
3694 av_log(c->fc, AV_LOG_WARNING, "Duplicated STSS atom\n");
3695 if (entries >= UINT_MAX / sizeof(int))
3696 return AVERROR_INVALIDDATA;
3697 av_freep(&sc->keyframes);
3698 sc->keyframe_count = 0;
3699 sc->keyframes = av_malloc_array(entries, sizeof(*sc->keyframes));
3700 if (!sc->keyframes)
3701 return AVERROR(ENOMEM);
3702
3703 for (i = 0; i < entries && !pb->eof_reached; i++) {
3704 sc->keyframes[i] = avio_rb32(pb);
3705 }
3706
3707 sc->keyframe_count = i;
3708
3709 if (pb->eof_reached) {
3710 av_log(c->fc, AV_LOG_WARNING, "reached eof, corrupted STSS atom\n");
3711 return AVERROR_EOF;
3712 }
3713
3714 return 0;
3715}
3716
3718{
3719 AVStream *st;
3720 MOVStreamContext *sc;
3721 unsigned int i, entries, sample_size, field_size, num_bytes;
3722 GetBitContext gb;
3723 unsigned char* buf;
3724 int ret;
3725
3726 if (c->trak_index < 0) {
3727 av_log(c->fc, AV_LOG_WARNING, "STSZ outside TRAK\n");
3728 return 0;
3729 }
3730
3731 if (c->fc->nb_streams < 1)
3732 return 0;
3733 st = c->fc->streams[c->fc->nb_streams-1];
3734 sc = st->priv_data;
3735
3736 avio_r8(pb); /* version */
3737 avio_rb24(pb); /* flags */
3738
3739 if (atom.type == MKTAG('s','t','s','z')) {
3740 sample_size = avio_rb32(pb);
3741 if (!sc->sample_size) /* do not overwrite value computed in stsd */
3742 sc->sample_size = sample_size;
3743 sc->stsz_sample_size = sample_size;
3744 field_size = 32;
3745 } else {
3746 sample_size = 0;
3747 avio_rb24(pb); /* reserved */
3748 field_size = avio_r8(pb);
3749 }
3750 entries = avio_rb32(pb);
3751
3752 av_log(c->fc, AV_LOG_TRACE, "sample_size = %u sample_count = %u\n", sc->sample_size, entries);
3753
3754 sc->sample_count = entries;
3755 if (sample_size)
3756 return 0;
3757
3758 if (field_size != 4 && field_size != 8 && field_size != 16 && field_size != 32) {
3759 av_log(c->fc, AV_LOG_ERROR, "Invalid sample field size %u\n", field_size);
3760 return AVERROR_INVALIDDATA;
3761 }
3762
3763 if (!entries)
3764 return 0;
3765 if (entries >= (INT_MAX - 4 - 8 * AV_INPUT_BUFFER_PADDING_SIZE) / field_size)
3766 return AVERROR_INVALIDDATA;
3767 if (sc->sample_sizes)
3768 av_log(c->fc, AV_LOG_WARNING, "Duplicated STSZ atom\n");
3769 av_free(sc->sample_sizes);
3770 sc->sample_count = 0;
3771 sc->sample_sizes = av_malloc_array(entries, sizeof(*sc->sample_sizes));
3772 if (!sc->sample_sizes)
3773 return AVERROR(ENOMEM);
3774
3775 num_bytes = (entries*field_size+4)>>3;
3776
3777 buf = av_malloc(num_bytes+AV_INPUT_BUFFER_PADDING_SIZE);
3778 if (!buf) {
3779 av_freep(&sc->sample_sizes);
3780 return AVERROR(ENOMEM);
3781 }
3782
3783 ret = ffio_read_size(pb, buf, num_bytes);
3784 if (ret < 0) {
3785 av_freep(&sc->sample_sizes);
3786 av_free(buf);
3787 av_log(c->fc, AV_LOG_WARNING, "STSZ atom truncated\n");
3788 return 0;
3789 }
3790
3791 init_get_bits(&gb, buf, 8*num_bytes);
3792
3793 for (i = 0; i < entries; i++) {
3794 sc->sample_sizes[i] = get_bits_long(&gb, field_size);
3795 if (sc->sample_sizes[i] > INT64_MAX - sc->data_size) {
3796 av_free(buf);
3797 av_log(c->fc, AV_LOG_ERROR, "Sample size overflow in STSZ\n");
3798 return AVERROR_INVALIDDATA;
3799 }
3800 sc->data_size += sc->sample_sizes[i];
3801 }
3802
3803 sc->sample_count = i;
3804
3805 av_free(buf);
3806
3807 return 0;
3808}
3809
3811{
3812 AVStream *st;
3813 MOVStreamContext *sc;
3814 unsigned int i, entries;
3815 int64_t duration = 0;
3816 int64_t total_sample_count = 0;
3817 int64_t current_dts = 0;
3818 int64_t corrected_dts = 0;
3819
3820 if (c->trak_index < 0) {
3821 av_log(c->fc, AV_LOG_WARNING, "STTS outside TRAK\n");
3822 return 0;
3823 }
3824
3825 if (c->fc->nb_streams < 1)
3826 return 0;
3827 st = c->fc->streams[c->fc->nb_streams-1];
3828 sc = st->priv_data;
3829
3830 avio_r8(pb); /* version */
3831 avio_rb24(pb); /* flags */
3832 entries = avio_rb32(pb);
3833
3834 av_log(c->fc, AV_LOG_TRACE, "track[%u].stts.entries = %u\n",
3835 c->fc->nb_streams-1, entries);
3836
3837 if (sc->stts_data)
3838 av_log(c->fc, AV_LOG_WARNING, "Duplicated STTS atom\n");
3839 av_freep(&sc->stts_data);
3840 sc->stts_count = 0;
3841 if (entries >= INT_MAX / sizeof(*sc->stts_data))
3842 return AVERROR(ENOMEM);
3843
3844 for (i = 0; i < entries && !pb->eof_reached; i++) {
3845 unsigned int sample_duration;
3846 unsigned int sample_count;
3847 unsigned int min_entries = FFMIN(FFMAX(i + 1, 1024 * 1024), entries);
3849 min_entries * sizeof(*sc->stts_data));
3850 if (!stts_data) {
3851 av_freep(&sc->stts_data);
3852 sc->stts_count = 0;
3853 return AVERROR(ENOMEM);
3854 }
3855 sc->stts_count = min_entries;
3856 sc->stts_data = stts_data;
3857
3858 sample_count = avio_rb32(pb);
3859 sample_duration = avio_rb32(pb);
3860
3861 sc->stts_data[i].count= sample_count;
3862 sc->stts_data[i].duration= sample_duration;
3863
3864 av_log(c->fc, AV_LOG_TRACE, "sample_count=%u, sample_duration=%u\n",
3865 sample_count, sample_duration);
3866
3867 /* STTS sample offsets are uint32 but some files store it as int32
3868 * with negative values used to correct DTS delays.
3869 There may be abnormally large values as well. */
3870 if (sample_duration > c->max_stts_delta) {
3871 // assume high delta is a correction if negative when cast as int32
3872 int32_t delta_magnitude = (int32_t)sample_duration;
3873 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",
3874 sample_duration, i, sample_count, st->index);
3875 sc->stts_data[i].duration = 1;
3876 corrected_dts = av_sat_add64(corrected_dts, (delta_magnitude < 0 ? (int64_t)delta_magnitude : 1) * sample_count);
3877 } else {
3878 corrected_dts += sample_duration * (uint64_t)sample_count;
3879 }
3880
3881 current_dts += sc->stts_data[i].duration * (uint64_t)sample_count;
3882
3883 if (current_dts > corrected_dts) {
3884 int64_t drift = av_sat_sub64(current_dts, corrected_dts) / FFMAX(sample_count, 1);
3885 uint32_t correction = (sc->stts_data[i].duration > drift) ? drift : sc->stts_data[i].duration - 1;
3886 current_dts -= correction * (uint64_t)sample_count;
3887 sc->stts_data[i].duration -= correction;
3888 }
3889
3890 duration+=(int64_t)sc->stts_data[i].duration*(uint64_t)sc->stts_data[i].count;
3891 total_sample_count+=sc->stts_data[i].count;
3892 }
3893
3894 sc->stts_count = i;
3895
3896 if (duration > 0 &&
3897 duration <= INT64_MAX - sc->duration_for_fps &&
3898 total_sample_count <= INT_MAX - sc->nb_frames_for_fps) {
3900 sc->nb_frames_for_fps += total_sample_count;
3901 }
3902
3903 if (pb->eof_reached) {
3904 av_log(c->fc, AV_LOG_WARNING, "reached eof, corrupted STTS atom\n");
3905 return AVERROR_EOF;
3906 }
3907
3908 st->nb_frames= total_sample_count;
3909 if (duration)
3910 st->duration= FFMIN(st->duration, duration);
3911
3912 // All samples have zero duration. They have higher chance be chose by
3913 // mov_find_next_sample, which leads to seek again and again.
3914 //
3915 // It's AVERROR_INVALIDDATA actually, but such files exist in the wild.
3916 // So only mark data stream as discarded for safety.
3917 if (!duration && sc->stts_count &&
3919 av_log(c->fc, AV_LOG_WARNING,
3920 "All samples in data stream index:id [%d:%d] have zero "
3921 "duration, stream set to be discarded by default. Override "
3922 "using AVStream->discard or -discard for ffmpeg command.\n",
3923 st->index, sc->id);
3924 st->discard = AVDISCARD_ALL;
3925 }
3926 sc->track_end = duration;
3927 return 0;
3928}
3929
3931{
3932 AVStream *st;
3933 MOVStreamContext *sc;
3934 unsigned int i;
3935 int64_t entries;
3936
3937 if (c->fc->nb_streams < 1)
3938 return 0;
3939 st = c->fc->streams[c->fc->nb_streams - 1];
3940 sc = st->priv_data;
3941
3942 avio_r8(pb); /* version */
3943 avio_rb24(pb); /* flags */
3944 entries = atom.size - 4;
3945
3946 av_log(c->fc, AV_LOG_TRACE, "track[%u].sdtp.entries = %" PRId64 "\n",
3947 c->fc->nb_streams - 1, entries);
3948
3949 if (sc->sdtp_data)
3950 av_log(c->fc, AV_LOG_WARNING, "Duplicated SDTP atom\n");
3951 av_freep(&sc->sdtp_data);
3952 sc->sdtp_count = 0;
3953
3954 if (entries < 0 || entries > UINT_MAX)
3955 return AVERROR(ERANGE);
3956
3957 sc->sdtp_data = av_malloc(entries);
3958 if (!sc->sdtp_data)
3959 return AVERROR(ENOMEM);
3960
3961 for (i = 0; i < entries && !pb->eof_reached; i++)
3962 sc->sdtp_data[i] = avio_r8(pb);
3963 sc->sdtp_count = i;
3964
3965 return 0;
3966}
3967
3968static void mov_update_dts_shift(MOVStreamContext *sc, int duration, void *logctx)
3969{
3970 if (duration < 0) {
3971 if (duration == INT_MIN) {
3972 av_log(logctx, AV_LOG_WARNING, "mov_update_dts_shift(): dts_shift set to %d\n", INT_MAX);
3973 duration++;
3974 }
3975 sc->dts_shift = FFMAX(sc->dts_shift, -duration);
3976 }
3977}
3978
3980{
3981 AVStream *st;
3982 MOVStreamContext *sc;
3983 unsigned int i, entries, ctts_count = 0;
3984
3985 if (c->trak_index < 0) {
3986 av_log(c->fc, AV_LOG_WARNING, "CTTS outside TRAK\n");
3987 return 0;
3988 }
3989
3990 if (c->fc->nb_streams < 1)
3991 return 0;
3992 st = c->fc->streams[c->fc->nb_streams-1];
3993 sc = st->priv_data;
3994
3995 avio_r8(pb); /* version */
3996 avio_rb24(pb); /* flags */
3997 entries = avio_rb32(pb);
3998
3999 av_log(c->fc, AV_LOG_TRACE, "track[%u].ctts.entries = %u\n", c->fc->nb_streams - 1, entries);
4000
4001 if (!entries)
4002 return 0;
4003 if (entries >= UINT_MAX / sizeof(*sc->ctts_data))
4004 return AVERROR_INVALIDDATA;
4005 av_freep(&sc->ctts_data);
4006 sc->ctts_data = av_fast_realloc(NULL, &sc->ctts_allocated_size, entries * sizeof(*sc->ctts_data));
4007 if (!sc->ctts_data)
4008 return AVERROR(ENOMEM);
4009
4010 for (i = 0; i < entries && !pb->eof_reached; i++) {
4011 MOVCtts *ctts_data;
4012 const size_t min_size_needed = (ctts_count + 1) * sizeof(MOVCtts);
4013 const size_t requested_size =
4014 min_size_needed > sc->ctts_allocated_size ?
4015 FFMAX(min_size_needed, 2 * sc->ctts_allocated_size) :
4016 min_size_needed;
4017 int count = avio_rb32(pb);
4018 int duration = avio_rb32(pb);
4019
4020 if (count <= 0) {
4021 av_log(c->fc, AV_LOG_TRACE,
4022 "ignoring CTTS entry with count=%d duration=%d\n",
4023 count, duration);
4024 continue;
4025 }
4026
4027 if (ctts_count >= UINT_MAX / sizeof(MOVCtts) - 1)
4028 return AVERROR(ENOMEM);
4029
4030 ctts_data = av_fast_realloc(sc->ctts_data, &sc->ctts_allocated_size, requested_size);
4031
4032 if (!ctts_data)
4033 return AVERROR(ENOMEM);
4034
4035 sc->ctts_data = ctts_data;
4036
4037 ctts_data[ctts_count].count = count;
4038 ctts_data[ctts_count].offset = duration;
4039 ctts_count++;
4040
4041 av_log(c->fc, AV_LOG_TRACE, "count=%d, duration=%d\n",
4042 count, duration);
4043
4044 if (i+2<entries)
4046 }
4047
4048 sc->ctts_count = ctts_count;
4049
4050 if (pb->eof_reached) {
4051 av_log(c->fc, AV_LOG_WARNING, "reached eof, corrupted CTTS atom\n");
4052 return AVERROR_EOF;
4053 }
4054
4055 av_log(c->fc, AV_LOG_TRACE, "dts shift %d\n", sc->dts_shift);
4056
4057 return 0;
4058}
4059
4061{
4062 AVStream *st;
4063 MOVStreamContext *sc;
4064 uint8_t version;
4065 uint32_t grouping_type;
4066 uint32_t default_length;
4067 av_unused uint32_t default_group_description_index;
4068 uint32_t entry_count;
4069
4070 if (c->fc->nb_streams < 1)
4071 return 0;
4072 st = c->fc->streams[c->fc->nb_streams - 1];
4073 sc = st->priv_data;
4074
4075 version = avio_r8(pb); /* version */
4076 avio_rb24(pb); /* flags */
4077 grouping_type = avio_rl32(pb);
4078
4079 /*
4080 * This function only supports "sync" boxes, but the code is able to parse
4081 * other boxes (such as "tscl", "tsas" and "stsa")
4082 */
4083 if (grouping_type != MKTAG('s','y','n','c'))
4084 return 0;
4085
4086 default_length = version >= 1 ? avio_rb32(pb) : 0;
4087 default_group_description_index = version >= 2 ? avio_rb32(pb) : 0;
4088 entry_count = avio_rb32(pb);
4089
4090 if (entry_count > atom.size)
4091 return AVERROR_INVALIDDATA;
4092
4093 av_freep(&sc->sgpd_sync);
4094 sc->sgpd_sync_count = entry_count;
4095 sc->sgpd_sync = av_calloc(entry_count, sizeof(*sc->sgpd_sync));
4096 if (!sc->sgpd_sync)
4097 return AVERROR(ENOMEM);
4098
4099 for (uint32_t i = 0; i < entry_count && !pb->eof_reached; i++) {
4100 uint32_t description_length = default_length;
4101 if (version >= 1 && default_length == 0)
4102 description_length = avio_rb32(pb);
4103 if (grouping_type == MKTAG('s','y','n','c')) {
4104 const uint8_t nal_unit_type = avio_r8(pb) & 0x3f;
4105 sc->sgpd_sync[i] = nal_unit_type;
4106 description_length -= 1;
4107 }
4108 avio_skip(pb, description_length);
4109 }
4110
4111 if (pb->eof_reached) {
4112 av_log(c->fc, AV_LOG_WARNING, "reached eof, corrupted SGPD atom\n");
4113 return AVERROR_EOF;
4114 }
4115
4116 return 0;
4117}
4118
4120{
4121 AVStream *st;
4122 MOVStreamContext *sc;
4123 unsigned int i, entries;
4124 uint8_t version;
4125 uint32_t grouping_type;
4126 MOVSbgp *table, **tablep;
4127 int *table_count;
4128
4129 if (c->fc->nb_streams < 1)
4130 return 0;
4131 st = c->fc->streams[c->fc->nb_streams-1];
4132 sc = st->priv_data;
4133
4134 version = avio_r8(pb); /* version */
4135 avio_rb24(pb); /* flags */
4136 grouping_type = avio_rl32(pb);
4137
4138 if (grouping_type == MKTAG('r','a','p',' ')) {
4139 tablep = &sc->rap_group;
4140 table_count = &sc->rap_group_count;
4141 } else if (grouping_type == MKTAG('s','y','n','c')) {
4142 tablep = &sc->sync_group;
4143 table_count = &sc->sync_group_count;
4144 } else {
4145 return 0;
4146 }
4147
4148 if (version == 1)
4149 avio_rb32(pb); /* grouping_type_parameter */
4150
4151 entries = avio_rb32(pb);
4152 if (!entries)
4153 return 0;
4154 if (*tablep)
4155 av_log(c->fc, AV_LOG_WARNING, "Duplicated SBGP %s atom\n", av_fourcc2str(grouping_type));
4156 av_freep(tablep);
4157 table = av_malloc_array(entries, sizeof(*table));
4158 if (!table)
4159 return AVERROR(ENOMEM);
4160 *tablep = table;
4161
4162 for (i = 0; i < entries && !pb->eof_reached; i++) {
4163 table[i].count = avio_rb32(pb); /* sample_count */
4164 table[i].index = avio_rb32(pb); /* group_description_index */
4165 }
4166
4167 *table_count = i;
4168
4169 if (pb->eof_reached) {
4170 av_log(c->fc, AV_LOG_WARNING, "reached eof, corrupted SBGP atom\n");
4171 return AVERROR_EOF;
4172 }
4173
4174 return 0;
4175}
4176
4177/**
4178 * Get ith edit list entry (media time, duration).
4179 */
4181 const MOVStreamContext *msc,
4182 unsigned int edit_list_index,
4183 int64_t *edit_list_media_time,
4184 int64_t *edit_list_duration,
4185 int64_t global_timescale)
4186{
4187 if (edit_list_index == msc->elst_count) {
4188 return 0;
4189 }
4190 *edit_list_media_time = msc->elst_data[edit_list_index].time;
4191 *edit_list_duration = msc->elst_data[edit_list_index].duration;
4192
4193 /* duration is in global timescale units;convert to msc timescale */
4194 if (global_timescale == 0) {
4195 avpriv_request_sample(mov->fc, "Support for mvhd.timescale = 0 with editlists");
4196 return 0;
4197 }
4198 *edit_list_duration = av_rescale(*edit_list_duration, msc->time_scale,
4199 global_timescale);
4200
4201 if (*edit_list_duration + (uint64_t)*edit_list_media_time > INT64_MAX)
4202 *edit_list_duration = 0;
4203
4204 return 1;
4205}
4206
4207/**
4208 * Find the closest previous frame to the timestamp_pts, in e_old index
4209 * entries. Searching for just any frame / just key frames can be controlled by
4210 * last argument 'flag'.
4211 * Note that if ctts_data is not NULL, we will always search for a key frame
4212 * irrespective of the value of 'flag'. If we don't find any keyframe, we will
4213 * return the first frame of the video.
4214 *
4215 * Here the timestamp_pts is considered to be a presentation timestamp and
4216 * the timestamp of index entries are considered to be decoding timestamps.
4217 *
4218 * Returns 0 if successful in finding a frame, else returns -1.
4219 * Places the found index corresponding output arg.
4220 *
4221 * If ctts_old is not NULL, then refines the searched entry by searching
4222 * backwards from the found timestamp, to find the frame with correct PTS.
4223 *
4224 * Places the found ctts_index and ctts_sample in corresponding output args.
4225 */
4227 AVIndexEntry *e_old,
4228 int nb_old,
4229 MOVTimeToSample *tts_data,
4230 int64_t tts_count,
4231 int64_t timestamp_pts,
4232 int flag,
4233 int64_t* index,
4234 int64_t* tts_index,
4235 int64_t* tts_sample)
4236{
4237 MOVStreamContext *msc = st->priv_data;
4238 FFStream *const sti = ffstream(st);
4239 AVIndexEntry *e_keep = sti->index_entries;
4240 int nb_keep = sti->nb_index_entries;
4241 int64_t i = 0;
4242
4244
4245 // If dts_shift > 0, then all the index timestamps will have to be offset by
4246 // at least dts_shift amount to obtain PTS.
4247 // Hence we decrement the searched timestamp_pts by dts_shift to find the closest index element.
4248 if (msc->dts_shift > 0) {
4249 timestamp_pts -= msc->dts_shift;
4250 }
4251
4252 sti->index_entries = e_old;
4253 sti->nb_index_entries = nb_old;
4255
4256 // Keep going backwards in the index entries until the timestamp is the same.
4257 if (*index >= 0) {
4258 for (i = *index; i > 0 && e_old[i].timestamp == e_old[i - 1].timestamp;
4259 i--) {
4260 if ((flag & AVSEEK_FLAG_ANY) ||
4261 (e_old[i - 1].flags & AVINDEX_KEYFRAME)) {
4262 *index = i - 1;
4263 }
4264 }
4265 }
4266
4267 // If we have CTTS then refine the search, by searching backwards over PTS
4268 // computed by adding corresponding CTTS durations to index timestamps.
4269 if (msc->ctts_count && *index >= 0) {
4270 av_assert0(tts_index);
4271 av_assert0(tts_sample);
4272 // Find out the ctts_index for the found frame.
4273 *tts_index = 0;
4274 *tts_sample = 0;
4275 for (int64_t index_tts_count = 0; index_tts_count < *index; index_tts_count++) {
4276 if (*tts_index < tts_count) {
4277 (*tts_sample)++;
4278 if (tts_data[*tts_index].count == *tts_sample) {
4279 (*tts_index)++;
4280 *tts_sample = 0;
4281 }
4282 }
4283 }
4284
4285 while (*index >= 0 && (*tts_index) >= 0 && (*tts_index) < tts_count) {
4286 // Find a "key frame" with PTS <= timestamp_pts (So that we can decode B-frames correctly).
4287 // No need to add dts_shift to the timestamp here because timestamp_pts has already been
4288 // compensated by dts_shift above.
4289 if ((e_old[*index].timestamp + tts_data[*tts_index].offset) <= timestamp_pts &&
4290 (e_old[*index].flags & AVINDEX_KEYFRAME)) {
4291 break;
4292 }
4293
4294 (*index)--;
4295 if (*tts_sample == 0) {
4296 (*tts_index)--;
4297 if (*tts_index >= 0)
4298 *tts_sample = tts_data[*tts_index].count - 1;
4299 } else {
4300 (*tts_sample)--;
4301 }
4302 }
4303 }
4304
4305 /* restore AVStream state*/
4306 sti->index_entries = e_keep;
4307 sti->nb_index_entries = nb_keep;
4308 return *index >= 0 ? 0 : -1;
4309}
4310
4311/**
4312 * Add index entry with the given values, to the end of ffstream(st)->index_entries.
4313 * Returns the new size ffstream(st)->index_entries if successful, else returns -1.
4314 *
4315 * This function is similar to ff_add_index_entry in libavformat/utils.c
4316 * except that here we are always unconditionally adding an index entry to
4317 * the end, instead of searching the entries list and skipping the add if
4318 * there is an existing entry with the same timestamp.
4319 * This is needed because the mov_fix_index calls this func with the same
4320 * unincremented timestamp for successive discarded frames.
4321 */
4323 int size, int distance, int flags)
4324{
4325 FFStream *const sti = ffstream(st);
4326 AVIndexEntry *entries, *ie;
4327 int64_t index = -1;
4328 const size_t min_size_needed = (sti->nb_index_entries + 1) * sizeof(AVIndexEntry);
4329
4330 // Double the allocation each time, to lower memory fragmentation.
4331 // Another difference from ff_add_index_entry function.
4332 const size_t requested_size =
4333 min_size_needed > sti->index_entries_allocated_size ?
4334 FFMAX(min_size_needed, 2 * sti->index_entries_allocated_size) :
4335 min_size_needed;
4336
4337 if (sti->nb_index_entries + 1U >= UINT_MAX / sizeof(AVIndexEntry))
4338 return -1;
4339
4340 entries = av_fast_realloc(sti->index_entries,
4342 requested_size);
4343 if (!entries)
4344 return -1;
4345
4346 sti->index_entries = entries;
4347
4348 index = sti->nb_index_entries++;
4349 ie= &entries[index];
4350
4351 ie->pos = pos;
4352 ie->timestamp = timestamp;
4354 ie->size= size;
4355 ie->flags = flags;
4356 return index;
4357}
4358
4359/**
4360 * Rewrite timestamps of index entries in the range [end_index - frame_duration_buffer_size, end_index)
4361 * by subtracting end_ts successively by the amounts given in frame_duration_buffer.
4362 */
4363static void fix_index_entry_timestamps(AVStream* st, int end_index, int64_t end_ts,
4364 int64_t* frame_duration_buffer,
4365 int frame_duration_buffer_size) {
4366 FFStream *const sti = ffstream(st);
4367 int i = 0;
4368 av_assert0(end_index >= 0 && end_index <= sti->nb_index_entries);
4369 for (i = 0; i < frame_duration_buffer_size; i++) {
4370 end_ts -= frame_duration_buffer[frame_duration_buffer_size - 1 - i];
4371 sti->index_entries[end_index - 1 - i].timestamp = end_ts;
4372 }
4373}
4374
4375static int add_tts_entry(MOVTimeToSample **tts_data, unsigned int *tts_count, unsigned int *allocated_size,
4376 int count, int offset, unsigned int duration)
4377{
4378 MOVTimeToSample *tts_buf_new;
4379 const size_t min_size_needed = (*tts_count + 1) * sizeof(MOVTimeToSample);
4380 const size_t requested_size =
4381 min_size_needed > *allocated_size ?
4382 FFMAX(min_size_needed, 2 * (*allocated_size)) :
4383 min_size_needed;
4384
4385 if ((unsigned)(*tts_count) >= UINT_MAX / sizeof(MOVTimeToSample) - 1)
4386 return -1;
4387
4388 tts_buf_new = av_fast_realloc(*tts_data, allocated_size, requested_size);
4389
4390 if (!tts_buf_new)
4391 return -1;
4392
4393 *tts_data = tts_buf_new;
4394
4395 tts_buf_new[*tts_count].count = count;
4396 tts_buf_new[*tts_count].offset = offset;
4397 tts_buf_new[*tts_count].duration = duration;
4398
4399 *tts_count = (*tts_count) + 1;
4400 return 0;
4401}
4402
4403#define MAX_REORDER_DELAY 16
4405{
4406 MOVStreamContext *msc = st->priv_data;
4407 FFStream *const sti = ffstream(st);
4408 int ctts_ind = 0;
4409 int ctts_sample = 0;
4410 int64_t pts_buf[MAX_REORDER_DELAY + 1]; // Circular buffer to sort pts.
4411 int buf_start = 0;
4412 int j, r, num_swaps;
4413
4414 for (j = 0; j < MAX_REORDER_DELAY + 1; j++)
4415 pts_buf[j] = INT64_MIN;
4416
4417 if (st->codecpar->video_delay <= 0 && msc->ctts_count &&
4419 st->codecpar->video_delay = 0;
4420 for (int ind = 0; ind < sti->nb_index_entries && ctts_ind < msc->tts_count; ++ind) {
4421 // Point j to the last elem of the buffer and insert the current pts there.
4422 j = buf_start;
4423 buf_start = (buf_start + 1);
4424 if (buf_start == MAX_REORDER_DELAY + 1)
4425 buf_start = 0;
4426
4427 pts_buf[j] = sti->index_entries[ind].timestamp + msc->tts_data[ctts_ind].offset;
4428
4429 // The timestamps that are already in the sorted buffer, and are greater than the
4430 // current pts, are exactly the timestamps that need to be buffered to output PTS
4431 // in correct sorted order.
4432 // Hence the video delay (which is the buffer size used to sort DTS and output PTS),
4433 // can be computed as the maximum no. of swaps any particular timestamp needs to
4434 // go through, to keep this buffer in sorted order.
4435 num_swaps = 0;
4436 while (j != buf_start) {
4437 r = j - 1;
4438 if (r < 0) r = MAX_REORDER_DELAY;
4439 if (pts_buf[j] < pts_buf[r]) {
4440 FFSWAP(int64_t, pts_buf[j], pts_buf[r]);
4441 ++num_swaps;
4442 } else {
4443 break;
4444 }
4445 j = r;
4446 }
4447 st->codecpar->video_delay = FFMAX(st->codecpar->video_delay, num_swaps);
4448
4449 ctts_sample++;
4450 if (ctts_sample == msc->tts_data[ctts_ind].count) {
4451 ctts_ind++;
4452 ctts_sample = 0;
4453 }
4454 }
4455 av_log(c->fc, AV_LOG_DEBUG, "Setting codecpar->delay to %d for stream st: %d\n",
4456 st->codecpar->video_delay, st->index);
4457 }
4458}
4459
4461{
4462 sc->current_sample++;
4463 sc->current_index++;
4464 if (sc->index_ranges &&
4466 sc->current_index_range->end) {
4467 sc->current_index_range++;
4469 }
4470}
4471
4473{
4474 sc->current_sample--;
4475 sc->current_index--;
4476 if (sc->index_ranges &&
4479 sc->current_index_range--;
4480 sc->current_index = sc->current_index_range->end - 1;
4481 }
4482}
4483
4484static void mov_current_sample_set(MOVStreamContext *sc, int current_sample)
4485{
4486 int64_t range_size;
4487
4488 sc->current_sample = current_sample;
4489 sc->current_index = current_sample;
4490 if (!sc->index_ranges) {
4491 return;
4492 }
4493
4494 for (sc->current_index_range = sc->index_ranges;
4496 sc->current_index_range++) {
4497 range_size = sc->current_index_range->end - sc->current_index_range->start;
4498 if (range_size > current_sample) {
4499 sc->current_index = sc->current_index_range->start + current_sample;
4500 break;
4501 }
4502 current_sample -= range_size;
4503 }
4504}
4505
4506/**
4507 * Fix ffstream(st)->index_entries, so that it contains only the entries (and the entries
4508 * which are needed to decode them) that fall in the edit list time ranges.
4509 * Also fixes the timestamps of the index entries to match the timeline
4510 * specified the edit lists.
4511 */
4512static void mov_fix_index(MOVContext *mov, AVStream *st)
4513{
4514 MOVStreamContext *msc = st->priv_data;
4515 FFStream *const sti = ffstream(st);
4516 AVIndexEntry *e_old = sti->index_entries;
4517 int nb_old = sti->nb_index_entries;
4518 const AVIndexEntry *e_old_end = e_old + nb_old;
4519 const AVIndexEntry *current = NULL;
4520 MOVTimeToSample *tts_data_old = msc->tts_data;
4521 int64_t tts_index_old = 0;
4522 int64_t tts_sample_old = 0;
4523 int64_t tts_count_old = msc->tts_count;
4524 int64_t edit_list_media_time = 0;
4525 int64_t edit_list_duration = 0;
4526 int64_t frame_duration = 0;
4527 int64_t edit_list_dts_counter = 0;
4528 int64_t edit_list_dts_entry_end = 0;
4529 int64_t edit_list_start_tts_sample = 0;
4530 int64_t curr_cts;
4531 int64_t curr_ctts = 0;
4532 int64_t empty_edits_sum_duration = 0;
4533 int64_t edit_list_index = 0;
4534 int64_t index;
4535 int flags;
4536 int64_t start_dts = 0;
4537 int64_t edit_list_start_encountered = 0;
4538 int64_t search_timestamp = 0;
4539 int64_t* frame_duration_buffer = NULL;
4540 int num_discarded_begin = 0;
4541 int first_non_zero_audio_edit = -1;
4542 int packet_skip_samples = 0;
4543 MOVIndexRange *current_index_range = NULL;
4544 int found_keyframe_after_edit = 0;
4545 int found_non_empty_edit = 0;
4546
4547 if (!msc->elst_data || msc->elst_count <= 0 || nb_old <= 0) {
4548 return;
4549 }
4550
4551 // allocate the index ranges array
4552 msc->index_ranges = av_malloc_array(msc->elst_count + 1,
4553 sizeof(msc->index_ranges[0]));
4554 if (!msc->index_ranges) {
4555 av_log(mov->fc, AV_LOG_ERROR, "Cannot allocate index ranges buffer\n");
4556 return;
4557 }
4559
4560 // Clean AVStream from traces of old index
4561 sti->index_entries = NULL;
4563 sti->nb_index_entries = 0;
4564
4565 // Clean time to sample fields of MOVStreamContext
4566 msc->tts_data = NULL;
4567 msc->tts_count = 0;
4568 msc->tts_index = 0;
4569 msc->tts_sample = 0;
4570 msc->tts_allocated_size = 0;
4571
4572 // Reinitialize min_corrected_pts so that it can be computed again.
4573 msc->min_corrected_pts = -1;
4574
4575 // If the dts_shift is positive (in case of negative ctts values in mov),
4576 // then negate the DTS by dts_shift
4577 if (msc->dts_shift > 0) {
4578 edit_list_dts_entry_end -= msc->dts_shift;
4579 av_log(mov->fc, AV_LOG_DEBUG, "Shifting DTS by %d because of negative CTTS.\n", msc->dts_shift);
4580 }
4581
4582 start_dts = edit_list_dts_entry_end;
4583
4584 while (get_edit_list_entry(mov, msc, edit_list_index, &edit_list_media_time,
4585 &edit_list_duration, mov->time_scale)) {
4586 av_log(mov->fc, AV_LOG_DEBUG, "Processing st: %d, edit list %"PRId64" - media time: %"PRId64", duration: %"PRId64"\n",
4587 st->index, edit_list_index, edit_list_media_time, edit_list_duration);
4588 edit_list_index++;
4589 edit_list_dts_counter = edit_list_dts_entry_end;
4590 edit_list_dts_entry_end = av_sat_add64(edit_list_dts_entry_end, edit_list_duration);
4591 if (edit_list_dts_entry_end == INT64_MAX) {
4592 av_log(mov->fc, AV_LOG_ERROR, "Cannot calculate dts entry length with duration %"PRId64"\n",
4593 edit_list_duration);
4594 break;
4595 }
4596 num_discarded_begin = 0;
4597 if (!found_non_empty_edit && edit_list_media_time == -1) {
4598 empty_edits_sum_duration += edit_list_duration;
4599 continue;
4600 }
4601 found_non_empty_edit = 1;
4602
4603 // If we encounter a non-negative edit list reset the skip_samples/initial_padding fields and set them
4604 // according to the edit list below.
4606 if (first_non_zero_audio_edit < 0) {
4607 first_non_zero_audio_edit = 1;
4608 } else {
4609 first_non_zero_audio_edit = 0;
4610 }
4611
4612 if (first_non_zero_audio_edit > 0)
4613 sti->skip_samples = st->codecpar->initial_padding = 0;
4614 }
4615
4616 // While reordering frame index according to edit list we must handle properly
4617 // the scenario when edit list entry starts from none key frame.
4618 // We find closest previous key frame and preserve it and consequent frames in index.
4619 // All frames which are outside edit list entry time boundaries will be dropped after decoding.
4620 search_timestamp = edit_list_media_time;
4622 // Audio decoders like AAC need need a decoder delay samples previous to the current sample,
4623 // to correctly decode this frame. Hence for audio we seek to a frame 1 sec. before the
4624 // edit_list_media_time to cover the decoder delay.
4625 search_timestamp = FFMAX(search_timestamp - msc->time_scale, e_old[0].timestamp);
4626 }
4627
4628 if (find_prev_closest_index(st, e_old, nb_old, tts_data_old, tts_count_old, search_timestamp, 0,
4629 &index, &tts_index_old, &tts_sample_old) < 0) {
4630 av_log(mov->fc, AV_LOG_WARNING,
4631 "st: %d edit list: %"PRId64" Missing key frame while searching for timestamp: %"PRId64"\n",
4632 st->index, edit_list_index, search_timestamp);
4633 if (find_prev_closest_index(st, e_old, nb_old, tts_data_old, tts_count_old, search_timestamp, AVSEEK_FLAG_ANY,
4634 &index, &tts_index_old, &tts_sample_old) < 0) {
4635 av_log(mov->fc, AV_LOG_WARNING,
4636 "st: %d edit list %"PRId64" Cannot find an index entry before timestamp: %"PRId64".\n",
4637 st->index, edit_list_index, search_timestamp);
4638 index = 0;
4639 tts_index_old = 0;
4640 tts_sample_old = 0;
4641 }
4642 }
4643 current = e_old + index;
4644 edit_list_start_tts_sample = tts_sample_old;
4645
4646 // Iterate over index and arrange it according to edit list
4647 edit_list_start_encountered = 0;
4648 found_keyframe_after_edit = 0;
4649 for (; current < e_old_end; current++, index++) {
4650 // check if frame outside edit list mark it for discard
4651 frame_duration = (current + 1 < e_old_end) ?
4652 ((current + 1)->timestamp - current->timestamp) : edit_list_duration;
4653
4654 flags = current->flags;
4655
4656 // frames (pts) before or after edit list
4657 curr_cts = current->timestamp + msc->dts_shift;
4658 curr_ctts = 0;
4659
4660 if (tts_data_old && tts_index_old < tts_count_old) {
4661 curr_ctts = tts_data_old[tts_index_old].offset;
4662 av_log(mov->fc, AV_LOG_TRACE, "stts: %"PRId64" ctts: %"PRId64", tts_index: %"PRId64", tts_count: %"PRId64"\n",
4663 curr_cts, curr_ctts, tts_index_old, tts_count_old);
4664 curr_cts += curr_ctts;
4665 tts_sample_old++;
4666 if (tts_sample_old == tts_data_old[tts_index_old].count) {
4667 if (add_tts_entry(&msc->tts_data, &msc->tts_count,
4668 &msc->tts_allocated_size,
4669 tts_data_old[tts_index_old].count - edit_list_start_tts_sample,
4670 tts_data_old[tts_index_old].offset, tts_data_old[tts_index_old].duration) == -1) {
4671 av_log(mov->fc, AV_LOG_ERROR, "Cannot add Time To Sample entry %"PRId64" - {%"PRId64", %d}\n",
4672 tts_index_old,
4673 tts_data_old[tts_index_old].count - edit_list_start_tts_sample,
4674 tts_data_old[tts_index_old].offset);
4675 break;
4676 }
4677 tts_index_old++;
4678 tts_sample_old = 0;
4679 edit_list_start_tts_sample = 0;
4680 }
4681 }
4682
4683 if (curr_cts < edit_list_media_time || curr_cts >= (edit_list_duration + edit_list_media_time)) {
4685 curr_cts < edit_list_media_time && curr_cts + frame_duration > edit_list_media_time &&
4686 first_non_zero_audio_edit > 0) {
4687 packet_skip_samples = edit_list_media_time - curr_cts;
4688 sti->skip_samples += packet_skip_samples;
4689
4690 // Shift the index entry timestamp by packet_skip_samples to be correct.
4691 edit_list_dts_counter -= packet_skip_samples;
4692 if (edit_list_start_encountered == 0) {
4693 edit_list_start_encountered = 1;
4694 // Make timestamps strictly monotonically increasing for audio, by rewriting timestamps for
4695 // discarded packets.
4696 if (frame_duration_buffer) {
4697 fix_index_entry_timestamps(st, sti->nb_index_entries, edit_list_dts_counter,
4698 frame_duration_buffer, num_discarded_begin);
4699 av_freep(&frame_duration_buffer);
4700 }
4701 }
4702
4703 av_log(mov->fc, AV_LOG_DEBUG, "skip %d audio samples from curr_cts: %"PRId64"\n", packet_skip_samples, curr_cts);
4704 } else {
4706 av_log(mov->fc, AV_LOG_DEBUG, "drop a frame at curr_cts: %"PRId64" @ %"PRId64"\n", curr_cts, index);
4707
4708 if (edit_list_start_encountered == 0) {
4709 num_discarded_begin++;
4710 if (av_reallocp_array(&frame_duration_buffer, num_discarded_begin,
4711 sizeof(*frame_duration_buffer)) < 0) {
4712 av_log(mov->fc, AV_LOG_ERROR, "Cannot reallocate frame duration buffer\n");
4713 break;
4714 }
4715 frame_duration_buffer[num_discarded_begin - 1] = frame_duration;
4716
4717 // Increment skip_samples for the first non-zero audio edit list
4719 first_non_zero_audio_edit > 0 && st->codecpar->codec_id != AV_CODEC_ID_VORBIS) {
4720 sti->skip_samples += frame_duration;
4721 }
4722 }
4723 }
4724 } else {
4725 if (msc->min_corrected_pts < 0) {
4726 msc->min_corrected_pts = edit_list_dts_counter + curr_ctts + msc->dts_shift;
4727 } else {
4728 msc->min_corrected_pts = FFMIN(msc->min_corrected_pts, edit_list_dts_counter + curr_ctts + msc->dts_shift);
4729 }
4730 if (edit_list_start_encountered == 0) {
4731 edit_list_start_encountered = 1;
4732 // Make timestamps strictly monotonically increasing by rewriting timestamps for
4733 // discarded packets.
4734 if (frame_duration_buffer) {
4735 fix_index_entry_timestamps(st, sti->nb_index_entries, edit_list_dts_counter,
4736 frame_duration_buffer, num_discarded_begin);
4737 av_freep(&frame_duration_buffer);
4738 }
4739 }
4740 }
4741
4742 if (add_index_entry(st, current->pos, edit_list_dts_counter, current->size,
4743 current->min_distance, flags) == -1) {
4744 av_log(mov->fc, AV_LOG_ERROR, "Cannot add index entry\n");
4745 break;
4746 }
4747
4748 // Update the index ranges array
4749 if (!current_index_range || index != current_index_range->end) {
4750 current_index_range = current_index_range ? current_index_range + 1
4751 : msc->index_ranges;
4752 current_index_range->start = index;
4753 }
4754 current_index_range->end = index + 1;
4755
4756 // Only start incrementing DTS in frame_duration amounts, when we encounter a frame in edit list.
4757 if (edit_list_start_encountered > 0) {
4758 edit_list_dts_counter = edit_list_dts_counter + frame_duration;
4759 }
4760
4761 // Break when found first key frame after edit entry completion
4762 if ((curr_cts + frame_duration >= (edit_list_duration + edit_list_media_time)) &&
4764 if (msc->ctts_count) {
4765 // If we have CTTS and this is the first keyframe after edit elist,
4766 // wait for one more, because there might be trailing B-frames after this I-frame
4767 // that do belong to the edit.
4768 if (st->codecpar->codec_type != AVMEDIA_TYPE_AUDIO && found_keyframe_after_edit == 0) {
4769 found_keyframe_after_edit = 1;
4770 continue;
4771 }
4772 if (tts_sample_old != 0) {
4773 if (add_tts_entry(&msc->tts_data, &msc->tts_count,
4774 &msc->tts_allocated_size,
4775 tts_sample_old - edit_list_start_tts_sample,
4776 tts_data_old[tts_index_old].offset, tts_data_old[tts_index_old].duration) == -1) {
4777 av_log(mov->fc, AV_LOG_ERROR, "Cannot add Time To Sample entry %"PRId64" - {%"PRId64", %d}\n",
4778 tts_index_old, tts_sample_old - edit_list_start_tts_sample,
4779 tts_data_old[tts_index_old].offset);
4780 break;
4781 }
4782 }
4783 }
4784 break;
4785 }
4786 }
4787 }
4788 // If there are empty edits, then msc->min_corrected_pts might be positive
4789 // intentionally. So we subtract the sum duration of empty edits here.
4790 msc->min_corrected_pts -= empty_edits_sum_duration;
4791
4792 // If the minimum pts turns out to be greater than zero after fixing the index, then we subtract the
4793 // dts by that amount to make the first pts zero.
4795 if (msc->min_corrected_pts > 0) {
4796 av_log(mov->fc, AV_LOG_DEBUG, "Offset DTS by %"PRId64" to make first pts zero.\n", msc->min_corrected_pts);
4797 for (int i = 0; i < sti->nb_index_entries; ++i)
4799 }
4800 }
4801 // Start time should be equal to zero or the duration of any empty edits.
4802 st->start_time = empty_edits_sum_duration;
4803
4804 // Update av stream length, if it ends up shorter than the track's media duration
4805 st->duration = FFMIN(st->duration, edit_list_dts_entry_end - start_dts);
4807
4808 // Free the old index and the old CTTS structures
4809 av_free(e_old);
4810 av_free(tts_data_old);
4811 av_freep(&frame_duration_buffer);
4812
4813 // Null terminate the index ranges array
4814 current_index_range = current_index_range ? current_index_range + 1
4815 : msc->index_ranges;
4816 current_index_range->start = 0;
4817 current_index_range->end = 0;
4818 msc->current_index = msc->index_ranges[0].start;
4819}
4820
4821static uint32_t get_sgpd_sync_index(const MOVStreamContext *sc, int nal_unit_type)
4822{
4823 for (uint32_t i = 0; i < sc->sgpd_sync_count; i++)
4824 if (sc->sgpd_sync[i] == nal_unit_type)
4825 return i + 1;
4826 return 0;
4827}
4828
4830{
4831 int k;
4832 int sample_id = 0;
4833 uint32_t cra_index;
4834 MOVStreamContext *sc = st->priv_data;
4835
4837 return 0;
4838
4839 /* Build an unrolled index of the samples */
4840 sc->sample_offsets_count = 0;
4841 for (uint32_t i = 0; i < sc->ctts_count; i++) {
4842 if (sc->ctts_data[i].count > INT_MAX - sc->sample_offsets_count)
4843 return AVERROR(ENOMEM);
4845 }
4848 if (!sc->sample_offsets)
4849 return AVERROR(ENOMEM);
4850 k = 0;
4851 for (uint32_t i = 0; i < sc->ctts_count; i++)
4852 for (int j = 0; j < sc->ctts_data[i].count; j++)
4853 sc->sample_offsets[k++] = sc->ctts_data[i].offset;
4854
4855 /* The following HEVC NAL type reveal the use of open GOP sync points
4856 * (TODO: BLA types may also be concerned) */
4857 cra_index = get_sgpd_sync_index(sc, HEVC_NAL_CRA_NUT); /* Clean Random Access */
4858 if (!cra_index)
4859 return 0;
4860
4861 /* Build a list of open-GOP key samples */
4862 sc->open_key_samples_count = 0;
4863 for (uint32_t i = 0; i < sc->sync_group_count; i++)
4864 if (sc->sync_group[i].index == cra_index) {
4865 if (sc->sync_group[i].count > INT_MAX - sc->open_key_samples_count)
4866 return AVERROR(ENOMEM);
4868 }
4871 if (!sc->open_key_samples)
4872 return AVERROR(ENOMEM);
4873 k = 0;
4874 for (uint32_t i = 0; i < sc->sync_group_count; i++) {
4875 const MOVSbgp *sg = &sc->sync_group[i];
4876 if (sg->index == cra_index)
4877 for (uint32_t j = 0; j < sg->count; j++)
4878 sc->open_key_samples[k++] = sample_id;
4879 if (sg->count > INT_MAX - sample_id)
4880 return AVERROR_PATCHWELCOME;
4881 sample_id += sg->count;
4882 }
4883
4884 /* Identify the minimal time step between samples */
4885 sc->min_sample_duration = UINT_MAX;
4886 for (uint32_t i = 0; i < sc->stts_count; i++)
4888
4889 return 0;
4890}
4891
4892#define MOV_MERGE_CTTS 1
4893#define MOV_MERGE_STTS 2
4894/*
4895 * Merge stts and ctts arrays into a new combined array.
4896 * stts_count and ctts_count may be left untouched as they will be
4897 * used to check for the presence of either of them.
4898 */
4900{
4901 MOVStreamContext *sc = st->priv_data;
4902 int ctts = sc->ctts_data && (flags & MOV_MERGE_CTTS);
4903 int stts = sc->stts_data && (flags & MOV_MERGE_STTS);
4904 int idx = 0;
4905
4906 if (!sc->ctts_data && !sc->stts_data)
4907 return 0;
4908 // Expand time to sample entries such that we have a 1-1 mapping with samples
4909 if (!sc->sample_count || sc->sample_count >= UINT_MAX / sizeof(*sc->tts_data))
4910 return -1;
4911
4912 if (ctts) {
4914 sc->sample_count * sizeof(*sc->tts_data));
4915 if (!sc->tts_data)
4916 return -1;
4917
4918 memset(sc->tts_data, 0, sc->tts_allocated_size);
4919
4920 for (int i = 0; i < sc->ctts_count &&
4921 idx < sc->sample_count; i++)
4922 for (int j = 0; j < sc->ctts_data[i].count &&
4923 idx < sc->sample_count; j++) {
4924 sc->tts_data[idx].offset = sc->ctts_data[i].offset;
4925 sc->tts_data[idx++].count = 1;
4926 }
4927
4928 sc->tts_count = idx;
4929 } else
4930 sc->ctts_count = 0;
4931 av_freep(&sc->ctts_data);
4932 sc->ctts_allocated_size = 0;
4933
4934 idx = 0;
4935 if (stts) {
4937 sc->sample_count * sizeof(*sc->tts_data));
4938 if (!tts_data)
4939 return -1;
4940
4941 if (!sc->tts_data)
4942 memset(tts_data, 0, sc->tts_allocated_size);
4943 sc->tts_data = tts_data;
4944
4945 for (int i = 0; i < sc->stts_count &&
4946 idx < sc->sample_count; i++)
4947 for (int j = 0; j < sc->stts_data[i].count &&
4948 idx < sc->sample_count; j++) {
4949 sc->tts_data[idx].duration = sc->stts_data[i].duration;
4950 sc->tts_data[idx++].count = 1;
4951 }
4952
4953 sc->tts_count = FFMAX(sc->tts_count, idx);
4954 } else
4955 sc->stts_count = 0;
4956 av_freep(&sc->stts_data);
4957 sc->stts_allocated_size = 0;
4958
4959 return 0;
4960}
4961
4963{
4964 MOVStreamContext *sc = st->priv_data;
4965 FFStream *const sti = ffstream(st);
4966 int64_t current_offset;
4967 int64_t current_dts = 0;
4968 unsigned int stts_index = 0;
4969 unsigned int stsc_index = 0;
4970 unsigned int stss_index = 0;
4971 unsigned int stps_index = 0;
4972 unsigned int i, j;
4973 uint64_t stream_size = 0;
4974
4975 int ret = build_open_gop_key_points(st);
4976 if (ret < 0)
4977 return;
4978
4979 if (sc->elst_count) {
4980 int i, edit_start_index = 0, multiple_edits = 0;
4981 int64_t empty_duration = 0; // empty duration of the first edit list entry
4982 int64_t start_time = 0; // start time of the media
4983
4984 for (i = 0; i < sc->elst_count; i++) {
4985 const MOVElst *e = &sc->elst_data[i];
4986 if (i == 0 && e->time == -1) {
4987 /* if empty, the first entry is the start time of the stream
4988 * relative to the presentation itself */
4989 empty_duration = e->duration;
4990 edit_start_index = 1;
4991 } else if (i == edit_start_index && e->time >= 0) {
4992 start_time = e->time;
4993 } else {
4994 multiple_edits = 1;
4995 }
4996 }
4997
4998 if (multiple_edits && !mov->advanced_editlist) {
5000 av_log(mov->fc, AV_LOG_WARNING, "multiple edit list entries, "
5001 "not supported in fragmented MP4 files\n");
5002 else
5003 av_log(mov->fc, AV_LOG_WARNING, "multiple edit list entries, "
5004 "Use -advanced_editlist to correctly decode otherwise "
5005 "a/v desync might occur\n");
5006 }
5007
5008 /* adjust first dts according to edit list */
5009 if ((empty_duration || start_time) && mov->time_scale > 0) {
5010 if (empty_duration)
5011 empty_duration = av_rescale(empty_duration, sc->time_scale, mov->time_scale);
5012
5013 if (av_sat_sub64(start_time, empty_duration) != start_time - (uint64_t)empty_duration)
5014 av_log(mov->fc, AV_LOG_WARNING, "start_time - empty_duration is not representable\n");
5015
5016 sc->time_offset = start_time - (uint64_t)empty_duration;
5018 if (!mov->advanced_editlist)
5019 current_dts = -av_clip64(sc->time_offset, -INT64_MAX, INT64_MAX);
5020 }
5021
5022 if (!multiple_edits && !mov->advanced_editlist &&
5025 (AVRational){1, st->codecpar->sample_rate});
5026 }
5027
5028 /* only use old uncompressed audio chunk demuxing when stts specifies it */
5029 if (!(st->codecpar->codec_type == AVMEDIA_TYPE_AUDIO &&
5030 sc->stts_count == 1 && sc->stts_data && sc->stts_data[0].duration == 1)) {
5031 unsigned int current_sample = 0;
5032 unsigned int stts_sample = 0;
5033 unsigned int sample_size;
5034 unsigned int distance = 0;
5035 unsigned int rap_group_index = 0;
5036 unsigned int rap_group_sample = 0;
5037 int rap_group_present = sc->rap_group_count && sc->rap_group;
5038 int key_off = (sc->keyframe_count && sc->keyframes[0] > 0) || (sc->stps_count && sc->stps_data[0] > 0);
5039
5040 av_assert0(sc->dts_shift >= 0);
5041 if (current_dts < INT64_MIN + sc->dts_shift)
5042 return;
5043 current_dts -= sc->dts_shift;
5044 if (!sc->sample_count || sti->nb_index_entries || sc->tts_count)
5045 return;
5046 if (sc->sample_count >= UINT_MAX / sizeof(*sti->index_entries) - sti->nb_index_entries)
5047 return;
5049 sti->nb_index_entries + sc->sample_count,
5050 sizeof(*sti->index_entries)) < 0) {
5051 sti->nb_index_entries = 0;
5052 return;
5053 }
5054 sti->index_entries_allocated_size = (sti->nb_index_entries + sc->sample_count) * sizeof(*sti->index_entries);
5055
5057 if (ret < 0)
5058 return;
5059
5060 for (i = 0; i < sc->chunk_count; i++) {
5061 int64_t next_offset = i+1 < sc->chunk_count ? sc->chunk_offsets[i+1] : INT64_MAX;
5062 current_offset = sc->chunk_offsets[i];
5063 while (mov_stsc_index_valid(stsc_index, sc->stsc_count) &&
5064 i + 1 == sc->stsc_data[stsc_index + 1].first)
5065 stsc_index++;
5066
5067 if (next_offset > current_offset && sc->sample_size>0 && sc->sample_size < sc->stsz_sample_size &&
5068 sc->stsc_data[stsc_index].count * (int64_t)sc->stsz_sample_size > next_offset - current_offset) {
5069 av_log(mov->fc, AV_LOG_WARNING, "STSZ sample size %d invalid (too large), ignoring\n", sc->stsz_sample_size);
5070 sc->stsz_sample_size = sc->sample_size;
5071 }
5072 if (sc->stsz_sample_size>0 && sc->stsz_sample_size < sc->sample_size) {
5073 av_log(mov->fc, AV_LOG_WARNING, "STSZ sample size %d invalid (too small), ignoring\n", sc->stsz_sample_size);
5074 sc->stsz_sample_size = sc->sample_size;
5075 }
5076
5077 for (j = 0; j < sc->stsc_data[stsc_index].count; j++) {
5078 int keyframe = 0;
5079 if (current_sample >= sc->sample_count) {
5080 av_log(mov->fc, AV_LOG_ERROR, "wrong sample count\n");
5081 return;
5082 }
5083
5084 if (!sc->keyframe_absent && (!sc->keyframe_count || current_sample+key_off == sc->keyframes[stss_index])) {
5085 keyframe = 1;
5086 if (stss_index + 1 < sc->keyframe_count)
5087 stss_index++;
5088 } else if (sc->stps_count && current_sample+key_off == sc->stps_data[stps_index]) {
5089 keyframe = 1;
5090 if (stps_index + 1 < sc->stps_count)
5091 stps_index++;
5092 }
5093 if (rap_group_present && rap_group_index < sc->rap_group_count) {
5094 if (sc->rap_group[rap_group_index].index > 0)
5095 keyframe = 1;
5096 if (++rap_group_sample == sc->rap_group[rap_group_index].count) {
5097 rap_group_sample = 0;
5098 rap_group_index++;
5099 }
5100 }
5101 if (sc->keyframe_absent
5102 && !sc->stps_count
5103 && !rap_group_present
5104 && (st->codecpar->codec_type == AVMEDIA_TYPE_AUDIO || (i==0 && j==0)))
5105 keyframe = 1;
5106 if (keyframe)
5107 distance = 0;
5108 sample_size = sc->stsz_sample_size > 0 ? sc->stsz_sample_size : sc->sample_sizes[current_sample];
5109 if (current_offset > INT64_MAX - sample_size) {
5110 av_log(mov->fc, AV_LOG_ERROR, "Current offset %"PRId64" or sample size %u is too large\n",
5111 current_offset,
5112 sample_size);
5113 return;
5114 }
5115
5116 if (sc->pseudo_stream_id == -1 ||
5117 sc->stsc_data[stsc_index].id - 1 == sc->pseudo_stream_id) {
5118 AVIndexEntry *e;
5119 if (sample_size > 0x3FFFFFFF) {
5120 av_log(mov->fc, AV_LOG_ERROR, "Sample size %u is too large\n", sample_size);
5121 return;
5122 }
5123 e = &sti->index_entries[sti->nb_index_entries++];
5124 e->pos = current_offset;
5125 e->timestamp = current_dts;
5126 e->size = sample_size;
5128 e->flags = keyframe ? AVINDEX_KEYFRAME : 0;
5129 av_log(mov->fc, AV_LOG_TRACE, "AVIndex stream %d, sample %u, offset %"PRIx64", dts %"PRId64", "
5130 "size %u, distance %u, keyframe %d\n", st->index, current_sample,
5131 current_offset, current_dts, sample_size, distance, keyframe);
5132 if (st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO && sti->nb_index_entries < 100)
5133 ff_rfps_add_frame(mov->fc, st, current_dts);
5134 }
5135
5136 current_offset += sample_size;
5137 stream_size += sample_size;
5138
5139 if (current_dts > INT64_MAX - sc->tts_data[stts_index].duration)
5140 return;
5141 current_dts += sc->tts_data[stts_index].duration;
5142
5143 distance++;
5144 stts_sample++;
5145 current_sample++;
5146 if (stts_index + 1 < sc->tts_count && stts_sample == sc->tts_data[stts_index].count) {
5147 stts_sample = 0;
5148 stts_index++;
5149 }
5150 }
5151 }
5152 if (st->duration > 0)
5153 st->codecpar->bit_rate = stream_size*8*sc->time_scale/st->duration;
5154 } else {
5155 unsigned chunk_samples, total = 0;
5156
5157 if (!sc->chunk_count || sc->tts_count)
5158 return;
5159
5160 // compute total chunk count
5161 for (i = 0; i < sc->stsc_count; i++) {
5162 unsigned count, chunk_count;
5163
5164 chunk_samples = sc->stsc_data[i].count;
5165 if (i != sc->stsc_count - 1 &&
5166 sc->samples_per_frame && chunk_samples % sc->samples_per_frame) {
5167 av_log(mov->fc, AV_LOG_ERROR, "error unaligned chunk\n");
5168 return;
5169 }
5170
5171 if (sc->samples_per_frame >= 160) { // gsm
5172 count = chunk_samples / sc->samples_per_frame;
5173 } else if (sc->samples_per_frame > 1) {
5174 unsigned samples = (1024/sc->samples_per_frame)*sc->samples_per_frame;
5175 count = (chunk_samples+samples-1) / samples;
5176 } else {
5177 count = (chunk_samples+1023) / 1024;
5178 }
5179
5181 chunk_count = sc->stsc_data[i+1].first - sc->stsc_data[i].first;
5182 else
5183 chunk_count = sc->chunk_count - (sc->stsc_data[i].first - 1);
5184 total += chunk_count * count;
5185 }
5186
5187 av_log(mov->fc, AV_LOG_TRACE, "chunk count %u\n", total);
5188 if (total >= UINT_MAX / sizeof(*sti->index_entries) - sti->nb_index_entries)
5189 return;
5191 sti->nb_index_entries + total,
5192 sizeof(*sti->index_entries)) < 0) {
5193 sti->nb_index_entries = 0;
5194 return;
5195 }
5196 sti->index_entries_allocated_size = (sti->nb_index_entries + total) * sizeof(*sti->index_entries);
5197
5198 // populate index
5199 for (i = 0; i < sc->chunk_count; i++) {
5200 current_offset = sc->chunk_offsets[i];
5201 if (mov_stsc_index_valid(stsc_index, sc->stsc_count) &&
5202 i + 1 == sc->stsc_data[stsc_index + 1].first)
5203 stsc_index++;
5204 chunk_samples = sc->stsc_data[stsc_index].count;
5205
5206 while (chunk_samples > 0) {
5207 AVIndexEntry *e;
5208 unsigned size, samples;
5209
5210 if (sc->samples_per_frame > 1 && !sc->bytes_per_frame) {
5212 "Zero bytes per frame, but %d samples per frame",
5213 sc->samples_per_frame);
5214 return;
5215 }
5216
5217 if (sc->samples_per_frame >= 160) { // gsm
5218 samples = sc->samples_per_frame;
5219 size = sc->bytes_per_frame;
5220 } else {
5221 if (sc->samples_per_frame > 1) {
5222 samples = FFMIN((1024 / sc->samples_per_frame)*
5223 sc->samples_per_frame, chunk_samples);
5224 size = (samples / sc->samples_per_frame) * sc->bytes_per_frame;
5225 } else {
5226 samples = FFMIN(1024, chunk_samples);
5227 size = samples * sc->sample_size;
5228 }
5229 }
5230
5231 if (sti->nb_index_entries >= total) {
5232 av_log(mov->fc, AV_LOG_ERROR, "wrong chunk count %u\n", total);
5233 return;
5234 }
5235 if (size > 0x3FFFFFFF) {
5236 av_log(mov->fc, AV_LOG_ERROR, "Sample size %u is too large\n", size);
5237 return;
5238 }
5239 e = &sti->index_entries[sti->nb_index_entries++];
5240 e->pos = current_offset;
5241 e->timestamp = current_dts;
5242 e->size = size;
5243 e->min_distance = 0;
5245 av_log(mov->fc, AV_LOG_TRACE, "AVIndex stream %d, chunk %u, offset %"PRIx64", dts %"PRId64", "
5246 "size %u, duration %u\n", st->index, i, current_offset, current_dts,
5247 size, samples);
5248
5249 current_offset += size;
5250 if (current_dts > INT64_MAX - samples)
5251 return;
5252 current_dts += samples;
5253 chunk_samples -= samples;
5254 }
5255 }
5256
5257 ret = mov_merge_tts_data(mov, st, MOV_MERGE_CTTS);
5258 if (ret < 0)
5259 return;
5260 }
5261
5262 if (!mov->ignore_editlist && mov->advanced_editlist) {
5263 // Fix index according to edit lists.
5264 mov_fix_index(mov, st);
5265 }
5266
5267 // Update start time of the stream.
5270 if (sc->tts_data) {
5272 }
5273 }
5274
5275 mov_estimate_video_delay(mov, st);
5276}
5277
5282
5283static int mov_compare_presentation_samples(const void *a, const void *b)
5284{
5285 const MOVPresentationSample *sa = a;
5286 const MOVPresentationSample *sb = b;
5287
5288 if (sa->pts != sb->pts)
5289 return (sa->pts > sb->pts) - (sa->pts < sb->pts);
5290 return (sa->index > sb->index) - (sa->index < sb->index);
5291}
5292
5293/*
5294 * Set sample durations from adjacent presentation timestamps.
5295 */
5297{
5298 MOVStreamContext *sc = st->priv_data;
5299 FFStream *const sti = ffstream(st);
5300 MOVPresentationSample *samples = NULL;
5301 MOVTimeToSample *tts_data = NULL;
5302 unsigned int tts_index = 0, tts_sample = 0;
5303 int count = sti->nb_index_entries;
5304
5305 /* A single STTS entry describes a fixed sample delta. */
5307 !sc->ctts_count || sc->stts_count < 2 ||
5308 !sc->tts_data || count < 2 ||
5309 count >= UINT_MAX / sizeof(*tts_data))
5310 return;
5311
5312 samples = av_malloc_array(count, sizeof(*samples));
5313 tts_data = av_malloc_array(count, sizeof(*tts_data));
5314 if (!samples || !tts_data)
5315 goto fail;
5316
5317 for (int i = 0; i < count; i++) {
5318 int64_t dts, offset;
5319
5320 if (tts_index >= sc->tts_count || !sc->tts_data[tts_index].count)
5321 goto fail;
5322
5323 tts_data[i] = sc->tts_data[tts_index];
5324 tts_data[i].count = 1;
5325
5326 dts = sti->index_entries[i].timestamp;
5327 offset = (int64_t)sc->dts_shift + tts_data[i].offset;
5328 if (dts == AV_NOPTS_VALUE ||
5329 (offset > 0 && dts > INT64_MAX - offset) ||
5330 (offset < 0 && dts < INT64_MIN - offset))
5331 goto fail;
5332
5333 samples[i].index = i;
5334 samples[i].pts = dts + offset;
5335
5336 if (++tts_sample == sc->tts_data[tts_index].count) {
5337 tts_index++;
5338 tts_sample = 0;
5339 }
5340 }
5341 if (tts_index != sc->tts_count || tts_sample)
5342 goto fail;
5343
5344 qsort(samples, count, sizeof(*samples), mov_compare_presentation_samples);
5345
5346 for (int i = 0; i + 1 < count; i++) {
5347 uint64_t duration;
5348
5349 if (samples[i].pts >= samples[i + 1].pts)
5350 goto fail;
5351
5352 /*
5353 * In VFR streams with reordered frames, STTS deltas follow decode
5354 * order while AVPacket.duration follows presentation order. CTTS
5355 * may produce presentation intervals that cannot be obtained by
5356 * merely permuting the STTS deltas, so derive each known duration
5357 * from adjacent PTS.
5358 */
5359 duration = (uint64_t)samples[i + 1].pts - samples[i].pts;
5360 if (!duration || duration > UINT_MAX)
5361 goto fail;
5362
5363 tts_data[samples[i].index].duration = (unsigned int)duration;
5364 }
5365
5366 av_log(mov->fc, AV_LOG_DEBUG,
5367 "Updated sample durations in presentation order for stream %d\n",
5368 st->index);
5369
5370 av_freep(&sc->tts_data);
5371 sc->tts_data = tts_data;
5372 sc->tts_count = count;
5373 sc->tts_allocated_size = count * sizeof(*tts_data);
5374 tts_data = NULL;
5375
5376fail:
5377 av_free(samples);
5378 av_free(tts_data);
5379}
5380
5381static int test_same_origin(const char *src, const char *ref) {
5382 char src_proto[64];
5383 char ref_proto[64];
5384 char src_auth[256];
5385 char ref_auth[256];
5386 char src_host[256];
5387 char ref_host[256];
5388 int src_port=-1;
5389 int ref_port=-1;
5390
5391 av_url_split(src_proto, sizeof(src_proto), src_auth, sizeof(src_auth), src_host, sizeof(src_host), &src_port, NULL, 0, src);
5392 av_url_split(ref_proto, sizeof(ref_proto), ref_auth, sizeof(ref_auth), ref_host, sizeof(ref_host), &ref_port, NULL, 0, ref);
5393
5394 if (strlen(src) == 0) {
5395 return -1;
5396 } else if (strlen(src_auth) + 1 >= sizeof(src_auth) ||
5397 strlen(ref_auth) + 1 >= sizeof(ref_auth) ||
5398 strlen(src_host) + 1 >= sizeof(src_host) ||
5399 strlen(ref_host) + 1 >= sizeof(ref_host)) {
5400 return 0;
5401 } else if (strcmp(src_proto, ref_proto) ||
5402 strcmp(src_auth, ref_auth) ||
5403 strcmp(src_host, ref_host) ||
5404 src_port != ref_port) {
5405 return 0;
5406 } else
5407 return 1;
5408}
5409
5410static int mov_open_dref(MOVContext *c, AVIOContext **pb, const char *src, MOVDref *ref)
5411{
5412 /* try relative path, we do not try the absolute because it can leak information about our
5413 system to an attacker */
5414 if (ref->nlvl_to > 0 && ref->nlvl_from > 0) {
5415 char filename[1025];
5416 const char *src_path;
5417 int i, l;
5418
5419 /* find a source dir */
5420 src_path = strrchr(src, '/');
5421 if (src_path)
5422 src_path++;
5423 else
5424 src_path = src;
5425
5426 /* find a next level down to target */
5427 for (i = 0, l = strlen(ref->path) - 1; l >= 0; l--)
5428 if (ref->path[l] == '/') {
5429 if (i == ref->nlvl_to - 1)
5430 break;
5431 else
5432 i++;
5433 }
5434
5435 /* compose filename if next level down to target was found */
5436 if (i == ref->nlvl_to - 1 && src_path - src < sizeof(filename)) {
5437 memcpy(filename, src, src_path - src);
5438 filename[src_path - src] = 0;
5439
5440 for (i = 1; i < ref->nlvl_from; i++)
5441 av_strlcat(filename, "../", sizeof(filename));
5442
5443 av_strlcat(filename, ref->path + l + 1, sizeof(filename));
5444 if (!c->use_absolute_path) {
5445 int same_origin = test_same_origin(src, filename);
5446
5447 if (!same_origin) {
5448 av_log(c->fc, AV_LOG_ERROR,
5449 "Reference with mismatching origin, %s not tried for security reasons, "
5450 "set demuxer option use_absolute_path to allow it anyway\n",
5451 ref->path);
5452 return AVERROR(ENOENT);
5453 }
5454
5455 if (strstr(ref->path + l + 1, "..") ||
5456 strstr(ref->path + l + 1, ":") ||
5457 (ref->nlvl_from > 1 && same_origin < 0) ||
5458 (filename[0] == '/' && src_path == src))
5459 return AVERROR(ENOENT);
5460 }
5461
5462 if (strlen(filename) + 1 == sizeof(filename))
5463 return AVERROR(ENOENT);
5464 if (!c->fc->io_open(c->fc, pb, filename, AVIO_FLAG_READ, NULL))
5465 return 0;
5466 }
5467 } else if (c->use_absolute_path) {
5468 av_log(c->fc, AV_LOG_WARNING, "Using absolute path on user request, "
5469 "this is a possible security issue\n");
5470 if (!c->fc->io_open(c->fc, pb, ref->path, AVIO_FLAG_READ, NULL))
5471 return 0;
5472 } else {
5473 av_log(c->fc, AV_LOG_ERROR,
5474 "Absolute path %s not tried for security reasons, "
5475 "set demuxer option use_absolute_path to allow absolute paths\n",
5476 ref->path);
5477 }
5478
5479 return AVERROR(ENOENT);
5480}
5481
5483{
5484 if (sc->time_scale <= 0) {
5485 av_log(c->fc, AV_LOG_WARNING, "stream %d, timescale not set\n", sc->ffindex);
5486 sc->time_scale = c->time_scale;
5487 if (sc->time_scale <= 0)
5488 sc->time_scale = 1;
5489 }
5490}
5491
5492#if CONFIG_IAMFDEC
5493static int mov_update_iamf_streams(MOVContext *c, const AVStream *st)
5494{
5495 const MOVStreamContext *sc = st->priv_data;
5496 const IAMFContext *iamf = &sc->iamf->iamf;
5497
5498 for (int i = 0; i < iamf->nb_audio_elements; i++) {
5499 const AVStreamGroup *stg = NULL;
5500
5501 for (int j = 0; j < c->fc->nb_stream_groups; j++)
5502 if (c->fc->stream_groups[j]->id == iamf->audio_elements[i]->audio_element_id)
5503 stg = c->fc->stream_groups[j];
5504 av_assert0(stg);
5505
5506 for (int j = 0; j < stg->nb_streams; j++) {
5507 const FFStream *sti = cffstream(st);
5508 AVStream *out = stg->streams[j];
5509 FFStream *out_sti = ffstream(stg->streams[j]);
5510
5511 out->codecpar->bit_rate = 0;
5512
5513 if (out == st)
5514 continue;
5515
5516 out->time_base = st->time_base;
5517 out->start_time = st->start_time;
5518 out->duration = st->duration;
5519 out->nb_frames = st->nb_frames;
5520 out->discard = st->discard;
5521
5522 av_assert0(!out_sti->index_entries);
5524 if (!out_sti->index_entries)
5525 return AVERROR(ENOMEM);
5526
5528 out_sti->nb_index_entries = sti->nb_index_entries;
5529 out_sti->skip_samples = sti->skip_samples;
5530 memcpy(out_sti->index_entries, sti->index_entries, sti->index_entries_allocated_size);
5531 }
5532 }
5533
5534 return 0;
5535}
5536#endif
5537
5538static int sanity_checks(void *log_obj, MOVStreamContext *sc, int index)
5539{
5540 if ((sc->chunk_count && (!sc->stts_count || !sc->stsc_count ||
5541 (!sc->sample_size && !sc->sample_count))) ||
5542 (sc->sample_count && (!sc->chunk_count ||
5543 (!sc->sample_size && !sc->sample_sizes)))) {
5544 av_log(log_obj, AV_LOG_ERROR, "stream %d, missing mandatory atoms, broken header\n",
5545 index);
5546 return 1;
5547 }
5548
5549 if (sc->stsc_count && sc->stsc_data[ sc->stsc_count - 1 ].first > sc->chunk_count) {
5550 av_log(log_obj, AV_LOG_ERROR, "stream %d, contradictionary STSC and STCO\n",
5551 index);
5552 return 2;
5553 }
5554 return 0;
5555}
5556
5558{
5559 AVStream *st;
5560 MOVStreamContext *sc;
5561 int ret;
5562
5563 st = avformat_new_stream(c->fc, NULL);
5564 if (!st) return AVERROR(ENOMEM);
5565 st->id = -1;
5566 sc = av_mallocz(sizeof(MOVStreamContext));
5567 if (!sc) return AVERROR(ENOMEM);
5568
5569 st->priv_data = sc;
5571 sc->ffindex = st->index;
5572 c->trak_index = st->index;
5573 sc->refcount = 1;
5574
5575 if ((ret = mov_read_default(c, pb, atom)) < 0)
5576 return ret;
5577
5578 c->trak_index = -1;
5579
5580 // Here stsc refers to a chunk not described in stco. This is technically invalid,
5581 // but we can overlook it (clearing stsc) whenever stts_count == 0 (indicating no samples).
5582 if (!sc->chunk_count && !sc->stts_count && sc->stsc_count) {
5583 sc->stsc_count = 0;
5584 av_freep(&sc->stsc_data);
5585 }
5586
5587 ret = sanity_checks(c->fc, sc, st->index);
5588 if (ret)
5589 return ret > 1 ? AVERROR_INVALIDDATA : 0;
5590
5591 fix_timescale(c, sc);
5592
5593 avpriv_set_pts_info(st, 64, 1, sc->time_scale);
5594
5595 /*
5596 * Advanced edit list support does not work with fragemented MP4s, which
5597 * have stsc, stsz, stco, and stts with zero entries in the moov atom.
5598 * In these files, trun atoms may be streamed in.
5599 */
5600 if (!sc->stts_count && c->advanced_editlist) {
5601
5602 av_log(c->fc, AV_LOG_VERBOSE, "advanced_editlist does not work with fragmented "
5603 "MP4. disabling.\n");
5604 c->advanced_editlist = 0;
5605 c->advanced_editlist_autodisabled = 1;
5606 }
5607
5608 mov_build_index(c, st);
5609 /*
5610 * Fragment samples are appended later by mov_read_trun() and are not
5611 * covered by this non-fragmented track update.
5612 */
5614
5615#if CONFIG_IAMFDEC
5616 if (sc->iamf) {
5617 ret = mov_update_iamf_streams(c, st);
5618 if (ret < 0)
5619 return ret;
5620 }
5621#endif
5622
5623 if (sc->dref_id-1 < sc->drefs_count && sc->drefs[sc->dref_id-1].path) {
5624 MOVDref *dref = &sc->drefs[sc->dref_id - 1];
5625 if (c->enable_drefs) {
5626 if (mov_open_dref(c, &sc->pb, c->fc->url, dref) < 0)
5627 av_log(c->fc, AV_LOG_ERROR,
5628 "stream %d, error opening alias: path='%s', dir='%s', "
5629 "filename='%s', volume='%s', nlvl_from=%d, nlvl_to=%d\n",
5630 st->index, dref->path, dref->dir, dref->filename,
5631 dref->volume, dref->nlvl_from, dref->nlvl_to);
5632 } else {
5633 av_log(c->fc, AV_LOG_WARNING,
5634 "Skipped opening external track: "
5635 "stream %d, alias: path='%s', dir='%s', "
5636 "filename='%s', volume='%s', nlvl_from=%d, nlvl_to=%d."
5637 "Set enable_drefs to allow this.\n",
5638 st->index, dref->path, dref->dir, dref->filename,
5639 dref->volume, dref->nlvl_from, dref->nlvl_to);
5640 }
5641 } else {
5642 sc->pb = c->fc->pb;
5643 sc->pb_is_copied = 1;
5644 }
5645
5647 int stts_constant = sc->stts_count && sc->tts_count;
5648 if (sc->h_spacing && sc->v_spacing)
5650 sc->h_spacing, sc->v_spacing, INT_MAX);
5651 if (!st->sample_aspect_ratio.num && st->codecpar->width && st->codecpar->height &&
5652 sc->height && sc->width &&
5653 (st->codecpar->width != sc->width || st->codecpar->height != sc->height)) {
5655 (int64_t)st->codecpar->height * sc->width,
5656 (int64_t)st->codecpar->width * sc->height, INT_MAX);
5657 }
5658
5659#if FF_API_R_FRAME_RATE
5660 for (unsigned int i = 1; sc->stts_count && i + 1 < sc->tts_count; i++) {
5661 if (sc->tts_data[i].duration == sc->tts_data[0].duration)
5662 continue;
5663 stts_constant = 0;
5664 }
5665 if (stts_constant)
5667 sc->time_scale, sc->tts_data[0].duration, INT_MAX);
5668#endif
5669 }
5670
5671#if CONFIG_H261_DECODER || CONFIG_H263_DECODER || CONFIG_MPEG4_DECODER
5672 switch (st->codecpar->codec_id) {
5673#if CONFIG_H261_DECODER
5674 case AV_CODEC_ID_H261:
5675#endif
5676#if CONFIG_H263_DECODER
5677 case AV_CODEC_ID_H263:
5678#endif
5679#if CONFIG_MPEG4_DECODER
5680 case AV_CODEC_ID_MPEG4:
5681#endif
5682 st->codecpar->width = 0; /* let decoder init width/height */
5683 st->codecpar->height= 0;
5684 break;
5685 }
5686#endif
5687
5688 // If the duration of the mp3 packets is not constant, then they could need a parser
5690 && sc->time_scale == st->codecpar->sample_rate) {
5691 int stts_constant = 1;
5692 for (int i = 1; sc->stts_count && i < sc->tts_count; i++) {
5693 if (sc->tts_data[i].duration == sc->tts_data[0].duration)
5694 continue;
5695 stts_constant = 0;
5696 }
5697 if (!stts_constant)
5699 }
5700 /* Do not need those anymore. */
5701 av_freep(&sc->chunk_offsets);
5702 av_freep(&sc->sample_sizes);
5703 av_freep(&sc->keyframes);
5704 av_freep(&sc->stps_data);
5705 av_freep(&sc->elst_data);
5706 av_freep(&sc->rap_group);
5707 av_freep(&sc->sync_group);
5708 av_freep(&sc->sgpd_sync);
5709
5710 return 0;
5711}
5712
5714{
5715 int ret;
5716 c->itunes_metadata = 1;
5717 ret = mov_read_default(c, pb, atom);
5718 c->itunes_metadata = 0;
5719 return ret;
5720}
5721
5723{
5724 uint32_t count;
5725 uint32_t i;
5726
5727 if (atom.size < 8)
5728 return 0;
5729
5730 avio_skip(pb, 4);
5731 count = avio_rb32(pb);
5732 atom.size -= 8;
5733 if (count > atom.size / 8 || count >= UINT_MAX / sizeof(*c->meta_keys)) {
5734 av_log(c->fc, AV_LOG_ERROR,
5735 "The 'keys' atom with the invalid key count: %"PRIu32"\n", count);
5736 return AVERROR_INVALIDDATA;
5737 }
5738
5739 c->meta_keys = av_malloc_array(count + 1, sizeof(*c->meta_keys));
5740 if (!c->meta_keys)
5741 return AVERROR(ENOMEM);
5742
5743 c->meta_keys[0] = NULL;
5744 c->meta_keys_count = 1;
5745 for (i = 1; i <= count; ++i) {
5746 uint32_t key_size = avio_rb32(pb);
5747 uint32_t type = avio_rl32(pb);
5748 c->meta_keys[i] = NULL;
5749 c->meta_keys_count = i + 1;
5750 if (key_size < 8 || key_size > atom.size) {
5751 av_log(c->fc, AV_LOG_ERROR,
5752 "The key# %"PRIu32" in meta has invalid size:"
5753 "%"PRIu32"\n", i, key_size);
5754 return AVERROR_INVALIDDATA;
5755 }
5756 atom.size -= key_size;
5757 key_size -= 8;
5758 if (type != MKTAG('m','d','t','a')) {
5759 avio_skip(pb, key_size);
5760 continue;
5761 }
5762 c->meta_keys[i] = av_malloc(key_size + 1);
5763 if (!c->meta_keys[i])
5764 return AVERROR(ENOMEM);
5765 int ret = ffio_read_size(pb, c->meta_keys[i], key_size);
5766 if (ret < 0)
5767 return ret;
5768 c->meta_keys[i][key_size] = 0;
5769 }
5770
5771 return 0;
5772}
5773
5775{
5776 int64_t end = av_sat_add64(avio_tell(pb), atom.size);
5777 uint8_t *key = NULL, *val = NULL, *mean = NULL;
5778 int i;
5779 int ret = 0;
5780 AVStream *st;
5781
5782 if (c->fc->nb_streams < 1)
5783 return 0;
5784 st = c->fc->streams[c->fc->nb_streams-1];
5785
5786 for (i = 0; i < 3; i++) {
5787 uint8_t **p;
5788 uint32_t len, tag;
5789
5790 if (end - avio_tell(pb) <= 12)
5791 break;
5792
5793 len = avio_rb32(pb);
5794 tag = avio_rl32(pb);
5795 avio_skip(pb, 4); // flags
5796
5797 if (len < 12 || len - 12 > end - avio_tell(pb))
5798 break;
5799 len -= 12;
5800
5801 if (tag == MKTAG('m', 'e', 'a', 'n'))
5802 p = &mean;
5803 else if (tag == MKTAG('n', 'a', 'm', 'e'))
5804 p = &key;
5805 else if (tag == MKTAG('d', 'a', 't', 'a') && len > 4) {
5806 avio_skip(pb, 4);
5807 len -= 4;
5808 p = &val;
5809 } else
5810 break;
5811
5812 if (*p)
5813 break;
5814
5815 *p = av_malloc(len + 1);
5816 if (!*p) {
5817 ret = AVERROR(ENOMEM);
5818 break;
5819 }
5820 ret = ffio_read_size(pb, *p, len);
5821 if (ret < 0) {
5822 av_freep(p);
5823 break;
5824 }
5825 (*p)[len] = 0;
5826 }
5827
5828 if (mean && key && val) {
5829 if (strcmp(key, "iTunSMPB") == 0) {
5830 int64_t priming, remainder, samples;
5831 if (ff_itunes_parse_smpb(val, &priming, &remainder, &samples) >= 0) {
5832 if(priming>0 && priming<16384)
5833 st->codecpar->initial_padding = priming = av_rescale_q(priming, st->time_base,
5834 (AVRational){ 1, st->codecpar->sample_rate });
5835 if (remainder > 0) {
5837 (AVRational){ 1, st->codecpar->sample_rate });
5838 remainder = av_rescale_q(remainder, st->time_base,
5839 (AVRational){ 1, st->codecpar->sample_rate });
5840 samples = av_rescale_q(samples, st->time_base,
5841 (AVRational){ 1, st->codecpar->sample_rate });
5842 if (duration > remainder && duration > samples) {
5843 ffstream(st)->first_discard_sample = duration - remainder;
5845 }
5846 }
5847 av_log(c->fc, AV_LOG_DEBUG, "Parsed iTunSMPB: priming %"PRId64", "
5848 "remainder %"PRId64" samples %"PRId64"\n",
5849 priming, remainder, samples);
5850 }
5851 }
5852 if (strcmp(mean, "com.apple.iTunes") == 0 &&
5853 strcmp(key, "DISCSUBTITLE") == 0) {
5854 av_dict_set(&c->fc->metadata, "disc_subtitle", val,
5856 val = NULL;
5857 }
5858 if (strcmp(key, "cdec") != 0) {
5859 av_dict_set(&c->fc->metadata, key, val,
5861 key = val = NULL;
5862 }
5863 } else {
5864 av_log(c->fc, AV_LOG_VERBOSE,
5865 "Unhandled or malformed custom metadata of size %"PRId64"\n", atom.size);
5866 }
5867
5868 avio_seek(pb, end, SEEK_SET);
5869 av_freep(&key);
5870 av_freep(&val);
5871 av_freep(&mean);
5872 return ret;
5873}
5874
5876{
5877 MOVStreamContext *sc;
5878 AVStream *st;
5879
5880 st = avformat_new_stream(c->fc, NULL);
5881 if (!st)
5882 return AVERROR(ENOMEM);
5883 sc = av_mallocz(sizeof(MOVStreamContext));
5884 if (!sc)
5885 goto fail;
5886
5887 item->st = st;
5888 st->id = item->item_id;
5889 st->priv_data = sc;
5891 st->codecpar->codec_id = mov_codec_id(st, item->type);
5892 sc->id = st->id;
5893 sc->ffindex = st->index;
5894 st->avg_frame_rate.num = st->avg_frame_rate.den = 1;
5895 st->time_base.num = st->time_base.den = 1;
5896 st->nb_frames = 1;
5897 sc->time_scale = 1;
5898 sc->pb = c->fc->pb;
5899 sc->pb_is_copied = 1;
5900 sc->refcount = 1;
5901
5902 if (item->name)
5903 av_dict_set(&st->metadata, "title", item->name, 0);
5904
5905 // Populate the necessary fields used by mov_build_index.
5906 sc->stsc_data = av_malloc_array(1, sizeof(*sc->stsc_data));
5907 if (!sc->stsc_data)
5908 goto fail;
5909 sc->stsc_count = 1;
5910 sc->stsc_data[0].first = 1;
5911 sc->stsc_data[0].count = 1;
5912 sc->stsc_data[0].id = 1;
5913 sc->chunk_offsets = av_malloc_array(1, sizeof(*sc->chunk_offsets));
5914 if (!sc->chunk_offsets)
5915 goto fail;
5916 sc->chunk_count = 1;
5917 sc->stts_data = av_malloc_array(1, sizeof(*sc->stts_data));
5918 if (!sc->stts_data)
5919 goto fail;
5920 sc->stts_count = 1;
5921 sc->stts_data[0].count = 1;
5922 // Not used for still images. But needed by mov_build_index.
5923 sc->stts_data[0].duration = 0;
5924
5925 return 0;
5926fail:
5927 mov_free_stream_context(c->fc, st);
5928 ff_remove_stream(c->fc, st);
5929 item->st = NULL;
5930
5931 return AVERROR(ENOMEM);
5932}
5933
5935{
5936 while (atom.size > 8) {
5937 uint32_t tag;
5938 if (avio_feof(pb))
5939 return AVERROR_EOF;
5940 tag = avio_rl32(pb);
5941 atom.size -= 4;
5942 if (tag == MKTAG('h','d','l','r')) {
5943 avio_seek(pb, -8, SEEK_CUR);
5944 atom.size += 8;
5945 return mov_read_default(c, pb, atom);
5946 }
5947 }
5948 return 0;
5949}
5950
5951// return 1 when matrix is identity, 0 otherwise
5952#define IS_MATRIX_IDENT(matrix) \
5953 ( (matrix)[0][0] == (1 << 16) && \
5954 (matrix)[1][1] == (1 << 16) && \
5955 (matrix)[2][2] == (1 << 30) && \
5956 !(matrix)[0][1] && !(matrix)[0][2] && \
5957 !(matrix)[1][0] && !(matrix)[1][2] && \
5958 !(matrix)[2][0] && !(matrix)[2][1])
5959
5961{
5962 int i, j, e;
5963 int width;
5964 int height;
5965 int display_matrix[3][3];
5966 int res_display_matrix[3][3] = { { 0 } };
5967 AVStream *st;
5968 MOVStreamContext *sc;
5969 int version;
5970 int flags;
5971
5972 if (c->fc->nb_streams < 1)
5973 return 0;
5974 st = c->fc->streams[c->fc->nb_streams-1];
5975 sc = st->priv_data;
5976
5977 // Each stream (trak) should have exactly 1 tkhd. This catches bad files and
5978 // avoids corrupting AVStreams mapped to an earlier tkhd.
5979 if (st->id != -1)
5980 return AVERROR_INVALIDDATA;
5981
5982 version = avio_r8(pb);
5983 flags = avio_rb24(pb);
5985
5986 if (version == 1) {
5987 avio_rb64(pb);
5988 avio_rb64(pb);
5989 } else {
5990 avio_rb32(pb); /* creation time */
5991 avio_rb32(pb); /* modification time */
5992 }
5993 st->id = (int)avio_rb32(pb); /* track id (NOT 0 !)*/
5994 sc->id = st->id;
5995 avio_rb32(pb); /* reserved */
5996
5997 /* highlevel (considering edits) duration in movie timebase */
5998 (version == 1) ? avio_rb64(pb) : avio_rb32(pb);
5999 avio_rb32(pb); /* reserved */
6000 avio_rb32(pb); /* reserved */
6001
6002 avio_rb16(pb); /* layer */
6003 avio_rb16(pb); /* alternate group */
6004 avio_rb16(pb); /* volume */
6005 avio_rb16(pb); /* reserved */
6006
6007 //read in the display matrix (outlined in ISO 14496-12, Section 6.2.2)
6008 // they're kept in fixed point format through all calculations
6009 // save u,v,z to store the whole matrix in the AV_PKT_DATA_DISPLAYMATRIX
6010 // side data, but the scale factor is not needed to calculate aspect ratio
6011 for (i = 0; i < 3; i++) {
6012 display_matrix[i][0] = avio_rb32(pb); // 16.16 fixed point
6013 display_matrix[i][1] = avio_rb32(pb); // 16.16 fixed point
6014 display_matrix[i][2] = avio_rb32(pb); // 2.30 fixed point
6015 }
6016
6017 width = avio_rb32(pb); // 16.16 fixed point track width
6018 height = avio_rb32(pb); // 16.16 fixed point track height
6019 sc->width = width >> 16;
6020 sc->height = height >> 16;
6021
6022 // apply the moov display matrix (after the tkhd one)
6023 for (i = 0; i < 3; i++) {
6024 const int sh[3] = { 16, 16, 30 };
6025 for (j = 0; j < 3; j++) {
6026 for (e = 0; e < 3; e++) {
6027 res_display_matrix[i][j] +=
6028 ((int64_t) display_matrix[i][e] *
6029 c->movie_display_matrix[e][j]) >> sh[e];
6030 }
6031 }
6032 }
6033
6034 // save the matrix when it is not the default identity
6035 if (!IS_MATRIX_IDENT(res_display_matrix)) {
6037 sc->display_matrix = av_malloc(sizeof(int32_t) * 9);
6038 if (!sc->display_matrix)
6039 return AVERROR(ENOMEM);
6040
6041 for (i = 0; i < 3; i++)
6042 for (j = 0; j < 3; j++)
6043 sc->display_matrix[i * 3 + j] = res_display_matrix[i][j];
6044 }
6045
6046 // transform the display width/height according to the matrix
6047 // to keep the same scale, use [width height 1<<16]
6048 if (width && height && sc->display_matrix) {
6049 double disp_transform[2];
6050
6051 for (i = 0; i < 2; i++)
6052 disp_transform[i] = hypot(sc->display_matrix[0 + i],
6053 sc->display_matrix[3 + i]);
6054
6055 if (disp_transform[0] > 1 && disp_transform[1] > 1 &&
6056 disp_transform[0] < (1<<24) && disp_transform[1] < (1<<24) &&
6057 fabs((disp_transform[0] / disp_transform[1]) - 1.0) > 0.01)
6059 disp_transform[0] / disp_transform[1],
6060 INT_MAX);
6061 }
6062 return 0;
6063}
6064
6066{
6067 MOVFragment *frag = &c->fragment;
6068 MOVTrackExt *trex = NULL;
6069 int flags, track_id, i;
6070 MOVFragmentStreamInfo * frag_stream_info;
6071
6072 avio_r8(pb); /* version */
6073 flags = avio_rb24(pb);
6074
6075 track_id = avio_rb32(pb);
6076 if (!track_id)
6077 return AVERROR_INVALIDDATA;
6078 for (i = 0; i < c->trex_count; i++)
6079 if (c->trex_data[i].track_id == track_id) {
6080 trex = &c->trex_data[i];
6081 break;
6082 }
6083 if (!trex) {
6084 av_log(c->fc, AV_LOG_WARNING, "could not find corresponding trex (id %u)\n", track_id);
6085 return 0;
6086 }
6087 c->fragment.found_tfhd = 1;
6088 frag->track_id = track_id;
6089 set_frag_stream(&c->frag_index, track_id);
6090
6093 frag->moof_offset : frag->implicit_offset;
6094 frag->stsd_id = flags & MOV_TFHD_STSD_ID ? avio_rb32(pb) : trex->stsd_id;
6095
6097 avio_rb32(pb) : trex->duration;
6098 frag->size = flags & MOV_TFHD_DEFAULT_SIZE ?
6099 avio_rb32(pb) : trex->size;
6101 avio_rb32(pb) : trex->flags;
6102 av_log(c->fc, AV_LOG_TRACE, "frag flags 0x%x\n", frag->flags);
6103
6104 frag_stream_info = get_current_frag_stream_info(&c->frag_index);
6105 if (frag_stream_info) {
6106 frag_stream_info->next_trun_dts = AV_NOPTS_VALUE;
6107 frag_stream_info->stsd_id = frag->stsd_id;
6108 }
6109 return 0;
6110}
6111
6113{
6114 unsigned i, num;
6115 void *new_tracks;
6116
6117 num = atom.size / 4;
6118 if (!(new_tracks = av_malloc_array(num, sizeof(int))))
6119 return AVERROR(ENOMEM);
6120
6121 av_free(c->chapter_tracks);
6122 c->chapter_tracks = new_tracks;
6123 c->nb_chapter_tracks = num;
6124
6125 for (i = 0; i < num && !pb->eof_reached; i++)
6126 c->chapter_tracks[i] = avio_rb32(pb);
6127
6128 c->nb_chapter_tracks = i;
6129
6130 return 0;
6131}
6132
6134{
6135 MOVTrackExt *trex;
6136 int err;
6137
6138 if ((uint64_t)c->trex_count+1 >= UINT_MAX / sizeof(*c->trex_data))
6139 return AVERROR_INVALIDDATA;
6140 if ((err = av_reallocp_array(&c->trex_data, c->trex_count + 1,
6141 sizeof(*c->trex_data))) < 0) {
6142 c->trex_count = 0;
6143 return err;
6144 }
6145
6146 c->fc->duration = AV_NOPTS_VALUE; // the duration from mvhd is not representing the whole file when fragments are used.
6147
6148 trex = &c->trex_data[c->trex_count++];
6149 avio_r8(pb); /* version */
6150 avio_rb24(pb); /* flags */
6151 trex->track_id = avio_rb32(pb);
6152 trex->stsd_id = avio_rb32(pb);
6153 trex->duration = avio_rb32(pb);
6154 trex->size = avio_rb32(pb);
6155 trex->flags = avio_rb32(pb);
6156 return 0;
6157}
6158
6160{
6161 MOVFragment *frag = &c->fragment;
6162 AVStream *st = NULL;
6163 MOVStreamContext *sc;
6164 int version, i;
6165 MOVFragmentStreamInfo * frag_stream_info;
6166 int64_t base_media_decode_time;
6167
6168 for (i = 0; i < c->fc->nb_streams; i++) {
6169 sc = c->fc->streams[i]->priv_data;
6170 if (sc->id == frag->track_id) {
6171 st = c->fc->streams[i];
6172 break;
6173 }
6174 }
6175 if (!st) {
6176 av_log(c->fc, AV_LOG_WARNING, "could not find corresponding track id %u\n", frag->track_id);
6177 return 0;
6178 }
6179 sc = st->priv_data;
6180 if (sc->pseudo_stream_id + 1 != frag->stsd_id && sc->pseudo_stream_id != -1)
6181 return 0;
6182 version = avio_r8(pb);
6183 avio_rb24(pb); /* flags */
6184 if (version) {
6185 base_media_decode_time = avio_rb64(pb);
6186 } else {
6187 base_media_decode_time = avio_rb32(pb);
6188 }
6189
6190 frag_stream_info = get_current_frag_stream_info(&c->frag_index);
6191 if (frag_stream_info)
6192 frag_stream_info->tfdt_dts = base_media_decode_time;
6193 sc->track_end = base_media_decode_time;
6194
6195 return 0;
6196}
6197
6199{
6200 MOVFragment *frag = &c->fragment;
6201 AVStream *st = NULL;
6202 FFStream *sti = NULL;
6203 MOVStreamContext *sc;
6204 MOVTimeToSample *tts_data;
6205 uint64_t offset;
6206 int64_t dts, pts = AV_NOPTS_VALUE;
6207 int data_offset = 0;
6208 unsigned entries, first_sample_flags = frag->flags;
6209 int flags, distance, i;
6210 int64_t prev_dts = AV_NOPTS_VALUE;
6211 int next_frag_index = -1, index_entry_pos;
6212 size_t requested_size;
6213 AVIndexEntry *new_entries;
6214 MOVFragmentStreamInfo * frag_stream_info;
6215
6216 if (!frag->found_tfhd) {
6217 av_log(c->fc, AV_LOG_ERROR, "trun track id unknown, no tfhd was found\n");
6218 return AVERROR_INVALIDDATA;
6219 }
6220
6221 for (i = 0; i < c->fc->nb_streams; i++) {
6222 sc = c->fc->streams[i]->priv_data;
6223 if (sc->id == frag->track_id) {
6224 st = c->fc->streams[i];
6225 sti = ffstream(st);
6226 break;
6227 }
6228 }
6229 if (!st) {
6230 av_log(c->fc, AV_LOG_WARNING, "could not find corresponding track id %u\n", frag->track_id);
6231 return 0;
6232 }
6233 sc = st->priv_data;
6234 if (sc->pseudo_stream_id+1 != frag->stsd_id && sc->pseudo_stream_id != -1)
6235 return 0;
6236
6237 // Find the next frag_index index that has a valid index_entry for
6238 // the current track_id.
6239 //
6240 // A valid index_entry means the trun for the fragment was read
6241 // and it's samples are in index_entries at the given position.
6242 // New index entries will be inserted before the index_entry found.
6243 index_entry_pos = sti->nb_index_entries;
6244 for (i = c->frag_index.current + 1; i < c->frag_index.nb_items; i++) {
6245 frag_stream_info = get_frag_stream_info(&c->frag_index, i, frag->track_id);
6246 if (frag_stream_info && frag_stream_info->index_entry >= 0) {
6247 next_frag_index = i;
6248 index_entry_pos = frag_stream_info->index_entry;
6249 break;
6250 }
6251 }
6252 av_assert0(index_entry_pos <= sti->nb_index_entries);
6253
6254 avio_r8(pb); /* version */
6255 flags = avio_rb24(pb);
6256 entries = avio_rb32(pb);
6257 av_log(c->fc, AV_LOG_TRACE, "flags 0x%x entries %u\n", flags, entries);
6258
6259 /* Explicit zero sizes are bounded by the trun payload. Reject a zero
6260 * default size before allocating or updating the sample index. */
6261 if (entries && !frag->size && !(flags & MOV_TRUN_SAMPLE_SIZE))
6262 return AVERROR_INVALIDDATA;
6263
6264 if ((uint64_t)entries+sc->tts_count >= UINT_MAX/sizeof(*sc->tts_data))
6265 return AVERROR_INVALIDDATA;
6266 if (flags & MOV_TRUN_DATA_OFFSET) data_offset = avio_rb32(pb);
6267 if (flags & MOV_TRUN_FIRST_SAMPLE_FLAGS) first_sample_flags = avio_rb32(pb);
6268
6269 int entry_size = !!(flags & MOV_TRUN_SAMPLE_DURATION) * 4
6270 + !!(flags & MOV_TRUN_SAMPLE_SIZE) * 4
6271 + !!(flags & MOV_TRUN_SAMPLE_FLAGS) * 4
6272 + !!(flags & MOV_TRUN_SAMPLE_CTS) * 4;
6273 int64_t sample_data_size = avio_size(sc->pb);
6274 int64_t max_entries = INT64_MAX;
6275
6276 if (sample_data_size > 0)
6277 max_entries = sample_data_size - sti->nb_index_entries;
6278 if (entry_size) {
6279 int64_t size = sc->pb == pb ? sample_data_size : avio_size(pb);
6280 int64_t pos = avio_tell(pb);
6281 int64_t left = atom.size - 8 - !!(flags & MOV_TRUN_DATA_OFFSET) * 4
6283
6284 if (pos >= 0 && size >= pos)
6285 left = FFMIN(left, size - pos);
6286 max_entries = FFMIN(max_entries, left / entry_size);
6287 }
6288 if (entries > max_entries) {
6289 av_log(c->fc, AV_LOG_ERROR, "trun sample count %u exceeds the %"PRId64" "
6290 "samples the input can hold\n", entries, max_entries);
6291 return AVERROR_INVALIDDATA;
6292 }
6293
6294 frag_stream_info = get_current_frag_stream_info(&c->frag_index);
6295 if (frag_stream_info) {
6296 if (frag_stream_info->next_trun_dts != AV_NOPTS_VALUE) {
6297 dts = frag_stream_info->next_trun_dts - sc->time_offset;
6298 } else if (frag_stream_info->first_tfra_pts != AV_NOPTS_VALUE &&
6299 c->use_mfra_for == FF_MOV_FLAG_MFRA_PTS) {
6300 pts = frag_stream_info->first_tfra_pts;
6301 av_log(c->fc, AV_LOG_DEBUG, "found mfra time %"PRId64
6302 ", using it for pts\n", pts);
6303 } else if (frag_stream_info->first_tfra_pts != AV_NOPTS_VALUE &&
6304 c->use_mfra_for == FF_MOV_FLAG_MFRA_DTS) {
6305 dts = frag_stream_info->first_tfra_pts;
6306 av_log(c->fc, AV_LOG_DEBUG, "found mfra time %"PRId64
6307 ", using it for dts\n", pts);
6308 } else {
6309 int has_tfdt = frag_stream_info->tfdt_dts != AV_NOPTS_VALUE;
6310 int has_sidx = frag_stream_info->sidx_pts != AV_NOPTS_VALUE;
6311 int fallback_tfdt = !c->use_tfdt && !has_sidx && has_tfdt;
6312 int fallback_sidx = c->use_tfdt && !has_tfdt && has_sidx;
6313
6314 if (fallback_sidx) {
6315 av_log(c->fc, AV_LOG_DEBUG, "use_tfdt set but no tfdt found, using sidx instead\n");
6316 }
6317 if (fallback_tfdt) {
6318 av_log(c->fc, AV_LOG_DEBUG, "use_tfdt not set but no sidx found, using tfdt instead\n");
6319 }
6320
6321 if (has_tfdt && c->use_tfdt || fallback_tfdt) {
6322 dts = frag_stream_info->tfdt_dts - sc->time_offset;
6323 av_log(c->fc, AV_LOG_DEBUG, "found tfdt time %"PRId64
6324 ", using it for dts\n", dts);
6325 } else if (has_sidx && !c->use_tfdt || fallback_sidx) {
6326 // FIXME: sidx earliest_presentation_time is *PTS*, s.b.
6327 // pts = frag_stream_info->sidx_pts;
6328 dts = frag_stream_info->sidx_pts;
6329 av_log(c->fc, AV_LOG_DEBUG, "found sidx time %"PRId64
6330 ", using it for dts\n", frag_stream_info->sidx_pts);
6331 } else {
6332 dts = sc->track_end - sc->time_offset;
6333 av_log(c->fc, AV_LOG_DEBUG, "found track end time %"PRId64
6334 ", using it for dts\n", dts);
6335 }
6336 }
6337 } else {
6338 dts = sc->track_end - sc->time_offset;
6339 av_log(c->fc, AV_LOG_DEBUG, "found track end time %"PRId64
6340 ", using it for dts\n", dts);
6341 }
6342 offset = frag->base_data_offset + data_offset;
6343 distance = 0;
6344 av_log(c->fc, AV_LOG_TRACE, "first sample flags 0x%x\n", first_sample_flags);
6345
6346 // realloc space for new index entries
6347 if ((uint64_t)sti->nb_index_entries + entries >= UINT_MAX / sizeof(AVIndexEntry)) {
6348 entries = UINT_MAX / sizeof(AVIndexEntry) - sti->nb_index_entries;
6349 av_log(c->fc, AV_LOG_ERROR, "Failed to add index entry\n");
6350 }
6351 if (entries == 0)
6352 return 0;
6353
6354 requested_size = (sti->nb_index_entries + entries) * sizeof(AVIndexEntry);
6355 new_entries = av_fast_realloc(sti->index_entries,
6357 requested_size);
6358 if (!new_entries)
6359 return AVERROR(ENOMEM);
6360 sti->index_entries= new_entries;
6361
6362 requested_size = (sti->nb_index_entries + entries) * sizeof(*sc->tts_data);
6363 tts_data = av_fast_realloc(sc->tts_data, &sc->tts_allocated_size,
6364 requested_size);
6365 if (!tts_data)
6366 return AVERROR(ENOMEM);
6367 sc->tts_data = tts_data;
6368
6369 // In case there were samples without time to sample entries, ensure they get
6370 // zero valued entries. This ensures clips which mix boxes with and
6371 // without time to sample entries don't pickup uninitialized data.
6372 if (sc->tts_count < sti->nb_index_entries)
6373 memset(sc->tts_data + sc->tts_count, 0,
6374 sizeof(*sc->tts_data) * (sti->nb_index_entries - sc->tts_count));
6375
6376 if (index_entry_pos < sti->nb_index_entries) {
6377 // Make hole in index_entries and tts_data for new samples
6378 memmove(sti->index_entries + index_entry_pos + entries,
6379 sti->index_entries + index_entry_pos,
6380 sizeof(*sti->index_entries) *
6381 (sti->nb_index_entries - index_entry_pos));
6382 memmove(sc->tts_data + index_entry_pos + entries,
6383 sc->tts_data + index_entry_pos,
6384 sizeof(*sc->tts_data) * (sti->nb_index_entries - index_entry_pos));
6385 if (index_entry_pos < sc->current_sample) {
6386 sc->current_sample += entries;
6387 }
6388 }
6389
6390 sti->nb_index_entries += entries;
6391 sc->tts_count = sti->nb_index_entries;
6392 sc->stts_count = sti->nb_index_entries;
6394 sc->ctts_count = sti->nb_index_entries;
6395
6396 // Record the index_entry position in frag_index of this fragment
6397 if (frag_stream_info) {
6398 frag_stream_info->index_entry = index_entry_pos;
6399 if (frag_stream_info->index_base < 0)
6400 frag_stream_info->index_base = index_entry_pos;
6401 }
6402
6403 if (index_entry_pos > 0)
6404 prev_dts = sti->index_entries[index_entry_pos-1].timestamp;
6405
6406 for (i = 0; i < entries && !pb->eof_reached; i++) {
6407 unsigned sample_size = frag->size;
6408 int sample_flags = i ? frag->flags : first_sample_flags;
6409 unsigned sample_duration = frag->duration;
6410 unsigned ctts_duration = 0;
6411 int keyframe = 0;
6412 int index_entry_flags = 0;
6413
6414 if (flags & MOV_TRUN_SAMPLE_DURATION) sample_duration = avio_rb32(pb);
6415 if (flags & MOV_TRUN_SAMPLE_SIZE) sample_size = avio_rb32(pb);
6416 if (flags & MOV_TRUN_SAMPLE_FLAGS) sample_flags = avio_rb32(pb);
6417 if (flags & MOV_TRUN_SAMPLE_CTS) ctts_duration = avio_rb32(pb);
6418
6419 if (sample_duration > c->max_stts_delta) {
6420 av_log(c->fc, AV_LOG_WARNING,
6421 "Too large sample duration %u in trun entry %u in st:%d. Clipping to 1.\n",
6422 sample_duration, i, st->index);
6423 sample_duration = 1;
6424 }
6425
6426 mov_update_dts_shift(sc, ctts_duration, c->fc);
6427 if (pts != AV_NOPTS_VALUE) {
6428 dts = pts - sc->dts_shift;
6429 if (flags & MOV_TRUN_SAMPLE_CTS) {
6430 dts -= ctts_duration;
6431 } else {
6432 dts -= sc->time_offset;
6433 }
6434 av_log(c->fc, AV_LOG_DEBUG,
6435 "pts %"PRId64" calculated dts %"PRId64
6436 " sc->dts_shift %d ctts.duration %d"
6437 " sc->time_offset %"PRId64
6438 " flags & MOV_TRUN_SAMPLE_CTS %d\n",
6439 pts, dts,
6440 sc->dts_shift, ctts_duration,
6443 }
6444
6445 keyframe =
6446 !(sample_flags & (MOV_FRAG_SAMPLE_FLAG_IS_NON_SYNC |
6448 if (keyframe) {
6449 distance = 0;
6450 index_entry_flags |= AVINDEX_KEYFRAME;
6451 }
6452 // Fragments can overlap in time. Discard overlapping frames after
6453 // decoding.
6454 if (prev_dts >= dts)
6455 index_entry_flags |= AVINDEX_DISCARD_FRAME;
6456
6457 sti->index_entries[index_entry_pos].pos = offset;
6458 sti->index_entries[index_entry_pos].timestamp = dts;
6459 sti->index_entries[index_entry_pos].size = sample_size;
6460 sti->index_entries[index_entry_pos].min_distance = distance;
6461 sti->index_entries[index_entry_pos].flags = index_entry_flags;
6462
6463 sc->tts_data[index_entry_pos].count = 1;
6464 sc->tts_data[index_entry_pos].offset = ctts_duration;
6465 sc->tts_data[index_entry_pos].duration = sample_duration;
6466 index_entry_pos++;
6467
6468 av_log(c->fc, AV_LOG_TRACE, "AVIndex stream %d, sample %d, offset %"PRIx64", dts %"PRId64", "
6469 "size %u, distance %d, keyframe %d\n", st->index,
6470 index_entry_pos, offset, dts, sample_size, distance, keyframe);
6471 distance++;
6472 if (av_sat_add64(dts, sample_duration) != dts + (uint64_t)sample_duration)
6473 return AVERROR_INVALIDDATA;
6474 dts += sample_duration;
6475 offset += sample_size;
6476 sc->data_size += sample_size;
6477
6478 if (sample_duration <= INT64_MAX - sc->duration_for_fps &&
6479 1 <= INT_MAX - sc->nb_frames_for_fps
6480 ) {
6481 sc->duration_for_fps += sample_duration;
6482 sc->nb_frames_for_fps ++;
6483 }
6484 }
6485 if (frag_stream_info)
6486 frag_stream_info->next_trun_dts = dts + sc->time_offset;
6487 if (i < entries) {
6488 // EOF found before reading all entries. Fix the hole this would
6489 // leave in index_entries and tts_data
6490 int gap = entries - i;
6491 memmove(sti->index_entries + index_entry_pos,
6492 sti->index_entries + index_entry_pos + gap,
6493 sizeof(*sti->index_entries) *
6494 (sti->nb_index_entries - (index_entry_pos + gap)));
6495 memmove(sc->tts_data + index_entry_pos,
6496 sc->tts_data + index_entry_pos + gap,
6497 sizeof(*sc->tts_data) *
6498 (sc->tts_count - (index_entry_pos + gap)));
6499
6500 sti->nb_index_entries -= gap;
6501 sc->tts_count -= gap;
6502 if (index_entry_pos < sc->current_sample) {
6503 sc->current_sample -= gap;
6504 }
6505 entries = i;
6506 }
6507
6508 // The end of this new fragment may overlap in time with the start
6509 // of the next fragment in index_entries. Mark the samples in the next
6510 // fragment that overlap with AVINDEX_DISCARD_FRAME
6511 prev_dts = AV_NOPTS_VALUE;
6512 if (index_entry_pos > 0)
6513 prev_dts = sti->index_entries[index_entry_pos-1].timestamp;
6514 for (int i = index_entry_pos; i < sti->nb_index_entries; i++) {
6515 if (prev_dts < sti->index_entries[i].timestamp)
6516 break;
6518 }
6519
6520 // If a hole was created to insert the new index_entries into,
6521 // the index_entry recorded for all subsequent moof must
6522 // be incremented by the number of entries inserted.
6523 fix_frag_index_entries(&c->frag_index, next_frag_index,
6524 frag->track_id, entries);
6525
6526 if (pb->eof_reached) {
6527 av_log(c->fc, AV_LOG_WARNING, "reached eof, corrupted TRUN atom\n");
6528 return AVERROR_EOF;
6529 }
6530
6531 frag->implicit_offset = offset;
6532
6533 sc->track_end = dts + sc->time_offset;
6534 if (st->duration < sc->track_end)
6535 st->duration = sc->track_end;
6536
6537 return 0;
6538}
6539
6541{
6542 int64_t stream_size = avio_size(pb);
6543 int64_t offset = av_sat_add64(avio_tell(pb), atom.size), pts, timestamp;
6544 uint8_t version, is_complete;
6545 int64_t offadd;
6546 unsigned i, j, track_id, item_count;
6547 AVStream *st = NULL;
6548 AVStream *ref_st = NULL;
6549 MOVStreamContext *sc, *ref_sc = NULL;
6550 AVRational timescale;
6551
6552 version = avio_r8(pb);
6553 if (version > 1) {
6554 avpriv_request_sample(c->fc, "sidx version %u", version);
6555 return 0;
6556 }
6557
6558 avio_rb24(pb); // flags
6559
6560 track_id = avio_rb32(pb); // Reference ID
6561 for (i = 0; i < c->fc->nb_streams; i++) {
6562 sc = c->fc->streams[i]->priv_data;
6563 if (sc->id == track_id) {
6564 st = c->fc->streams[i];
6565 break;
6566 }
6567 }
6568 if (!st) {
6569 av_log(c->fc, AV_LOG_WARNING, "could not find corresponding track id %d\n", track_id);
6570 return 0;
6571 }
6572
6573 sc = st->priv_data;
6574
6575 timescale = av_make_q(1, avio_rb32(pb));
6576
6577 if (timescale.den <= 0) {
6578 av_log(c->fc, AV_LOG_ERROR, "Invalid sidx timescale 1/%d\n", timescale.den);
6579 return AVERROR_INVALIDDATA;
6580 }
6581
6582 if (version == 0) {
6583 pts = avio_rb32(pb);
6584 offadd= avio_rb32(pb);
6585 } else {
6586 pts = avio_rb64(pb);
6587 offadd= avio_rb64(pb);
6588 }
6589 if (av_sat_add64(offset, offadd) != offset + (uint64_t)offadd)
6590 return AVERROR_INVALIDDATA;
6591
6592 offset += (uint64_t)offadd;
6593
6594 avio_rb16(pb); // reserved
6595
6596 item_count = avio_rb16(pb);
6597 if (item_count == 0)
6598 return AVERROR_INVALIDDATA;
6599
6600 for (i = 0; i < item_count; i++) {
6601 int index;
6602 MOVFragmentStreamInfo * frag_stream_info;
6603 uint32_t size = avio_rb32(pb);
6604 uint32_t duration = avio_rb32(pb);
6605 if (size & 0x80000000) {
6606 avpriv_request_sample(c->fc, "sidx reference_type 1");
6607 return AVERROR_PATCHWELCOME;
6608 }
6609 avio_rb32(pb); // sap_flags
6610 timestamp = av_rescale_q(pts, timescale, st->time_base);
6611
6613 frag_stream_info = get_frag_stream_info(&c->frag_index, index, track_id);
6614 if (frag_stream_info)
6615 frag_stream_info->sidx_pts = timestamp;
6616
6617 if (av_sat_add64(offset, size) != offset + (uint64_t)size ||
6618 av_sat_add64(pts, duration) != pts + (uint64_t)duration
6619 )
6620 return AVERROR_INVALIDDATA;
6621 offset += size;
6622 pts += duration;
6623 }
6624
6625 st->duration = sc->track_end = pts;
6626
6627 sc->has_sidx = 1;
6628
6629 // See if the remaining bytes are just an mfra which we can ignore.
6630 is_complete = offset == stream_size;
6631 if (!is_complete && (pb->seekable & AVIO_SEEKABLE_NORMAL) && stream_size > 0 ) {
6632 int64_t ret;
6633 int64_t original_pos = avio_tell(pb);
6634 if (!c->have_read_mfra_size) {
6635 if ((ret = avio_seek(pb, stream_size - 4, SEEK_SET)) < 0)
6636 return ret;
6637 c->mfra_size = avio_rb32(pb);
6638 c->have_read_mfra_size = 1;
6639 if ((ret = avio_seek(pb, original_pos, SEEK_SET)) < 0)
6640 return ret;
6641 }
6642 if (offset == stream_size - c->mfra_size)
6643 is_complete = 1;
6644 }
6645
6646 if (is_complete) {
6647 // Find first entry in fragment index that came from an sidx.
6648 // This will pretty much always be the first entry.
6649 for (i = 0; i < c->frag_index.nb_items; i++) {
6650 MOVFragmentIndexItem * item = &c->frag_index.item[i];
6651 for (j = 0; ref_st == NULL && j < item->nb_stream_info; j++) {
6653 si = &item->stream_info[j];
6654 if (si->sidx_pts != AV_NOPTS_VALUE) {
6655 ref_st = c->fc->streams[j];
6656 ref_sc = ref_st->priv_data;
6657 break;
6658 }
6659 }
6660 }
6661 if (ref_st) for (i = 0; i < c->fc->nb_streams; i++) {
6662 st = c->fc->streams[i];
6663 sc = st->priv_data;
6664 if (!sc->has_sidx) {
6665 st->duration = sc->track_end = av_rescale(ref_st->duration, sc->time_scale, ref_sc->time_scale);
6666 }
6667 }
6668
6669 if (offadd == 0)
6670 c->frag_index.complete = 1;
6671 }
6672
6673 return 0;
6674}
6675
6676/* this atom should be null (from specs), but some buggy files put the 'moov' atom inside it... */
6677/* like the files created with Adobe Premiere 5.0, for samples see */
6678/* http://graphics.tudelft.nl/~wouter/publications/soundtests/ */
6680{
6681 int err;
6682
6683 if (atom.size < 8)
6684 return 0; /* continue */
6685 if (avio_rb32(pb) != 0) { /* 0 sized mdat atom... use the 'wide' atom size */
6686 avio_skip(pb, atom.size - 4);
6687 return 0;
6688 }
6689 atom.type = avio_rl32(pb);
6690 atom.size -= 8;
6691 if (atom.type != MKTAG('m','d','a','t')) {
6692 avio_skip(pb, atom.size);
6693 return 0;
6694 }
6695 err = mov_read_mdat(c, pb, atom);
6696 return err;
6697}
6698
6700{
6701#if CONFIG_ZLIB
6703 uint8_t *cmov_data;
6704 uint8_t *moov_data; /* uncompressed data */
6705 long cmov_len, moov_len;
6706 int ret = -1;
6707
6708 avio_rb32(pb); /* dcom atom */
6709 if (avio_rl32(pb) != MKTAG('d','c','o','m'))
6710 return AVERROR_INVALIDDATA;
6711 if (avio_rl32(pb) != MKTAG('z','l','i','b')) {
6712 av_log(c->fc, AV_LOG_ERROR, "unknown compression for cmov atom !\n");
6713 return AVERROR_INVALIDDATA;
6714 }
6715 avio_rb32(pb); /* cmvd atom */
6716 if (avio_rl32(pb) != MKTAG('c','m','v','d'))
6717 return AVERROR_INVALIDDATA;
6718 moov_len = avio_rb32(pb); /* uncompressed size */
6719 cmov_len = atom.size - 6 * 4;
6720
6721 cmov_data = av_malloc(cmov_len);
6722 if (!cmov_data)
6723 return AVERROR(ENOMEM);
6724 moov_data = av_malloc(moov_len);
6725 if (!moov_data) {
6726 av_free(cmov_data);
6727 return AVERROR(ENOMEM);
6728 }
6729 ret = ffio_read_size(pb, cmov_data, cmov_len);
6730 if (ret < 0)
6731 goto free_and_return;
6732
6733 ret = AVERROR_INVALIDDATA;
6734 if (uncompress (moov_data, (uLongf *) &moov_len, (const Bytef *)cmov_data, cmov_len) != Z_OK)
6735 goto free_and_return;
6736 ffio_init_read_context(&ctx, moov_data, moov_len);
6737 ctx.pub.seekable = AVIO_SEEKABLE_NORMAL;
6738 atom.type = MKTAG('m','o','o','v');
6739 atom.size = moov_len;
6740 ret = mov_read_default(c, &ctx.pub, atom);
6741free_and_return:
6742 av_free(moov_data);
6743 av_free(cmov_data);
6744 return ret;
6745#else
6746 av_log(c->fc, AV_LOG_ERROR, "this file requires zlib support compiled in\n");
6747 return AVERROR(ENOSYS);
6748#endif
6749}
6750
6751/* edit list atom */
6753{
6754 MOVStreamContext *sc;
6755 int i, edit_count, version;
6756 int64_t elst_entry_size;
6757
6758 if (c->fc->nb_streams < 1 || c->ignore_editlist)
6759 return 0;
6760 sc = c->fc->streams[c->fc->nb_streams-1]->priv_data;
6761
6762 version = avio_r8(pb); /* version */
6763 avio_rb24(pb); /* flags */
6764 edit_count = avio_rb32(pb); /* entries */
6765 atom.size -= 8;
6766
6767 elst_entry_size = version == 1 ? 20 : 12;
6768 if (atom.size != edit_count * elst_entry_size) {
6769 if (c->fc->strict_std_compliance >= FF_COMPLIANCE_STRICT) {
6770 av_log(c->fc, AV_LOG_ERROR, "Invalid edit list entry_count: %d for elst atom of size: %"PRId64" bytes.\n",
6771 edit_count, atom.size + 8);
6772 return AVERROR_INVALIDDATA;
6773 } else {
6774 edit_count = atom.size / elst_entry_size;
6775 if (edit_count * elst_entry_size != atom.size) {
6776 av_log(c->fc, AV_LOG_WARNING, "ELST atom of %"PRId64" bytes, bigger than %d entries.\n", atom.size, edit_count);
6777 }
6778 }
6779 }
6780
6781 if (!edit_count)
6782 return 0;
6783 if (sc->elst_data)
6784 av_log(c->fc, AV_LOG_WARNING, "Duplicated ELST atom\n");
6785 av_free(sc->elst_data);
6786 sc->elst_count = 0;
6787 sc->elst_data = av_malloc_array(edit_count, sizeof(*sc->elst_data));
6788 if (!sc->elst_data)
6789 return AVERROR(ENOMEM);
6790
6791 av_log(c->fc, AV_LOG_TRACE, "track[%u].edit_count = %i\n", c->fc->nb_streams - 1, edit_count);
6792 for (i = 0; i < edit_count && atom.size > 0 && !pb->eof_reached; i++) {
6793 MOVElst *e = &sc->elst_data[i];
6794
6795 if (version == 1) {
6796 e->duration = avio_rb64(pb);
6797 e->time = avio_rb64(pb);
6798 atom.size -= 16;
6799 } else {
6800 e->duration = avio_rb32(pb); /* segment duration */
6801 e->time = (int32_t)avio_rb32(pb); /* media time */
6802 atom.size -= 8;
6803 }
6804 e->rate = avio_rb32(pb) / 65536.0;
6805 atom.size -= 4;
6806 av_log(c->fc, AV_LOG_TRACE, "duration=%"PRId64" time=%"PRId64" rate=%f\n",
6807 e->duration, e->time, e->rate);
6808
6809 if (e->time < 0 && e->time != -1 &&
6810 c->fc->strict_std_compliance >= FF_COMPLIANCE_STRICT) {
6811 av_log(c->fc, AV_LOG_ERROR, "Track %d, edit %d: Invalid edit list media time=%"PRId64"\n",
6812 c->fc->nb_streams-1, i, e->time);
6813 return AVERROR_INVALIDDATA;
6814 }
6815 if (e->duration < 0) {
6816 av_log(c->fc, AV_LOG_ERROR, "Track %d, edit %d: Invalid edit list duration=%"PRId64"\n",
6817 c->fc->nb_streams-1, i, e->duration);
6818 return AVERROR_INVALIDDATA;
6819 }
6820 }
6821 sc->elst_count = i;
6822
6823 return 0;
6824}
6825
6827{
6828 MOVStreamContext *sc;
6829 int err;
6830
6831 if (c->fc->nb_streams < 1)
6832 return AVERROR_INVALIDDATA;
6833 sc = c->fc->streams[c->fc->nb_streams - 1]->priv_data;
6834
6835 if (atom.size % sizeof(uint32_t))
6836 return AVERROR_INVALIDDATA;
6837
6838 MovTref *tag = mov_add_tref_tag(sc, atom.type);
6839 if (!tag)
6840 return AVERROR(ENOMEM);
6841
6842 int nb_timecode_track = atom.size >> 2;
6843 for (int i = 0; i < nb_timecode_track; i++) {
6844 if (avio_feof(pb))
6845 return AVERROR_INVALIDDATA;
6846 err = mov_add_tref_id(tag, avio_rb32(pb));
6847 if (err < 0)
6848 return err;
6849 }
6850
6851 return 0;
6852}
6853
6855{
6856 AVStream *st;
6857 int version, color_range, color_primaries, color_trc, color_space;
6858
6859 if (c->fc->nb_streams < 1)
6860 return 0;
6861 st = c->fc->streams[c->fc->nb_streams - 1];
6862
6863 if (atom.size < 5) {
6864 av_log(c->fc, AV_LOG_ERROR, "Empty VP Codec Configuration box\n");
6865 return AVERROR_INVALIDDATA;
6866 }
6867
6868 version = avio_r8(pb);
6869 if (version != 1) {
6870 av_log(c->fc, AV_LOG_WARNING, "Unsupported VP Codec Configuration box version %d\n", version);
6871 return 0;
6872 }
6873 avio_skip(pb, 3); /* flags */
6874
6875 avio_skip(pb, 2); /* profile + level */
6876 color_range = avio_r8(pb); /* bitDepth, chromaSubsampling, videoFullRangeFlag */
6878 color_trc = avio_r8(pb);
6879 color_space = avio_r8(pb);
6880 if (avio_rb16(pb)) /* codecIntializationDataSize */
6881 return AVERROR_INVALIDDATA;
6882
6885 if (!av_color_transfer_name(color_trc))
6886 color_trc = AVCOL_TRC_UNSPECIFIED;
6887 if (!av_color_space_name(color_space))
6888 color_space = AVCOL_SPC_UNSPECIFIED;
6889
6892 st->codecpar->color_trc = color_trc;
6893 st->codecpar->color_space = color_space;
6894
6895 return 0;
6896}
6897
6899{
6900 MOVStreamContext *sc;
6901 int i, version;
6902
6903 if (c->fc->nb_streams < 1)
6904 return AVERROR_INVALIDDATA;
6905
6906 sc = c->fc->streams[c->fc->nb_streams - 1]->priv_data;
6907
6908 if (atom.size < 5) {
6909 av_log(c->fc, AV_LOG_ERROR, "Empty Mastering Display Metadata box\n");
6910 return AVERROR_INVALIDDATA;
6911 }
6912
6913 version = avio_r8(pb);
6914 if (version) {
6915 av_log(c->fc, AV_LOG_WARNING, "Unsupported Mastering Display Metadata box version %d\n", version);
6916 return 0;
6917 }
6918 if (sc->mastering) {
6919 av_log(c->fc, AV_LOG_WARNING, "Ignoring duplicate Mastering Display Metadata\n");
6920 return 0;
6921 }
6922
6923 avio_skip(pb, 3); /* flags */
6924
6926 if (!sc->mastering)
6927 return AVERROR(ENOMEM);
6928
6929 for (i = 0; i < 3; i++) {
6930 sc->mastering->display_primaries[i][0] = av_make_q(avio_rb16(pb), 1 << 16);
6931 sc->mastering->display_primaries[i][1] = av_make_q(avio_rb16(pb), 1 << 16);
6932 }
6933 sc->mastering->white_point[0] = av_make_q(avio_rb16(pb), 1 << 16);
6934 sc->mastering->white_point[1] = av_make_q(avio_rb16(pb), 1 << 16);
6935
6936 sc->mastering->max_luminance = av_make_q(avio_rb32(pb), 1 << 8);
6937 sc->mastering->min_luminance = av_make_q(avio_rb32(pb), 1 << 14);
6938
6939 sc->mastering->has_primaries = 1;
6940 sc->mastering->has_luminance = 1;
6941
6942 return 0;
6943}
6944
6946{
6947 MOVStreamContext *sc;
6948 const int mapping[3] = {1, 2, 0};
6949 const int chroma_den = 50000;
6950 const int luma_den = 10000;
6951 int i;
6952
6953 if (c->fc->nb_streams < 1)
6954 return AVERROR_INVALIDDATA;
6955
6956 sc = c->fc->streams[c->fc->nb_streams - 1]->priv_data;
6957
6958 if (atom.size < 24) {
6959 av_log(c->fc, AV_LOG_ERROR, "Invalid Mastering Display Color Volume box\n");
6960 return AVERROR_INVALIDDATA;
6961 }
6962
6963 if (sc->mastering) {
6964 av_log(c->fc, AV_LOG_WARNING, "Ignoring duplicate Mastering Display Color Volume\n");
6965 return 0;
6966 }
6967
6969 if (!sc->mastering)
6970 return AVERROR(ENOMEM);
6971
6972 for (i = 0; i < 3; i++) {
6973 const int j = mapping[i];
6974 sc->mastering->display_primaries[j][0] = av_make_q(avio_rb16(pb), chroma_den);
6975 sc->mastering->display_primaries[j][1] = av_make_q(avio_rb16(pb), chroma_den);
6976 }
6977 sc->mastering->white_point[0] = av_make_q(avio_rb16(pb), chroma_den);
6978 sc->mastering->white_point[1] = av_make_q(avio_rb16(pb), chroma_den);
6979
6980 sc->mastering->max_luminance = av_make_q(avio_rb32(pb), luma_den);
6981 sc->mastering->min_luminance = av_make_q(avio_rb32(pb), luma_den);
6982
6983 sc->mastering->has_luminance = 1;
6984 sc->mastering->has_primaries = 1;
6985
6986 return 0;
6987}
6988
6990{
6991 MOVStreamContext *sc;
6992 int version;
6993
6994 if (c->fc->nb_streams < 1)
6995 return AVERROR_INVALIDDATA;
6996
6997 sc = c->fc->streams[c->fc->nb_streams - 1]->priv_data;
6998
6999 if (atom.size < 5) {
7000 av_log(c->fc, AV_LOG_ERROR, "Empty Content Light Level box\n");
7001 return AVERROR_INVALIDDATA;
7002 }
7003
7004 version = avio_r8(pb);
7005 if (version) {
7006 av_log(c->fc, AV_LOG_WARNING, "Unsupported Content Light Level box version %d\n", version);
7007 return 0;
7008 }
7009 avio_skip(pb, 3); /* flags */
7010
7011 if (sc->coll){
7012 av_log(c->fc, AV_LOG_WARNING, "Ignoring duplicate COLL\n");
7013 return 0;
7014 }
7015
7017 if (!sc->coll)
7018 return AVERROR(ENOMEM);
7019
7020 sc->coll->MaxCLL = avio_rb16(pb);
7021 sc->coll->MaxFALL = avio_rb16(pb);
7022
7023 return 0;
7024}
7025
7027{
7028 MOVStreamContext *sc;
7029
7030 if (c->fc->nb_streams < 1)
7031 return AVERROR_INVALIDDATA;
7032
7033 sc = c->fc->streams[c->fc->nb_streams - 1]->priv_data;
7034
7035 if (atom.size < 4) {
7036 av_log(c->fc, AV_LOG_ERROR, "Empty Content Light Level Info box\n");
7037 return AVERROR_INVALIDDATA;
7038 }
7039
7040 if (sc->coll){
7041 av_log(c->fc, AV_LOG_WARNING, "Ignoring duplicate CLLI/COLL\n");
7042 return 0;
7043 }
7044
7046 if (!sc->coll)
7047 return AVERROR(ENOMEM);
7048
7049 sc->coll->MaxCLL = avio_rb16(pb);
7050 sc->coll->MaxFALL = avio_rb16(pb);
7051
7052 return 0;
7053}
7054
7056{
7057 MOVStreamContext *sc;
7058 const int illuminance_den = 10000;
7059 const int ambient_den = 50000;
7060 if (c->fc->nb_streams < 1)
7061 return AVERROR_INVALIDDATA;
7062 sc = c->fc->streams[c->fc->nb_streams - 1]->priv_data;
7063 if (atom.size < 6) {
7064 av_log(c->fc, AV_LOG_ERROR, "Empty Ambient Viewing Environment Info box\n");
7065 return AVERROR_INVALIDDATA;
7066 }
7067 if (sc->ambient){
7068 av_log(c->fc, AV_LOG_WARNING, "Ignoring duplicate AMVE\n");
7069 return 0;
7070 }
7072 if (!sc->ambient)
7073 return AVERROR(ENOMEM);
7074 sc->ambient->ambient_illuminance = av_make_q(avio_rb32(pb), illuminance_den);
7075 sc->ambient->ambient_light_x = av_make_q(avio_rb16(pb), ambient_den);
7076 sc->ambient->ambient_light_y = av_make_q(avio_rb16(pb), ambient_den);
7077 return 0;
7078}
7079
7081{
7082 AVStream *st;
7083 MOVStreamContext *sc;
7084 enum AVStereo3DType type;
7085 int mode;
7086
7087 if (c->fc->nb_streams < 1)
7088 return 0;
7089
7090 st = c->fc->streams[c->fc->nb_streams - 1];
7091 sc = st->priv_data;
7092
7093 if (atom.size < 5) {
7094 av_log(c->fc, AV_LOG_ERROR, "Empty stereoscopic video box\n");
7095 return AVERROR_INVALIDDATA;
7096 }
7097
7098 if (sc->stereo3d)
7099 return AVERROR_INVALIDDATA;
7100
7101 avio_skip(pb, 4); /* version + flags */
7102
7103 mode = avio_r8(pb);
7104 switch (mode) {
7105 case 0:
7107 break;
7108 case 1:
7110 break;
7111 case 2:
7113 break;
7114 default:
7115 av_log(c->fc, AV_LOG_WARNING, "Unknown st3d mode value %d\n", mode);
7116 return 0;
7117 }
7118
7120 if (!sc->stereo3d)
7121 return AVERROR(ENOMEM);
7122
7123 sc->stereo3d->type = type;
7124 return 0;
7125}
7126
7128{
7129 AVStream *st;
7130 MOVStreamContext *sc;
7131 int size = 0;
7132 int64_t remaining;
7133 uint32_t tag = 0;
7135
7136 if (c->fc->nb_streams < 1)
7137 return 0;
7138
7139 st = c->fc->streams[c->fc->nb_streams - 1];
7140 sc = st->priv_data;
7141
7142 remaining = atom.size;
7143 while (remaining > 0) {
7144 size = avio_rb32(pb);
7145 if (size < 8 || size > remaining ) {
7146 av_log(c->fc, AV_LOG_ERROR, "Invalid child size in pack box\n");
7147 return AVERROR_INVALIDDATA;
7148 }
7149
7150 tag = avio_rl32(pb);
7151 switch (tag) {
7152 case MKTAG('p','k','i','n'): {
7153 if (size != 16) {
7154 av_log(c->fc, AV_LOG_ERROR, "Invalid size of pkin box: %d\n", size);
7155 return AVERROR_INVALIDDATA;
7156 }
7157 avio_skip(pb, 1); // version
7158 avio_skip(pb, 3); // flags
7159
7160 tag = avio_rl32(pb);
7161 switch (tag) {
7162 case MKTAG('s','i','d','e'):
7164 break;
7165 case MKTAG('o','v','e','r'):
7167 break;
7168 case 0:
7169 // This means value will be set in another layer
7170 break;
7171 default:
7172 av_log(c->fc, AV_LOG_WARNING, "Unknown tag in pkin: %s\n",
7174 avio_skip(pb, size - 8);
7175 break;
7176 }
7177
7178 break;
7179 }
7180 default:
7181 av_log(c->fc, AV_LOG_WARNING, "Unknown tag in pack: %s\n",
7183 avio_skip(pb, size - 8);
7184 break;
7185 }
7186 remaining -= size;
7187 }
7188
7189 if (remaining != 0) {
7190 av_log(c->fc, AV_LOG_ERROR, "Broken pack box\n");
7191 return AVERROR_INVALIDDATA;
7192 }
7193
7194 if (type == AV_STEREO3D_2D)
7195 return 0;
7196
7197 if (!sc->stereo3d) {
7199 if (!sc->stereo3d)
7200 return AVERROR(ENOMEM);
7201 }
7202
7203 sc->stereo3d->type = type;
7204
7205 return 0;
7206}
7207
7209{
7210 AVStream *st;
7211 MOVStreamContext *sc;
7212 int size, version, layout;
7213 int32_t yaw, pitch, roll;
7214 uint32_t l = 0, t = 0, r = 0, b = 0;
7215 uint32_t tag, padding = 0;
7216 enum AVSphericalProjection projection;
7217
7218 if (c->fc->nb_streams < 1)
7219 return 0;
7220
7221 st = c->fc->streams[c->fc->nb_streams - 1];
7222 sc = st->priv_data;
7223
7224 if (atom.size < 8) {
7225 av_log(c->fc, AV_LOG_ERROR, "Empty spherical video box\n");
7226 return AVERROR_INVALIDDATA;
7227 }
7228
7229 size = avio_rb32(pb);
7230 if (size <= 12 || size > atom.size)
7231 return AVERROR_INVALIDDATA;
7232
7233 tag = avio_rl32(pb);
7234 if (tag != MKTAG('s','v','h','d')) {
7235 av_log(c->fc, AV_LOG_ERROR, "Missing spherical video header\n");
7236 return 0;
7237 }
7238 version = avio_r8(pb);
7239 if (version != 0) {
7240 av_log(c->fc, AV_LOG_WARNING, "Unknown spherical version %d\n",
7241 version);
7242 return 0;
7243 }
7244 avio_skip(pb, 3); /* flags */
7245 avio_skip(pb, size - 12); /* metadata_source */
7246
7247 size = avio_rb32(pb);
7248 if (size > atom.size)
7249 return AVERROR_INVALIDDATA;
7250
7251 tag = avio_rl32(pb);
7252 if (tag != MKTAG('p','r','o','j')) {
7253 av_log(c->fc, AV_LOG_ERROR, "Missing projection box\n");
7254 return 0;
7255 }
7256
7257 size = avio_rb32(pb);
7258 if (size > atom.size)
7259 return AVERROR_INVALIDDATA;
7260
7261 tag = avio_rl32(pb);
7262 if (tag != MKTAG('p','r','h','d')) {
7263 av_log(c->fc, AV_LOG_ERROR, "Missing projection header box\n");
7264 return 0;
7265 }
7266 version = avio_r8(pb);
7267 if (version != 0) {
7268 av_log(c->fc, AV_LOG_WARNING, "Unknown spherical version %d\n",
7269 version);
7270 return 0;
7271 }
7272 avio_skip(pb, 3); /* flags */
7273
7274 /* 16.16 fixed point */
7275 yaw = avio_rb32(pb);
7276 pitch = avio_rb32(pb);
7277 roll = avio_rb32(pb);
7278
7279 size = avio_rb32(pb);
7280 if (size > atom.size)
7281 return AVERROR_INVALIDDATA;
7282
7283 tag = avio_rl32(pb);
7284 version = avio_r8(pb);
7285 if (version != 0) {
7286 av_log(c->fc, AV_LOG_WARNING, "Unknown spherical version %d\n",
7287 version);
7288 return 0;
7289 }
7290 avio_skip(pb, 3); /* flags */
7291 switch (tag) {
7292 case MKTAG('c','b','m','p'):
7293 layout = avio_rb32(pb);
7294 if (layout) {
7295 av_log(c->fc, AV_LOG_WARNING,
7296 "Unsupported cubemap layout %d\n", layout);
7297 return 0;
7298 }
7299 projection = AV_SPHERICAL_CUBEMAP;
7300 padding = avio_rb32(pb);
7301 break;
7302 case MKTAG('e','q','u','i'):
7303 t = avio_rb32(pb);
7304 b = avio_rb32(pb);
7305 l = avio_rb32(pb);
7306 r = avio_rb32(pb);
7307
7308 if (b >= UINT_MAX - t || r >= UINT_MAX - l) {
7309 av_log(c->fc, AV_LOG_ERROR,
7310 "Invalid bounding rectangle coordinates "
7311 "%"PRIu32",%"PRIu32",%"PRIu32",%"PRIu32"\n", l, t, r, b);
7312 return AVERROR_INVALIDDATA;
7313 }
7314
7315 if (l || t || r || b)
7317 else
7318 projection = AV_SPHERICAL_EQUIRECTANGULAR;
7319 break;
7320 default:
7321 av_log(c->fc, AV_LOG_ERROR, "Unknown projection type: %s\n", av_fourcc2str(tag));
7322 return 0;
7323 }
7324
7326 if (!sc->spherical)
7327 return AVERROR(ENOMEM);
7328
7329 sc->spherical->projection = projection;
7330
7331 sc->spherical->yaw = yaw;
7332 sc->spherical->pitch = pitch;
7333 sc->spherical->roll = roll;
7334
7335 sc->spherical->padding = padding;
7336
7337 sc->spherical->bound_left = l;
7338 sc->spherical->bound_top = t;
7339 sc->spherical->bound_right = r;
7340 sc->spherical->bound_bottom = b;
7341
7342 return 0;
7343}
7344
7346{
7347 AVStream *st;
7348 MOVStreamContext *sc;
7349 int size;
7350 uint32_t tag;
7351 enum AVSphericalProjection projection;
7352
7353 if (c->fc->nb_streams < 1)
7354 return 0;
7355
7356 st = c->fc->streams[c->fc->nb_streams - 1];
7357 sc = st->priv_data;
7358
7359 if (atom.size < 16) {
7360 av_log(c->fc, AV_LOG_ERROR, "Invalid size for proj box: %"PRIu64"\n", atom.size);
7361 return AVERROR_INVALIDDATA;
7362 }
7363
7364 size = avio_rb32(pb);
7365 if (size < 16) {
7366 av_log(c->fc, AV_LOG_ERROR, "Invalid size for prji box: %d\n", size);
7367 return AVERROR_INVALIDDATA;
7368 } else if (size > 16) {
7369 av_log(c->fc, AV_LOG_WARNING, "Box has more bytes (%d) than prji box required (16) \n", size);
7370 }
7371
7372 tag = avio_rl32(pb);
7373 if (tag != MKTAG('p','r','j','i')) {
7374 av_log(c->fc, AV_LOG_ERROR, "Invalid child box of proj box: %s\n",
7376 return AVERROR_INVALIDDATA;
7377 }
7378
7379 // version and flags, only support (0, 0)
7380 unsigned n = avio_rl32(pb);
7381 if (n != 0) {
7382 av_log(c->fc, AV_LOG_ERROR, "prji version %u, flag %u are not supported\n",
7383 n & 0xFF, n >> 8);
7384 return AVERROR_PATCHWELCOME;
7385 }
7386
7387 tag = avio_rl32(pb);
7388 switch (tag) {
7389 case MKTAG('r','e','c','t'):
7390 projection = AV_SPHERICAL_RECTILINEAR;
7391 break;
7392 case MKTAG('e','q','u','i'):
7393 projection = AV_SPHERICAL_EQUIRECTANGULAR;
7394 break;
7395 case MKTAG('h','e','q','u'):
7397 break;
7398 case MKTAG('f','i','s','h'):
7399 projection = AV_SPHERICAL_FISHEYE;
7400 break;
7401 case MKTAG('p','r','i','m'):
7403 break;
7404 default:
7405 av_log(c->fc, AV_LOG_ERROR, "Invalid projection type in prji box: %s\n", av_fourcc2str(tag));
7406 return AVERROR_INVALIDDATA;
7407 }
7408
7410 if (!sc->spherical)
7411 return AVERROR(ENOMEM);
7412
7413 sc->spherical->projection = projection;
7414
7415 return 0;
7416}
7417
7419{
7420 AVStream *st;
7421 MOVStreamContext *sc;
7422 int size, flags = 0;
7423 int64_t remaining;
7424 uint32_t tag, baseline = 0;
7427 enum AVStereo3DPrimaryEye primary_eye = AV_PRIMARY_EYE_NONE;
7428 AVRational horizontal_disparity_adjustment = { 0, 1 };
7429
7430 if (c->fc->nb_streams < 1)
7431 return 0;
7432
7433 st = c->fc->streams[c->fc->nb_streams - 1];
7434 sc = st->priv_data;
7435
7436 remaining = atom.size;
7437 while (remaining > 0) {
7438 size = avio_rb32(pb);
7439 if (size < 8 || size > remaining ) {
7440 av_log(c->fc, AV_LOG_ERROR, "Invalid child size in eyes box\n");
7441 return AVERROR_INVALIDDATA;
7442 }
7443
7444 tag = avio_rl32(pb);
7445 switch (tag) {
7446 case MKTAG('s','t','r','i'): {
7447 int has_right, has_left;
7448 uint8_t tmp;
7449 if (size != 13) {
7450 av_log(c->fc, AV_LOG_ERROR, "Invalid size of stri box: %d\n", size);
7451 return AVERROR_INVALIDDATA;
7452 }
7453 avio_skip(pb, 1); // version
7454 avio_skip(pb, 3); // flags
7455
7456 tmp = avio_r8(pb);
7457
7458 // eye_views_reversed
7459 if (tmp & 8) {
7461 }
7462 // has_additional_views
7463 if (tmp & 4) {
7464 // skip...
7465 }
7466
7467 has_right = tmp & 2; // has_right_eye_view
7468 has_left = tmp & 1; // has_left_eye_view
7469
7470 if (has_left && has_right)
7472 else if (has_left)
7473 view = AV_STEREO3D_VIEW_LEFT;
7474 else if (has_right)
7476 if (has_left || has_right)
7478
7479 break;
7480 }
7481 case MKTAG('h','e','r','o'): {
7482 int tmp;
7483 if (size != 13) {
7484 av_log(c->fc, AV_LOG_ERROR, "Invalid size of hero box: %d\n", size);
7485 return AVERROR_INVALIDDATA;
7486 }
7487 avio_skip(pb, 1); // version
7488 avio_skip(pb, 3); // flags
7489
7490 tmp = avio_r8(pb);
7491 if (tmp == 0)
7492 primary_eye = AV_PRIMARY_EYE_NONE;
7493 else if (tmp == 1)
7494 primary_eye = AV_PRIMARY_EYE_LEFT;
7495 else if (tmp == 2)
7496 primary_eye = AV_PRIMARY_EYE_RIGHT;
7497 else
7498 av_log(c->fc, AV_LOG_WARNING, "Unknown hero eye type: %d\n", tmp);
7499
7500 break;
7501 }
7502 case MKTAG('c','a','m','s'): {
7503 uint32_t subtag;
7504 int subsize;
7505 if (size != 24) {
7506 av_log(c->fc, AV_LOG_ERROR, "Invalid size of cams box: %d\n", size);
7507 return AVERROR_INVALIDDATA;
7508 }
7509
7510 subsize = avio_rb32(pb);
7511 if (subsize != 16) {
7512 av_log(c->fc, AV_LOG_ERROR, "Invalid size of blin box: %d\n", size);
7513 return AVERROR_INVALIDDATA;
7514 }
7515
7516 subtag = avio_rl32(pb);
7517 if (subtag != MKTAG('b','l','i','n')) {
7518 av_log(c->fc, AV_LOG_ERROR, "Expected blin box, got %s\n",
7519 av_fourcc2str(subtag));
7520 return AVERROR_INVALIDDATA;
7521 }
7522
7523 avio_skip(pb, 1); // version
7524 avio_skip(pb, 3); // flags
7525
7526 baseline = avio_rb32(pb);
7527
7528 break;
7529 }
7530 case MKTAG('c','m','f','y'): {
7531 uint32_t subtag;
7532 int subsize;
7533 int32_t adjustment;
7534 if (size != 24) {
7535 av_log(c->fc, AV_LOG_ERROR, "Invalid size of cmfy box: %d\n", size);
7536 return AVERROR_INVALIDDATA;
7537 }
7538
7539 subsize = avio_rb32(pb);
7540 if (subsize != 16) {
7541 av_log(c->fc, AV_LOG_ERROR, "Invalid size of dadj box: %d\n", size);
7542 return AVERROR_INVALIDDATA;
7543 }
7544
7545 subtag = avio_rl32(pb);
7546 if (subtag != MKTAG('d','a','d','j')) {
7547 av_log(c->fc, AV_LOG_ERROR, "Expected dadj box, got %s\n",
7548 av_fourcc2str(subtag));
7549 return AVERROR_INVALIDDATA;
7550 }
7551
7552 avio_skip(pb, 1); // version
7553 avio_skip(pb, 3); // flags
7554
7555 adjustment = (int32_t) avio_rb32(pb);
7556
7557 horizontal_disparity_adjustment.num = (int) adjustment;
7558 horizontal_disparity_adjustment.den = 10000;
7559
7560 break;
7561 }
7562 default:
7563 av_log(c->fc, AV_LOG_WARNING, "Unknown tag in eyes: %s\n",
7565 avio_skip(pb, size - 8);
7566 break;
7567 }
7568 remaining -= size;
7569 }
7570
7571 if (remaining != 0) {
7572 av_log(c->fc, AV_LOG_ERROR, "Broken eyes box\n");
7573 return AVERROR_INVALIDDATA;
7574 }
7575
7576 if (type == AV_STEREO3D_2D)
7577 return 0;
7578
7579 if (!sc->stereo3d) {
7581 if (!sc->stereo3d)
7582 return AVERROR(ENOMEM);
7583 }
7584
7585 sc->stereo3d->flags = flags;
7586 /* eyes/stri only records packed vs single-eye, not SBS/TB. Keep a more
7587 * specific type already set by st3d. */
7588 if (type != AV_STEREO3D_UNSPEC)
7589 sc->stereo3d->type = type;
7590 else if (sc->stereo3d->type == AV_STEREO3D_2D)
7591 sc->stereo3d->type = type;
7592 sc->stereo3d->view = view;
7593 sc->stereo3d->primary_eye = primary_eye;
7594 sc->stereo3d->baseline = baseline;
7595 sc->stereo3d->horizontal_disparity_adjustment = horizontal_disparity_adjustment;
7596
7597 return 0;
7598}
7599
7601{
7602 int size;
7603 int64_t remaining;
7604 uint32_t tag;
7605
7606 if (c->fc->nb_streams < 1)
7607 return 0;
7608
7609 if (atom.size < 8) {
7610 av_log(c->fc, AV_LOG_ERROR, "Empty video extension usage box\n");
7611 return AVERROR_INVALIDDATA;
7612 }
7613
7614 remaining = atom.size;
7615 while (remaining > 0) {
7616 size = avio_rb32(pb);
7617 if (size < 8 || size > remaining ) {
7618 av_log(c->fc, AV_LOG_ERROR, "Invalid child size in vexu box\n");
7619 return AVERROR_INVALIDDATA;
7620 }
7621
7622 tag = avio_rl32(pb);
7623 switch (tag) {
7624 case MKTAG('p','r','o','j'): {
7625 MOVAtom proj = { tag, size - 8 };
7626 int ret = mov_read_vexu_proj(c, pb, proj);
7627 if (ret < 0)
7628 return ret;
7629 break;
7630 }
7631 case MKTAG('e','y','e','s'): {
7632 MOVAtom eyes = { tag, size - 8 };
7633 int ret = mov_read_eyes(c, pb, eyes);
7634 if (ret < 0)
7635 return ret;
7636 break;
7637 }
7638 case MKTAG('p','a','c','k'): {
7639 MOVAtom pack = { tag, size - 8 };
7640 int ret = mov_read_pack(c, pb, pack);
7641 if (ret < 0)
7642 return ret;
7643 break;
7644 }
7645 default:
7646 av_log(c->fc, AV_LOG_WARNING, "Unknown tag in vexu: %s\n",
7648 avio_skip(pb, size - 8);
7649 break;
7650 }
7651 remaining -= size;
7652 }
7653
7654 if (remaining != 0) {
7655 av_log(c->fc, AV_LOG_ERROR, "Broken vexu box\n");
7656 return AVERROR_INVALIDDATA;
7657 }
7658
7659 return 0;
7660}
7661
7663{
7664 AVStream *st;
7665 MOVStreamContext *sc;
7666
7667 if (c->fc->nb_streams < 1)
7668 return 0;
7669
7670 st = c->fc->streams[c->fc->nb_streams - 1];
7671 sc = st->priv_data;
7672
7673 if (atom.size != 4) {
7674 av_log(c->fc, AV_LOG_ERROR, "Invalid size of hfov box: %"PRIu64"\n", atom.size);
7675 return AVERROR_INVALIDDATA;
7676 }
7677
7678
7679 if (!sc->stereo3d) {
7681 if (!sc->stereo3d)
7682 return AVERROR(ENOMEM);
7683 }
7684
7686 sc->stereo3d->horizontal_field_of_view.den = 1000; // thousands of a degree
7687
7688 return 0;
7689}
7690
7692{
7693 int ret = 0;
7694 uint8_t *buffer = av_malloc(len + 1);
7695 const char *val;
7696
7697 if (!buffer)
7698 return AVERROR(ENOMEM);
7699 buffer[len] = '\0';
7700
7701 ret = ffio_read_size(pb, buffer, len);
7702 if (ret < 0)
7703 goto out;
7704
7705 /* Check for mandatory keys and values, try to support XML as best-effort */
7706 if (!sc->spherical &&
7707 av_stristr(buffer, "<GSpherical:StitchingSoftware>") &&
7708 (val = av_stristr(buffer, "<GSpherical:Spherical>")) &&
7709 av_stristr(val, "true") &&
7710 (val = av_stristr(buffer, "<GSpherical:Stitched>")) &&
7711 av_stristr(val, "true") &&
7712 (val = av_stristr(buffer, "<GSpherical:ProjectionType>")) &&
7713 av_stristr(val, "equirectangular")) {
7715 if (!sc->spherical)
7716 goto out;
7717
7719
7720 if (av_stristr(buffer, "<GSpherical:StereoMode>") && !sc->stereo3d) {
7721 enum AVStereo3DType mode;
7722
7723 if (av_stristr(buffer, "left-right"))
7725 else if (av_stristr(buffer, "top-bottom"))
7727 else
7729
7731 if (!sc->stereo3d)
7732 goto out;
7733
7734 sc->stereo3d->type = mode;
7735 }
7736
7737 /* orientation */
7738 val = av_stristr(buffer, "<GSpherical:InitialViewHeadingDegrees>");
7739 if (val)
7740 sc->spherical->yaw = strtol(val, NULL, 10) * (1 << 16);
7741 val = av_stristr(buffer, "<GSpherical:InitialViewPitchDegrees>");
7742 if (val)
7743 sc->spherical->pitch = strtol(val, NULL, 10) * (1 << 16);
7744 val = av_stristr(buffer, "<GSpherical:InitialViewRollDegrees>");
7745 if (val)
7746 sc->spherical->roll = strtol(val, NULL, 10) * (1 << 16);
7747 }
7748
7749out:
7750 av_free(buffer);
7751 return ret;
7752}
7753
7755{
7756 AVStream *st;
7757 MOVStreamContext *sc;
7758 int64_t ret;
7759 AVUUID uuid;
7760 static const AVUUID uuid_isml_manifest = {
7761 0xa5, 0xd4, 0x0b, 0x30, 0xe8, 0x14, 0x11, 0xdd,
7762 0xba, 0x2f, 0x08, 0x00, 0x20, 0x0c, 0x9a, 0x66
7763 };
7764 static const AVUUID uuid_xmp = {
7765 0xbe, 0x7a, 0xcf, 0xcb, 0x97, 0xa9, 0x42, 0xe8,
7766 0x9c, 0x71, 0x99, 0x94, 0x91, 0xe3, 0xaf, 0xac
7767 };
7768 static const AVUUID uuid_spherical = {
7769 0xff, 0xcc, 0x82, 0x63, 0xf8, 0x55, 0x4a, 0x93,
7770 0x88, 0x14, 0x58, 0x7a, 0x02, 0x52, 0x1f, 0xdd,
7771 };
7772
7773 if (atom.size < AV_UUID_LEN || atom.size >= FFMIN(INT_MAX, SIZE_MAX))
7774 return AVERROR_INVALIDDATA;
7775
7776 if (c->fc->nb_streams < 1)
7777 return 0;
7778 st = c->fc->streams[c->fc->nb_streams - 1];
7779 sc = st->priv_data;
7780
7781 ret = ffio_read_size(pb, uuid, AV_UUID_LEN);
7782 if (ret < 0)
7783 return ret;
7784 if (av_uuid_equal(uuid, uuid_isml_manifest)) {
7785 uint8_t *buffer, *ptr;
7786 char *endptr;
7787 size_t len = atom.size - AV_UUID_LEN;
7788
7789 if (len < 4) {
7790 return AVERROR_INVALIDDATA;
7791 }
7792 ret = avio_skip(pb, 4); // zeroes
7793 len -= 4;
7794
7795 buffer = av_mallocz(len + 1);
7796 if (!buffer) {
7797 return AVERROR(ENOMEM);
7798 }
7799 ret = ffio_read_size(pb, buffer, len);
7800 if (ret < 0) {
7801 av_free(buffer);
7802 return ret;
7803 }
7804
7805 ptr = buffer;
7806 while ((ptr = av_stristr(ptr, "systemBitrate=\""))) {
7807 ptr += sizeof("systemBitrate=\"") - 1;
7808 c->bitrates_count++;
7809 c->bitrates = av_realloc_f(c->bitrates, c->bitrates_count, sizeof(*c->bitrates));
7810 if (!c->bitrates) {
7811 c->bitrates_count = 0;
7812 av_free(buffer);
7813 return AVERROR(ENOMEM);
7814 }
7815 errno = 0;
7816 ret = strtol(ptr, &endptr, 10);
7817 if (ret < 0 || errno || *endptr != '"') {
7818 c->bitrates[c->bitrates_count - 1] = 0;
7819 } else {
7820 c->bitrates[c->bitrates_count - 1] = ret;
7821 }
7822 }
7823
7824 av_free(buffer);
7825 } else if (av_uuid_equal(uuid, uuid_xmp)) {
7826 uint8_t *buffer;
7827 size_t len = atom.size - AV_UUID_LEN;
7828 if (c->export_xmp) {
7829 buffer = av_mallocz(len + 1);
7830 if (!buffer) {
7831 return AVERROR(ENOMEM);
7832 }
7833 ret = ffio_read_size(pb, buffer, len);
7834 if (ret < 0) {
7835 av_free(buffer);
7836 return ret;
7837 }
7838 buffer[len] = '\0';
7839 av_dict_set(&c->fc->metadata, "xmp",
7841 } else {
7842 // skip all uuid atom, which makes it fast for long uuid-xmp file
7843 ret = avio_skip(pb, len);
7844 if (ret < 0)
7845 return ret;
7846 }
7847 } else if (av_uuid_equal(uuid, uuid_spherical)) {
7848 size_t len = atom.size - AV_UUID_LEN;
7849 ret = mov_parse_uuid_spherical(sc, pb, len);
7850 if (ret < 0)
7851 return ret;
7852 if (!sc->spherical)
7853 av_log(c->fc, AV_LOG_WARNING, "Invalid spherical metadata found\n");
7854 }
7855
7856 return 0;
7857}
7858
7860{
7861 int ret;
7862 uint8_t content[16];
7863
7864 if (atom.size < 8)
7865 return 0;
7866
7867 ret = ffio_read_size(pb, content, FFMIN(sizeof(content), atom.size));
7868 if (ret < 0)
7869 return ret;
7870
7871 if ( !c->found_moov
7872 && !c->found_mdat
7873 && !memcmp(content, "Anevia\x1A\x1A", 8)
7874 && c->use_mfra_for == FF_MOV_FLAG_MFRA_AUTO) {
7875 c->use_mfra_for = FF_MOV_FLAG_MFRA_PTS;
7876 }
7877
7878 return 0;
7879}
7880
7882{
7883 uint32_t format = avio_rl32(pb);
7884 MOVStreamContext *sc;
7885 enum AVCodecID id;
7886 AVStream *st;
7887
7888 if (c->fc->nb_streams < 1)
7889 return 0;
7890 st = c->fc->streams[c->fc->nb_streams - 1];
7891 sc = st->priv_data;
7892
7893 switch (sc->format)
7894 {
7895 case MKTAG('e','n','c','v'): // encrypted video
7896 case MKTAG('e','n','c','a'): // encrypted audio
7897 id = mov_codec_id(st, format);
7898 if (st->codecpar->codec_id != AV_CODEC_ID_NONE &&
7899 st->codecpar->codec_id != id) {
7900 av_log(c->fc, AV_LOG_WARNING,
7901 "ignoring 'frma' atom of '%.4s', stream has codec id %d\n",
7902 (char*)&format, st->codecpar->codec_id);
7903 break;
7904 }
7905
7906 st->codecpar->codec_id = id;
7907 sc->format = format;
7908 break;
7909
7910 default:
7911 if (format != sc->format) {
7912 av_log(c->fc, AV_LOG_WARNING,
7913 "ignoring 'frma' atom of '%.4s', stream format is '%.4s'\n",
7914 (char*)&format, (char*)&sc->format);
7915 }
7916 break;
7917 }
7918
7919 return 0;
7920}
7921
7922/**
7923 * Gets the current encryption info and associated current stream context. If
7924 * we are parsing a track fragment, this will return the specific encryption
7925 * info for this fragment; otherwise this will return the global encryption
7926 * info for the current stream.
7927 */
7929{
7930 MOVFragmentStreamInfo *frag_stream_info;
7931 AVStream *st;
7932 int i;
7933
7934 frag_stream_info = get_current_frag_stream_info(&c->frag_index);
7935 if (frag_stream_info) {
7936 for (i = 0; i < c->fc->nb_streams; i++) {
7937 *sc = c->fc->streams[i]->priv_data;
7938 if ((*sc)->id == frag_stream_info->id) {
7939 st = c->fc->streams[i];
7940 break;
7941 }
7942 }
7943 if (i == c->fc->nb_streams)
7944 return 0;
7945 *sc = st->priv_data;
7946
7947 if (!frag_stream_info->encryption_index) {
7948 // If this stream isn't encrypted, don't create the index.
7949 if (!(*sc)->cenc.default_encrypted_sample)
7950 return 0;
7951 frag_stream_info->encryption_index = av_mallocz(sizeof(*frag_stream_info->encryption_index));
7952 if (!frag_stream_info->encryption_index)
7953 return AVERROR(ENOMEM);
7954 }
7955 *encryption_index = frag_stream_info->encryption_index;
7956 return 1;
7957 } else {
7958 // No current track fragment, using stream level encryption info.
7959
7960 if (c->fc->nb_streams < 1)
7961 return 0;
7962 st = c->fc->streams[c->fc->nb_streams - 1];
7963 *sc = st->priv_data;
7964
7965 if (!(*sc)->cenc.encryption_index) {
7966 // If this stream isn't encrypted, don't create the index.
7967 if (!(*sc)->cenc.default_encrypted_sample)
7968 return 0;
7969 (*sc)->cenc.encryption_index = av_mallocz(sizeof(*frag_stream_info->encryption_index));
7970 if (!(*sc)->cenc.encryption_index)
7971 return AVERROR(ENOMEM);
7972 }
7973
7974 *encryption_index = (*sc)->cenc.encryption_index;
7975 return 1;
7976 }
7977}
7978
7980{
7981 int i, ret;
7982 unsigned int subsample_count;
7983 AVSubsampleEncryptionInfo *subsamples;
7984
7985 if (!sc->cenc.default_encrypted_sample) {
7986 av_log(c->fc, AV_LOG_ERROR, "Missing schm or tenc\n");
7987 return AVERROR_INVALIDDATA;
7988 }
7989
7990 if (sc->cenc.per_sample_iv_size || use_subsamples) {
7992 if (!*sample)
7993 return AVERROR(ENOMEM);
7994 } else
7995 *sample = NULL;
7996
7997 if (sc->cenc.per_sample_iv_size != 0) {
7998 if ((ret = ffio_read_size(pb, (*sample)->iv, sc->cenc.per_sample_iv_size)) < 0) {
7999 av_log(c->fc, AV_LOG_ERROR, "failed to read the initialization vector\n");
8001 *sample = NULL;
8002 return ret;
8003 }
8004 }
8005
8006 if (use_subsamples) {
8007 subsample_count = avio_rb16(pb);
8008 av_free((*sample)->subsamples);
8009 (*sample)->subsamples = av_calloc(subsample_count, sizeof(*subsamples));
8010 if (!(*sample)->subsamples) {
8012 *sample = NULL;
8013 return AVERROR(ENOMEM);
8014 }
8015
8016 for (i = 0; i < subsample_count && !pb->eof_reached; i++) {
8017 (*sample)->subsamples[i].bytes_of_clear_data = avio_rb16(pb);
8018 (*sample)->subsamples[i].bytes_of_protected_data = avio_rb32(pb);
8019 }
8020
8021 if (pb->eof_reached) {
8022 av_log(c->fc, AV_LOG_ERROR, "hit EOF while reading sub-sample encryption info\n");
8024 *sample = NULL;
8025 return AVERROR_INVALIDDATA;
8026 }
8027 (*sample)->subsample_count = subsample_count;
8028 }
8029
8030 return 0;
8031}
8032
8034{
8035 AVEncryptionInfo **encrypted_samples;
8036 MOVEncryptionIndex *encryption_index;
8037 MOVStreamContext *sc;
8038 int use_subsamples, ret;
8039 unsigned int sample_count, i, alloc_size = 0;
8040
8041 ret = get_current_encryption_info(c, &encryption_index, &sc);
8042 if (ret != 1)
8043 return ret;
8044
8045 if (encryption_index->nb_encrypted_samples) {
8046 // This can happen if we have both saio/saiz and senc atoms.
8047 av_log(c->fc, AV_LOG_DEBUG, "Ignoring duplicate encryption info in senc\n");
8048 return 0;
8049 }
8050
8051 avio_r8(pb); /* version */
8052 use_subsamples = avio_rb24(pb) & 0x02; /* flags */
8053
8054 sample_count = avio_rb32(pb);
8055 if (sample_count >= INT_MAX / sizeof(*encrypted_samples))
8056 return AVERROR(ENOMEM);
8057
8058 for (i = 0; i < sample_count; i++) {
8059 unsigned int min_samples = FFMIN(FFMAX(i + 1, 1024 * 1024), sample_count);
8060 encrypted_samples = av_fast_realloc(encryption_index->encrypted_samples, &alloc_size,
8061 min_samples * sizeof(*encrypted_samples));
8062 if (encrypted_samples) {
8063 encryption_index->encrypted_samples = encrypted_samples;
8064
8066 c, pb, sc, &encryption_index->encrypted_samples[i], use_subsamples);
8067 } else {
8068 ret = AVERROR(ENOMEM);
8069 }
8070 if (pb->eof_reached) {
8071 av_log(c->fc, AV_LOG_ERROR, "Hit EOF while reading senc\n");
8072 if (ret >= 0)
8073 av_encryption_info_free(encryption_index->encrypted_samples[i]);
8074 ret = AVERROR_INVALIDDATA;
8075 }
8076
8077 if (ret < 0) {
8078 for (; i > 0; i--)
8079 av_encryption_info_free(encryption_index->encrypted_samples[i - 1]);
8080 av_freep(&encryption_index->encrypted_samples);
8081 return ret;
8082 }
8083 }
8084 encryption_index->nb_encrypted_samples = sample_count;
8085
8086 return 0;
8087}
8088
8090{
8091 AVEncryptionInfo **sample, **encrypted_samples;
8092 int64_t prev_pos;
8093 size_t sample_count, sample_info_size, i;
8094 int ret = 0;
8095 unsigned int alloc_size = 0;
8096
8097 if (encryption_index->nb_encrypted_samples)
8098 return 0;
8099 sample_count = encryption_index->auxiliary_info_sample_count;
8100 if (encryption_index->auxiliary_offsets_count != 1) {
8101 av_log(c->fc, AV_LOG_ERROR, "Multiple auxiliary info chunks are not supported\n");
8102 return AVERROR_PATCHWELCOME;
8103 }
8104 if (sample_count >= INT_MAX / sizeof(*encrypted_samples))
8105 return AVERROR(ENOMEM);
8106
8107 prev_pos = avio_tell(pb);
8108 if (!(pb->seekable & AVIO_SEEKABLE_NORMAL) ||
8109 avio_seek(pb, encryption_index->auxiliary_offsets[0], SEEK_SET) != encryption_index->auxiliary_offsets[0]) {
8110 av_log(c->fc, AV_LOG_INFO, "Failed to seek for auxiliary info, will only parse senc atoms for encryption info\n");
8111 goto finish;
8112 }
8113
8114 for (i = 0; i < sample_count && !pb->eof_reached; i++) {
8115 unsigned int min_samples = FFMIN(FFMAX(i + 1, 1024 * 1024), sample_count);
8116 encrypted_samples = av_fast_realloc(encryption_index->encrypted_samples, &alloc_size,
8117 min_samples * sizeof(*encrypted_samples));
8118 if (!encrypted_samples) {
8119 ret = AVERROR(ENOMEM);
8120 goto finish;
8121 }
8122 encryption_index->encrypted_samples = encrypted_samples;
8123
8124 sample = &encryption_index->encrypted_samples[i];
8125 sample_info_size = encryption_index->auxiliary_info_default_size
8126 ? encryption_index->auxiliary_info_default_size
8127 : encryption_index->auxiliary_info_sizes[i];
8128
8129 ret = mov_read_sample_encryption_info(c, pb, sc, sample, sample_info_size > sc->cenc.per_sample_iv_size);
8130 if (ret < 0)
8131 goto finish;
8132 }
8133 if (pb->eof_reached) {
8134 av_log(c->fc, AV_LOG_ERROR, "Hit EOF while reading auxiliary info\n");
8135 ret = AVERROR_INVALIDDATA;
8136 } else {
8137 encryption_index->nb_encrypted_samples = sample_count;
8138 }
8139
8140finish:
8141 avio_seek(pb, prev_pos, SEEK_SET);
8142 if (ret < 0) {
8143 for (; i > 0; i--) {
8144 av_encryption_info_free(encryption_index->encrypted_samples[i - 1]);
8145 }
8146 av_freep(&encryption_index->encrypted_samples);
8147 }
8148 return ret;
8149}
8150
8152{
8153 MOVEncryptionIndex *encryption_index;
8154 MOVStreamContext *sc;
8155 int ret;
8156 unsigned int sample_count, aux_info_type, aux_info_param;
8157
8158 ret = get_current_encryption_info(c, &encryption_index, &sc);
8159 if (ret != 1)
8160 return ret;
8161
8162 if (encryption_index->nb_encrypted_samples) {
8163 // This can happen if we have both saio/saiz and senc atoms.
8164 av_log(c->fc, AV_LOG_DEBUG, "Ignoring duplicate encryption info in saiz\n");
8165 return 0;
8166 }
8167
8168 if (encryption_index->auxiliary_info_sample_count) {
8169 av_log(c->fc, AV_LOG_ERROR, "Duplicate saiz atom\n");
8170 return AVERROR_INVALIDDATA;
8171 }
8172
8173 avio_r8(pb); /* version */
8174 if (avio_rb24(pb) & 0x01) { /* flags */
8175 aux_info_type = avio_rb32(pb);
8176 aux_info_param = avio_rb32(pb);
8178 if (aux_info_type != sc->cenc.default_encrypted_sample->scheme) {
8179 av_log(c->fc, AV_LOG_DEBUG, "Ignoring saiz box with non-zero aux_info_type\n");
8180 return 0;
8181 }
8182 if (aux_info_param != 0) {
8183 av_log(c->fc, AV_LOG_DEBUG, "Ignoring saiz box with non-zero aux_info_type_parameter\n");
8184 return 0;
8185 }
8186 } else {
8187 // Didn't see 'schm' or 'tenc', so this isn't encrypted.
8188 if ((aux_info_type == MKBETAG('c','e','n','c') ||
8189 aux_info_type == MKBETAG('c','e','n','s') ||
8190 aux_info_type == MKBETAG('c','b','c','1') ||
8191 aux_info_type == MKBETAG('c','b','c','s')) &&
8192 aux_info_param == 0) {
8193 av_log(c->fc, AV_LOG_ERROR, "Saw encrypted saiz without schm/tenc\n");
8194 return AVERROR_INVALIDDATA;
8195 } else {
8196 return 0;
8197 }
8198 }
8199 } else if (!sc->cenc.default_encrypted_sample) {
8200 // Didn't see 'schm' or 'tenc', so this isn't encrypted.
8201 return 0;
8202 }
8203
8204 encryption_index->auxiliary_info_default_size = avio_r8(pb);
8205 sample_count = avio_rb32(pb);
8206
8207 if (encryption_index->auxiliary_info_default_size == 0) {
8208 if (sample_count == 0)
8209 return AVERROR_INVALIDDATA;
8210
8211 encryption_index->auxiliary_info_sizes = av_malloc(sample_count);
8212 if (!encryption_index->auxiliary_info_sizes)
8213 return AVERROR(ENOMEM);
8214
8215 ret = avio_read(pb, encryption_index->auxiliary_info_sizes, sample_count);
8216 if (ret != sample_count) {
8217 av_freep(&encryption_index->auxiliary_info_sizes);
8218
8219 if (ret >= 0)
8220 ret = AVERROR_INVALIDDATA;
8221 av_log(c->fc, AV_LOG_ERROR, "Failed to read the auxiliary info, %s\n",
8222 av_err2str(ret));
8223 return ret;
8224 }
8225 }
8226 encryption_index->auxiliary_info_sample_count = sample_count;
8227
8228 if (encryption_index->auxiliary_offsets_count) {
8229 return mov_parse_auxiliary_info(c, sc, pb, encryption_index);
8230 }
8231
8232 return 0;
8233}
8234
8236{
8237 uint64_t *auxiliary_offsets;
8238 MOVEncryptionIndex *encryption_index;
8239 MOVStreamContext *sc;
8240 int i, ret;
8241 unsigned int version, entry_count, aux_info_type, aux_info_param;
8242 unsigned int alloc_size = 0;
8243
8244 ret = get_current_encryption_info(c, &encryption_index, &sc);
8245 if (ret != 1)
8246 return ret;
8247
8248 if (encryption_index->nb_encrypted_samples) {
8249 // This can happen if we have both saio/saiz and senc atoms.
8250 av_log(c->fc, AV_LOG_DEBUG, "Ignoring duplicate encryption info in saio\n");
8251 return 0;
8252 }
8253
8254 if (encryption_index->auxiliary_offsets_count) {
8255 av_log(c->fc, AV_LOG_ERROR, "Duplicate saio atom\n");
8256 return AVERROR_INVALIDDATA;
8257 }
8258
8259 version = avio_r8(pb); /* version */
8260 if (avio_rb24(pb) & 0x01) { /* flags */
8261 aux_info_type = avio_rb32(pb);
8262 aux_info_param = avio_rb32(pb);
8264 if (aux_info_type != sc->cenc.default_encrypted_sample->scheme) {
8265 av_log(c->fc, AV_LOG_DEBUG, "Ignoring saio box with non-zero aux_info_type\n");
8266 return 0;
8267 }
8268 if (aux_info_param != 0) {
8269 av_log(c->fc, AV_LOG_DEBUG, "Ignoring saio box with non-zero aux_info_type_parameter\n");
8270 return 0;
8271 }
8272 } else {
8273 // Didn't see 'schm' or 'tenc', so this isn't encrypted.
8274 if ((aux_info_type == MKBETAG('c','e','n','c') ||
8275 aux_info_type == MKBETAG('c','e','n','s') ||
8276 aux_info_type == MKBETAG('c','b','c','1') ||
8277 aux_info_type == MKBETAG('c','b','c','s')) &&
8278 aux_info_param == 0) {
8279 av_log(c->fc, AV_LOG_ERROR, "Saw encrypted saio without schm/tenc\n");
8280 return AVERROR_INVALIDDATA;
8281 } else {
8282 return 0;
8283 }
8284 }
8285 } else if (!sc->cenc.default_encrypted_sample) {
8286 // Didn't see 'schm' or 'tenc', so this isn't encrypted.
8287 return 0;
8288 }
8289
8290 entry_count = avio_rb32(pb);
8291 if (entry_count >= INT_MAX / sizeof(*auxiliary_offsets))
8292 return AVERROR(ENOMEM);
8293
8294 for (i = 0; i < entry_count && !pb->eof_reached; i++) {
8295 unsigned int min_offsets = FFMIN(FFMAX(i + 1, 1024), entry_count);
8296 auxiliary_offsets = av_fast_realloc(
8297 encryption_index->auxiliary_offsets, &alloc_size,
8298 min_offsets * sizeof(*auxiliary_offsets));
8299 if (!auxiliary_offsets) {
8300 av_freep(&encryption_index->auxiliary_offsets);
8301 return AVERROR(ENOMEM);
8302 }
8303 encryption_index->auxiliary_offsets = auxiliary_offsets;
8304
8305 if (version == 0) {
8306 encryption_index->auxiliary_offsets[i] = avio_rb32(pb);
8307 } else {
8308 encryption_index->auxiliary_offsets[i] = avio_rb64(pb);
8309 }
8310 if (c->frag_index.current >= 0) {
8311 encryption_index->auxiliary_offsets[i] += c->fragment.base_data_offset;
8312 }
8313 }
8314
8315 if (pb->eof_reached) {
8316 av_log(c->fc, AV_LOG_ERROR, "Hit EOF while reading saio\n");
8317 av_freep(&encryption_index->auxiliary_offsets);
8318 return AVERROR_INVALIDDATA;
8319 }
8320
8321 encryption_index->auxiliary_offsets_count = entry_count;
8322
8323 if (encryption_index->auxiliary_info_sample_count) {
8324 return mov_parse_auxiliary_info(c, sc, pb, encryption_index);
8325 }
8326
8327 return 0;
8328}
8329
8331{
8332 AVEncryptionInitInfo *info, *old_init_info;
8333 uint8_t **key_ids;
8334 AVStream *st;
8335 const AVPacketSideData *old_side_data;
8336 uint8_t *side_data, *extra_data;
8337 size_t side_data_size;
8338 int ret = 0;
8339 unsigned int version, kid_count, extra_data_size, alloc_size = 0;
8340
8341 if (c->fc->nb_streams < 1)
8342 return 0;
8343 st = c->fc->streams[c->fc->nb_streams-1];
8344
8345 version = avio_r8(pb); /* version */
8346 avio_rb24(pb); /* flags */
8347
8348 info = av_encryption_init_info_alloc(/* system_id_size */ 16, /* num_key_ids */ 0,
8349 /* key_id_size */ 16, /* data_size */ 0);
8350 if (!info)
8351 return AVERROR(ENOMEM);
8352
8353 if ((ret = ffio_read_size(pb, info->system_id, 16)) < 0) {
8354 av_log(c->fc, AV_LOG_ERROR, "Failed to read the system id\n");
8355 goto finish;
8356 }
8357
8358 if (version > 0) {
8359 kid_count = avio_rb32(pb);
8360 if (kid_count >= INT_MAX / sizeof(*key_ids)) {
8361 ret = AVERROR(ENOMEM);
8362 goto finish;
8363 }
8364
8365 for (unsigned int i = 0; i < kid_count && !pb->eof_reached; i++) {
8366 unsigned int min_kid_count = FFMIN(FFMAX(i + 1, 1024), kid_count);
8367 key_ids = av_fast_realloc(info->key_ids, &alloc_size,
8368 min_kid_count * sizeof(*key_ids));
8369 if (!key_ids) {
8370 ret = AVERROR(ENOMEM);
8371 goto finish;
8372 }
8373 info->key_ids = key_ids;
8374
8375 info->key_ids[i] = av_mallocz(16);
8376 if (!info->key_ids[i]) {
8377 ret = AVERROR(ENOMEM);
8378 goto finish;
8379 }
8380 info->num_key_ids = i + 1;
8381
8382 if ((ret = ffio_read_size(pb, info->key_ids[i], 16)) < 0) {
8383 av_log(c->fc, AV_LOG_ERROR, "Failed to read the key id\n");
8384 goto finish;
8385 }
8386 }
8387
8388 if (pb->eof_reached) {
8389 av_log(c->fc, AV_LOG_ERROR, "Hit EOF while reading pssh\n");
8390 ret = AVERROR_INVALIDDATA;
8391 goto finish;
8392 }
8393 }
8394
8395 extra_data_size = avio_rb32(pb);
8396 extra_data = av_malloc(extra_data_size);
8397 if (!extra_data) {
8398 ret = AVERROR(ENOMEM);
8399 goto finish;
8400 }
8401 ret = avio_read(pb, extra_data, extra_data_size);
8402 if (ret != extra_data_size) {
8403 av_free(extra_data);
8404
8405 if (ret >= 0)
8406 ret = AVERROR_INVALIDDATA;
8407 goto finish;
8408 }
8409
8410 av_freep(&info->data); // malloc(0) may still allocate something.
8411 info->data = extra_data;
8412 info->data_size = extra_data_size;
8413
8414 // If there is existing initialization data, append to the list.
8417 if (old_side_data) {
8418 old_init_info = av_encryption_init_info_get_side_data(old_side_data->data, old_side_data->size);
8419 if (old_init_info) {
8420 // Append to the end of the list.
8421 for (AVEncryptionInitInfo *cur = old_init_info;; cur = cur->next) {
8422 if (!cur->next) {
8423 cur->next = info;
8424 break;
8425 }
8426 }
8427 info = old_init_info;
8428 } else {
8429 // Assume existing side-data will be valid, so the only error we could get is OOM.
8430 ret = AVERROR(ENOMEM);
8431 goto finish;
8432 }
8433 }
8434
8435 side_data = av_encryption_init_info_add_side_data(info, &side_data_size);
8436 if (!side_data) {
8437 ret = AVERROR(ENOMEM);
8438 goto finish;
8439 }
8443 side_data, side_data_size, 0))
8444 av_free(side_data);
8445
8446finish:
8448 return ret;
8449}
8450
8452{
8453 AVStream *st;
8454 MOVStreamContext *sc;
8455
8456 if (c->fc->nb_streams < 1)
8457 return 0;
8458 st = c->fc->streams[c->fc->nb_streams-1];
8459 sc = st->priv_data;
8460
8461 if (sc->pseudo_stream_id != 0) {
8462 av_log(c->fc, AV_LOG_ERROR, "schm boxes are only supported in first sample descriptor\n");
8463 return AVERROR_PATCHWELCOME;
8464 }
8465
8466 if (atom.size < 8)
8467 return AVERROR_INVALIDDATA;
8468
8469 avio_rb32(pb); /* version and flags */
8470
8471 if (!sc->cenc.default_encrypted_sample) {
8473 if (!sc->cenc.default_encrypted_sample) {
8474 return AVERROR(ENOMEM);
8475 }
8476 }
8477
8479 return 0;
8480}
8481
8483{
8484 AVStream *st;
8485 MOVStreamContext *sc;
8486 unsigned int version, pattern, is_protected, iv_size;
8487
8488 if (c->fc->nb_streams < 1)
8489 return 0;
8490 st = c->fc->streams[c->fc->nb_streams-1];
8491 sc = st->priv_data;
8492
8493 if (sc->pseudo_stream_id != 0) {
8494 av_log(c->fc, AV_LOG_ERROR, "tenc atom are only supported in first sample descriptor\n");
8495 return AVERROR_PATCHWELCOME;
8496 }
8497
8498 if (!sc->cenc.default_encrypted_sample) {
8500 if (!sc->cenc.default_encrypted_sample) {
8501 return AVERROR(ENOMEM);
8502 }
8503 }
8504
8505 if (atom.size < 20)
8506 return AVERROR_INVALIDDATA;
8507
8508 version = avio_r8(pb); /* version */
8509 avio_rb24(pb); /* flags */
8510
8511 avio_r8(pb); /* reserved */
8512 pattern = avio_r8(pb);
8513
8514 if (version > 0) {
8516 sc->cenc.default_encrypted_sample->skip_byte_block = pattern & 0xf;
8517 }
8518
8519 is_protected = avio_r8(pb);
8520 if (is_protected && !sc->cenc.encryption_index) {
8521 // The whole stream should be by-default encrypted.
8523 if (!sc->cenc.encryption_index)
8524 return AVERROR(ENOMEM);
8525 }
8526 iv_size = avio_r8(pb);
8527 if (iv_size != 0 && iv_size != 8 && iv_size != 16) {
8528 av_log(c->fc, AV_LOG_ERROR, "invalid per-sample IV size value\n");
8529 return AVERROR_INVALIDDATA;
8530 }
8531 sc->cenc.per_sample_iv_size = iv_size;
8532 if (avio_read(pb, sc->cenc.default_encrypted_sample->key_id, 16) != 16) {
8533 av_log(c->fc, AV_LOG_ERROR, "failed to read the default key ID\n");
8534 return AVERROR_INVALIDDATA;
8535 }
8536
8537 if (is_protected && !sc->cenc.per_sample_iv_size) {
8538 iv_size = avio_r8(pb);
8539 if (iv_size != 8 && iv_size != 16) {
8540 av_log(c->fc, AV_LOG_ERROR, "invalid default_constant_IV_size in tenc atom\n");
8541 return AVERROR_INVALIDDATA;
8542 }
8543
8544 if (avio_read(pb, sc->cenc.default_encrypted_sample->iv, iv_size) != iv_size) {
8545 av_log(c->fc, AV_LOG_ERROR, "failed to read the default IV\n");
8546 return AVERROR_INVALIDDATA;
8547 }
8548 }
8549
8550 return 0;
8551}
8552
8554{
8555 AVStream *st;
8556 int last, type, size, ret;
8557 uint8_t buf[4];
8558
8559 if (c->fc->nb_streams < 1)
8560 return 0;
8561 st = c->fc->streams[c->fc->nb_streams-1];
8562
8563 if ((uint64_t)atom.size > (1<<30) || atom.size < 42)
8564 return AVERROR_INVALIDDATA;
8565
8566 /* Check FlacSpecificBox version. */
8567 if (avio_r8(pb) != 0)
8568 return AVERROR_INVALIDDATA;
8569
8570 avio_rb24(pb); /* Flags */
8571
8572 if (avio_read(pb, buf, sizeof(buf)) != sizeof(buf)) {
8573 av_log(c->fc, AV_LOG_ERROR, "failed to read FLAC metadata block header\n");
8574 return pb->error < 0 ? pb->error : AVERROR_INVALIDDATA;
8575 }
8576 flac_parse_block_header(buf, &last, &type, &size);
8577
8579 av_log(c->fc, AV_LOG_ERROR, "STREAMINFO must be first FLACMetadataBlock\n");
8580 return AVERROR_INVALIDDATA;
8581 }
8582
8583 ret = ff_get_extradata(c->fc, st->codecpar, pb, size);
8584 if (ret < 0)
8585 return ret;
8586
8587 if (!last)
8588 av_log(c->fc, AV_LOG_WARNING, "non-STREAMINFO FLACMetadataBlock(s) ignored\n");
8589
8590 return 0;
8591}
8592
8594 AVDictionaryEntry *key_entry_hex;
8595 char kid_hex[16*2+1];
8596
8597 if (c->decryption_default_key && c->decryption_default_key_len != len) {
8598 av_log(c->fc, AV_LOG_ERROR, "invalid default decryption key length: got %d, expected %d\n", c->decryption_default_key_len, len);
8599 return -1;
8600 }
8601
8602 if (!c->decryption_keys) {
8603 av_assert0(c->decryption_default_key);
8604 memcpy(out, c->decryption_default_key, len);
8605 return 0;
8606 }
8607
8608 if (sample->key_id_size != 16) {
8609 av_log(c->fc, AV_LOG_ERROR, "invalid key ID size: got %u, expected 16\n", sample->key_id_size);
8610 return -1;
8611 }
8612
8613 ff_data_to_hex(kid_hex, sample->key_id, 16, 1);
8614 key_entry_hex = av_dict_get(c->decryption_keys, kid_hex, NULL, AV_DICT_DONT_STRDUP_KEY|AV_DICT_DONT_STRDUP_VAL);
8615 if (!key_entry_hex) {
8616 if (!c->decryption_default_key) {
8617 av_log(c->fc, AV_LOG_ERROR, "unable to find KID %s\n", kid_hex);
8618 return -1;
8619 }
8620 memcpy(out, c->decryption_default_key, len);
8621 return 0;
8622 }
8623 if (strlen(key_entry_hex->value) != len*2) {
8624 return -1;
8625 }
8626 ff_hex_to_data(out, key_entry_hex->value);
8627 return 0;
8628}
8629
8631{
8632 int i, ret;
8633 int bytes_of_protected_data;
8634 uint8_t decryption_key[AES_CTR_KEY_SIZE];
8635
8636 if (!sc->cenc.aes_ctr) {
8637 ret = get_key_from_kid(decryption_key, sizeof(decryption_key), c, sample);
8638 if (ret < 0) {
8639 return ret;
8640 }
8641
8642 /* initialize the cipher */
8644 if (!sc->cenc.aes_ctr) {
8645 return AVERROR(ENOMEM);
8646 }
8647
8648 ret = av_aes_ctr_init(sc->cenc.aes_ctr, decryption_key);
8649 if (ret < 0) {
8650 return ret;
8651 }
8652 }
8653
8655
8656 if (!sample->subsample_count) {
8657 /* decrypt the whole packet */
8658 av_aes_ctr_crypt(sc->cenc.aes_ctr, input, input, size);
8659 return 0;
8660 }
8661
8662 for (i = 0; i < sample->subsample_count; i++) {
8663 if (sample->subsamples[i].bytes_of_clear_data + (int64_t)sample->subsamples[i].bytes_of_protected_data > size) {
8664 av_log(c->fc, AV_LOG_ERROR, "subsample size exceeds the packet size left\n");
8665 return AVERROR_INVALIDDATA;
8666 }
8667
8668 /* skip the clear bytes */
8669 input += sample->subsamples[i].bytes_of_clear_data;
8670 size -= sample->subsamples[i].bytes_of_clear_data;
8671
8672 /* decrypt the encrypted bytes */
8673
8674 bytes_of_protected_data = sample->subsamples[i].bytes_of_protected_data;
8675 av_aes_ctr_crypt(sc->cenc.aes_ctr, input, input, bytes_of_protected_data);
8676
8677 input += bytes_of_protected_data;
8678 size -= bytes_of_protected_data;
8679 }
8680
8681 if (size > 0) {
8682 av_log(c->fc, AV_LOG_ERROR, "leftover packet bytes after subsample processing\n");
8683 return AVERROR_INVALIDDATA;
8684 }
8685
8686 return 0;
8687}
8688
8690{
8691 int i, ret;
8692 int num_of_encrypted_blocks;
8693 uint8_t iv[16];
8694 uint8_t decryption_key[16];
8695
8696 if (!sc->cenc.aes_ctx) {
8697 ret = get_key_from_kid(decryption_key, sizeof(decryption_key), c, sample);
8698 if (ret < 0) {
8699 return ret;
8700 }
8701
8702 /* initialize the cipher */
8703 sc->cenc.aes_ctx = av_aes_alloc();
8704 if (!sc->cenc.aes_ctx) {
8705 return AVERROR(ENOMEM);
8706 }
8707
8708 ret = av_aes_init(sc->cenc.aes_ctx, decryption_key, 16 * 8, 1);
8709 if (ret < 0) {
8710 return ret;
8711 }
8712 }
8713
8714 memcpy(iv, sample->iv, 16);
8715
8716 /* whole-block full sample encryption */
8717 if (!sample->subsample_count) {
8718 /* decrypt the whole packet */
8719 av_aes_crypt(sc->cenc.aes_ctx, input, input, size/16, iv, 1);
8720 return 0;
8721 }
8722
8723 for (i = 0; i < sample->subsample_count; i++) {
8724 if (sample->subsamples[i].bytes_of_clear_data + (int64_t)sample->subsamples[i].bytes_of_protected_data > size) {
8725 av_log(c->fc, AV_LOG_ERROR, "subsample size exceeds the packet size left\n");
8726 return AVERROR_INVALIDDATA;
8727 }
8728
8729 if (sample->subsamples[i].bytes_of_protected_data % 16) {
8730 av_log(c->fc, AV_LOG_ERROR, "subsample BytesOfProtectedData is not a multiple of 16\n");
8731 return AVERROR_INVALIDDATA;
8732 }
8733
8734 /* skip the clear bytes */
8735 input += sample->subsamples[i].bytes_of_clear_data;
8736 size -= sample->subsamples[i].bytes_of_clear_data;
8737
8738 /* decrypt the encrypted bytes */
8739 num_of_encrypted_blocks = sample->subsamples[i].bytes_of_protected_data/16;
8740 if (num_of_encrypted_blocks > 0) {
8741 av_aes_crypt(sc->cenc.aes_ctx, input, input, num_of_encrypted_blocks, iv, 1);
8742 }
8743 input += sample->subsamples[i].bytes_of_protected_data;
8744 size -= sample->subsamples[i].bytes_of_protected_data;
8745 }
8746
8747 if (size > 0) {
8748 av_log(c->fc, AV_LOG_ERROR, "leftover packet bytes after subsample processing\n");
8749 return AVERROR_INVALIDDATA;
8750 }
8751
8752 return 0;
8753}
8754
8756{
8757 int i, ret, rem_bytes;
8758 uint8_t *data;
8759 uint8_t decryption_key[AES_CTR_KEY_SIZE];
8760
8761 if (!sc->cenc.aes_ctr) {
8762 ret = get_key_from_kid(decryption_key, sizeof(decryption_key), c, sample);
8763 if (ret < 0) {
8764 return ret;
8765 }
8766
8767 /* initialize the cipher */
8769 if (!sc->cenc.aes_ctr) {
8770 return AVERROR(ENOMEM);
8771 }
8772
8773 ret = av_aes_ctr_init(sc->cenc.aes_ctr, decryption_key);
8774 if (ret < 0) {
8775 return ret;
8776 }
8777 }
8778
8780
8781 /* whole-block full sample encryption */
8782 if (!sample->subsample_count) {
8783 /* decrypt the whole packet */
8784 av_aes_ctr_crypt(sc->cenc.aes_ctr, input, input, size);
8785 return 0;
8786 } else if (!sample->crypt_byte_block && !sample->skip_byte_block) {
8787 av_log(c->fc, AV_LOG_ERROR, "pattern encryption is not present in 'cens' scheme\n");
8788 return AVERROR_INVALIDDATA;
8789 }
8790
8791 for (i = 0; i < sample->subsample_count; i++) {
8792 if (sample->subsamples[i].bytes_of_clear_data + (int64_t)sample->subsamples[i].bytes_of_protected_data > size) {
8793 av_log(c->fc, AV_LOG_ERROR, "subsample size exceeds the packet size left\n");
8794 return AVERROR_INVALIDDATA;
8795 }
8796
8797 /* skip the clear bytes */
8798 input += sample->subsamples[i].bytes_of_clear_data;
8799 size -= sample->subsamples[i].bytes_of_clear_data;
8800
8801 /* decrypt the encrypted bytes */
8802 data = input;
8803 rem_bytes = sample->subsamples[i].bytes_of_protected_data;
8804 while (rem_bytes > 0) {
8805 if (rem_bytes < 16*sample->crypt_byte_block) {
8806 break;
8807 }
8808 av_aes_ctr_crypt(sc->cenc.aes_ctr, data, data, 16*sample->crypt_byte_block);
8809 data += 16*sample->crypt_byte_block;
8810 rem_bytes -= 16*sample->crypt_byte_block;
8811 data += FFMIN(16*sample->skip_byte_block, rem_bytes);
8812 rem_bytes -= FFMIN(16*sample->skip_byte_block, rem_bytes);
8813 }
8814 input += sample->subsamples[i].bytes_of_protected_data;
8815 size -= sample->subsamples[i].bytes_of_protected_data;
8816 }
8817
8818 if (size > 0) {
8819 av_log(c->fc, AV_LOG_ERROR, "leftover packet bytes after subsample processing\n");
8820 return AVERROR_INVALIDDATA;
8821 }
8822
8823 return 0;
8824}
8825
8827{
8828 int i, ret, rem_bytes;
8829 uint8_t iv[16];
8830 uint8_t *data;
8831 uint8_t decryption_key[16];
8832
8833 if (!sc->cenc.aes_ctx) {
8834 ret = get_key_from_kid(decryption_key, sizeof(decryption_key), c, sample);
8835 if (ret < 0) {
8836 return ret;
8837 }
8838
8839 /* initialize the cipher */
8840 sc->cenc.aes_ctx = av_aes_alloc();
8841 if (!sc->cenc.aes_ctx) {
8842 return AVERROR(ENOMEM);
8843 }
8844
8845 ret = av_aes_init(sc->cenc.aes_ctx, decryption_key, 16 * 8, 1);
8846 if (ret < 0) {
8847 return ret;
8848 }
8849 }
8850
8851 /* whole-block full sample encryption */
8852 if (!sample->subsample_count) {
8853 /* decrypt the whole packet */
8854 memcpy(iv, sample->iv, 16);
8855 av_aes_crypt(sc->cenc.aes_ctx, input, input, size/16, iv, 1);
8856 return 0;
8857 } else if (!sample->crypt_byte_block && !sample->skip_byte_block) {
8858 av_log(c->fc, AV_LOG_ERROR, "pattern encryption is not present in 'cbcs' scheme\n");
8859 return AVERROR_INVALIDDATA;
8860 }
8861
8862 for (i = 0; i < sample->subsample_count; i++) {
8863 if (sample->subsamples[i].bytes_of_clear_data + (int64_t)sample->subsamples[i].bytes_of_protected_data > size) {
8864 av_log(c->fc, AV_LOG_ERROR, "subsample size exceeds the packet size left\n");
8865 return AVERROR_INVALIDDATA;
8866 }
8867
8868 /* skip the clear bytes */
8869 input += sample->subsamples[i].bytes_of_clear_data;
8870 size -= sample->subsamples[i].bytes_of_clear_data;
8871
8872 /* decrypt the encrypted bytes */
8873 memcpy(iv, sample->iv, 16);
8874 data = input;
8875 rem_bytes = sample->subsamples[i].bytes_of_protected_data;
8876 while (rem_bytes > 0) {
8877 if (rem_bytes < 16*sample->crypt_byte_block) {
8878 break;
8879 }
8880 av_aes_crypt(sc->cenc.aes_ctx, data, data, sample->crypt_byte_block, iv, 1);
8881 data += 16*sample->crypt_byte_block;
8882 rem_bytes -= 16*sample->crypt_byte_block;
8883 data += FFMIN(16*sample->skip_byte_block, rem_bytes);
8884 rem_bytes -= FFMIN(16*sample->skip_byte_block, rem_bytes);
8885 }
8886 input += sample->subsamples[i].bytes_of_protected_data;
8887 size -= sample->subsamples[i].bytes_of_protected_data;
8888 }
8889
8890 if (size > 0) {
8891 av_log(c->fc, AV_LOG_ERROR, "leftover packet bytes after subsample processing\n");
8892 return AVERROR_INVALIDDATA;
8893 }
8894
8895 return 0;
8896}
8897
8898static int cenc_decrypt(MOVContext *c, MOVStreamContext *sc, AVEncryptionInfo *sample, uint8_t *input, int size)
8899{
8900 if (sample->scheme == MKBETAG('c','e','n','c') && !sample->crypt_byte_block && !sample->skip_byte_block) {
8901 return cenc_scheme_decrypt(c, sc, sample, input, size);
8902 } else if (sample->scheme == MKBETAG('c','b','c','1') && !sample->crypt_byte_block && !sample->skip_byte_block) {
8903 return cbc1_scheme_decrypt(c, sc, sample, input, size);
8904 } else if (sample->scheme == MKBETAG('c','e','n','s')) {
8905 return cens_scheme_decrypt(c, sc, sample, input, size);
8906 } else if (sample->scheme == MKBETAG('c','b','c','s')) {
8907 return cbcs_scheme_decrypt(c, sc, sample, input, size);
8908 } else {
8909 av_log(c->fc, AV_LOG_ERROR, "invalid encryption scheme\n");
8910 return AVERROR_INVALIDDATA;
8911 }
8912}
8913
8915{
8916 int current = frag_index->current;
8917
8918 if (!frag_index->nb_items)
8919 return NULL;
8920
8921 // Check frag_index->current is the right one for pkt. It can out of sync.
8922 if (current >= 0 && current < frag_index->nb_items) {
8923 if (frag_index->item[current].moof_offset < pkt->pos &&
8924 (current + 1 == frag_index->nb_items ||
8925 frag_index->item[current + 1].moof_offset > pkt->pos))
8926 return get_frag_stream_info(frag_index, current, id);
8927 }
8928
8929
8930 for (int i = 0; i < frag_index->nb_items; i++) {
8931 if (frag_index->item[i].moof_offset > pkt->pos)
8932 break;
8933 current = i;
8934 }
8935 frag_index->current = current;
8936 return get_frag_stream_info(frag_index, current, id);
8937}
8938
8939static int cenc_filter(MOVContext *mov, AVStream* st, MOVStreamContext *sc, AVPacket *pkt, int current_index)
8940{
8941 MOVFragmentStreamInfo *frag_stream_info;
8942 MOVEncryptionIndex *encryption_index;
8943 AVEncryptionInfo *encrypted_sample;
8944 int encrypted_index, ret;
8945
8946 frag_stream_info = get_frag_stream_info_from_pkt(&mov->frag_index, pkt, sc->id);
8947 encrypted_index = current_index;
8948 encryption_index = NULL;
8949 if (frag_stream_info) {
8950 // Note this only supports encryption info in the first sample descriptor.
8951 if (frag_stream_info->stsd_id == 1) {
8952 if (frag_stream_info->encryption_index) {
8953 encrypted_index = current_index - frag_stream_info->index_base;
8954 encryption_index = frag_stream_info->encryption_index;
8955 } else {
8956 encryption_index = sc->cenc.encryption_index;
8957 }
8958 }
8959 } else {
8960 encryption_index = sc->cenc.encryption_index;
8961 }
8962
8963 if (encryption_index) {
8964 if (encryption_index->auxiliary_info_sample_count &&
8965 !encryption_index->nb_encrypted_samples) {
8966 av_log(mov->fc, AV_LOG_ERROR, "saiz atom found without saio\n");
8967 return AVERROR_INVALIDDATA;
8968 }
8969 if (encryption_index->auxiliary_offsets_count &&
8970 !encryption_index->nb_encrypted_samples) {
8971 av_log(mov->fc, AV_LOG_ERROR, "saio atom found without saiz\n");
8972 return AVERROR_INVALIDDATA;
8973 }
8974
8975 encrypted_sample = NULL;
8976 if (!encryption_index->nb_encrypted_samples) {
8977 // Full-sample encryption with default settings.
8978 encrypted_sample = sc->cenc.default_encrypted_sample;
8979 } else if (encrypted_index >= 0 && encrypted_index < encryption_index->nb_encrypted_samples) {
8980 // Per-sample setting override.
8981 encrypted_sample = encryption_index->encrypted_samples[encrypted_index];
8982 if (!encrypted_sample) {
8983 encrypted_sample = sc->cenc.default_encrypted_sample;
8984 }
8985 }
8986
8987 if (!encrypted_sample) {
8988 av_log(mov->fc, AV_LOG_ERROR, "Incorrect number of samples in encryption info\n");
8989 return AVERROR_INVALIDDATA;
8990 }
8991
8992 if (mov->decryption_keys || mov->decryption_default_key) {
8993 return cenc_decrypt(mov, sc, encrypted_sample, pkt->data, pkt->size);
8994 } else {
8995 size_t size;
8996 uint8_t *side_data = av_encryption_info_add_side_data(encrypted_sample, &size);
8997 if (!side_data)
8998 return AVERROR(ENOMEM);
9000 if (ret < 0)
9001 av_free(side_data);
9002 return ret;
9003 }
9004 }
9005
9006 return 0;
9007}
9008
9010{
9011 const int OPUS_SEEK_PREROLL_MS = 80;
9012 int ret;
9013 AVStream *st;
9014 size_t size;
9015 uint16_t pre_skip;
9016
9017 if (c->fc->nb_streams < 1)
9018 return 0;
9019 st = c->fc->streams[c->fc->nb_streams-1];
9020
9021 if ((uint64_t)atom.size > (1<<30) || atom.size < 11 || st->codecpar->extradata)
9022 return AVERROR_INVALIDDATA;
9023
9024 /* Check OpusSpecificBox version. */
9025 if (avio_r8(pb) != 0) {
9026 av_log(c->fc, AV_LOG_ERROR, "unsupported OpusSpecificBox version\n");
9027 return AVERROR_INVALIDDATA;
9028 }
9029
9030 /* OpusSpecificBox size plus magic for Ogg OpusHead header. */
9031 size = atom.size + 8;
9032
9033 if ((ret = ff_alloc_extradata(st->codecpar, size)) < 0)
9034 return ret;
9035
9036 AV_WL32A(st->codecpar->extradata, MKTAG('O','p','u','s'));
9037 AV_WL32A(st->codecpar->extradata + 4, MKTAG('H','e','a','d'));
9038 AV_WB8(st->codecpar->extradata + 8, 1); /* OpusHead version */
9039 if ((ret = ffio_read_size(pb, st->codecpar->extradata + 9, size - 9)) < 0) {
9041 st->codecpar->extradata_size = 0;
9042 return ret;
9043 }
9044
9045 /* OpusSpecificBox is stored in big-endian, but OpusHead is
9046 little-endian; aside from the preceding magic and version they're
9047 otherwise currently identical. Data after output gain at offset 16
9048 doesn't need to be bytewapped. */
9049 pre_skip = AV_RB16A(st->codecpar->extradata + 10);
9050 AV_WL16A(st->codecpar->extradata + 10, pre_skip);
9051 AV_WL32A(st->codecpar->extradata + 12, AV_RB32A(st->codecpar->extradata + 12));
9052 AV_WL16A(st->codecpar->extradata + 16, AV_RB16A(st->codecpar->extradata + 16));
9053
9054 st->codecpar->initial_padding = pre_skip;
9056 (AVRational){1, 1000},
9057 (AVRational){1, 48000});
9058
9059 return 0;
9060}
9061
9063{
9064 AVStream *st;
9065 unsigned format_info;
9066 int channel_assignment, channel_assignment1, channel_assignment2;
9067 int ratebits;
9068 uint64_t chmask;
9069
9070 if (c->fc->nb_streams < 1)
9071 return 0;
9072 st = c->fc->streams[c->fc->nb_streams-1];
9073
9074 if (atom.size < 10)
9075 return AVERROR_INVALIDDATA;
9076
9077 format_info = avio_rb32(pb);
9078
9079 ratebits = (format_info >> 28) & 0xF;
9080 channel_assignment1 = (format_info >> 15) & 0x1F;
9081 channel_assignment2 = format_info & 0x1FFF;
9082 if (channel_assignment2)
9083 channel_assignment = channel_assignment2;
9084 else
9085 channel_assignment = channel_assignment1;
9086
9087 st->codecpar->frame_size = 40 << (ratebits & 0x7);
9088 st->codecpar->sample_rate = mlp_samplerate(ratebits);
9089
9091 chmask = truehd_layout(channel_assignment);
9093
9094 return 0;
9095}
9096
9098{
9099 AVStream *st;
9100 uint8_t buf[ISOM_DVCC_DVVC_SIZE];
9101 int ret;
9102 int64_t read_size = atom.size;
9103
9104 if (c->fc->nb_streams < 1)
9105 return 0;
9106 st = c->fc->streams[c->fc->nb_streams-1];
9107
9108 // At most 24 bytes
9109 read_size = FFMIN(read_size, ISOM_DVCC_DVVC_SIZE);
9110
9111 if ((ret = ffio_read_size(pb, buf, read_size)) < 0)
9112 return ret;
9113
9114 return ff_isom_parse_dvcc_dvvc(c->fc, st, buf, read_size);
9115}
9116
9118{
9119 AVStream *st;
9120 AVPacketSideData *sd;
9121 int ret;
9122
9123 if (c->fc->nb_streams < 1)
9124 return 0;
9125 st = c->fc->streams[c->fc->nb_streams - 1];
9126
9127 if (atom.size < 23 || atom.size > INT_MAX - AV_INPUT_BUFFER_PADDING_SIZE)
9128 return AVERROR_INVALIDDATA;
9129
9133 atom.size, 0);
9134 if (!sd)
9135 return AVERROR(ENOMEM);
9136
9137 ret = ffio_read_size(pb, sd->data, atom.size);
9138 if (ret < 0)
9139 return ret;
9140
9141 return 0;
9142}
9143
9145{
9146 AVStream *st;
9147 uint8_t *buf;
9148 int ret, old_size, num_arrays;
9149
9150 if (c->fc->nb_streams < 1)
9151 return 0;
9152 st = c->fc->streams[c->fc->nb_streams-1];
9153
9154 if (!st->codecpar->extradata_size)
9155 // TODO: handle lhvC when present before hvcC
9156 return 0;
9157
9158 if (atom.size < 6 || st->codecpar->extradata_size < 23 ||
9159 atom.size > INT_MAX - AV_INPUT_BUFFER_PADDING_SIZE) {
9160 return AVERROR_INVALIDDATA;
9161 }
9162
9164 if (!buf)
9165 return AVERROR(ENOMEM);
9166 memset(buf + atom.size, 0, AV_INPUT_BUFFER_PADDING_SIZE);
9167
9168 ret = ffio_read_size(pb, buf, atom.size);
9169 if (ret < 0) {
9170 av_free(buf);
9171 av_log(c->fc, AV_LOG_WARNING, "lhvC atom truncated\n");
9172 return 0;
9173 }
9174
9175 num_arrays = buf[5];
9176 old_size = st->codecpar->extradata_size;
9177 atom.size -= 8 /* account for mov_realloc_extradata offsetting */
9178 + 6 /* lhvC bytes before the arrays*/;
9179
9180 ret = mov_realloc_extradata(st->codecpar, atom);
9181 if (ret < 0) {
9182 av_free(buf);
9183 return ret;
9184 }
9185
9186 st->codecpar->extradata[22] += num_arrays;
9187 memcpy(st->codecpar->extradata + old_size, buf + 6, atom.size + 8);
9188
9190
9191 av_free(buf);
9192 return 0;
9193}
9194
9196{
9197 AVFormatContext *ctx = c->fc;
9198 AVStream *st = NULL;
9199 AVBPrint scheme_buf, value_buf;
9200 int64_t scheme_str_len = 0, value_str_len = 0;
9201 int version, flags, ret = AVERROR_BUG;
9202 int64_t size = atom.size;
9203
9204 if (atom.size < 6)
9205 // 4 bytes for version + flags, 2x 1 byte for null
9206 return AVERROR_INVALIDDATA;
9207
9208 if (c->fc->nb_streams < 1)
9209 return 0;
9210 st = c->fc->streams[c->fc->nb_streams-1];
9211
9212 version = avio_r8(pb);
9213 flags = avio_rb24(pb);
9214 size -= 4;
9215
9216 if (version != 0 || flags != 0) {
9218 "Unsupported 'kind' box with version %d, flags: %x",
9219 version, flags);
9220 return AVERROR_INVALIDDATA;
9221 }
9222
9225
9226 if ((scheme_str_len = ff_read_string_to_bprint_overwrite(pb, &scheme_buf,
9227 size)) < 0) {
9228 ret = scheme_str_len;
9229 goto cleanup;
9230 }
9231
9232 if (scheme_str_len + 1 >= size) {
9233 // we need to have another string, even if nullptr.
9234 // we check with + 1 since we expect that if size was not hit,
9235 // an additional null was read.
9236 ret = AVERROR_INVALIDDATA;
9237 goto cleanup;
9238 }
9239
9240 size -= scheme_str_len + 1;
9241
9242 if ((value_str_len = ff_read_string_to_bprint_overwrite(pb, &value_buf,
9243 size)) < 0) {
9244 ret = value_str_len;
9245 goto cleanup;
9246 }
9247
9248 if (value_str_len == size) {
9249 // in case of no trailing null, box is not valid.
9250 ret = AVERROR_INVALIDDATA;
9251 goto cleanup;
9252 }
9253
9255 "%s stream %d KindBox(scheme: %s, value: %s)\n",
9257 st->index,
9258 scheme_buf.str, value_buf.str);
9259
9260 for (int i = 0; ff_mov_track_kind_table[i].scheme_uri; i++) {
9262 if (!av_strstart(scheme_buf.str, map.scheme_uri, NULL))
9263 continue;
9264
9265 for (int j = 0; map.value_maps[j].disposition; j++) {
9266 const struct MP4TrackKindValueMapping value_map = map.value_maps[j];
9267 if (!av_strstart(value_buf.str, value_map.value, NULL))
9268 continue;
9269
9270 st->disposition |= value_map.disposition;
9271 }
9272 }
9273
9274 ret = 0;
9275
9276cleanup:
9277
9278 av_bprint_finalize(&scheme_buf, NULL);
9279 av_bprint_finalize(&value_buf, NULL);
9280
9281 return ret;
9282}
9283
9285{
9286 AVStream *st;
9287 AVChannelLayout ch_layout = { 0 };
9288 int ret, i, version, type;
9289 int ambisonic_order, channel_order, normalization, channel_count;
9290 int ambi_channels, non_diegetic_channels;
9291
9292 if (c->fc->nb_streams < 1)
9293 return 0;
9294
9295 st = c->fc->streams[c->fc->nb_streams - 1];
9296
9297 if (atom.size < 16) {
9298 av_log(c->fc, AV_LOG_ERROR, "SA3D audio box too small\n");
9299 return AVERROR_INVALIDDATA;
9300 }
9301
9302 version = avio_r8(pb);
9303 if (version) {
9304 av_log(c->fc, AV_LOG_WARNING, "Unsupported SA3D box version %d\n", version);
9305 return 0;
9306 }
9307
9308 type = avio_r8(pb);
9309 if (type & 0x7f) {
9310 av_log(c->fc, AV_LOG_WARNING,
9311 "Unsupported ambisonic type %d\n", type & 0x7f);
9312 return 0;
9313 }
9314 non_diegetic_channels = (type >> 7) * 2; // head_locked_stereo
9315
9316 ambisonic_order = avio_rb32(pb);
9317
9318 channel_order = avio_r8(pb);
9319 if (channel_order) {
9320 av_log(c->fc, AV_LOG_WARNING,
9321 "Unsupported channel_order %d\n", channel_order);
9322 return 0;
9323 }
9324
9325 normalization = avio_r8(pb);
9326 if (normalization) {
9327 av_log(c->fc, AV_LOG_WARNING,
9328 "Unsupported normalization %d\n", normalization);
9329 return 0;
9330 }
9331
9332 channel_count = avio_rb32(pb);
9333 if (ambisonic_order < 0 || ambisonic_order > 31 ||
9334 channel_count != ((ambisonic_order + 1LL) * (ambisonic_order + 1LL) +
9335 non_diegetic_channels)) {
9336 av_log(c->fc, AV_LOG_ERROR,
9337 "Invalid number of channels (%d / %d)\n",
9338 channel_count, ambisonic_order);
9339 return 0;
9340 }
9341 ambi_channels = channel_count - non_diegetic_channels;
9342
9343 ret = av_channel_layout_custom_init(&ch_layout, channel_count);
9344 if (ret < 0)
9345 return 0;
9346
9347 for (i = 0; i < channel_count; i++) {
9348 unsigned channel = avio_rb32(pb);
9349
9350 if (channel >= channel_count) {
9351 av_log(c->fc, AV_LOG_ERROR, "Invalid channel index (%d / %d)\n",
9352 channel, ambisonic_order);
9353 av_channel_layout_uninit(&ch_layout);
9354 return 0;
9355 }
9356 if (channel >= ambi_channels)
9357 ch_layout.u.map[i].id = channel - ambi_channels;
9358 else
9359 ch_layout.u.map[i].id = AV_CHAN_AMBISONIC_BASE + channel;
9360 }
9361
9363 if (ret < 0) {
9364 av_channel_layout_uninit(&ch_layout);
9365 return 0;
9366 }
9367
9369 st->codecpar->ch_layout = ch_layout;
9370
9371 return 0;
9372}
9373
9375{
9376 AVStream *st;
9377 int version;
9378
9379 if (c->fc->nb_streams < 1)
9380 return 0;
9381
9382 st = c->fc->streams[c->fc->nb_streams - 1];
9383
9384 if (atom.size < 5) {
9385 av_log(c->fc, AV_LOG_ERROR, "Empty SAND audio box\n");
9386 return AVERROR_INVALIDDATA;
9387 }
9388
9389 version = avio_r8(pb);
9390 if (version) {
9391 av_log(c->fc, AV_LOG_WARNING, "Unsupported SAND box version %d\n", version);
9392 return 0;
9393 }
9394
9396
9397 return 0;
9398}
9399
9400static int rb_size(AVIOContext *pb, int64_t *value, int size)
9401{
9402 if (size == 0)
9403 *value = 0;
9404 else if (size == 1)
9405 *value = avio_r8(pb);
9406 else if (size == 2)
9407 *value = avio_rb16(pb);
9408 else if (size == 4)
9409 *value = avio_rb32(pb);
9410 else if (size == 8) {
9411 *value = avio_rb64(pb);
9412 if (*value < 0)
9413 return -1;
9414 } else
9415 return -1;
9416 return size;
9417}
9418
9420{
9421 avio_rb32(pb); // version & flags.
9422 c->primary_item_id = avio_rb16(pb);
9423 av_log(c->fc, AV_LOG_TRACE, "pitm: primary_item_id %d\n", c->primary_item_id);
9424 return atom.size;
9425}
9426
9428{
9429 c->idat_offset = avio_tell(pb);
9430 return 0;
9431}
9432
9434{
9435 HEIFItem **heif_item;
9436 int version, offset_size, length_size, base_offset_size, index_size;
9437 int item_count, extent_count;
9438 int64_t base_offset, extent_offset, extent_length;
9439 uint8_t value;
9440
9441 if (c->found_iloc) {
9442 av_log(c->fc, AV_LOG_INFO, "Duplicate iloc box found\n");
9443 return 0;
9444 }
9445
9446 version = avio_r8(pb);
9447 avio_rb24(pb); // flags.
9448
9449 value = avio_r8(pb);
9450 offset_size = (value >> 4) & 0xF;
9451 length_size = value & 0xF;
9452 value = avio_r8(pb);
9453 base_offset_size = (value >> 4) & 0xF;
9454 index_size = !version ? 0 : (value & 0xF);
9455 if (index_size) {
9456 avpriv_report_missing_feature(c->fc, "iloc: index_size != 0");
9457 return AVERROR_PATCHWELCOME;
9458 }
9459 item_count = (version < 2) ? avio_rb16(pb) : avio_rb32(pb);
9460
9461 if (item_count > atom.size)
9462 return AVERROR_INVALIDDATA;
9463
9464 heif_item = av_realloc_array(c->heif_item, FFMAX(item_count, c->nb_heif_item), sizeof(*c->heif_item));
9465 if (!heif_item)
9466 return AVERROR(ENOMEM);
9467 c->heif_item = heif_item;
9468 if (item_count > c->nb_heif_item)
9469 memset(&c->heif_item[c->nb_heif_item], 0,
9470 sizeof(*c->heif_item) * (item_count - c->nb_heif_item));
9471 c->nb_heif_item = FFMAX(c->nb_heif_item, item_count);
9472
9473 av_log(c->fc, AV_LOG_TRACE, "iloc: item_count %d\n", item_count);
9474 for (int i = 0; i < item_count; i++) {
9475 HEIFItem *item = NULL;
9476 int item_id = (version < 2) ? avio_rb16(pb) : avio_rb32(pb);
9477 int offset_type = (version > 0) ? avio_rb16(pb) & 0xf : 0;
9478 int j;
9479
9480 if (avio_feof(pb))
9481 return AVERROR_INVALIDDATA;
9482 if (offset_type > 1) {
9483 avpriv_report_missing_feature(c->fc, "iloc offset type %d", offset_type);
9484 return AVERROR_PATCHWELCOME;
9485 }
9486
9487 avio_rb16(pb); // data_reference_index.
9488 if (rb_size(pb, &base_offset, base_offset_size) < 0)
9489 return AVERROR_INVALIDDATA;
9490 extent_count = avio_rb16(pb);
9491 if (extent_count > 1) {
9492 // For still AVIF images, we only support one extent item.
9493 avpriv_report_missing_feature(c->fc, "iloc: extent_count > 1");
9494 return AVERROR_PATCHWELCOME;
9495 }
9496
9497 if (rb_size(pb, &extent_offset, offset_size) < 0 ||
9498 rb_size(pb, &extent_length, length_size) < 0 ||
9499 base_offset > INT64_MAX - extent_offset)
9500 return AVERROR_INVALIDDATA;
9501
9502 for (j = 0; j < c->nb_heif_item; j++) {
9503 item = c->heif_item[j];
9504 if (!item)
9505 item = c->heif_item[j] = av_mallocz(sizeof(*item));
9506 else if (item->item_id != item_id)
9507 continue;
9508 break;
9509 }
9510 if (!item)
9511 return AVERROR(ENOMEM);
9512 if (j == c->nb_heif_item)
9513 return AVERROR_INVALIDDATA;
9514
9515 item->item_id = item_id;
9516
9517 if (offset_type == 1)
9518 item->is_idat_relative = 1;
9519 item->extent_length = extent_length;
9520 item->extent_offset = base_offset + extent_offset;
9521 av_log(c->fc, AV_LOG_TRACE, "iloc: item_idx %d, item->item_id %d, offset_type %d, "
9522 "extent_offset %"PRId64", extent_length %"PRId64"\n",
9523 i, item->item_id, offset_type, item->extent_offset, item->extent_length);
9524 }
9525
9526 c->found_iloc = 1;
9527 return atom.size;
9528}
9529
9531{
9532 HEIFItem *item = NULL;
9533 AVBPrint item_name;
9534 int64_t size = atom.size;
9535 uint32_t item_type;
9536 int item_id;
9537 int i, version, ret;
9538
9539 version = avio_r8(pb);
9540 avio_rb24(pb); // flags.
9541 size -= 4;
9542 if (size < 0)
9543 return AVERROR_INVALIDDATA;
9544
9545 if (version < 2) {
9546 avpriv_report_missing_feature(c->fc, "infe version < 2");
9547 avio_skip(pb, size);
9548 return 1;
9549 }
9550
9551 item_id = version > 2 ? avio_rb32(pb) : avio_rb16(pb);
9552 avio_rb16(pb); // item_protection_index
9553 item_type = avio_rl32(pb);
9554 size -= 8;
9555 if (size < 1)
9556 return AVERROR_INVALIDDATA;
9557
9560 if (ret < 0) {
9562 return ret;
9563 }
9564
9565 av_log(c->fc, AV_LOG_TRACE, "infe: item_id %d, item_type %s, item_name %s\n",
9566 item_id, av_fourcc2str(item_type), item_name.str);
9567
9568 size -= ret + 1;
9569 if (size > 0)
9570 avio_skip(pb, size);
9571
9572 for (i = 0; i < c->nb_heif_item; i++) {
9573 item = c->heif_item[i];
9574 if (!item)
9575 item = c->heif_item[i] = av_mallocz(sizeof(*item));
9576 else if (item->item_id != item_id)
9577 continue;
9578 break;
9579 }
9580 if (!item) {
9582 return AVERROR(ENOMEM);
9583 }
9584 if (i == c->nb_heif_item) {
9586 return AVERROR_INVALIDDATA;
9587 }
9588
9589 av_freep(&item->name);
9590 av_bprint_finalize(&item_name, ret ? &item->name : NULL);
9591 item->item_id = item_id;
9592 item->type = item_type;
9593
9594 switch (item_type) {
9595 case MKTAG('a','v','0','1'):
9596 case MKTAG('j','p','e','g'):
9597 case MKTAG('h','v','c','1'):
9598 ret = heif_add_stream(c, item);
9599 if (ret < 0)
9600 return ret;
9601 break;
9602 }
9603
9604 return 0;
9605}
9606
9608{
9609 HEIFItem **heif_item;
9610 int entry_count;
9611 int version, got_stream = 0, ret, i;
9612
9613 if (c->found_iinf) {
9614 av_log(c->fc, AV_LOG_WARNING, "Duplicate iinf box found\n");
9615 return 0;
9616 }
9617
9618 version = avio_r8(pb);
9619 avio_rb24(pb); // flags.
9620 entry_count = version ? avio_rb32(pb) : avio_rb16(pb);
9621
9622 if (entry_count > atom.size)
9623 return AVERROR_INVALIDDATA;
9624
9625 heif_item = av_realloc_array(c->heif_item, FFMAX(entry_count, c->nb_heif_item), sizeof(*c->heif_item));
9626 if (!heif_item)
9627 return AVERROR(ENOMEM);
9628 c->heif_item = heif_item;
9629 if (entry_count > c->nb_heif_item)
9630 memset(&c->heif_item[c->nb_heif_item], 0,
9631 sizeof(*c->heif_item) * (entry_count - c->nb_heif_item));
9632 c->nb_heif_item = FFMAX(c->nb_heif_item, entry_count);
9633
9634 for (i = 0; i < entry_count; i++) {
9635 MOVAtom infe;
9636
9637 infe.size = avio_rb32(pb) - 8;
9638 infe.type = avio_rl32(pb);
9639 if (avio_feof(pb)) {
9640 ret = AVERROR_INVALIDDATA;
9641 goto fail;
9642 }
9643 ret = mov_read_infe(c, pb, infe);
9644 if (ret < 0)
9645 goto fail;
9646 if (!ret)
9647 got_stream = 1;
9648 }
9649
9650 c->found_iinf = got_stream;
9651 return 0;
9652fail:
9653 for (; i >= 0; i--) {
9654 HEIFItem *item = c->heif_item[i];
9655
9656 if (!item)
9657 continue;
9658
9659 av_freep(&item->name);
9660 }
9661 return ret;
9662}
9663
9665{
9666 HEIFItem *item = NULL;
9667 HEIFGrid *grid;
9668 int entries, i;
9669 int from_item_id = version ? avio_rb32(pb) : avio_rb16(pb);
9670 int ret = 0;
9671
9672 for (int i = 0; i < c->nb_heif_grid; i++) {
9673 if (c->heif_grid[i].item->item_id == from_item_id) {
9674 av_log(c->fc, AV_LOG_ERROR, "More than one 'dimg' box "
9675 "referencing the same Derived Image item\n");
9676 return AVERROR_INVALIDDATA;
9677 }
9678 }
9679 for (int i = 0; i < c->nb_heif_item; i++) {
9680 if (!c->heif_item[i] || c->heif_item[i]->item_id != from_item_id)
9681 continue;
9682 item = c->heif_item[i];
9683
9684 switch (item->type) {
9685 case MKTAG('g','r','i','d'):
9686 case MKTAG('i','o','v','l'):
9687 break;
9688 default:
9689 avpriv_report_missing_feature(c->fc, "Derived Image item of type %s",
9690 av_fourcc2str(item->type));
9691 return 0;
9692 }
9693 break;
9694 }
9695 if (!item) {
9696 av_log(c->fc, AV_LOG_ERROR, "Missing grid information\n");
9697 return AVERROR_INVALIDDATA;
9698 }
9699
9700 entries = avio_rb16(pb);
9701 if (!entries) {
9702 av_log(c->fc, AV_LOG_ERROR,
9703 "Derived image item references no input images\n");
9704 return AVERROR_INVALIDDATA;
9705 }
9706
9707 grid = av_realloc_array(c->heif_grid, c->nb_heif_grid + 1U,
9708 sizeof(*c->heif_grid));
9709 if (!grid)
9710 return AVERROR(ENOMEM);
9711 c->heif_grid = grid;
9712 grid = &grid[c->nb_heif_grid];
9713
9714 grid->tile_id_list = av_malloc_array(entries, sizeof(*grid->tile_id_list));
9715 grid->tile_idx_list = av_calloc(entries, sizeof(*grid->tile_idx_list));
9716 grid->tile_item_list = av_calloc(entries, sizeof(*grid->tile_item_list));
9717 if (!grid->tile_id_list || !grid->tile_item_list || !grid->tile_idx_list) {
9718 ret = AVERROR(ENOMEM);
9719 goto fail;
9720 }
9721 /* 'to' item ids */
9722 for (i = 0; i < entries; i++) {
9723 grid->tile_id_list[i] = version ? avio_rb32(pb) : avio_rb16(pb);
9724
9725 if (avio_feof(pb)) {
9726 ret = AVERROR_INVALIDDATA;
9727 goto fail;
9728 }
9729 }
9730
9731 grid->nb_tiles = entries;
9732 grid->item = item;
9733 ++c->nb_heif_grid;
9734
9735 av_log(c->fc, AV_LOG_TRACE, "dimg: from_item_id %d, entries %d\n",
9736 from_item_id, entries);
9737
9738 return 0;
9739fail:
9740 av_freep(&grid->tile_id_list);
9741 av_freep(&grid->tile_idx_list);
9742 av_freep(&grid->tile_item_list);
9743
9744 return ret;
9745}
9746
9747static int mov_read_iref_cdsc(MOVContext *c, AVIOContext *pb, uint32_t type, int version, uint32_t size)
9748{
9749 HEIFItem *from_item = NULL;
9750 int entries;
9751 int item_id_size = version ? 4 : 2;
9752 int from_item_id = version ? avio_rb32(pb) : avio_rb16(pb);
9753 const HEIFItemRef ref = { type, from_item_id };
9754
9755 from_item = get_heif_item(c, from_item_id);
9756 if (!from_item) {
9757 av_log(c->fc, AV_LOG_ERROR, "Missing stream referenced by thmb item\n");
9758 return AVERROR_INVALIDDATA;
9759 }
9760
9761 entries = avio_rb16(pb);
9762 if ((int64_t)entries * item_id_size > (int64_t)size - item_id_size - 2) {
9763 av_log(c->fc, AV_LOG_ERROR, "iref %s entry count %d exceeds the sub-box size\n",
9764 av_fourcc2str(type), entries);
9765 return AVERROR_INVALIDDATA;
9766 }
9767 /* 'to' item ids */
9768 for (int i = 0; i < entries; i++) {
9769 HEIFItem *item = get_heif_item(c, version ? avio_rb32(pb) : avio_rb16(pb));
9770
9771 if (avio_feof(pb))
9772 return AVERROR_INVALIDDATA;
9773
9774 if (!item) {
9775 av_log(c->fc, AV_LOG_WARNING, "Missing stream referenced by %s item\n",
9777 continue;
9778 }
9779
9780 if (!av_dynarray2_add((void **)&item->iref_list, &item->nb_iref_list,
9781 sizeof(*item->iref_list), (const uint8_t *)&ref))
9782 return AVERROR(ENOMEM);
9783 }
9784
9785 av_log(c->fc, AV_LOG_TRACE, "%s: from_item_id %d, entries %d\n",
9786 av_fourcc2str(type), from_item_id, entries);
9787
9788 return 0;
9789}
9790
9792{
9793 int version = avio_r8(pb);
9794 int ret;
9795
9796 avio_rb24(pb); // flags
9797 atom.size -= 4;
9798
9799 if (version > 1) {
9800 av_log(c->fc, AV_LOG_WARNING, "Unknown iref box version %d\n", version);
9801 return 0;
9802 }
9803
9804 while (atom.size) {
9805 int64_t next = avio_tell(pb);
9806 uint32_t type, size = avio_rb32(pb);
9807
9808 if (size < 14 || size > atom.size || next > INT64_MAX - size)
9809 return AVERROR_INVALIDDATA;
9810
9811 next += size;
9812 type = avio_rl32(pb);
9813 switch (type) {
9814 case MKTAG('d','i','m','g'):
9815 ret = mov_read_iref_dimg(c, pb, version);
9816 if (ret < 0)
9817 return ret;
9818 break;
9819 case MKTAG('c','d','s','c'):
9820 case MKTAG('t','h','m','b'):
9821 ret = mov_read_iref_cdsc(c, pb, type, version, size - 8);
9822 if (ret < 0)
9823 return ret;
9824 break;
9825 default:
9826 av_log(c->fc, AV_LOG_DEBUG, "Unknown iref type %s size %"PRIu32"\n",
9828 }
9829
9830 atom.size -= size;
9831 avio_seek(pb, next, SEEK_SET);
9832 }
9833 return 0;
9834}
9835
9837{
9838 HEIFItem *item;
9839 uint32_t width, height;
9840
9841 avio_r8(pb); /* version */
9842 avio_rb24(pb); /* flags */
9843 width = avio_rb32(pb);
9844 height = avio_rb32(pb);
9845
9846 av_log(c->fc, AV_LOG_TRACE, "ispe: item_id %d, width %"PRIu32", height %"PRIu32"\n",
9847 c->cur_item_id, width, height);
9848
9849 if (!width || !height || width > INT_MAX || height > INT_MAX) {
9850 av_log(c->fc, AV_LOG_ERROR, "Invalid ispe dimensions %"PRIu32"x%"PRIu32"\n",
9851 width, height);
9852 return AVERROR_INVALIDDATA;
9853 }
9854
9855 item = get_heif_item(c, c->cur_item_id);
9856 if (item) {
9857 item->width = width;
9858 item->height = height;
9859 }
9860
9861 return 0;
9862}
9863
9865{
9866 HEIFItem *item;
9867 int angle;
9868
9869 angle = avio_r8(pb) & 0x3;
9870
9871 av_log(c->fc, AV_LOG_TRACE, "irot: item_id %d, angle %u\n",
9872 c->cur_item_id, angle);
9873
9874 item = get_heif_item(c, c->cur_item_id);
9875 if (item) {
9876 // angle * 90 specifies the angle (in anti-clockwise direction)
9877 // in units of degrees.
9878 item->rotation = angle * 90;
9879 }
9880
9881 return 0;
9882}
9883
9885{
9886 HEIFItem *item;
9887 int axis;
9888
9889 axis = avio_r8(pb) & 0x1;
9890
9891 av_log(c->fc, AV_LOG_TRACE, "imir: item_id %d, axis %u\n",
9892 c->cur_item_id, axis);
9893
9894 item = get_heif_item(c, c->cur_item_id);
9895 if (item) {
9896 item->hflip = axis;
9897 item->vflip = !axis;
9898 }
9899
9900 return 0;
9901}
9902
9904{
9905 typedef struct MOVAtoms {
9906 FFIOContext b;
9907 uint32_t type;
9908 int64_t size;
9909 uint8_t *data;
9910 } MOVAtoms;
9911 MOVAtoms *atoms = NULL;
9912 MOVAtom a;
9913 unsigned count;
9914 int nb_atoms = 0;
9915 int version, flags;
9916 int ret;
9917
9918 a.size = avio_rb32(pb);
9919 a.type = avio_rl32(pb);
9920
9921 if (a.size < 8 || a.size > atom.size || a.type != MKTAG('i','p','c','o'))
9922 return AVERROR_INVALIDDATA;
9923
9924 atom.size -= a.size;
9925 a.size -= 8;
9926 while (a.size >= 8) {
9927 MOVAtoms *ref = av_dynarray2_add((void**)&atoms, &nb_atoms, sizeof(MOVAtoms), NULL);
9928 if (!ref) {
9929 ret = AVERROR(ENOMEM);
9930 goto fail;
9931 }
9932 ref->data = NULL;
9933 ref->size = avio_rb32(pb);
9934 ref->type = avio_rl32(pb);
9935 if (ref->size > a.size || ref->size < 8)
9936 break;
9937 ref->data = av_malloc(ref->size);
9938 if (!ref->data) {
9939 ret = AVERROR_INVALIDDATA;
9940 goto fail;
9941 }
9942 av_log(c->fc, AV_LOG_TRACE, "ipco: index %d, box type %s\n", nb_atoms, av_fourcc2str(ref->type));
9943 AV_WB32(ref->data, ref->size);
9944 AV_WL32(ref->data + 4, ref->type);
9945 if (avio_read(pb, ref->data + 8, ref->size - 8) != ref->size - 8) {
9946 ret = AVERROR_INVALIDDATA;
9947 goto fail;
9948 }
9949 ffio_init_read_context(&ref->b, ref->data, ref->size);
9950 a.size -= ref->size;
9951 }
9952
9953 if (a.size) {
9954 ret = AVERROR_INVALIDDATA;
9955 goto fail;
9956 }
9957
9958 a.size = avio_rb32(pb);
9959 a.type = avio_rl32(pb);
9960
9961 if (a.size < 16 || a.size > atom.size || a.type != MKTAG('i','p','m','a')) {
9962 ret = AVERROR_INVALIDDATA;
9963 goto fail;
9964 }
9965
9966 version = avio_r8(pb);
9967 flags = avio_rb24(pb);
9968 count = avio_rb32(pb);
9969 a.size -= 16;
9970
9971 for (int i = 0; i < count; i++) {
9972 int item_id = version ? avio_rb32(pb) : avio_rb16(pb);
9973 int assoc_count = avio_r8(pb);
9974
9975 a.size -= (version ? 5 : 3) + assoc_count * (1 + (flags & 1));
9976 if (avio_feof(pb) || a.size < 0) {
9977 ret = AVERROR_INVALIDDATA;
9978 goto fail;
9979 }
9980
9981 for (int j = 0; j < assoc_count; j++) {
9982 MOVAtoms *ref;
9983 int index = avio_r8(pb) & 0x7f;
9984 if (flags & 1) {
9985 index <<= 8;
9986 index |= avio_r8(pb);
9987 }
9988 if (!index)
9989 continue;
9990 if (index > nb_atoms) {
9991 ret = AVERROR_INVALIDDATA;
9992 goto fail;
9993 }
9994 ref = &atoms[--index];
9995
9996 av_log(c->fc, AV_LOG_TRACE, "ipma: property_index %d, item_id %d, item_type %s\n",
9997 index + 1, item_id, av_fourcc2str(ref->type));
9998
9999 c->cur_item_id = item_id;
10000
10001 ret = mov_read_default(c, &ref->b.pub,
10002 (MOVAtom) { .size = ref->size,
10003 .type = MKTAG('i','p','c','o') });
10004 if (ret < 0)
10005 goto fail;
10006 ffio_init_read_context(&ref->b, ref->data, ref->size);
10007 }
10008 }
10009
10010 ret = 0;
10011fail:
10012 c->cur_item_id = -1;
10013 for (int i = 0; i < nb_atoms; i++)
10014 av_free(atoms[i].data);
10015 av_free(atoms);
10016
10017 return ret;
10018}
10019
10021{
10022 avio_rb32(pb); // version & flags
10023 uint16_t graphics_mode = avio_rb16(pb);
10024 // ignored: opcolor[3]
10025
10026 if (c->fc->nb_streams < 1)
10027 return 0;
10028 AVStream *st = c->fc->streams[c->fc->nb_streams - 1];
10030 return 0;
10031
10032 switch (graphics_mode) {
10036 break;
10039 break;
10042 break;
10043 default:
10045 av_log(c->fc, AV_LOG_WARNING, "Unhandled graphics mode: 0x%x\n",
10046 graphics_mode);
10047 break;
10048 }
10049
10050 return 0;
10051}
10052
10054{
10055 AVFormatContext *ctx = c->fc;
10056 AVStream *st;
10057 int profile_level_indication, reference_ch_layout, config_length;
10058 int ret = 0;
10059
10060 if (ctx->nb_streams < 1)
10061 return 0;
10062
10063 st = ctx->streams[ctx->nb_streams - 1];
10065 return 0;
10066
10067 if (avio_r8(pb) != 1) // ConfigurationVersion
10068 return 0;
10069
10070 profile_level_indication = avio_r8(pb);
10071 st->codecpar->profile = (profile_level_indication - 1) / 5;
10072 st->codecpar->level = ((profile_level_indication - 1) % 5) + 1;
10073
10074 reference_ch_layout = avio_r8(pb);
10075 config_length = avio_rb16(pb);
10076 if (config_length)
10077 ret = ff_get_extradata(ctx, st->codecpar, pb, config_length);
10078
10079 if (!reference_ch_layout ||
10080 reference_ch_layout >= FF_ARRAY_ELEMS(ff_mpa_cicp_channel_layout_masks)) {
10081 av_log(ctx, AV_LOG_WARNING, "Unknown referenceChannelLayout value: %d\n", reference_ch_layout);
10082 return ret;
10083 }
10084
10086 ff_mpa_cicp_channel_layout_masks[reference_ch_layout]);
10087
10088 return ret;
10089}
10090
10092{ MKTAG('A','C','L','R'), mov_read_aclr },
10093{ MKTAG('A','P','R','G'), mov_read_avid },
10094{ MKTAG('A','A','L','P'), mov_read_avid },
10095{ MKTAG('A','R','E','S'), mov_read_ares },
10096{ MKTAG('a','v','s','s'), mov_read_avss },
10097{ MKTAG('a','v','1','C'), mov_read_glbl },
10098{ MKTAG('c','h','p','l'), mov_read_chpl },
10099{ MKTAG('c','o','6','4'), mov_read_stco },
10100{ MKTAG('c','o','l','r'), mov_read_colr },
10101{ MKTAG('c','t','t','s'), mov_read_ctts }, /* composition time to sample */
10102{ MKTAG('d','i','n','f'), mov_read_default },
10103{ MKTAG('D','p','x','E'), mov_read_dpxe },
10104{ MKTAG('d','r','e','f'), mov_read_dref },
10105{ MKTAG('e','d','t','s'), mov_read_default },
10106{ MKTAG('e','l','s','t'), mov_read_elst },
10107{ MKTAG('e','n','d','a'), mov_read_enda },
10108{ MKTAG('f','i','e','l'), mov_read_fiel },
10109{ MKTAG('a','d','r','m'), mov_read_adrm },
10110{ MKTAG('f','t','y','p'), mov_read_ftyp },
10111{ MKTAG('g','l','b','l'), mov_read_glbl },
10112{ MKTAG('h','d','l','r'), mov_read_hdlr },
10113{ MKTAG('i','l','s','t'), mov_read_ilst },
10114{ MKTAG('j','p','2','h'), mov_read_jp2h },
10115{ MKTAG('m','d','a','t'), mov_read_mdat },
10116{ MKTAG('m','d','h','d'), mov_read_mdhd },
10117{ MKTAG('m','d','i','a'), mov_read_default },
10118{ MKTAG('m','e','t','a'), mov_read_meta },
10119{ MKTAG('m','i','n','f'), mov_read_default },
10120{ MKTAG('m','o','o','f'), mov_read_moof },
10121{ MKTAG('m','o','o','v'), mov_read_moov },
10122{ MKTAG('m','v','e','x'), mov_read_default },
10123{ MKTAG('m','v','h','d'), mov_read_mvhd },
10124{ MKTAG('S','M','I',' '), mov_read_svq3 },
10125{ MKTAG('a','l','a','c'), mov_read_alac }, /* alac specific atom */
10126{ MKTAG('a','v','c','C'), mov_read_glbl },
10127{ MKTAG('p','a','s','p'), mov_read_pasp },
10128{ MKTAG('c','l','a','p'), mov_read_clap },
10129{ MKTAG('c','d','s','c'), mov_read_cdsc_rndr },
10130{ MKTAG('r','n','d','r'), mov_read_cdsc_rndr },
10131{ MKTAG('s','b','a','s'), mov_read_sbas },
10132{ MKTAG('v','d','e','p'), mov_read_vdep },
10133{ MKTAG('s','i','d','x'), mov_read_sidx },
10134{ MKTAG('s','t','b','l'), mov_read_default },
10135{ MKTAG('s','t','c','o'), mov_read_stco },
10136{ MKTAG('s','t','p','s'), mov_read_stps },
10137{ MKTAG('s','t','r','f'), mov_read_strf },
10138{ MKTAG('s','t','s','c'), mov_read_stsc },
10139{ MKTAG('s','t','s','d'), mov_read_stsd }, /* sample description */
10140{ MKTAG('s','t','s','s'), mov_read_stss }, /* sync sample */
10141{ MKTAG('s','t','s','z'), mov_read_stsz }, /* sample size */
10142{ MKTAG('s','t','t','s'), mov_read_stts },
10143{ MKTAG('s','t','z','2'), mov_read_stsz }, /* compact sample size */
10144{ MKTAG('s','d','t','p'), mov_read_sdtp }, /* independent and disposable samples */
10145{ MKTAG('t','k','h','d'), mov_read_tkhd }, /* track header */
10146{ MKTAG('t','f','d','t'), mov_read_tfdt },
10147{ MKTAG('t','f','h','d'), mov_read_tfhd }, /* track fragment header */
10148{ MKTAG('t','r','a','k'), mov_read_trak },
10149{ MKTAG('t','r','a','f'), mov_read_default },
10150{ MKTAG('t','r','e','f'), mov_read_default },
10151{ MKTAG('t','m','c','d'), mov_read_tmcd },
10152{ MKTAG('c','h','a','p'), mov_read_chap },
10153{ MKTAG('t','r','e','x'), mov_read_trex },
10154{ MKTAG('t','r','u','n'), mov_read_trun },
10155{ MKTAG('u','d','t','a'), mov_read_default },
10156{ MKTAG('w','a','v','e'), mov_read_wave },
10157{ MKTAG('e','s','d','s'), mov_read_esds },
10158{ MKTAG('d','a','c','3'), mov_read_dac3 }, /* AC-3 info */
10159{ MKTAG('d','e','c','3'), mov_read_dec3 }, /* EAC-3 info */
10160{ MKTAG('d','d','t','s'), mov_read_ddts }, /* DTS audio descriptor */
10161{ MKTAG('w','i','d','e'), mov_read_wide }, /* place holder */
10162{ MKTAG('w','f','e','x'), mov_read_wfex },
10163{ MKTAG('c','m','o','v'), mov_read_cmov },
10164{ MKTAG('c','h','a','n'), mov_read_chan }, /* channel layout from quicktime */
10165{ MKTAG('c','h','n','l'), mov_read_chnl }, /* channel layout from ISO-14496-12 */
10166{ MKTAG('d','v','c','1'), mov_read_dvc1 },
10167{ MKTAG('s','g','p','d'), mov_read_sgpd },
10168{ MKTAG('s','b','g','p'), mov_read_sbgp },
10169{ MKTAG('h','v','c','C'), mov_read_glbl },
10170{ MKTAG('v','v','c','C'), mov_read_glbl },
10171{ MKTAG('u','u','i','d'), mov_read_uuid },
10172{ MKTAG('C','i','n', 0x8e), mov_read_targa_y216 },
10173{ MKTAG('f','r','e','e'), mov_read_free },
10174{ MKTAG('-','-','-','-'), mov_read_custom },
10175{ MKTAG('s','i','n','f'), mov_read_default },
10176{ MKTAG('f','r','m','a'), mov_read_frma },
10177{ MKTAG('s','e','n','c'), mov_read_senc },
10178{ MKTAG('s','a','i','z'), mov_read_saiz },
10179{ MKTAG('s','a','i','o'), mov_read_saio },
10180{ MKTAG('p','s','s','h'), mov_read_pssh },
10181{ MKTAG('s','c','h','m'), mov_read_schm },
10182{ MKTAG('s','c','h','i'), mov_read_default },
10183{ MKTAG('t','e','n','c'), mov_read_tenc },
10184{ MKTAG('d','f','L','a'), mov_read_dfla },
10185{ MKTAG('s','t','3','d'), mov_read_st3d }, /* stereoscopic 3D video box */
10186{ MKTAG('s','v','3','d'), mov_read_sv3d }, /* spherical video box */
10187{ MKTAG('v','e','x','u'), mov_read_vexu }, /* video extension usage */
10188{ MKTAG('h','f','o','v'), mov_read_hfov },
10189{ MKTAG('d','O','p','s'), mov_read_dops },
10190{ MKTAG('d','m','l','p'), mov_read_dmlp },
10191{ MKTAG('S','m','D','m'), mov_read_smdm },
10192{ MKTAG('C','o','L','L'), mov_read_coll },
10193{ MKTAG('v','p','c','C'), mov_read_vpcc },
10194{ MKTAG('m','d','c','v'), mov_read_mdcv },
10195{ MKTAG('c','l','l','i'), mov_read_clli },
10196{ MKTAG('d','v','c','C'), mov_read_dvcc_dvvc },
10197{ MKTAG('d','v','v','C'), mov_read_dvcc_dvvc },
10198{ MKTAG('d','v','w','C'), mov_read_dvcc_dvvc },
10199{ MKTAG('h','v','c','E'), mov_read_hvce },
10200{ MKTAG('k','i','n','d'), mov_read_kind },
10201{ MKTAG('S','A','3','D'), mov_read_SA3D }, /* ambisonic audio box */
10202{ MKTAG('S','A','N','D'), mov_read_SAND }, /* non diegetic audio box */
10203{ MKTAG('i','l','o','c'), mov_read_iloc },
10204{ MKTAG('p','c','m','C'), mov_read_pcmc }, /* PCM configuration box */
10205{ MKTAG('p','i','t','m'), mov_read_pitm },
10206{ MKTAG('e','v','c','C'), mov_read_glbl },
10207{ MKTAG('i','d','a','t'), mov_read_idat },
10208{ MKTAG('i','m','i','r'), mov_read_imir },
10209{ MKTAG('i','r','e','f'), mov_read_iref },
10210{ MKTAG('i','s','p','e'), mov_read_ispe },
10211{ MKTAG('i','r','o','t'), mov_read_irot },
10212{ MKTAG('i','p','r','p'), mov_read_iprp },
10213{ MKTAG('i','i','n','f'), mov_read_iinf },
10214{ MKTAG('a','m','v','e'), mov_read_amve }, /* ambient viewing environment box */
10215{ MKTAG('l','h','v','C'), mov_read_lhvc },
10216{ MKTAG('l','v','c','C'), mov_read_glbl },
10217{ MKTAG('a','p','v','C'), mov_read_glbl },
10218#if CONFIG_IAMFDEC
10219{ MKTAG('i','a','c','b'), mov_read_iacb },
10220#endif
10221{ MKTAG('s','r','a','t'), mov_read_srat },
10222{ MKTAG('v','m','h','d'), mov_read_vmhd },
10223{ MKTAG('m','h','a','C'), mov_read_mhac },
10224{ 0, NULL }
10225};
10226
10228{
10229 int64_t total_size = 0;
10230 MOVAtom a;
10231 int i;
10232
10233 if (c->atom_depth > 10) {
10234 av_log(c->fc, AV_LOG_ERROR, "Atoms too deeply nested\n");
10235 return AVERROR_INVALIDDATA;
10236 }
10237 c->atom_depth ++;
10238
10239 if (atom.size < 0)
10240 atom.size = INT64_MAX;
10241 while (total_size <= atom.size - 8) {
10242 int (*parse)(MOVContext*, AVIOContext*, MOVAtom) = NULL;
10243 a.size = avio_rb32(pb);
10244 a.type = avio_rl32(pb);
10245 if (avio_feof(pb))
10246 break;
10247 if (((a.type == MKTAG('f','r','e','e') && c->moov_retry) ||
10248 a.type == MKTAG('h','o','o','v')) &&
10249 a.size >= 8 &&
10250 c->fc->strict_std_compliance < FF_COMPLIANCE_STRICT) {
10251 uint32_t type;
10252 avio_skip(pb, 4);
10253 type = avio_rl32(pb);
10254 if (avio_feof(pb))
10255 break;
10256 avio_seek(pb, -8, SEEK_CUR);
10257 if (type == MKTAG('m','v','h','d') ||
10258 type == MKTAG('c','m','o','v')) {
10259 av_log(c->fc, AV_LOG_ERROR, "Detected moov in a free or hoov atom.\n");
10260 a.type = MKTAG('m','o','o','v');
10261 }
10262 }
10263 if (atom.type != MKTAG('r','o','o','t') &&
10264 atom.type != MKTAG('m','o','o','v')) {
10265 if (a.type == MKTAG('t','r','a','k') ||
10266 a.type == MKTAG('m','d','a','t')) {
10267 av_log(c->fc, AV_LOG_ERROR, "Broken file, trak/mdat not at top-level\n");
10268 avio_skip(pb, -8);
10269 c->atom_depth --;
10270 return 0;
10271 }
10272 }
10273 total_size += 8;
10274 if (a.size == 1 && total_size + 8 <= atom.size) { /* 64 bit extended size */
10275 a.size = avio_rb64(pb) - 8;
10276 total_size += 8;
10277 }
10278 av_log(c->fc, AV_LOG_TRACE, "type:'%s' parent:'%s' sz: %"PRId64" %"PRId64" %"PRId64"\n",
10279 av_fourcc2str(a.type), av_fourcc2str(atom.type), a.size, total_size, atom.size);
10280 if (a.size == 0) {
10281 a.size = atom.size - total_size + 8;
10282 }
10283 if (a.size < 0)
10284 break;
10285 a.size -= 8;
10286 if (a.size < 0)
10287 break;
10288 a.size = FFMIN(a.size, atom.size - total_size);
10289
10290 for (i = 0; mov_default_parse_table[i].type; i++)
10291 if (mov_default_parse_table[i].type == a.type) {
10293 break;
10294 }
10295
10296 // container is user data
10297 if (!parse && (atom.type == MKTAG('u','d','t','a') ||
10298 atom.type == MKTAG('i','l','s','t')))
10300
10301 // Supports parsing the QuickTime Metadata Keys.
10302 // https://developer.apple.com/library/mac/documentation/QuickTime/QTFF/Metadata/Metadata.html
10303 if (!parse && c->found_hdlr_mdta &&
10304 atom.type == MKTAG('m','e','t','a') &&
10305 a.type == MKTAG('k','e','y','s') &&
10306 c->meta_keys_count == 0) {
10308 }
10309
10310 if (!parse) { /* skip leaf atoms data */
10311 avio_skip(pb, a.size);
10312 } else {
10313 int64_t start_pos = avio_tell(pb);
10314 int64_t left;
10315 int err = parse(c, pb, a);
10316 if (err < 0) {
10317 c->atom_depth --;
10318 return err;
10319 }
10320 if (c->found_moov && c->found_mdat && a.size <= INT64_MAX - start_pos &&
10321 ((!(pb->seekable & AVIO_SEEKABLE_NORMAL) || c->fc->flags & AVFMT_FLAG_IGNIDX || c->frag_index.complete) ||
10322 start_pos + a.size == avio_size(pb))) {
10323 if (!(pb->seekable & AVIO_SEEKABLE_NORMAL) || c->fc->flags & AVFMT_FLAG_IGNIDX || c->frag_index.complete)
10324 c->next_root_atom = start_pos + a.size;
10325 c->atom_depth --;
10326 return 0;
10327 }
10328 left = a.size - avio_tell(pb) + start_pos;
10329 if (left > 0) /* skip garbage at atom end */
10330 avio_skip(pb, left);
10331 else if (left < 0) {
10332 av_log(c->fc, AV_LOG_WARNING,
10333 "overread end of atom '%s' by %"PRId64" bytes\n",
10334 av_fourcc2str(a.type), -left);
10335 avio_seek(pb, left, SEEK_CUR);
10336 }
10337 }
10338
10339 total_size += a.size;
10340 }
10341
10342 if (total_size < atom.size && atom.size < 0x7ffff)
10343 avio_skip(pb, atom.size - total_size);
10344
10345 c->atom_depth --;
10346 return 0;
10347}
10348
10349static int mov_probe(const AVProbeData *p)
10350{
10352 uint32_t tag;
10353 int score = 0;
10354 int moov_offset = -1;
10355
10356 /* check file header */
10357 offset = 0;
10358 for (;;) {
10359 int64_t size;
10360 int minsize = 8;
10361 /* ignore invalid offset */
10362 if ((offset + 8ULL) > (unsigned int)p->buf_size)
10363 break;
10364 size = AV_RB32(p->buf + offset);
10365 if (size == 1 && offset + 16 <= (unsigned int)p->buf_size) {
10366 size = AV_RB64(p->buf+offset + 8);
10367 minsize = 16;
10368 } else if (size == 0) {
10369 size = p->buf_size - offset;
10370 }
10371 if (size < minsize) {
10372 offset += 4;
10373 continue;
10374 }
10375 tag = AV_RL32(p->buf + offset + 4);
10376 switch(tag) {
10377 /* check for obvious tags */
10378 case MKTAG('m','o','o','v'):
10379 moov_offset = offset + 4;
10381 case MKTAG('m','d','a','t'):
10382 case MKTAG('p','n','o','t'): /* detect movs with preview pics like ew.mov and april.mov */
10383 case MKTAG('u','d','t','a'): /* Packet Video PVAuthor adds this and a lot of more junk */
10384 case MKTAG('f','t','y','p'):
10385 if (tag == MKTAG('f','t','y','p') &&
10386 ( AV_RL32(p->buf + offset + 8) == MKTAG('j','p','2',' ')
10387 || AV_RL32(p->buf + offset + 8) == MKTAG('j','p','x',' ')
10388 || AV_RL32(p->buf + offset + 8) == MKTAG('j','x','l',' ')
10389 )) {
10390 score = FFMAX(score, 5);
10391 } else {
10392 score = AVPROBE_SCORE_MAX;
10393 }
10394 break;
10395 /* those are more common words, so rate then a bit less */
10396 case MKTAG('e','d','i','w'): /* xdcam files have reverted first tags */
10397 case MKTAG('w','i','d','e'):
10398 case MKTAG('f','r','e','e'):
10399 case MKTAG('j','u','n','k'):
10400 case MKTAG('p','i','c','t'):
10401 score = FFMAX(score, AVPROBE_SCORE_MAX - 5);
10402 break;
10403 case MKTAG(0x82,0x82,0x7f,0x7d):
10404 score = FFMAX(score, AVPROBE_SCORE_EXTENSION - 5);
10405 break;
10406 case MKTAG('s','k','i','p'):
10407 case MKTAG('u','u','i','d'):
10408 case MKTAG('p','r','f','l'):
10409 /* if we only find those cause probedata is too small at least rate them */
10410 score = FFMAX(score, AVPROBE_SCORE_EXTENSION);
10411 break;
10412 }
10413 if (size > INT64_MAX - offset)
10414 break;
10415 offset += size;
10416 }
10417 if (score > AVPROBE_SCORE_MAX - 50 && moov_offset != -1) {
10418 /* moov atom in the header - we should make sure that this is not a
10419 * MOV-packed MPEG-PS */
10420 offset = moov_offset;
10421
10422 while (offset < (p->buf_size - 16)) { /* Sufficient space */
10423 /* We found an actual hdlr atom */
10424 if (AV_RL32(p->buf + offset ) == MKTAG('h','d','l','r') &&
10425 AV_RL32(p->buf + offset + 8) == MKTAG('m','h','l','r') &&
10426 AV_RL32(p->buf + offset + 12) == MKTAG('M','P','E','G')) {
10427 av_log(NULL, AV_LOG_WARNING, "Found media data tag MPEG indicating this is a MOV-packed MPEG-PS.\n");
10428 /* We found a media handler reference atom describing an
10429 * MPEG-PS-in-MOV, return a
10430 * low score to force expanding the probe window until
10431 * mpegps_probe finds what it needs */
10432 return 5;
10433 } else {
10434 /* Keep looking */
10435 offset += 2;
10436 }
10437 }
10438 }
10439
10440 return score;
10441}
10442
10443// must be done after parsing all trak because there's no order requirement
10445{
10446 MOVContext *mov = s->priv_data;
10447 MOVStreamContext *sc;
10448 int64_t cur_pos;
10449 int i, j;
10450 int chapter_track;
10451
10452 for (j = 0; j < mov->nb_chapter_tracks; j++) {
10453 AVStream *st = NULL;
10454 FFStream *sti = NULL;
10455 chapter_track = mov->chapter_tracks[j];
10456 for (i = 0; i < s->nb_streams; i++) {
10457 sc = mov->fc->streams[i]->priv_data;
10458 if (sc->id == chapter_track) {
10459 st = s->streams[i];
10460 break;
10461 }
10462 }
10463 if (!st) {
10464 av_log(s, AV_LOG_ERROR, "Referenced QT chapter track not found\n");
10465 continue;
10466 }
10467 sti = ffstream(st);
10468
10469 sc = st->priv_data;
10470 cur_pos = avio_tell(sc->pb);
10471
10474 if (!st->attached_pic.data && sti->nb_index_entries) {
10475 // Retrieve the first frame, if possible
10476 AVIndexEntry *sample = &sti->index_entries[0];
10477 if (avio_seek(sc->pb, sample->pos, SEEK_SET) != sample->pos) {
10478 av_log(s, AV_LOG_ERROR, "Failed to retrieve first frame\n");
10479 goto finish;
10480 }
10481
10482 if (ff_add_attached_pic(s, st, sc->pb, NULL, sample->size) < 0)
10483 goto finish;
10484 }
10485 } else {
10488 st->discard = AVDISCARD_ALL;
10489 for (int i = 0; i < sti->nb_index_entries; i++) {
10491 int64_t end = i+1 < sti->nb_index_entries ? sti->index_entries[i+1].timestamp : st->duration;
10492 uint8_t *title;
10493 uint16_t ch;
10494 int len, title_len;
10495
10496 if (end < sample->timestamp) {
10497 av_log(s, AV_LOG_WARNING, "ignoring stream duration which is shorter than chapters\n");
10498 end = AV_NOPTS_VALUE;
10499 }
10500
10501 if (avio_seek(sc->pb, sample->pos, SEEK_SET) != sample->pos) {
10502 av_log(s, AV_LOG_ERROR, "Chapter %d not found in file\n", i);
10503 goto finish;
10504 }
10505
10506 // the first two bytes are the length of the title
10507 len = avio_rb16(sc->pb);
10508 if (len > sample->size-2)
10509 continue;
10510 title_len = 2*len + 1;
10511 if (!(title = av_mallocz(title_len)))
10512 goto finish;
10513
10514 // The samples could theoretically be in any encoding if there's an encd
10515 // atom following, but in practice are only utf-8 or utf-16, distinguished
10516 // instead by the presence of a BOM
10517 if (!len) {
10518 title[0] = 0;
10519 } else {
10520 ch = avio_rb16(sc->pb);
10521 if (ch == 0xfeff)
10522 avio_get_str16be(sc->pb, len, title, title_len);
10523 else if (ch == 0xfffe)
10524 avio_get_str16le(sc->pb, len, title, title_len);
10525 else {
10526 AV_WB16(title, ch);
10527 if (len == 1 || len == 2)
10528 title[len] = 0;
10529 else
10530 avio_get_str(sc->pb, INT_MAX, title + 2, len - 1);
10531 }
10532 }
10533
10534 avpriv_new_chapter(s, i, st->time_base, sample->timestamp, end, title);
10535 av_freep(&title);
10536 }
10537 }
10538finish:
10539 avio_seek(sc->pb, cur_pos, SEEK_SET);
10540 }
10541}
10542
10544 int64_t value, int flags)
10545{
10546 AVTimecode tc;
10547 char buf[AV_TIMECODE_STR_SIZE];
10548 AVRational rate = st->avg_frame_rate;
10549 int ret = av_timecode_init(&tc, rate, flags, 0, s);
10550 if (ret < 0)
10551 return ret;
10552 av_dict_set(&st->metadata, "timecode",
10553 av_timecode_make_string(&tc, buf, value), 0);
10554 return 0;
10555}
10556
10558{
10559 MOVStreamContext *sc = st->priv_data;
10560 FFStream *const sti = ffstream(st);
10561 char buf[AV_TIMECODE_STR_SIZE];
10562 int64_t cur_pos = avio_tell(sc->pb);
10563 int hh, mm, ss, ff, drop;
10564
10565 if (!sti->nb_index_entries)
10566 return -1;
10567
10568 avio_seek(sc->pb, sti->index_entries->pos, SEEK_SET);
10569 avio_skip(s->pb, 13);
10570 hh = avio_r8(s->pb);
10571 mm = avio_r8(s->pb);
10572 ss = avio_r8(s->pb);
10573 drop = avio_r8(s->pb);
10574 ff = avio_r8(s->pb);
10575 snprintf(buf, AV_TIMECODE_STR_SIZE, "%02d:%02d:%02d%c%02d",
10576 hh, mm, ss, drop ? ';' : ':', ff);
10577 av_dict_set(&st->metadata, "timecode", buf, 0);
10578
10579 avio_seek(sc->pb, cur_pos, SEEK_SET);
10580 return 0;
10581}
10582
10584{
10585 MOVStreamContext *sc = st->priv_data;
10586 FFStream *const sti = ffstream(st);
10587 int flags = 0;
10588 int64_t cur_pos = avio_tell(sc->pb);
10589 int64_t value;
10590 AVRational tc_rate = st->avg_frame_rate;
10591 int tmcd_nb_frames = sc->tmcd_nb_frames;
10592 int rounded_tc_rate;
10593
10594 if (!sti->nb_index_entries)
10595 return -1;
10596
10597 if (!tc_rate.num || !tc_rate.den || !tmcd_nb_frames)
10598 return -1;
10599
10600 avio_seek(sc->pb, sti->index_entries->pos, SEEK_SET);
10601 value = avio_rb32(s->pb);
10602
10603 if (sc->tmcd_flags & 0x0001) flags |= AV_TIMECODE_FLAG_DROPFRAME;
10604 if (sc->tmcd_flags & 0x0002) flags |= AV_TIMECODE_FLAG_24HOURSMAX;
10605 if (sc->tmcd_flags & 0x0004) flags |= AV_TIMECODE_FLAG_ALLOWNEGATIVE;
10606
10607 /* Assume Counter flag is set to 1 in tmcd track (even though it is likely
10608 * not the case) and thus assume "frame number format" instead of QT one.
10609 * No sample with tmcd track can be found with a QT timecode at the moment,
10610 * despite what the tmcd track "suggests" (Counter flag set to 0 means QT
10611 * format). */
10612
10613 /* 60 fps content have tmcd_nb_frames set to 30 but tc_rate set to 60, so
10614 * we multiply the frame number with the quotient.
10615 * See tickets #9492, #9710. */
10616 rounded_tc_rate = (tc_rate.num + tc_rate.den / 2LL) / tc_rate.den;
10617 /* Work around files where tmcd_nb_frames is rounded down from frame rate
10618 * instead of up. See ticket #5978. */
10619 if (tmcd_nb_frames == tc_rate.num / tc_rate.den &&
10620 s->strict_std_compliance < FF_COMPLIANCE_STRICT)
10621 tmcd_nb_frames = rounded_tc_rate;
10622 value = av_rescale(value, rounded_tc_rate, tmcd_nb_frames);
10623
10625
10626 avio_seek(sc->pb, cur_pos, SEEK_SET);
10627 return 0;
10628}
10629
10631 int i;
10632 if (!index || !*index) return;
10633 for (i = 0; i < (*index)->nb_encrypted_samples; i++) {
10634 av_encryption_info_free((*index)->encrypted_samples[i]);
10635 }
10636 av_freep(&(*index)->encrypted_samples);
10637 av_freep(&(*index)->auxiliary_info_sizes);
10638 av_freep(&(*index)->auxiliary_offsets);
10639 av_freep(index);
10640}
10641
10643{
10644 MOVStreamContext *sc = st->priv_data;
10645
10646 if (!sc || --sc->refcount) {
10647 st->priv_data = NULL;
10648 return;
10649 }
10650
10651 av_freep(&sc->tts_data);
10652 for (int i = 0; i < sc->drefs_count; i++) {
10653 av_freep(&sc->drefs[i].path);
10654 av_freep(&sc->drefs[i].dir);
10655 }
10656 av_freep(&sc->drefs);
10657
10658 sc->drefs_count = 0;
10659
10660 if (!sc->pb_is_copied)
10661 ff_format_io_close(s, &sc->pb);
10662
10663 sc->pb = NULL;
10664 av_freep(&sc->chunk_offsets);
10665 av_freep(&sc->stsc_data);
10666 av_freep(&sc->sample_sizes);
10667 av_freep(&sc->keyframes);
10668 av_freep(&sc->ctts_data);
10669 av_freep(&sc->stts_data);
10670 av_freep(&sc->sdtp_data);
10671 av_freep(&sc->stps_data);
10672 av_freep(&sc->elst_data);
10673 av_freep(&sc->rap_group);
10674 av_freep(&sc->sync_group);
10675 av_freep(&sc->sgpd_sync);
10679 av_freep(&sc->index_ranges);
10680 for (int i = 0; i < sc->nb_tref_tags; i++)
10681 av_freep(&sc->tref_tags[i].id);
10682 av_freep(&sc->tref_tags);
10683
10684 if (sc->extradata)
10685 for (int i = 0; i < sc->stsd_count; i++)
10686 av_free(sc->extradata[i]);
10687 av_freep(&sc->extradata);
10689
10693
10694 av_freep(&sc->stereo3d);
10695 av_freep(&sc->spherical);
10696 av_freep(&sc->mastering);
10697 av_freep(&sc->coll);
10698 av_freep(&sc->ambient);
10699
10700#if CONFIG_IAMFDEC
10701 if (sc->iamf)
10703#endif
10704 av_freep(&sc->iamf);
10705}
10706
10708{
10709 MOVContext *mov = s->priv_data;
10710 int i, j;
10711
10712 for (i = 0; i < s->nb_streams; i++) {
10713 AVStream *st = s->streams[i];
10714
10716 }
10717
10718 av_freep(&mov->dv_demux);
10720 mov->dv_fctx = NULL;
10721
10722 if (mov->meta_keys) {
10723 for (i = 1; i < mov->meta_keys_count; i++) {
10724 av_freep(&mov->meta_keys[i]);
10725 }
10726 av_freep(&mov->meta_keys);
10727 }
10728
10729 av_freep(&mov->trex_data);
10730 av_freep(&mov->bitrates);
10731
10732 for (i = 0; i < mov->frag_index.nb_items; i++) {
10734 for (j = 0; j < mov->frag_index.item[i].nb_stream_info; j++) {
10735 mov_free_encryption_index(&frag[j].encryption_index);
10736 }
10738 }
10739 av_freep(&mov->frag_index.item);
10740
10741 av_freep(&mov->aes_decrypt);
10742 av_freep(&mov->chapter_tracks);
10743 for (i = 0; i < mov->nb_heif_item; i++) {
10744 if (!mov->heif_item[i])
10745 continue;
10746 av_freep(&mov->heif_item[i]->name);
10747 av_freep(&mov->heif_item[i]->iref_list);
10749 av_freep(&mov->heif_item[i]);
10750 }
10751 av_freep(&mov->heif_item);
10752 for (i = 0; i < mov->nb_heif_grid; i++) {
10756 }
10757 av_freep(&mov->heif_grid);
10758
10759 return 0;
10760}
10761
10762static int tmcd_is_referenced(AVFormatContext *s, int tmcd_id)
10763{
10764 int i;
10765
10766 for (i = 0; i < s->nb_streams; i++) {
10767 AVStream *st = s->streams[i];
10768 MOVStreamContext *sc = st->priv_data;
10769 MovTref *tag = mov_find_tref_tag(sc, MKTAG('t','m','c','d'));
10770
10771 if (!tag)
10772 continue;
10773 if (mov_find_tref_id(tag, tmcd_id))
10774 return 1;
10775 }
10776 return 0;
10777}
10778
10779/* look for a tmcd track not referenced by any video track, and export it globally */
10781{
10782 int i;
10783
10784 for (i = 0; i < s->nb_streams; i++) {
10785 AVStream *st = s->streams[i];
10786
10787 if (st->codecpar->codec_tag == MKTAG('t','m','c','d') &&
10788 !tmcd_is_referenced(s, st->id)) {
10789 AVDictionaryEntry *tcr = av_dict_get(st->metadata, "timecode", NULL, 0);
10790 if (tcr) {
10791 av_dict_set(&s->metadata, "timecode", tcr->value, 0);
10792 break;
10793 }
10794 }
10795 }
10796}
10797
10799{
10800 int version, fieldlength, i, j;
10802 uint32_t size = avio_rb32(f);
10803 unsigned track_id, item_count;
10804
10805 if (avio_rb32(f) != MKBETAG('t', 'f', 'r', 'a')) {
10806 return 1;
10807 }
10808 av_log(mov->fc, AV_LOG_VERBOSE, "found tfra\n");
10809
10810 version = avio_r8(f);
10811 avio_rb24(f);
10812 track_id = avio_rb32(f);
10813 fieldlength = avio_rb32(f);
10814 item_count = avio_rb32(f);
10815 for (i = 0; i < item_count; i++) {
10816 int64_t time, offset;
10817 int index;
10818 MOVFragmentStreamInfo * frag_stream_info;
10819
10820 if (avio_feof(f)) {
10821 return AVERROR_INVALIDDATA;
10822 }
10823
10824 if (version == 1) {
10825 time = avio_rb64(f);
10826 offset = avio_rb64(f);
10827 } else {
10828 time = avio_rb32(f);
10829 offset = avio_rb32(f);
10830 }
10831
10832 // The first sample of each stream in a fragment is always a random
10833 // access sample. So it's entry in the tfra can be used as the
10834 // initial PTS of the fragment.
10836 frag_stream_info = get_frag_stream_info(&mov->frag_index, index, track_id);
10837 if (frag_stream_info &&
10838 frag_stream_info->first_tfra_pts == AV_NOPTS_VALUE)
10839 frag_stream_info->first_tfra_pts = time;
10840
10841 for (j = 0; j < ((fieldlength >> 4) & 3) + 1; j++)
10842 avio_r8(f);
10843 for (j = 0; j < ((fieldlength >> 2) & 3) + 1; j++)
10844 avio_r8(f);
10845 for (j = 0; j < ((fieldlength >> 0) & 3) + 1; j++)
10846 avio_r8(f);
10847 }
10848
10849 avio_seek(f, pos + size, SEEK_SET);
10850 return 0;
10851}
10852
10854{
10855 int64_t stream_size = avio_size(f);
10856 int64_t original_pos = avio_tell(f);
10857 int64_t seek_ret;
10858 int ret = -1;
10859 if ((seek_ret = avio_seek(f, stream_size - 4, SEEK_SET)) < 0) {
10860 ret = seek_ret;
10861 goto fail;
10862 }
10863 c->mfra_size = avio_rb32(f);
10864 c->have_read_mfra_size = 1;
10865 if (!c->mfra_size || c->mfra_size > stream_size) {
10866 av_log(c->fc, AV_LOG_DEBUG, "doesn't look like mfra (unreasonable size)\n");
10867 goto fail;
10868 }
10869 if ((seek_ret = avio_seek(f, -((int64_t) c->mfra_size), SEEK_CUR)) < 0) {
10870 ret = seek_ret;
10871 goto fail;
10872 }
10873 if (avio_rb32(f) != c->mfra_size) {
10874 av_log(c->fc, AV_LOG_DEBUG, "doesn't look like mfra (size mismatch)\n");
10875 goto fail;
10876 }
10877 if (avio_rb32(f) != MKBETAG('m', 'f', 'r', 'a')) {
10878 av_log(c->fc, AV_LOG_DEBUG, "doesn't look like mfra (tag mismatch)\n");
10879 goto fail;
10880 }
10881 av_log(c->fc, AV_LOG_VERBOSE, "stream has mfra\n");
10882 do {
10883 ret = read_tfra(c, f);
10884 if (ret < 0)
10885 goto fail;
10886 } while (!ret);
10887 ret = 0;
10888 c->frag_index.complete = 1;
10889fail:
10890 seek_ret = avio_seek(f, original_pos, SEEK_SET);
10891 if (seek_ret < 0) {
10892 av_log(c->fc, AV_LOG_ERROR,
10893 "failed to seek back after looking for mfra\n");
10894 ret = seek_ret;
10895 }
10896 return ret;
10897}
10898
10899static int set_icc_profile_from_item(AVPacketSideData **coded_side_data, int *nb_coded_side_data,
10900 const HEIFItem *item)
10901{
10902 AVPacketSideData *sd = av_packet_side_data_new(coded_side_data, nb_coded_side_data,
10904 item->icc_profile_size, 0);
10905 if (!sd)
10906 return AVERROR(ENOMEM);
10907
10908 memcpy(sd->data, item->icc_profile, item->icc_profile_size);
10909
10910 return 0;
10911}
10912
10913static int set_display_matrix_from_item(AVPacketSideData **coded_side_data, int *nb_coded_side_data,
10914 const HEIFItem *item)
10915{
10916 int32_t *matrix;
10917 AVPacketSideData *sd = av_packet_side_data_new(coded_side_data,
10918 nb_coded_side_data,
10920 9 * sizeof(*matrix), 0);
10921 if (!sd)
10922 return AVERROR(ENOMEM);
10923
10924 matrix = (int32_t*)sd->data;
10925 /* rotation is in the counter-clockwise direction whereas
10926 * av_display_rotation_set() expects its argument to be
10927 * oriented clockwise, so we need to negate it. */
10930
10931 return 0;
10932}
10933
10935 AVStreamGroupTileGrid *tile_grid)
10936{
10937 MOVContext *c = s->priv_data;
10938 const HEIFItem *item = grid->item;
10939 int64_t coded_width = 0, coded_height = 0;
10940 int64_t offset = 0, pos = avio_tell(s->pb);
10941 int64_t x = 0, y = 0;
10942 int i = 0;
10943 int tile_rows, tile_cols;
10944 int flags, size;
10945
10946 if (!(s->pb->seekable & AVIO_SEEKABLE_NORMAL)) {
10947 av_log(c->fc, AV_LOG_INFO, "grid box with non seekable input\n");
10948 return AVERROR_PATCHWELCOME;
10949 }
10950 if (item->is_idat_relative) {
10951 if (!c->idat_offset) {
10952 av_log(c->fc, AV_LOG_ERROR, "missing idat box required by the image grid\n");
10953 return AVERROR_INVALIDDATA;
10954 }
10955 offset = c->idat_offset;
10956 }
10957
10958 if (offset > INT64_MAX - item->extent_offset)
10959 return AVERROR_INVALIDDATA;
10960
10961 avio_seek(s->pb, item->extent_offset + offset, SEEK_SET);
10962
10963 avio_r8(s->pb); /* version */
10964 flags = avio_r8(s->pb);
10965
10966 tile_rows = avio_r8(s->pb) + 1;
10967 tile_cols = avio_r8(s->pb) + 1;
10968 /* actual width and height of output image */
10969 tile_grid->width = (flags & 1) ? avio_rb32(s->pb) : avio_rb16(s->pb);
10970 tile_grid->height = (flags & 1) ? avio_rb32(s->pb) : avio_rb16(s->pb);
10971
10972 av_log(c->fc, AV_LOG_TRACE, "grid: grid_rows %d grid_cols %d output_width %d output_height %d\n",
10973 tile_rows, tile_cols, tile_grid->width, tile_grid->height);
10974
10975 avio_seek(s->pb, pos, SEEK_SET);
10976
10978 tile_grid->nb_tiles = grid->nb_tiles;
10979
10980 if (tile_grid->nb_tiles != size)
10981 return AVERROR_INVALIDDATA;
10982
10983 for (int i = 0; i < tile_cols; i++)
10984 coded_width += grid->tile_item_list[i]->width;
10985 for (int i = 0; i < size; i += tile_cols)
10986 coded_height += grid->tile_item_list[i]->height;
10987
10988 if (coded_width > INT_MAX || coded_height > INT_MAX)
10989 return AVERROR_INVALIDDATA;
10990
10991 tile_grid->coded_width = coded_width;
10992 tile_grid->coded_height = coded_height;
10993
10994 tile_grid->offsets = av_calloc(tile_grid->nb_tiles, sizeof(*tile_grid->offsets));
10995 if (!tile_grid->offsets)
10996 return AVERROR(ENOMEM);
10997
10998 while (y < tile_grid->coded_height) {
10999 int left_col = i;
11000
11001 while (x < tile_grid->coded_width) {
11002 if (i == tile_grid->nb_tiles)
11003 return AVERROR_INVALIDDATA;
11004
11005 tile_grid->offsets[i].idx = grid->tile_idx_list[i];
11006 tile_grid->offsets[i].horizontal = x;
11007 tile_grid->offsets[i].vertical = y;
11008
11009 x += grid->tile_item_list[i++]->width;
11010 }
11011
11012 if (x > tile_grid->coded_width) {
11013 av_log(c->fc, AV_LOG_ERROR, "Non uniform HEIF tiles\n");
11014 return AVERROR_INVALIDDATA;
11015 }
11016
11017 x = 0;
11018 y += grid->tile_item_list[left_col]->height;
11019 }
11020
11021 if (y > tile_grid->coded_height || i != tile_grid->nb_tiles) {
11022 av_log(c->fc, AV_LOG_ERROR, "Non uniform HEIF tiles\n");
11023 return AVERROR_INVALIDDATA;
11024 }
11025
11026 return 0;
11027}
11028
11030 AVStreamGroupTileGrid *tile_grid)
11031{
11032 MOVContext *c = s->priv_data;
11033 const HEIFItem *item = grid->item;
11034 uint16_t canvas_fill_value[4];
11035 int64_t offset = 0, pos = avio_tell(s->pb);
11036 int ret = 0, flags;
11037
11038 if (!(s->pb->seekable & AVIO_SEEKABLE_NORMAL)) {
11039 av_log(c->fc, AV_LOG_INFO, "iovl box with non seekable input\n");
11040 return AVERROR_PATCHWELCOME;
11041 }
11042 if (item->is_idat_relative) {
11043 if (!c->idat_offset) {
11044 av_log(c->fc, AV_LOG_ERROR, "missing idat box required by the image overlay\n");
11045 return AVERROR_INVALIDDATA;
11046 }
11047 offset = c->idat_offset;
11048 }
11049
11050 if (offset > INT64_MAX - item->extent_offset)
11051 return AVERROR_INVALIDDATA;
11052
11053 avio_seek(s->pb, item->extent_offset + offset, SEEK_SET);
11054
11055 avio_r8(s->pb); /* version */
11056 flags = avio_r8(s->pb);
11057
11058 for (int i = 0; i < 4; i++)
11059 canvas_fill_value[i] = avio_rb16(s->pb);
11060 av_log(c->fc, AV_LOG_TRACE, "iovl: canvas_fill_value { %u, %u, %u, %u }\n",
11061 canvas_fill_value[0], canvas_fill_value[1],
11062 canvas_fill_value[2], canvas_fill_value[3]);
11063 for (int i = 0; i < 4; i++)
11064 tile_grid->background[i] = canvas_fill_value[i];
11065
11066 /* actual width and height of output image */
11067 tile_grid->width =
11068 tile_grid->coded_width = (flags & 1) ? avio_rb32(s->pb) : avio_rb16(s->pb);
11069 tile_grid->height =
11070 tile_grid->coded_height = (flags & 1) ? avio_rb32(s->pb) : avio_rb16(s->pb);
11071
11072 av_log(c->fc, AV_LOG_TRACE, "iovl: output_width %d, output_height %d\n",
11073 tile_grid->width, tile_grid->height);
11074
11075 tile_grid->nb_tiles = grid->nb_tiles;
11076 tile_grid->offsets = av_malloc_array(tile_grid->nb_tiles, sizeof(*tile_grid->offsets));
11077 if (!tile_grid->offsets) {
11078 ret = AVERROR(ENOMEM);
11079 goto fail;
11080 }
11081
11082 for (int i = 0; i < tile_grid->nb_tiles; i++) {
11083 tile_grid->offsets[i].idx = grid->tile_idx_list[i];
11084 tile_grid->offsets[i].horizontal = (flags & 1) ? avio_rb32(s->pb) : avio_rb16(s->pb);
11085 tile_grid->offsets[i].vertical = (flags & 1) ? avio_rb32(s->pb) : avio_rb16(s->pb);
11086 av_log(c->fc, AV_LOG_TRACE, "iovl: stream_idx[%d] %u, "
11087 "horizontal_offset[%d] %d, vertical_offset[%d] %d\n",
11088 i, tile_grid->offsets[i].idx,
11089 i, tile_grid->offsets[i].horizontal, i, tile_grid->offsets[i].vertical);
11090 }
11091
11092fail:
11093 avio_seek(s->pb, pos, SEEK_SET);
11094
11095 return ret;
11096}
11097
11099 AVPacketSideData **coded_side_data, int *nb_coded_side_data,
11100 const HEIFItem *ref)
11101{
11102 MOVContext *c = s->priv_data;
11103 AVPacketSideData *sd;
11104 AVExifMetadata ifd = { 0 };
11105 AVBufferRef *buf;
11106 int64_t offset = 0, pos = avio_tell(s->pb);
11107 unsigned orientation_id = av_exif_get_tag_id("Orientation");
11108 int err;
11109
11110 if (!(s->pb->seekable & AVIO_SEEKABLE_NORMAL)) {
11111 av_log(c->fc, AV_LOG_WARNING, "Exif metadata with non seekable input\n");
11112 return AVERROR_PATCHWELCOME;
11113 }
11114 if (ref->is_idat_relative) {
11115 if (!c->idat_offset) {
11116 av_log(c->fc, AV_LOG_ERROR, "missing idat box required by the Exif metadata\n");
11117 return AVERROR_INVALIDDATA;
11118 }
11119 offset = c->idat_offset;
11120 }
11121
11122 buf = av_buffer_alloc(ref->extent_length);
11123 if (!buf)
11124 return AVERROR(ENOMEM);
11125
11126 if (offset > INT64_MAX - ref->extent_offset) {
11127 err = AVERROR(ENOMEM);
11128 goto fail;
11129 }
11130
11131 avio_seek(s->pb, ref->extent_offset + offset, SEEK_SET);
11132 err = avio_read(s->pb, buf->data, ref->extent_length);
11133 if (err != ref->extent_length) {
11134 if (err > 0)
11135 err = AVERROR_INVALIDDATA;
11136 goto fail;
11137 }
11138
11139 // HEIF spec states that Exif metadata is informative. The irot item property is
11140 // the normative source of rotation information. So we remove any Orientation tag
11141 // present in the Exif buffer.
11142 err = av_exif_parse_buffer(s, buf->data, ref->extent_length, &ifd, AV_EXIF_T_OFF);
11143 if (err < 0) {
11144 av_log(s, AV_LOG_ERROR, "Unable to parse Exif metadata\n");
11145 goto fail;
11146 }
11147
11148 err = av_exif_remove_entry(s, &ifd, orientation_id, 0);
11149 if (err < 0)
11150 goto fail;
11151 else if (!err)
11152 goto finish;
11153
11154 av_buffer_unref(&buf);
11155 err = av_exif_write(s, &ifd, &buf, AV_EXIF_T_OFF);
11156 if (err < 0)
11157 goto fail;
11158
11159finish:
11160 offset = AV_RB32(buf->data) + 4;
11161 if (offset >= buf->size) {
11162 err = AVERROR_INVALIDDATA;
11163 goto fail;
11164 }
11165 sd = av_packet_side_data_new(coded_side_data, nb_coded_side_data,
11166 AV_PKT_DATA_EXIF, buf->size - offset, 0);
11167 if (!sd) {
11168 err = AVERROR(ENOMEM);
11169 goto fail;
11170 }
11171 memcpy(sd->data, buf->data + offset, buf->size - offset);
11172
11173 err = 0;
11174fail:
11175 av_buffer_unref(&buf);
11176 av_exif_free(&ifd);
11177 avio_seek(s->pb, pos, SEEK_SET);
11178
11179 return err;
11180}
11181
11183{
11184 MOVContext *mov = s->priv_data;
11185
11186 for (int i = 0; i < mov->nb_heif_grid; i++) {
11188 AVStreamGroupTileGrid *tile_grid;
11189 const HEIFGrid *grid = &mov->heif_grid[i];
11190 int err, loop = 1;
11191
11192 if (!stg)
11193 return AVERROR(ENOMEM);
11194
11195 stg->id = grid->item->item_id;
11196 tile_grid = stg->params.tile_grid;
11197
11198 for (int j = 0; j < grid->nb_tiles; j++) {
11199 int tile_id = grid->tile_id_list[j];
11200 int k;
11201
11202 for (k = 0; k < mov->nb_heif_item; k++) {
11203 HEIFItem *item = mov->heif_item[k];
11204 AVStream *st;
11205
11206 if (!item || item->item_id != tile_id)
11207 continue;
11208 st = item->st;
11209 if (!st) {
11210 av_log(s, AV_LOG_WARNING, "HEIF item id %d from grid id %d doesn't "
11211 "reference a stream\n",
11212 tile_id, grid->item->item_id);
11214 loop = 0;
11215 break;
11216 }
11217
11218 grid->tile_item_list[j] = item;
11219 grid->tile_idx_list[j] = stg->nb_streams;
11220
11221 err = avformat_stream_group_add_stream(stg, st);
11222 if (err < 0) {
11223 int l;
11224 if (err != AVERROR(EEXIST))
11225 return err;
11226
11227 for (l = 0; l < stg->nb_streams; l++)
11228 if (stg->streams[l]->index == st->index)
11229 break;
11230 av_assert0(l < stg->nb_streams);
11231 grid->tile_idx_list[j] = l;
11232 }
11233
11234 if (item->item_id != mov->primary_item_id)
11236 break;
11237 }
11238
11239 if (k == mov->nb_heif_item) {
11241 av_log(s, AV_LOG_WARNING, "HEIF item id %d referenced by grid id %d doesn't "
11242 "exist\n",
11243 tile_id, grid->item->item_id);
11245 loop = 0;
11246 }
11247 if (!loop)
11248 break;
11249 }
11250
11251 if (!loop)
11252 continue;
11253
11254 switch (grid->item->type) {
11255 case MKTAG('g','r','i','d'):
11256 err = read_image_grid(s, grid, tile_grid);
11257 break;
11258 case MKTAG('i','o','v','l'):
11259 err = read_image_iovl(s, grid, tile_grid);
11260 break;
11261 default:
11262 av_assert0(0);
11263 }
11264 if (err < 0)
11265 return err;
11266
11267 for (int j = 0; j < grid->item->nb_iref_list; j++) {
11268 HEIFItem *ref = get_heif_item(mov, grid->item->iref_list[j].item_id);
11269
11270 av_assert0(ref);
11271 switch(ref->type) {
11272 case MKTAG('E','x','i','f'):
11273 err = mov_parse_exif_item(s, &tile_grid->coded_side_data,
11274 &tile_grid->nb_coded_side_data, ref);
11275 if (err < 0 && (s->error_recognition & AV_EF_EXPLODE))
11276 return err;
11277 break;
11278 default:
11279 break;
11280 }
11281 }
11282
11283 /* rotation */
11284 if (grid->item->rotation || grid->item->hflip || grid->item->vflip) {
11286 &tile_grid->nb_coded_side_data, grid->item);
11287 if (err < 0)
11288 return err;
11289 }
11290
11291 /* ICC profile */
11292 if (grid->item->icc_profile_size) {
11294 &tile_grid->nb_coded_side_data, grid->item);
11295 if (err < 0)
11296 return err;
11297 }
11298
11299 if (grid->item->name)
11300 av_dict_set(&stg->metadata, "title", grid->item->name, 0);
11301 if (grid->item->item_id == mov->primary_item_id)
11303 }
11304
11305 return 0;
11306}
11307
11309{
11310 MOVContext *mov = s->priv_data;
11311 int err;
11312
11313 for (int i = 0; i < mov->nb_heif_item; i++) {
11314 HEIFItem *item = mov->heif_item[i];
11315 MOVStreamContext *sc;
11316 AVStream *st;
11317 int64_t offset = 0;
11318
11319 if (!item)
11320 continue;
11321 if (!item->st) {
11322 continue;
11323 }
11324 if (item->is_idat_relative) {
11325 if (!mov->idat_offset) {
11326 av_log(s, AV_LOG_ERROR, "Missing idat box for item %d\n", item->item_id);
11327 return AVERROR_INVALIDDATA;
11328 }
11329 offset = mov->idat_offset;
11330 }
11331
11332 st = item->st;
11333 sc = st->priv_data;
11334 st->codecpar->width = item->width;
11335 st->codecpar->height = item->height;
11336
11337 sc->sample_size = sc->stsz_sample_size = item->extent_length;
11338 sc->sample_count = 1;
11339
11340 err = sanity_checks(s, sc, st->index);
11341 if (err)
11342 return AVERROR_INVALIDDATA;
11343
11344 if (offset > INT64_MAX - item->extent_offset)
11345 return AVERROR_INVALIDDATA;
11346
11347 sc->chunk_offsets[0] = item->extent_offset + offset;
11348
11349 if (item->item_id == mov->primary_item_id)
11351
11352 for (int j = 0; j < item->nb_iref_list; j++) {
11353 HEIFItem *ref = get_heif_item(mov, item->iref_list[j].item_id);
11354
11355 av_assert0(ref);
11356 switch(ref->type) {
11357 case MKTAG('E','x','i','f'):
11360 if (err < 0 && (s->error_recognition & AV_EF_EXPLODE))
11361 return err;
11362 break;
11363 default:
11364 break;
11365 }
11366 }
11367
11368 if (item->rotation || item->hflip || item->vflip) {
11370 &st->codecpar->nb_coded_side_data, item);
11371 if (err < 0)
11372 return err;
11373 }
11374
11375 mov_build_index(mov, st);
11376 }
11377
11378 if (mov->nb_heif_grid) {
11379 err = mov_parse_tiles(s);
11380 if (err < 0)
11381 return err;
11382 }
11383
11384 return 0;
11385}
11386
11388{
11389 int err;
11390
11391 for (int i = 0; i < s->nb_streams; i++) {
11392 AVStreamGroup *stg;
11393 const AVDictionaryEntry *tcr;
11394 AVStream *st = s->streams[i];
11395
11396 if (st->codecpar->codec_tag != MKTAG('t','m','c','d'))
11397 continue;
11398
11400 if (!stg)
11401 return AVERROR(ENOMEM);
11402
11403 stg->id = st->id;
11404 tcr = av_dict_get(st->metadata, "timecode", NULL, 0);
11405
11406 for (int j = 0; j < s->nb_streams; j++) {
11407 AVStream *st2 = s->streams[j];
11408 MOVStreamContext *sc2 = st2->priv_data;
11409 MovTref *tag = mov_find_tref_tag(sc2, MKTAG('t','m','c','d'));
11410
11411 if (!tag)
11412 continue;
11413
11414 for (int k = 0; k < tag->nb_id; k++) {
11415 if (tag->id[k] != st->id)
11416 continue;
11417
11418 err = avformat_stream_group_add_stream(stg, st2);
11419 if (err < 0)
11420 return err;
11421
11422 if (tcr)
11423 av_dict_set(&st2->metadata, "timecode", tcr->value, AV_DICT_DONT_OVERWRITE);
11424 }
11425 }
11426
11427 if (!stg->nb_streams) {
11429 continue;
11430 }
11431
11432 err = avformat_stream_group_add_stream(stg, st);
11433 if (err < 0)
11434 return err;
11435
11436 stg->params.tref->metadata_index = stg->nb_streams - 1;
11437 }
11439
11440 return 0;
11441}
11442
11444 uint32_t *tref_id, int nb_tref_id, int first_index)
11445{
11446 if (!nb_tref_id)
11447 return NULL;
11448
11449 for (int i = first_index; i < s->nb_streams; i++)
11450 for (int j = 0; j < nb_tref_id; j++)
11451 if (s->streams[i]->index != st->index &&
11452 s->streams[i]->id == tref_id[j])
11453 return s->streams[i];
11454
11455 return NULL;
11456}
11457
11459{
11460 static const uint32_t tref_tags[] = {
11461 MKTAG('c','d','s','c'),
11462 MKTAG('r','n','d','r'),
11463 };
11464
11465 int err;
11466
11467 // Don't try to add a group if there's only one track
11468 if (s->nb_streams <= 1)
11469 return 0;
11470
11471 for (int i = 0; i < s->nb_streams; i++) {
11472 AVStream *st = s->streams[i];
11473 MOVStreamContext *sc = st->priv_data;
11474
11475 for (int c = 0; c < FF_ARRAY_ELEMS(tref_tags); c++) {
11476 AVStreamGroup *stg;
11477 AVStream *st_ref;
11478 MovTref *tag = mov_find_tref_tag(sc, tref_tags[c]);
11479
11480 if (!tag)
11481 continue;
11482
11483 st_ref = mov_find_reference_track(s, st, tag->id, tag->nb_id, 0);
11484 if (!st_ref) {
11485 av_log(s, AV_LOG_WARNING, "Failed to find referenced stream\n");
11486 continue;
11487 }
11488
11490 if (!stg)
11491 return AVERROR(ENOMEM);
11492
11493 stg->id = st_ref->id;
11494
11495 err = avformat_stream_group_add_stream(stg, st_ref);
11496 if (err < 0)
11497 return err;
11498
11499 err = avformat_stream_group_add_stream(stg, st);
11500 if (err < 0)
11501 return err;
11502
11503 stg->params.tref->metadata_index = stg->nb_streams - 1;
11504 }
11505 }
11506
11507 return 0;
11508}
11509
11511{
11512 int err;
11513
11514 // Don't try to add a group if there's only one track
11515 if (s->nb_streams <= 1)
11516 return 0;
11517
11518 for (int i = 0; i < s->nb_streams; i++) {
11519 AVStreamGroup *stg;
11520 AVStream *st = s->streams[i];
11521 AVStream *st_base;
11522 MOVStreamContext *sc = st->priv_data;
11523 MovTref *tag = mov_find_tref_tag(sc, MKTAG('s','b','a','s'));
11524 int j = 0;
11525
11526 /* Find an enhancement stream. */
11527 if (st->codecpar->codec_id != AV_CODEC_ID_LCEVC || !tag)
11528 continue;
11529
11531 if (!stg)
11532 return AVERROR(ENOMEM);
11533
11534 stg->id = st->id;
11537
11538 while (st_base = mov_find_reference_track(s, st, tag->id, tag->nb_id, j)) {
11539 err = avformat_stream_group_add_stream(stg, st_base);
11540 if (err < 0)
11541 return err;
11542
11543 j = st_base->index + 1;
11544 }
11545 if (!j) {
11546 int loglevel = (s->error_recognition & AV_EF_EXPLODE) ? AV_LOG_ERROR : AV_LOG_WARNING;
11547 av_log(s, loglevel, "Failed to find base stream for LCEVC stream\n");
11549 if (s->error_recognition & AV_EF_EXPLODE)
11550 return AVERROR_INVALIDDATA;
11551 continue;
11552 }
11553
11554 err = avformat_stream_group_add_stream(stg, st);
11555 if (err < 0)
11556 return err;
11557
11558 stg->params.layered_video->el_index = stg->nb_streams - 1;
11559 }
11560
11561 return 0;
11562}
11563
11565{
11566 int err;
11567
11568 if (s->nb_streams <= 1)
11569 return 0;
11570
11571 /* Identify legacy dual-track Dolby Vision profile 7 carriage per Annex
11572 * C of "Dolby Vision Streams Within the ISO Base Media File Format",
11573 * v2.7.1. The 'vdep' track reference type is shared with depth video
11574 * and multi-view dependencies. The spec-mandated DV-specific sample
11575 * entry combined with the dvcC configuration record disambiguates
11576 * those uses. */
11577 for (int i = 0; i < s->nb_streams; i++) {
11578 AVStreamGroup *stg;
11579 AVStream *st = s->streams[i];
11580 AVStream *st_base;
11581 MOVStreamContext *sc = st->priv_data;
11582 MovTref *tag = mov_find_tref_tag(sc, MKTAG('v','d','e','p'));
11583 const AVPacketSideData *sd;
11585
11586 if (st->codecpar->codec_id != AV_CODEC_ID_HEVC || !tag)
11587 continue;
11588
11589 if (st->codecpar->codec_tag != MKTAG('d','v','h','e') &&
11590 st->codecpar->codec_tag != MKTAG('d','v','h','1'))
11591 continue;
11592
11596 if (!sd)
11597 continue;
11598 dovi = (const AVDOVIDecoderConfigurationRecord *)sd->data;
11599
11600 /* EL track of a dual-track stream: rpu_present_flag = 1,
11601 * el_present_flag = 1, bl_present_flag = 0, dv_profile = 7. */
11602 if (dovi->dv_profile != 7 || !dovi->rpu_present_flag ||
11603 !dovi->el_present_flag || dovi->bl_present_flag)
11604 continue;
11605
11606 st_base = mov_find_reference_track(s, st, tag->id, tag->nb_id, 0);
11607 if (!st_base) {
11608 int loglevel = (s->error_recognition & AV_EF_EXPLODE) ? AV_LOG_ERROR : AV_LOG_WARNING;
11609 av_log(s, loglevel, "Failed to find base layer for Dolby Vision EL stream\n");
11610 if (s->error_recognition & AV_EF_EXPLODE)
11611 return AVERROR_INVALIDDATA;
11612 continue;
11613 }
11614
11616 if (!stg)
11617 return AVERROR(ENOMEM);
11618
11619 stg->id = st->id;
11620
11621 err = avformat_stream_group_add_stream(stg, st_base);
11622 if (err < 0)
11623 return err;
11624
11625 err = avformat_stream_group_add_stream(stg, st);
11626 if (err < 0)
11627 return err;
11628
11629 stg->params.layered_video->el_index = stg->nb_streams - 1;
11630 stg->params.layered_video->width = st_base->codecpar->width;
11631 stg->params.layered_video->height = st_base->codecpar->height;
11632 }
11633
11634 return 0;
11635}
11636
11638{
11639 int highest_id = 0, lowest_iamf_id = INT_MAX;
11640
11641 for (int i = 0; i < s->nb_streams; i++) {
11642 const AVStream *st = s->streams[i];
11643 const MOVStreamContext *sc = st->priv_data;
11644 if (!sc->iamf)
11645 highest_id = FFMAX(highest_id, st->id);
11646 }
11647
11648 for (int i = 0; i < s->nb_stream_groups; i++) {
11649 AVStreamGroup *stg = s->stream_groups[i];
11651 continue;
11652 for (int j = 0; j < stg->nb_streams; j++) {
11653 AVStream *st = stg->streams[j];
11654 lowest_iamf_id = FFMIN(lowest_iamf_id, st->id);
11655 }
11656 }
11657
11658 if (highest_id < lowest_iamf_id)
11659 return;
11660
11661 highest_id += !lowest_iamf_id;
11662 for (int i = 0; highest_id > 1 && i < s->nb_stream_groups; i++) {
11663 AVStreamGroup *stg = s->stream_groups[i];
11665 continue;
11666 for (int j = 0; j < stg->nb_streams; j++) {
11667 AVStream *st = stg->streams[j];
11668 MOVStreamContext *sc = st->priv_data;
11669 st->id += highest_id;
11670 sc->iamf_stream_offset = highest_id;
11671 }
11672 }
11673}
11674
11676{
11677 MOVContext *mov = s->priv_data;
11678 AVIOContext *pb = s->pb;
11679 int j, err;
11680 MOVAtom atom = { AV_RL32("root") };
11681 int i;
11682
11683 mov->fc = s;
11684 mov->trak_index = -1;
11685 mov->primary_item_id = -1;
11686 mov->cur_item_id = -1;
11687 /* .mov and .mp4 aren't streamable anyway (only progressive download if moov is before mdat) */
11689 atom.size = avio_size(pb);
11690 else
11691 atom.size = INT64_MAX;
11692
11693 /* check MOV header */
11694 do {
11695 if (mov->moov_retry)
11696 avio_seek(pb, 0, SEEK_SET);
11697 if ((err = mov_read_default(mov, pb, atom)) < 0) {
11698 av_log(s, AV_LOG_ERROR, "error reading header\n");
11699 return err;
11700 }
11701 } while ((pb->seekable & AVIO_SEEKABLE_NORMAL) &&
11702 !mov->found_moov && (!mov->found_iloc || !mov->found_iinf) && !mov->moov_retry++);
11703 if (!mov->found_moov && !mov->found_iloc && !mov->found_iinf) {
11704 av_log(s, AV_LOG_ERROR, "moov atom not found\n");
11705 return AVERROR_INVALIDDATA;
11706 }
11707 av_log(mov->fc, AV_LOG_TRACE, "on_parse_exit_offset=%"PRId64"\n", avio_tell(pb));
11708
11709 if (mov->found_iloc && mov->found_iinf) {
11710 err = mov_parse_heif_items(s);
11711 if (err < 0)
11712 return err;
11713 }
11714 // prevent iloc and iinf boxes from being parsed while reading packets.
11715 // this is needed because an iinf box may have been parsed but ignored
11716 // for having old infe boxes which create no streams.
11717 mov->found_iloc = mov->found_iinf = 1;
11718
11719 if (pb->seekable & AVIO_SEEKABLE_NORMAL) {
11720 if (mov->nb_chapter_tracks > 0 && !mov->ignore_chapters)
11722 for (i = 0; i < s->nb_streams; i++)
11723 if (s->streams[i]->codecpar->codec_tag == AV_RL32("tmcd")) {
11724 mov_read_timecode_track(s, s->streams[i]);
11725 } else if (s->streams[i]->codecpar->codec_tag == AV_RL32("rtmd")) {
11726 mov_read_rtmd_track(s, s->streams[i]);
11727 }
11728 }
11729
11730 /* Create metadata stream groups. */
11732 if (err < 0)
11733 return err;
11734
11735 /* copy timecode metadata from tmcd tracks to the related video streams */
11737 if (err < 0)
11738 return err;
11739
11740 /* Create LCEVC stream groups. */
11742 if (err < 0)
11743 return err;
11744
11745 /* Create Dolby Vision Profile 7 stream groups. */
11747 if (err < 0)
11748 return err;
11749
11750 for (i = 0; i < s->nb_streams; i++) {
11751 AVStream *st = s->streams[i];
11752 FFStream *const sti = ffstream(st);
11753 MOVStreamContext *sc = st->priv_data;
11754 uint32_t dvdsub_clut[FF_DVDCLUT_CLUT_LEN] = {0};
11755 fix_timescale(mov, sc);
11756
11757 /* Set the primary extradata based on the first Sample if it doesn't reference the first stsd entry. */
11758 if (sc->stsc_count && sc->extradata_size && !sc->iamf &&
11759 sc->stsc_data[0].id > 1 && sc->stsc_data[0].id <= sc->stsd_count) {
11760 sc->last_stsd_index = sc->stsc_data[0].id - 1;
11763 if (sc->extradata_size[sc->last_stsd_index]) {
11765 if (!st->codecpar->extradata)
11766 return AVERROR(ENOMEM);
11768 }
11769 }
11770
11774 }
11777 sc->time_scale*(int64_t)sc->nb_frames_for_fps, sc->duration_for_fps, INT_MAX);
11779 if (st->codecpar->width <= 0 || st->codecpar->height <= 0) {
11780 st->codecpar->width = sc->width;
11781 st->codecpar->height = sc->height;
11782 }
11785
11786 for (j = 0; j < FF_DVDCLUT_CLUT_LEN; j++)
11787 dvdsub_clut[j] = AV_RB32(st->codecpar->extradata + j * 4);
11788
11789 err = ff_dvdclut_yuv_to_rgb(dvdsub_clut, FF_DVDCLUT_CLUT_SIZE);
11790 if (err < 0)
11791 return err;
11792
11794 st->codecpar->extradata_size = 0;
11795
11797 st->codecpar);
11798 if (err < 0)
11799 return err;
11800 }
11801 }
11802 if (mov->handbrake_version &&
11803 mov->handbrake_version <= 1000000*0 + 1000*10 + 2 && // 0.10.2
11805 av_log(s, AV_LOG_VERBOSE, "Forcing full parsing for mp3 stream\n");
11807 }
11808 }
11809
11810 if (mov->trex_data || mov->use_mfra_for > 0) {
11811 for (i = 0; i < s->nb_streams; i++) {
11812 AVStream *st = s->streams[i];
11813 MOVStreamContext *sc = st->priv_data;
11814 if (sc->duration_for_fps > 0) {
11815 /* Akin to sc->data_size * 8 * sc->time_scale / sc->duration_for_fps but accounting for overflows. */
11817 if (st->codecpar->bit_rate == INT64_MIN) {
11818 av_log(s, AV_LOG_WARNING, "Overflow during bit rate calculation %"PRId64" * 8 * %d\n",
11819 sc->data_size, sc->time_scale);
11820 st->codecpar->bit_rate = 0;
11821 if (s->error_recognition & AV_EF_EXPLODE)
11822 return AVERROR_INVALIDDATA;
11823 }
11824 }
11825 }
11826 }
11827
11828 for (i = 0; i < mov->bitrates_count && i < s->nb_streams; i++) {
11829 if (mov->bitrates[i]) {
11830 s->streams[i]->codecpar->bit_rate = mov->bitrates[i];
11831 }
11832 }
11833
11835
11836 for (i = 0; i < s->nb_streams; i++) {
11837 AVStream *st = s->streams[i];
11838 MOVStreamContext *sc = st->priv_data;
11839
11840 switch (st->codecpar->codec_type) {
11841 case AVMEDIA_TYPE_AUDIO:
11842 err = ff_replaygain_export(st, s->metadata);
11843 if (err < 0)
11844 return err;
11845 break;
11846 case AVMEDIA_TYPE_VIDEO:
11847 if (sc->display_matrix) {
11850 (uint8_t*)sc->display_matrix, sizeof(int32_t) * 9, 0))
11851 return AVERROR(ENOMEM);
11852
11853 sc->display_matrix = NULL;
11854 }
11855 if (sc->stereo3d) {
11858 (uint8_t *)sc->stereo3d, sc->stereo3d_size, 0))
11859 return AVERROR(ENOMEM);
11860
11861 sc->stereo3d = NULL;
11862 }
11863 if (sc->spherical) {
11866 (uint8_t *)sc->spherical, sc->spherical_size, 0))
11867 return AVERROR(ENOMEM);
11868
11869 sc->spherical = NULL;
11870 }
11871 if (sc->mastering) {
11874 (uint8_t *)sc->mastering, sc->mastering_size, 0))
11875 return AVERROR(ENOMEM);
11876
11877 sc->mastering = NULL;
11878 }
11879 if (sc->coll) {
11882 (uint8_t *)sc->coll, sc->coll_size, 0))
11883 return AVERROR(ENOMEM);
11884
11885 sc->coll = NULL;
11886 }
11887 if (sc->ambient) {
11890 (uint8_t *) sc->ambient, sc->ambient_size, 0))
11891 return AVERROR(ENOMEM);
11892
11893 sc->ambient = NULL;
11894 }
11895 break;
11896 }
11897 }
11898
11900
11902
11903 for (i = 0; i < mov->frag_index.nb_items; i++)
11904 if (mov->frag_index.item[i].moof_offset <= mov->fragment.moof_offset)
11905 mov->frag_index.item[i].headers_read = 1;
11906
11907 return 0;
11908}
11909
11911{
11913 int64_t best_dts = INT64_MAX;
11914 int i;
11915 MOVContext *mov = s->priv_data;
11916 int no_interleave = !mov->interleaved_read || !(s->pb->seekable & AVIO_SEEKABLE_NORMAL);
11917 for (i = 0; i < s->nb_streams; i++) {
11918 AVStream *avst = s->streams[i];
11919 FFStream *const avsti = ffstream(avst);
11920 MOVStreamContext *msc = avst->priv_data;
11921 if (msc->pb && msc->current_sample < avsti->nb_index_entries) {
11922 AVIndexEntry *current_sample = &avsti->index_entries[msc->current_sample];
11923 int64_t dts = av_rescale(current_sample->timestamp, AV_TIME_BASE, msc->time_scale);
11924 uint64_t dtsdiff = best_dts > dts ? best_dts - (uint64_t)dts : ((uint64_t)dts - best_dts);
11925 av_log(s, AV_LOG_TRACE, "stream %d, sample %d, dts %"PRId64"\n", i, msc->current_sample, dts);
11926 if (!sample || (no_interleave && current_sample->pos < sample->pos) ||
11927 ((s->pb->seekable & AVIO_SEEKABLE_NORMAL) &&
11928 ((msc->pb != s->pb && dts < best_dts) || (msc->pb == s->pb && dts != AV_NOPTS_VALUE &&
11929 ((dtsdiff <= AV_TIME_BASE && current_sample->pos < sample->pos) ||
11930 (dtsdiff > AV_TIME_BASE && dts < best_dts && mov->interleaved_read)))))) {
11931 sample = current_sample;
11932 best_dts = dts;
11933 *st = avst;
11934 }
11935 }
11936 }
11937 return sample;
11938}
11939
11940static int should_retry(AVIOContext *pb, int error_code) {
11941 if (error_code == AVERROR_EOF || avio_feof(pb))
11942 return 0;
11943
11944 return 1;
11945}
11946
11948{
11949 int ret;
11950 MOVContext *mov = s->priv_data;
11951
11952 if (index >= 0 && index < mov->frag_index.nb_items)
11953 target = mov->frag_index.item[index].moof_offset;
11954 if (target >= 0 && avio_seek(s->pb, target, SEEK_SET) != target) {
11955 av_log(mov->fc, AV_LOG_ERROR, "root atom offset 0x%"PRIx64": partial file\n", target);
11956 return AVERROR_INVALIDDATA;
11957 }
11958
11959 mov->next_root_atom = 0;
11960 if ((index < 0 && target >= 0) || index >= mov->frag_index.nb_items)
11961 index = search_frag_moof_offset(&mov->frag_index, target);
11962 if (index >= 0 && index < mov->frag_index.nb_items &&
11963 mov->frag_index.item[index].moof_offset == target) {
11964 if (index + 1 < mov->frag_index.nb_items)
11967 return 0;
11969 }
11970
11971 mov->found_mdat = 0;
11972
11973 ret = mov_read_default(mov, s->pb, (MOVAtom){ AV_RL32("root"), INT64_MAX });
11974 if (ret < 0)
11975 return ret;
11976 if (avio_feof(s->pb))
11977 return AVERROR_EOF;
11978 av_log(s, AV_LOG_TRACE, "read fragments, offset 0x%"PRIx64"\n", avio_tell(s->pb));
11979
11980 return 1;
11981}
11982
11984{
11985 MOVStreamContext *sc = st->priv_data;
11986 uint8_t *side, *extradata;
11987 int extradata_size;
11988
11989 /* Save the current index. */
11990 sc->last_stsd_index = sc->stsc_data[sc->stsc_index].id - 1;
11991
11992 /* Notify the decoder that extradata changed. */
11993 extradata_size = sc->extradata_size[sc->last_stsd_index];
11994 extradata = sc->extradata[sc->last_stsd_index];
11995 if (st->discard != AVDISCARD_ALL && extradata_size > 0 && extradata) {
11998 extradata_size);
11999 if (!side)
12000 return AVERROR(ENOMEM);
12001 memcpy(side, extradata, extradata_size);
12002 }
12003
12004 return 0;
12005}
12006
12007static int get_eia608_packet(AVIOContext *pb, AVPacket *pkt, int src_size)
12008{
12009 /* We can't make assumptions about the structure of the payload,
12010 because it may include multiple cdat and cdt2 samples. */
12011 const uint32_t cdat = AV_RB32("cdat");
12012 const uint32_t cdt2 = AV_RB32("cdt2");
12013 int ret, out_size = 0;
12014
12015 /* a valid payload must have size, 4cc, and at least 1 byte pair: */
12016 if (src_size < 10)
12017 return AVERROR_INVALIDDATA;
12018
12019 /* avoid an int overflow: */
12020 if ((src_size - 8) / 2 >= INT_MAX / 3)
12021 return AVERROR_INVALIDDATA;
12022
12023 ret = av_new_packet(pkt, ((src_size - 8) / 2) * 3);
12024 if (ret < 0)
12025 return ret;
12026
12027 /* parse and re-format the c608 payload in one pass. */
12028 while (src_size >= 10) {
12029 const uint32_t atom_size = avio_rb32(pb);
12030 const uint32_t atom_type = avio_rb32(pb);
12031 const uint32_t data_size = atom_size - 8;
12032 const uint8_t cc_field =
12033 atom_type == cdat ? 1 :
12034 atom_type == cdt2 ? 2 :
12035 0;
12036
12037 /* account for bytes consumed for atom size and type. */
12038 src_size -= 8;
12039
12040 /* make sure the data size stays within the buffer boundaries. */
12041 if (data_size < 2 || data_size > src_size) {
12042 ret = AVERROR_INVALIDDATA;
12043 break;
12044 }
12045
12046 /* make sure the data size is consistent with N byte pairs. */
12047 if (data_size % 2 != 0) {
12048 ret = AVERROR_INVALIDDATA;
12049 break;
12050 }
12051
12052 if (!cc_field) {
12053 /* neither cdat or cdt2 ... skip it */
12054 avio_skip(pb, data_size);
12055 src_size -= data_size;
12056 continue;
12057 }
12058
12059 for (uint32_t i = 0; i < data_size; i += 2) {
12060 pkt->data[out_size] = (0x1F << 3) | (1 << 2) | (cc_field - 1);
12061 pkt->data[out_size + 1] = avio_r8(pb);
12062 pkt->data[out_size + 2] = avio_r8(pb);
12063 out_size += 3;
12064 src_size -= 2;
12065 }
12066 }
12067
12068 if (src_size > 0)
12069 /* skip any remaining unread portion of the input payload */
12070 avio_skip(pb, src_size);
12071
12073 return ret;
12074}
12075
12077 int64_t current_index, AVPacket *pkt)
12078{
12079 MOVContext *mov = s->priv_data;
12080 MOVStreamContext *sc = st->priv_data;
12081
12082 pkt->stream_index = sc->ffindex;
12083 pkt->dts = sample->timestamp;
12084 if (sample->flags & AVINDEX_DISCARD_FRAME) {
12085 pkt->flags |= AV_PKT_FLAG_DISCARD;
12086 }
12087 if (sc->stts_count && sc->tts_index < sc->tts_count)
12088 pkt->duration = sc->tts_data[sc->tts_index].duration;
12089 if (sc->ctts_count && sc->tts_index < sc->tts_count) {
12090 pkt->pts = av_sat_add64(pkt->dts, av_sat_add64(sc->dts_shift, sc->tts_data[sc->tts_index].offset));
12091 } else {
12092 if (pkt->duration == 0) {
12093 int64_t next_dts = (sc->current_sample < ffstream(st)->nb_index_entries) ?
12095 if (next_dts >= pkt->dts)
12096 pkt->duration = next_dts - pkt->dts;
12097 }
12098 pkt->pts = pkt->dts;
12099 }
12100
12102 sc->current_sample >= ffstream(st)->nb_index_entries) {
12103 int64_t pts = av_rescale_q(pkt->pts, st->time_base, (AVRational){ 1, st->codecpar->sample_rate });
12104 int64_t total = av_rescale_q(st->duration, st->time_base, (AVRational){ 1, st->codecpar->sample_rate });
12105 int64_t duration = pkt->duration;
12106
12107 if (st->duration < pkt->pts) {
12108 duration = 0;
12109 } else
12110 duration = FFMIN(duration, (uint64_t)st->duration - pkt->pts);
12111
12112 duration = av_rescale_q(duration, st->time_base, (AVRational){ 1, st->codecpar->sample_rate });
12113
12114 if (!ffstream(st)->first_discard_sample)
12116 if (!ffstream(st)->last_discard_sample)
12117 ffstream(st)->last_discard_sample = total;
12118 }
12119
12120 if (sc->tts_data && sc->tts_index < sc->tts_count) {
12121 /* update tts context */
12122 sc->tts_sample++;
12123 if (sc->tts_index < sc->tts_count &&
12124 sc->tts_data[sc->tts_index].count == sc->tts_sample) {
12125 sc->tts_index++;
12126 sc->tts_sample = 0;
12127 }
12128 }
12129
12130 if (sc->sdtp_data && sc->current_sample <= sc->sdtp_count) {
12131 uint8_t sample_flags = sc->sdtp_data[sc->current_sample - 1];
12132 uint8_t sample_is_depended_on = (sample_flags >> 2) & 0x3;
12133 pkt->flags |= sample_is_depended_on == MOV_SAMPLE_DEPENDENCY_NO ? AV_PKT_FLAG_DISPOSABLE : 0;
12134 }
12135 pkt->flags |= sample->flags & AVINDEX_KEYFRAME ? AV_PKT_FLAG_KEY : 0;
12136 pkt->pos = sample->pos;
12137
12138 /* Multiple stsd handling. */
12139 if (sc->stsc_data) {
12140 if (sc->stsc_data[sc->stsc_index].id > 0 &&
12141 sc->stsc_data[sc->stsc_index].id - 1 < sc->stsd_count &&
12142 sc->stsc_data[sc->stsc_index].id - 1 != sc->last_stsd_index) {
12143 int ret = mov_change_extradata(st, pkt);
12144 if (ret < 0)
12145 return ret;
12146 }
12147
12148 /* Update the stsc index for the next sample */
12149 sc->stsc_sample++;
12152 sc->stsc_index++;
12153 sc->stsc_sample = 0;
12154 }
12155 }
12156
12157 return 0;
12158}
12159
12161{
12162 MOVContext *mov = s->priv_data;
12163 MOVStreamContext *sc;
12165 AVStream *st = NULL;
12166 FFStream *avsti = NULL;
12167 int64_t current_index;
12168 int ret;
12169 int i;
12170 mov->fc = s;
12171 retry:
12172 if (s->pb->pos == 0) {
12173
12174 // Discard current fragment index
12175 if (mov->frag_index.allocated_size > 0) {
12176 for(int i = 0; i < mov->frag_index.nb_items; i++) {
12178 }
12179 av_freep(&mov->frag_index.item);
12180 mov->frag_index.nb_items = 0;
12181 mov->frag_index.allocated_size = 0;
12182 mov->frag_index.current = -1;
12183 mov->frag_index.complete = 0;
12184 }
12185
12186 for (i = 0; i < s->nb_streams; i++) {
12187 AVStream *avst = s->streams[i];
12188 MOVStreamContext *msc = avst->priv_data;
12189
12190 // Clear current sample
12191 mov_current_sample_set(msc, 0);
12192 msc->tts_index = 0;
12193
12194 // Discard current index entries
12195 avsti = ffstream(avst);
12196 if (avsti->index_entries_allocated_size > 0) {
12197 av_freep(&avsti->index_entries);
12199 avsti->nb_index_entries = 0;
12200 }
12201 }
12202
12203 if ((ret = mov_switch_root(s, -1, -1)) < 0)
12204 return ret;
12205 }
12207 if (!sample || (mov->next_root_atom && sample->pos > mov->next_root_atom)) {
12208 if (!mov->next_root_atom)
12209 return AVERROR_EOF;
12210 if ((ret = mov_switch_root(s, mov->next_root_atom, -1)) < 0)
12211 return ret;
12212 goto retry;
12213 }
12214 sc = st->priv_data;
12215 /* must be done just before reading, to avoid infinite loop on sample */
12216 current_index = sc->current_index;
12218
12219 if (mov->next_root_atom) {
12220 sample->pos = FFMIN(sample->pos, mov->next_root_atom);
12221 sample->size = FFMIN(sample->size, (mov->next_root_atom - sample->pos));
12222 }
12223
12224 if (st->discard != AVDISCARD_ALL || sc->iamf) {
12225 int64_t ret64 = avio_seek(sc->pb, sample->pos, SEEK_SET);
12226 if (ret64 != sample->pos) {
12227 av_log(mov->fc, AV_LOG_ERROR, "stream %d, offset 0x%"PRIx64": partial file\n",
12228 sc->ffindex, sample->pos);
12229 if (should_retry(sc->pb, ret64)) {
12231 } else if (ret64 < 0) {
12232 return (int)ret64;
12233 }
12234 return AVERROR_INVALIDDATA;
12235 }
12236
12237 if (st->discard == AVDISCARD_NONKEY && !(sample->flags & AVINDEX_KEYFRAME)) {
12238 av_log(mov->fc, AV_LOG_DEBUG, "Nonkey frame from stream %d discarded due to AVDISCARD_NONKEY\n", sc->ffindex);
12239 goto retry;
12240 }
12241
12242 if (st->codecpar->codec_id == AV_CODEC_ID_EIA_608 && sample->size > 8)
12243 ret = get_eia608_packet(sc->pb, pkt, sample->size);
12244#if CONFIG_IAMFDEC
12245 else if (sc->iamf) {
12246 int64_t pts, dts, pos, duration;
12247 int flags, size = sample->size;
12248 ret = mov_finalize_packet(s, st, sample, current_index, pkt);
12249 pts = pkt->pts; dts = pkt->dts;
12250 pos = pkt->pos; flags = pkt->flags;
12251 duration = pkt->duration;
12252 while (!ret && size > 0) {
12253 ret = ff_iamf_read_packet(s, sc->iamf, sc->pb, size, sc->iamf_stream_offset, pkt);
12254 if (ret < 0) {
12255 if (should_retry(sc->pb, ret))
12257 return ret;
12258 }
12259 size -= ret;
12260
12261 if (pkt->flags & AV_PKT_FLAG_DISCARD) {
12263 ret = 0;
12264 continue;
12265 }
12266 pkt->pts = pts; pkt->dts = dts;
12267 pkt->pos = pos; pkt->flags |= flags;
12268 pkt->duration = duration;
12269 ret = ff_buffer_packet(s, pkt);
12270 }
12271 if (!ret)
12272 return FFERROR_REDO;
12273 }
12274#endif
12275 else if (st->codecpar->codec_id == AV_CODEC_ID_APV && sample->size > 4) {
12276 uint32_t au_size = avio_rb32(sc->pb);
12277 int explode = !!(mov->fc->error_recognition & AV_EF_EXPLODE);
12278 if (au_size > sample->size - 4) {
12279 av_log(s, explode ? AV_LOG_ERROR : AV_LOG_WARNING,
12280 "APV au_size %u exceeds sample body %d\n",
12281 au_size, sample->size - 4);
12282 if (explode)
12283 return AVERROR_INVALIDDATA;
12284 au_size = sample->size - 4;
12285 }
12286 ret = av_get_packet(sc->pb, pkt, au_size);
12287 } else
12288 ret = av_get_packet(sc->pb, pkt, sample->size);
12289 if (ret < 0) {
12290 if (should_retry(sc->pb, ret)) {
12292 }
12293 return ret;
12294 }
12295#if CONFIG_DV_DEMUXER
12296 if (mov->dv_demux && sc->dv_audio_container) {
12297 ret = avpriv_dv_produce_packet(mov->dv_demux, NULL, pkt->data, pkt->size, pkt->pos);
12299 if (ret < 0)
12300 return ret;
12301 ret = avpriv_dv_get_packet(mov->dv_demux, pkt);
12302 if (ret < 0)
12303 return ret;
12304 }
12305#endif
12306 if (sc->has_palette) {
12307 uint8_t *pal;
12308
12310 if (!pal) {
12311 av_log(mov->fc, AV_LOG_ERROR, "Cannot append palette to packet\n");
12312 } else {
12313 memcpy(pal, sc->palette, AVPALETTE_SIZE);
12314 sc->has_palette = 0;
12315 }
12316 }
12317 if (st->codecpar->codec_id == AV_CODEC_ID_MP3 && !ffstream(st)->need_parsing && pkt->size > 4) {
12318 if (ff_mpa_check_header(AV_RB32(pkt->data)) < 0)
12320 }
12321 }
12322
12323 ret = mov_finalize_packet(s, st, sample, current_index, pkt);
12324 if (ret < 0)
12325 return ret;
12326
12327 if (st->discard == AVDISCARD_ALL)
12328 goto retry;
12329
12330 if (mov->aax_mode)
12331 aax_filter(pkt->data, pkt->size, mov);
12332
12333 ret = cenc_filter(mov, st, sc, pkt, current_index);
12334 if (ret < 0) {
12335 return ret;
12336 }
12337
12338 return 0;
12339}
12340
12342{
12343 MOVContext *mov = s->priv_data;
12344 int index;
12345
12346 if (!mov->frag_index.complete)
12347 return 0;
12348
12349 index = search_frag_timestamp(s, &mov->frag_index, st, timestamp);
12350 if (index < 0)
12351 index = 0;
12352 if (!mov->frag_index.item[index].headers_read)
12353 return mov_switch_root(s, -1, index);
12354 if (index + 1 < mov->frag_index.nb_items)
12356
12357 return 0;
12358}
12359
12361{
12362 // TODO: a bisect search would scale much better
12363 for (int i = 0; i < sc->open_key_samples_count; i++) {
12364 const int oks = sc->open_key_samples[i];
12365 if (oks == sample)
12366 return 1;
12367 if (oks > sample) /* list is monotically increasing so we can stop early */
12368 break;
12369 }
12370 return 0;
12371}
12372
12373/*
12374 * Some key sample may be key frames but not IDR frames, so a random access to
12375 * them may not be allowed.
12376 */
12377static int can_seek_to_key_sample(AVStream *st, int sample, int64_t requested_pts)
12378{
12379 MOVStreamContext *sc = st->priv_data;
12380 FFStream *const sti = ffstream(st);
12381 int64_t key_sample_dts, key_sample_pts;
12382
12384 return 1;
12385
12386 if (sample >= sc->sample_offsets_count)
12387 return 1;
12388
12389 av_assert0(sample >= 0);
12390 key_sample_dts = sti->index_entries[sample].timestamp;
12391 key_sample_pts = key_sample_dts + sc->sample_offsets[sample] + sc->dts_shift;
12392
12393 /*
12394 * If the sample needs to be presented before an open key sample, they may
12395 * not be decodable properly, even though they come after in decoding
12396 * order.
12397 */
12398 if (is_open_key_sample(sc, sample) && key_sample_pts > requested_pts)
12399 return 0;
12400
12401 return 1;
12402}
12403
12404static int mov_seek_stream(AVFormatContext *s, AVStream *st, int64_t timestamp, int flags)
12405{
12406 MOVStreamContext *sc = st->priv_data;
12407 FFStream *const sti = ffstream(st);
12408 int sample, time_sample, ret, requested_sample;
12409 int64_t next_ts;
12410 unsigned int i;
12411
12412 // Here we consider timestamp to be PTS, hence try to offset it so that we
12413 // can search over the DTS timeline.
12414 timestamp -= (sc->min_corrected_pts + sc->dts_shift);
12415
12416 ret = mov_seek_fragment(s, st, timestamp);
12417 if (ret < 0)
12418 return ret;
12419
12420 for (;;) {
12421 sample = av_index_search_timestamp(st, timestamp, flags);
12422 av_log(s, AV_LOG_TRACE, "stream %d, timestamp %"PRId64", sample %d\n", st->index, timestamp, sample);
12423 if (sample < 0 && sti->nb_index_entries && timestamp < sti->index_entries[0].timestamp)
12424 sample = 0;
12425 if (sample < 0) /* not sure what to do */
12426 return AVERROR_INVALIDDATA;
12427
12428 if (!sample || can_seek_to_key_sample(st, sample, timestamp))
12429 break;
12430
12431 next_ts = timestamp - FFMAX(sc->min_sample_duration, 1);
12432 requested_sample = av_index_search_timestamp(st, next_ts, flags);
12433 if (requested_sample < 0)
12434 return AVERROR_INVALIDDATA;
12435
12436 // If we've reached a different sample trying to find a good pts to
12437 // seek to, give up searching because we'll end up seeking back to
12438 // sample 0 on every seek.
12439 if (sample != requested_sample && !can_seek_to_key_sample(st, requested_sample, next_ts))
12440 break;
12441
12442 timestamp = next_ts;
12443 }
12444
12446 av_log(s, AV_LOG_TRACE, "stream %d, found sample %d\n", st->index, sc->current_sample);
12447 /* adjust time to sample index */
12448 if (sc->tts_data) {
12449 time_sample = 0;
12450 for (i = 0; i < sc->tts_count; i++) {
12451 int next = time_sample + sc->tts_data[i].count;
12452 if (next > sc->current_sample) {
12453 sc->tts_index = i;
12454 sc->tts_sample = sc->current_sample - time_sample;
12455 break;
12456 }
12457 time_sample = next;
12458 }
12459 }
12460
12461 /* adjust stsd index */
12462 if (sc->chunk_count) {
12463 time_sample = 0;
12464 for (i = 0; i < sc->stsc_count; i++) {
12465 int64_t next = time_sample + mov_get_stsc_samples(sc, i);
12466 if (next > sc->current_sample) {
12467 sc->stsc_index = i;
12468 sc->stsc_sample = sc->current_sample - time_sample;
12469 break;
12470 }
12471 av_assert0(next == (int)next);
12472 time_sample = next;
12473 }
12474 }
12475
12476 return sample;
12477}
12478
12480{
12481 FFStream *const sti = ffstream(st);
12482 int64_t first_ts = sti->index_entries[0].timestamp;
12484 int64_t off;
12485
12487 return 0;
12488
12489 /* compute skip samples according to stream initial_padding, seek ts and first ts */
12490 off = av_rescale_q(ts - first_ts, st->time_base,
12491 (AVRational){1, st->codecpar->sample_rate});
12492 return FFMAX(st->codecpar->initial_padding - off, 0);
12493}
12494
12495static int mov_read_seek(AVFormatContext *s, int stream_index, int64_t sample_time, int flags)
12496{
12497 MOVContext *mc = s->priv_data;
12498 AVStream *st;
12499 FFStream *sti;
12500 int sample;
12501 int i;
12502
12503 if (stream_index >= s->nb_streams)
12504 return AVERROR_INVALIDDATA;
12505
12506 st = s->streams[stream_index];
12507 sti = ffstream(st);
12508 sample = mov_seek_stream(s, st, sample_time, flags);
12509 if (sample < 0)
12510 return sample;
12511
12512 if (mc->seek_individually) {
12513 /* adjust seek timestamp to found sample timestamp */
12514 int64_t seek_timestamp = sti->index_entries[sample].timestamp;
12516
12517 for (i = 0; i < s->nb_streams; i++) {
12518 AVStream *const st = s->streams[i];
12519 FFStream *const sti = ffstream(st);
12520 int64_t timestamp;
12521
12522 if (stream_index == i)
12523 continue;
12524
12525 timestamp = av_rescale_q(seek_timestamp, s->streams[stream_index]->time_base, st->time_base);
12526 sample = mov_seek_stream(s, st, timestamp, flags);
12527 if (sample >= 0)
12529 }
12530 } else {
12531 for (i = 0; i < s->nb_streams; i++) {
12532 MOVStreamContext *sc;
12533 st = s->streams[i];
12534 sc = st->priv_data;
12536 }
12537 while (1) {
12538 MOVStreamContext *sc;
12540 if (!entry)
12541 return AVERROR_INVALIDDATA;
12542 sc = st->priv_data;
12543 if (sc->ffindex == stream_index && sc->current_sample == sample)
12544 break;
12546 }
12547 }
12548 return 0;
12549}
12550
12551#define OFFSET(x) offsetof(MOVContext, x)
12552#define FLAGS AV_OPT_FLAG_VIDEO_PARAM | AV_OPT_FLAG_DECODING_PARAM
12553static const AVOption mov_options[] = {
12554 {"use_absolute_path",
12555 "allow using absolute path when opening alias, this is a possible security issue",
12556 OFFSET(use_absolute_path), AV_OPT_TYPE_BOOL, {.i64 = 0},
12557 0, 1, FLAGS},
12558 {"seek_streams_individually",
12559 "Seek each stream individually to the closest point",
12560 OFFSET(seek_individually), AV_OPT_TYPE_BOOL, { .i64 = 1 },
12561 0, 1, FLAGS},
12562 {"ignore_editlist", "Ignore the edit list atom.", OFFSET(ignore_editlist), AV_OPT_TYPE_BOOL, {.i64 = 0},
12563 0, 1, FLAGS},
12564 {"advanced_editlist",
12565 "Modify the AVIndex according to the editlists. Use this option to decode in the order specified by the edits.",
12566 OFFSET(advanced_editlist), AV_OPT_TYPE_BOOL, {.i64 = 1},
12567 0, 1, FLAGS},
12568 {"ignore_chapters", "", OFFSET(ignore_chapters), AV_OPT_TYPE_BOOL, {.i64 = 0},
12569 0, 1, FLAGS},
12570 {"use_mfra_for",
12571 "use mfra for fragment timestamps",
12572 OFFSET(use_mfra_for), AV_OPT_TYPE_INT, {.i64 = FF_MOV_FLAG_MFRA_AUTO},
12574 .unit = "use_mfra_for"},
12575 {"auto", "auto", 0, AV_OPT_TYPE_CONST, {.i64 = FF_MOV_FLAG_MFRA_AUTO}, 0, 0,
12576 FLAGS, .unit = "use_mfra_for" },
12577 {"dts", "dts", 0, AV_OPT_TYPE_CONST, {.i64 = FF_MOV_FLAG_MFRA_DTS}, 0, 0,
12578 FLAGS, .unit = "use_mfra_for" },
12579 {"pts", "pts", 0, AV_OPT_TYPE_CONST, {.i64 = FF_MOV_FLAG_MFRA_PTS}, 0, 0,
12580 FLAGS, .unit = "use_mfra_for" },
12581 {"use_tfdt", "use tfdt for fragment timestamps", OFFSET(use_tfdt), AV_OPT_TYPE_BOOL, {.i64 = 1},
12582 0, 1, FLAGS},
12583 { "export_all", "Export unrecognized metadata entries", OFFSET(export_all),
12584 AV_OPT_TYPE_BOOL, { .i64 = 0 }, 0, 1, .flags = FLAGS },
12585 { "export_xmp", "Export full XMP metadata", OFFSET(export_xmp),
12586 AV_OPT_TYPE_BOOL, { .i64 = 0 }, 0, 1, .flags = FLAGS },
12587 { "activation_bytes", "Secret bytes for Audible AAX files", OFFSET(activation_bytes),
12589 { "audible_key", "AES-128 Key for Audible AAXC files", OFFSET(audible_key),
12591 { "audible_iv", "AES-128 IV for Audible AAXC files", OFFSET(audible_iv),
12593 { "audible_fixed_key", // extracted from libAAX_SDK.so and AAXSDKWin.dll files!
12594 "Fixed key used for handling Audible AAX files", OFFSET(audible_fixed_key),
12595 AV_OPT_TYPE_BINARY, {.str="77214d4b196a87cd520045fd20a51d67"},
12596 .flags = AV_OPT_FLAG_DECODING_PARAM },
12597 { "decryption_key", "The default media decryption key (hex)", OFFSET(decryption_default_key), AV_OPT_TYPE_BINARY, .flags = AV_OPT_FLAG_DECODING_PARAM },
12598 { "decryption_keys", "The media decryption keys by KID (hex)", OFFSET(decryption_keys), AV_OPT_TYPE_DICT, .flags = AV_OPT_FLAG_DECODING_PARAM },
12599 { "enable_drefs", "Enable external track support.", OFFSET(enable_drefs), AV_OPT_TYPE_BOOL,
12600 {.i64 = 0}, 0, 1, FLAGS },
12601 { "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 },
12602 { "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 },
12603
12604 { NULL },
12605};
12606
12607static const AVClass mov_class = {
12608 .class_name = "mov,mp4,m4a,3gp,3g2,mj2",
12609 .item_name = av_default_item_name,
12610 .option = mov_options,
12611 .version = LIBAVUTIL_VERSION_INT,
12612};
12613
12615 .p.name = "mov,mp4,m4a,3gp,3g2,mj2",
12616 .p.long_name = NULL_IF_CONFIG_SMALL("QuickTime / MOV"),
12617 .p.priv_class = &mov_class,
12618 .p.extensions = "mov,mp4,m4a,3gp,3g2,mj2,psp,m4v,m4b,ism,ismv,isma,f4v,avif,heic,heif",
12620 .priv_data_size = sizeof(MOVContext),
12621 .flags_internal = FF_INFMT_FLAG_INIT_CLEANUP,
12627};
uint8_t ptrdiff_t const uint8_t ptrdiff_t int intptr_t intptr_t int int16_t * dst
Definition dsp.h:97
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:445
#define ctype
#define ALAC_EXTRADATA_SIZE
Definition alac.c:63
const FFInputFormat ff_mov_demuxer
Definition mov.c:12614
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:966
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:839
void ff_remove_stream(AVFormatContext *s, AVStream *st)
Remove a stream from its AVFormatContext and free it.
Definition avformat.c:123
void ff_remove_stream_group(AVFormatContext *s, AVStreamGroup *stg)
Remove a stream group from its AVFormatContext and free it.
Definition avformat.c:131
Main libavformat public API header.
#define AVFMT_EVENT_FLAG_METADATA_UPDATED
Definition avformat.h:1731
#define AVINDEX_KEYFRAME
Definition avformat.h:630
#define AVPROBE_SCORE_MAX
maximum score
Definition avformat.h:485
#define AVFMT_FLAG_IGNIDX
Ignore index.
Definition avformat.h:1490
@ AV_STREAM_GROUP_PARAMS_DOLBY_VISION
Definition avformat.h:1156
@ AV_STREAM_GROUP_PARAMS_TREF
Definition avformat.h:1155
@ AV_STREAM_GROUP_PARAMS_IAMF_MIX_PRESENTATION
Definition avformat.h:1152
@ AV_STREAM_GROUP_PARAMS_TILE_GRID
Definition avformat.h:1153
@ AV_STREAM_GROUP_PARAMS_IAMF_AUDIO_ELEMENT
Definition avformat.h:1151
@ AV_STREAM_GROUP_PARAMS_LCEVC
Definition avformat.h:1154
#define AVFMT_NO_BYTE_SEEK
Format does not allow seeking by bytes.
Definition avformat.h:508
#define AV_DISPOSITION_MULTILAYER
The video stream contains multiple layers, e.g.
Definition avformat.h:738
#define AV_DISPOSITION_DEPENDENT
The stream is intended to be mixed with another stream before presentation.
Definition avformat.h:729
#define AV_DISPOSITION_NON_DIEGETIC
The stream is intended to be mixed with a spatial audio track.
Definition avformat.h:706
#define AVPROBE_SCORE_EXTENSION
score for file extension
Definition avformat.h:483
#define AVFMT_SHOW_IDS
Show format stream IDs numbers.
Definition avformat.h:498
#define AVSEEK_FLAG_ANY
seek to any frame, even non-keyframes
Definition avformat.h:2622
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:694
#define AVFMT_SEEK_TO_PTS
Seeking is based on PTS.
Definition avformat.h:522
#define AVINDEX_DISCARD_FRAME
Definition avformat.h:631
#define AVSEEK_FLAG_BACKWARD
seek backward
Definition avformat.h:2620
#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:641
#define AV_DISPOSITION_TIMED_THUMBNAILS
The stream is sparse, and contains thumbnail images, often corresponding to chapter markers.
Definition avformat.h:699
@ AVSTREAM_PARSE_HEADERS
Only parse headers, do not repack.
Definition avformat.h:614
@ AVSTREAM_PARSE_FULL
full parsing and repack
Definition avformat.h:613
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)
#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)
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)
int avio_get_str(AVIOContext *pb, int maxlen, char *buf, int buflen)
Read a string from pb into buf.
Definition aviobuf.c:836
unsigned int avio_rb24(AVIOContext *s)
unsigned int avio_rb32(AVIOContext *s)
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:985
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:830
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:889
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:68
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:596
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:101
#define AV_PROFILE_DTS_HD_MA
Definition defs.h:100
#define AV_PROFILE_DTS
Definition defs.h:96
#define AV_PROFILE_UNKNOWN
Definition defs.h:65
#define AV_PROFILE_DTS_HD_HRA
Definition defs.h:99
#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:225
@ AV_FIELD_TT
Top coded_first, top displayed first.
Definition defs.h:228
@ AV_FIELD_BB
Bottom coded first, bottom displayed first.
Definition defs.h:229
@ AV_FIELD_UNKNOWN
Definition defs.h:226
@ AV_FIELD_PROGRESSIVE
Definition defs.h:227
@ AV_FIELD_BT
Bottom coded first, top displayed first.
Definition defs.h:231
@ AV_FIELD_TB
Top coded first, bottom displayed first.
Definition defs.h:230
#define AV_PROFILE_DTS_96_24
Definition defs.h:98
AVAudioServiceType
Definition defs.h:249
@ AV_AUDIO_SERVICE_TYPE_KARAOKE
Definition defs.h:258
#define AV_PROFILE_DTS_ES
Definition defs.h:97
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:883
void av_exif_free(AVExifMetadata *ifd)
Frees all resources associated with the given EXIF metadata struct.
Definition exif.c:660
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:754
int32_t av_exif_get_tag_id(const char *name)
Retrieves the tag ID associated with the provided tag string name.
Definition exif.c:245
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:1273
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:399
static int loop
Definition ffplay.c:407
static int64_t start_time
Definition ffplay.c:398
static unsigned int nb_streams
Definition ffprobe.c:353
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:557
AVCodecID
Identify the syntax and semantics of the bitstream.
Definition codec_id.h:47
@ AV_CODEC_ID_PCM_F32LE
Definition codec_id.h:353
@ AV_CODEC_ID_PCM_S24BE
Definition codec_id.h:345
@ AV_CODEC_ID_VORBIS
Definition codec_id.h:462
@ 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:497
@ AV_CODEC_ID_PCM_U8
Definition codec_id.h:337
@ AV_CODEC_ID_APV
Definition codec_id.h:323
@ AV_CODEC_ID_LCEVC
Definition codec_id.h:613
@ AV_CODEC_ID_PCM_S16LE
Definition codec_id.h:332
@ AV_CODEC_ID_GSM
as in Berlin toast format
Definition codec_id.h:475
@ AV_CODEC_ID_DVD_SUBTITLE
Definition codec_id.h:570
@ AV_CODEC_ID_TTML
Definition codec_id.h:594
@ AV_CODEC_ID_PCM_F32BE
Definition codec_id.h:352
@ 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:333
@ AV_CODEC_ID_PCM_S24LE
Definition codec_id.h:344
@ AV_CODEC_ID_PCM_S32LE
Definition codec_id.h:340
@ AV_CODEC_ID_PCM_S8
Definition codec_id.h:336
@ AV_CODEC_ID_AV1
Definition codec_id.h:275
@ AV_CODEC_ID_ADPCM_MS
Definition codec_id.h:378
@ 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:355
@ AV_CODEC_ID_ALAC
Definition codec_id.h:473
@ AV_CODEC_ID_EIA_608
Definition codec_id.h:580
@ AV_CODEC_ID_AMR_NB
Definition codec_id.h:438
@ 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:457
@ AV_CODEC_ID_DVAUDIO
Definition codec_id.h:463
@ AV_CODEC_ID_ADPCM_IMA_QT
Definition codec_id.h:372
@ AV_CODEC_ID_HEVC
Definition codec_id.h:223
@ AV_CODEC_ID_BIN_DATA
Definition codec_id.h:611
@ AV_CODEC_ID_AAC
Definition codec_id.h:459
@ 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:354
@ AV_CODEC_ID_H263
Definition codec_id.h:54
@ AV_CODEC_ID_QCELP
Definition codec_id.h:481
@ AV_CODEC_ID_AMR_WB
Definition codec_id.h:439
@ AV_CODEC_ID_AC3
Definition codec_id.h:460
@ AV_CODEC_ID_MACE3
Definition codec_id.h:466
@ AV_CODEC_ID_MACE6
Definition codec_id.h:467
@ AV_CODEC_ID_QDM2
Definition codec_id.h:476
@ AV_CODEC_ID_PCM_S32BE
Definition codec_id.h:341
@ 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:373
@ 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:492
@ AV_CODEC_ID_AVUI
Definition codec_id.h:252
@ AV_CODEC_ID_ILBC
Definition codec_id.h:516
@ AV_CODEC_ID_MP3
preferred ID for decoding MPEG audio layer 1, 2 or 3
Definition codec_id.h:458
@ 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:507
@ AV_CODEC_ID_ITUT_T35
Definition codec_id.h:615
@ 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:246
@ AVDISCARD_NONKEY
discard all frames except keyframes
Definition defs.h:245
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:472
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:561
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:151
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:234
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:140
AVBufferRef * av_buffer_alloc(size_t size)
Allocate an AVBuffer of the given size using av_malloc().
Definition buffer.c:78
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:447
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:601
void * av_realloc_array(void *ptr, size_t nmemb, size_t size)
Definition mem.c:318
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:289
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:326
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:50
void av_display_matrix_flip(int32_t matrix[9], int hflip, int vflip)
Flip the input matrix horizontally and/or vertically.
Definition display.c:65
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
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
#define MOV_GRAPHICS_MODE_COPY
Definition isom.h:443
int ff_mov_read_esds(AVFormatContext *fc, AVIOContext *pb)
Definition mov_esds.c:23
#define FF_MOV_FLAG_MFRA_PTS
Definition isom.h:477
#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:476
const AVCodecTag ff_codec_movaudio_tags[]
Definition isom_tags.c:307
#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:493
#define TAG_IS_AVCI(tag)
Definition isom.h:453
#define MOV_TRUN_FIRST_SAMPLE_FLAGS
Definition isom.h:417
#define MOV_GRAPHICS_MODE_PREMUL_BLACK_ALPHA
Definition isom.h:449
#define MOV_MP4_FPCM_TAG
Definition isom.h:495
#define MOV_FRAG_SAMPLE_FLAG_IS_NON_SYNC
Definition isom.h:424
#define MOV_TFHD_STSD_ID
Definition isom.h:409
#define MOV_GRAPHICS_MODE_DITHER_COPY
Definition isom.h:444
#define MOV_TRUN_SAMPLE_FLAGS
Definition isom.h:420
#define MOV_MP4_TTML_TAG
Definition isom.h:494
#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:496
static enum AVCodecID ff_mov_get_lpcm_codec_id(int bps, int flags)
Compute codec id for 'lpcm' tag.
Definition isom.h:483
#define MOV_TRUN_SAMPLE_SIZE
Definition isom.h:419
#define MOV_SAMPLE_DEPENDENCY_NO
Definition isom.h:440
#define MOV_GRAPHICS_MODE_STRAIGHT_ALPHA
Definition isom.h:447
#define FF_MOV_FLAG_MFRA_AUTO
Definition isom.h:475
#define MOV_TFHD_DEFAULT_DURATION
Definition isom.h:410
uint32_t type
Definition jpegmpfenc.c:80
unsigned offset
Definition libaomenc.c:763
static int mix(int c0, int c1)
Definition 4xm.c:717
enum TrimAxis axis
Definition trim.c:49
@ 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:626
int ff_hex_to_data(uint8_t *data, const char *p)
Parse a string of hexadecimal strings.
Definition utils.c:495
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:473
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:97
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 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:370
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:5713
static int64_t mov_get_skip_samples(AVStream *st, int sample)
Definition mov.c:12479
static int search_frag_moof_offset(MOVFragmentIndex *frag_index, int64_t offset)
Definition mov.c:1770
static int mov_read_sbas(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition mov.c:2737
static int update_frag_index(MOVContext *c, int64_t offset)
Definition mov.c:1871
static int get_eia608_packet(AVIOContext *pb, AVPacket *pkt, int src_size)
Definition mov.c:12007
static int mov_read_iloc(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition mov.c:9433
static int mov_read_pack(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition mov.c:7127
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:4226
static int mov_read_seek(AVFormatContext *s, int stream_index, int64_t sample_time, int flags)
Definition mov.c:12495
static HEIFItem * get_heif_item(MOVContext *c, unsigned id)
Get the requested item.
Definition mov.c:197
static void mov_free_stream_context(AVFormatContext *s, AVStream *st)
Definition mov.c:10642
static int mov_read_stsd(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition mov.c:3454
static void mov_parse_stsd_video(MOVContext *c, AVIOContext *pb, AVStream *st, MOVStreamContext *sc)
Definition mov.c:2928
static int heif_add_stream(MOVContext *c, HEIFItem *item)
Definition mov.c:5875
static int mov_read_dops(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition mov.c:9009
static int set_display_matrix_from_item(AVPacketSideData **coded_side_data, int *nb_coded_side_data, const HEIFItem *item)
Definition mov.c:10913
static int mov_compare_presentation_samples(const void *a, const void *b)
Definition mov.c:5283
static int mov_switch_root(AVFormatContext *s, int64_t target, int index)
Definition mov.c:11947
static int mov_read_vexu_proj(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition mov.c:7345
static int mov_read_srat(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition mov.c:1094
static int get_key_from_kid(uint8_t *out, int len, MOVContext *c, AVEncryptionInfo *sample)
Definition mov.c:8593
static int mov_read_aclr(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition mov.c:2478
static int mov_read_idat(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition mov.c:9427
static int mov_parse_tmcd_streams(AVFormatContext *s)
Definition mov.c:11387
static int mov_read_lhvc(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition mov.c:9144
static int aax_filter(uint8_t *input, int size, MOVContext *c)
Definition mov.c:1635
static void mov_current_sample_dec(MOVStreamContext *sc)
Definition mov.c:4472
static int mov_finalize_stsd_entry(MOVContext *c, AVStream *st)
Definition mov.c:3332
static int mov_read_pitm(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition mov.c:9419
static int mov_seek_stream(AVFormatContext *s, AVStream *st, int64_t timestamp, int flags)
Definition mov.c:12404
static int mov_read_packet(AVFormatContext *s, AVPacket *pkt)
Definition mov.c:12160
static int mov_parse_lcevc_streams(AVFormatContext *s)
Definition mov.c:11510
static int mov_read_hvce(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition mov.c:9117
static int cbcs_scheme_decrypt(MOVContext *c, MOVStreamContext *sc, AVEncryptionInfo *sample, uint8_t *input, int size)
Definition mov.c:8826
static int mov_read_default(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition mov.c:10227
static int mov_finalize_packet(AVFormatContext *s, AVStream *st, AVIndexEntry *sample, int64_t current_index, AVPacket *pkt)
Definition mov.c:12076
static int mov_read_stss(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition mov.c:3662
static uint64_t mov_dts_channel_layout_to_mask(unsigned int code)
Definition mov.c:1210
static int64_t get_stream_info_time(MOVFragmentStreamInfo *frag_stream_info)
Definition mov.c:1794
static int mov_read_saio(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition mov.c:8235
static int mov_skip_multiple_stsd(MOVContext *c, AVIOContext *pb, int codec_tag, int format, int64_t size)
Definition mov.c:3306
#define DRM_BLOB_SIZE
Definition mov.c:1507
static int mov_add_tref_id(MovTref *tag, uint32_t id)
Definition mov.c:2663
static int mov_read_mdhd(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition mov.c:2005
static int mov_read_tmcd(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition mov.c:6826
int ff_mov_read_stsd_entries(MOVContext *c, AVIOContext *pb, int entries)
Definition mov.c:3353
static int mov_metadata_gnre(MOVContext *c, AVIOContext *pb, unsigned len, const char *key)
Definition mov.c:137
static int mov_read_dref(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition mov.c:655
static int mov_read_dpxe(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition mov.c:2406
static MovTref * mov_find_tref_tag(const MOVStreamContext *sc, uint32_t name)
Definition mov.c:2678
static int mov_read_eyes(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition mov.c:7418
static int cenc_scheme_decrypt(MOVContext *c, MOVStreamContext *sc, AVEncryptionInfo *sample, uint8_t *input, int size)
Definition mov.c:8630
static int mov_read_wave(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition mov.c:2526
static int read_image_iovl(AVFormatContext *s, const HEIFGrid *grid, AVStreamGroupTileGrid *tile_grid)
Definition mov.c:11029
static int mov_metadata_hmmt(MOVContext *c, AVIOContext *pb, unsigned len)
Definition mov.c:327
static int mov_read_iref_dimg(MOVContext *c, AVIOContext *pb, int version)
Definition mov.c:9664
static int mov_read_stsz(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition mov.c:3717
static int mov_dts_stream_construction_to_profile(unsigned int sc)
Definition mov.c:1177
static int rb_size(AVIOContext *pb, int64_t *value, int size)
Definition mov.c:9400
static int mov_read_chpl(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition mov.c:616
static int mov_read_header(AVFormatContext *s)
Definition mov.c:11675
static int mov_read_dfla(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition mov.c:8553
static int mov_read_stco(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition mov.c:2823
static int mov_read_st3d(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition mov.c:7080
static int mov_read_elst(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition mov.c:6752
static int test_same_origin(const char *src, const char *ref)
Definition mov.c:5381
static int sanity_checks(void *log_obj, MOVStreamContext *sc, int index)
Definition mov.c:5538
static void mov_current_sample_set(MOVStreamContext *sc, int current_sample)
Definition mov.c:4484
static int mov_merge_tts_data(MOVContext *mov, AVStream *st, int flags)
Definition mov.c:4899
static int mov_aaxc_crypto(MOVContext *c)
Definition mov.c:1610
static int mov_read_sv3d(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition mov.c:7208
static int mov_read_ddts(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition mov.c:1238
static int mov_read_sdtp(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition mov.c:3930
static int mov_read_stts(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition mov.c:3810
static int cenc_filter(MOVContext *mov, AVStream *st, MOVStreamContext *sc, AVPacket *pkt, int current_index)
Definition mov.c:8939
static const AVClass mov_class
Definition mov.c:12607
static int mov_read_sample_encryption_info(MOVContext *c, AVIOContext *pb, MOVStreamContext *sc, AVEncryptionInfo **sample, int use_subsamples)
Definition mov.c:7979
static int mov_read_meta(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition mov.c:5934
static int mov_read_smdm(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition mov.c:6898
static const uint32_t mac_to_unicode[128]
Definition mov.c:153
static int mov_read_sidx(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition mov.c:6540
static int mov_read_strf(MOVContext *c, AVIOContext *pb, MOVAtom atom)
An strf atom is a BITMAPINFOHEADER struct.
Definition mov.c:2801
static uint32_t get_sgpd_sync_index(const MOVStreamContext *sc, int nal_unit_type)
Definition mov.c:4821
static void fix_frag_index_entries(MOVFragmentIndex *frag_index, int index, int id, int entries)
Definition mov.c:1934
static int mov_read_rtmd_track(AVFormatContext *s, AVStream *st)
Definition mov.c:10557
static int mov_read_dec3(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition mov.c:1128
static int mov_read_dmlp(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition mov.c:9062
static int mov_metadata_int8_bypass_padding(MOVContext *c, AVIOContext *pb, unsigned len, const char *key)
Definition mov.c:114
static int mov_read_schm(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition mov.c:8451
static int mov_metadata_loci(MOVContext *c, AVIOContext *pb, unsigned len)
Definition mov.c:277
static int read_tfra(MOVContext *mov, AVIOContext *f)
Definition mov.c:10798
static int mov_seek_fragment(AVFormatContext *s, AVStream *st, int64_t timestamp)
Definition mov.c:12341
static int mov_read_extradata(MOVContext *c, AVIOContext *pb, MOVAtom atom, enum AVCodecID codec_id)
Definition mov.c:2365
static int mov_read_enda(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition mov.c:2119
static int mov_read_covr(MOVContext *c, AVIOContext *pb, int type, int len)
Definition mov.c:234
static int mov_read_adrm(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition mov.c:1509
static int mov_parse_dovi_streams(AVFormatContext *s)
Definition mov.c:11564
static int mov_read_chnl(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition mov.c:1319
static void mov_metadata_creation_time(MOVContext *c, AVIOContext *pb, AVDictionary **metadata, int version)
Definition mov.c:1975
static int mov_parse_exif_item(AVFormatContext *s, AVPacketSideData **coded_side_data, int *nb_coded_side_data, const HEIFItem *ref)
Definition mov.c:11098
static int mov_stsc_index_valid(unsigned int index, unsigned int count)
Definition mov.c:3600
static int mov_read_hdlr(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition mov.c:799
#define MOV_MERGE_STTS
Definition mov.c:4893
static int mov_read_dvcc_dvvc(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition mov.c:9097
static int should_retry(AVIOContext *pb, int error_code)
Definition mov.c:11940
static int mov_read_mvhd(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition mov.c:2051
static int mov_read_tfdt(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition mov.c:6159
static int mov_read_moov(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition mov.c:1697
static int mov_read_clli(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition mov.c:7026
static int mov_read_trun(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition mov.c:6198
static void mov_update_dts_shift(MOVStreamContext *sc, int duration, void *logctx)
Definition mov.c:3968
static int mov_read_kind(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition mov.c:9195
static int mov_read_sbgp(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition mov.c:4119
static int mov_metadata_track_or_disc_number(MOVContext *c, AVIOContext *pb, unsigned len, const char *key)
Definition mov.c:94
static int mov_read_ares(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition mov.c:2433
static int mov_read_pssh(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition mov.c:8330
static int mov_finalize_stsd_codec(MOVContext *c, AVIOContext *pb, AVStream *st, MOVStreamContext *sc)
Definition mov.c:3202
static int mov_read_tkhd(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition mov.c:5960
static int mov_read_iprp(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition mov.c:9903
static int mov_read_cdsc_rndr(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition mov.c:2706
static int cens_scheme_decrypt(MOVContext *c, MOVStreamContext *sc, AVEncryptionInfo *sample, uint8_t *input, int size)
Definition mov.c:8755
static int mov_read_alac(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition mov.c:2391
static int mov_read_mfra(MOVContext *c, AVIOContext *f)
Definition mov.c:10853
#define MIN_DATA_ENTRY_BOX_SIZE
Definition mov.c:654
static int mov_change_extradata(AVStream *st, AVPacket *pkt)
Definition mov.c:11983
static int mov_read_mdcv(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition mov.c:6945
static int mov_read_timecode_track(AVFormatContext *s, AVStream *st)
Definition mov.c:10583
static int mov_read_imir(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition mov.c:9884
static int mov_read_stps(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition mov.c:3621
static int mov_read_svq3(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition mov.c:2521
static int mov_read_pcmc(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition mov.c:2128
static int mov_parse_cdsc_and_rndr_streams(AVFormatContext *s)
Definition mov.c:11458
static const MOVParseTableEntry mov_default_parse_table[]
Definition mov.c:10091
static int mov_read_jp2h(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition mov.c:2401
static int mov_read_iref(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition mov.c:9791
static int mov_read_trex(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition mov.c:6133
static int mov_read_saiz(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition mov.c:8151
static int mov_read_hfov(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition mov.c:7662
static int mov_read_free(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition mov.c:7859
static int set_icc_profile_from_item(AVPacketSideData **coded_side_data, int *nb_coded_side_data, const HEIFItem *item)
Definition mov.c:10899
static int mov_read_infe(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition mov.c:9530
static int mov_read_stsc(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition mov.c:3520
static AVStream * get_curr_st(MOVContext *c)
Get the current stream in the parsing process.
Definition mov.c:216
static int mov_parse_stsd_data(MOVContext *c, AVIOContext *pb, AVStream *st, MOVStreamContext *sc, int64_t size)
Definition mov.c:3129
static int mov_read_mdat(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition mov.c:1499
static int cbc1_scheme_decrypt(MOVContext *c, MOVStreamContext *sc, AVEncryptionInfo *sample, uint8_t *input, int size)
Definition mov.c:8689
static int mov_metadata_int8_no_padding(MOVContext *c, AVIOContext *pb, unsigned len, const char *key)
Definition mov.c:128
static int search_frag_timestamp(AVFormatContext *s, MOVFragmentIndex *frag_index, AVStream *st, int64_t timestamp)
Definition mov.c:1846
static int mov_read_avid(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition mov.c:2411
static void fix_timescale(MOVContext *c, MOVStreamContext *sc)
Definition mov.c:5482
static int mov_read_custom(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition mov.c:5774
static int mov_read_dac3(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition mov.c:870
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:7928
static int mov_read_close(AVFormatContext *s)
Definition mov.c:10707
static int mov_read_pasp(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition mov.c:1477
static int mov_open_dref(MOVContext *c, AVIOContext **pb, const char *src, MOVDref *ref)
Definition mov.c:5410
static MOVFragmentStreamInfo * get_frag_stream_info_from_pkt(MOVFragmentIndex *frag_index, AVPacket *pkt, int id)
Definition mov.c:8914
static int mov_read_avss(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition mov.c:2396
static int mov_read_tenc(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition mov.c:8482
static int mov_read_uuid(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition mov.c:7754
static int mov_read_chan(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition mov.c:1300
static int build_open_gop_key_points(AVStream *st)
Definition mov.c:4829
static void set_last_stream_little_endian(AVFormatContext *fc)
Definition mov.c:2090
static void mov_build_index(MOVContext *mov, AVStream *st)
Definition mov.c:4962
static void mov_update_sample_durations(MOVContext *mov, AVStream *st)
Definition mov.c:5296
static int mov_read_ctts(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition mov.c:3979
static int mov_find_tref_id(const MovTref *tag, uint32_t id)
Definition mov.c:2654
static int mov_read_amve(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition mov.c:7055
static int mov_read_keys(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition mov.c:5722
static int mov_read_wfex(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition mov.c:1353
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:2583
static int mov_read_ftyp(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition mov.c:1649
#define IS_MATRIX_IDENT(matrix)
Definition mov.c:5952
static int can_seek_to_key_sample(AVStream *st, int sample, int64_t requested_pts)
Definition mov.c:12377
static int mov_parse_auxiliary_info(MOVContext *c, MOVStreamContext *sc, AVIOContext *pb, MOVEncryptionIndex *encryption_index)
Definition mov.c:8089
static int64_t mov_get_stsc_samples(MOVStreamContext *sc, unsigned int index)
Definition mov.c:3606
static int mov_read_vpcc(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition mov.c:6854
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:4322
static int mov_parse_tiles(AVFormatContext *s)
Definition mov.c:11182
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:4512
#define DDTS_SIZE
static int mov_read_iref_cdsc(MOVContext *c, AVIOContext *pb, uint32_t type, int version, uint32_t size)
Definition mov.c:9747
static int cenc_decrypt(MOVContext *c, MOVStreamContext *sc, AVEncryptionInfo *sample, uint8_t *input, int size)
Definition mov.c:8898
static int mov_read_senc(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition mov.c:8033
static int mov_read_sgpd(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition mov.c:4060
static AVStream * mov_find_reference_track(AVFormatContext *s, AVStream *st, uint32_t *tref_id, int nb_tref_id, int first_index)
Definition mov.c:11443
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:4363
static int mov_read_trak(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition mov.c:5557
static int mov_read_colr(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition mov.c:2205
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:4375
static void mov_parse_stsd_subtitle(MOVContext *c, AVIOContext *pb, AVStream *st, MOVStreamContext *sc, int64_t size)
Definition mov.c:3113
static int mov_read_clap(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition mov.c:1368
static int mov_read_dvc1(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition mov.c:2629
static int mov_read_vdep(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition mov.c:2769
static int mov_read_SAND(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition mov.c:9374
static int64_t mov_read_atom_into_extradata(MOVContext *c, AVIOContext *pb, MOVAtom atom, AVCodecParameters *par, uint8_t *buf)
Definition mov.c:2343
static void mov_free_encryption_index(MOVEncryptionIndex **index)
Definition mov.c:10630
static int mov_read_mac_string(MOVContext *c, AVIOContext *pb, int len, char *dst, int dstlen)
Definition mov.c:172
static void fix_stream_ids(AVFormatContext *s)
Definition mov.c:11637
#define OFFSET(x)
Definition mov.c:12551
static AVIndexEntry * mov_find_next_sample(AVFormatContext *s, AVStream **st)
Definition mov.c:11910
static int mov_read_chap(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition mov.c:6112
#define MOV_MERGE_CTTS
Definition mov.c:4892
static int is_open_key_sample(const MOVStreamContext *sc, int sample)
Definition mov.c:12360
static int mov_read_moof(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition mov.c:1949
static int mov_read_SA3D(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition mov.c:9284
static int mov_realloc_extradata(AVCodecParameters *par, MOVAtom atom)
Definition mov.c:2328
static int mov_read_udta_string(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition mov.c:348
static int mov_read_coll(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition mov.c:6989
static int mov_read_frma(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition mov.c:7881
static int mov_read_ispe(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition mov.c:9836
static int mov_codec_id(AVStream *st, uint32_t format)
Definition mov.c:2888
static void export_orphan_timecode(AVFormatContext *s)
Definition mov.c:10780
static int mov_parse_heif_items(AVFormatContext *s)
Definition mov.c:11308
static void mov_estimate_video_delay(MOVContext *c, AVStream *st)
Definition mov.c:4404
static int mov_read_vmhd(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition mov.c:10020
static int mov_read_tfhd(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition mov.c:6065
static MOVFragmentStreamInfo * get_frag_stream_info(MOVFragmentIndex *frag_index, int index, int id)
Definition mov.c:1715
static int mov_read_irot(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition mov.c:9864
static int read_image_grid(AVFormatContext *s, const HEIFGrid *grid, AVStreamGroupTileGrid *tile_grid)
Definition mov.c:10934
static int mov_probe(const AVProbeData *p)
Definition mov.c:10349
static int parse_timecode_in_framenum_format(AVFormatContext *s, AVStream *st, int64_t value, int flags)
Definition mov.c:10543
static int mov_parse_uuid_spherical(MOVStreamContext *sc, AVIOContext *pb, size_t len)
Definition mov.c:7691
static void mov_current_sample_inc(MOVStreamContext *sc)
Definition mov.c:4460
static int mov_read_fiel(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition mov.c:2294
static int mov_read_targa_y216(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition mov.c:2419
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:4180
static void mov_parse_stsd_audio(MOVContext *c, AVIOContext *pb, AVStream *st, MOVStreamContext *sc)
Definition mov.c:2992
static int mov_read_wide(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition mov.c:6679
static int64_t get_frag_time(AVFormatContext *s, AVStream *dst_st, MOVFragmentIndex *frag_index, int index)
Definition mov.c:1804
static MOVFragmentStreamInfo * get_current_frag_stream_info(MOVFragmentIndex *frag_index)
Definition mov.c:1754
static int mov_read_esds(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition mov.c:865
static int mov_read_iinf(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition mov.c:9607
static int tmcd_is_referenced(AVFormatContext *s, int tmcd_id)
Definition mov.c:10762
static void mov_read_chapters(AVFormatContext *s)
Definition mov.c:10444
static int mov_read_mhac(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition mov.c:10053
static int mov_read_cmov(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition mov.c:6699
static void set_frag_stream(MOVFragmentIndex *frag_index, int id)
Definition mov.c:1734
static const AVOption mov_options[]
Definition mov.c:12553
static MovTref * mov_add_tref_tag(MOVStreamContext *sc, uint32_t name)
Definition mov.c:2689
static int mov_read_vexu(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition mov.c:7600
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:2128
mpeg audio layer common tables.
const uint64_t ff_mpa_cicp_channel_layout_masks[20]
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_malloc(s)
Definition ops_static.c:52
AVOptions.
const char * av_color_space_name(enum AVColorSpace space)
Definition pixdesc.c:3884
const char * av_color_transfer_name(enum AVColorTransferCharacteristic transfer)
Definition pixdesc.c:3851
const char * av_color_primaries_name(enum AVColorPrimaries primaries)
Definition pixdesc.c:3818
@ AVCOL_RANGE_MPEG
Narrow or limited range content.
Definition pixfmt.h:771
@ AVCOL_RANGE_JPEG
Full range content.
Definition pixfmt.h:788
@ AVALPHA_MODE_STRAIGHT
Alpha channel is independent of color values.
Definition pixfmt.h:824
@ AVALPHA_MODE_UNSPECIFIED
Unknown alpha handling, or no alpha channel.
Definition pixfmt.h:822
@ AVALPHA_MODE_PREMULTIPLIED
Alpha channel is multiplied into color values.
Definition pixfmt.h:823
#define AVPALETTE_SIZE
Definition pixfmt.h:32
@ AVCOL_PRI_UNSPECIFIED
Definition pixfmt.h:650
@ AVCOL_TRC_UNSPECIFIED
Definition pixfmt.h:680
@ AVCOL_SPC_UNSPECIFIED
Definition pixfmt.h:714
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)
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
enum AVAlphaMode alpha_mode
Video with alpha channel only.
Definition codec_par.h:261
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:1337
AVStream ** streams
A list of all streams in the file.
Definition avformat.h:1405
int error_recognition
Error recognition; higher values will detect more errors but may misdetect some more or less valid pa...
Definition avformat.h:1611
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:623
int min_distance
Minimum distance between this and the previous keyframe, used to avoid unneeded searching.
Definition avformat.h:634
int64_t timestamp
Timestamp in AVStream.time_base units, preferably the time from which on correctly decoded frames are...
Definition avformat.h:624
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:473
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:1121
unsigned int el_index
Index of the enhancement layer stream in AVStreamGroup.
Definition avformat.h:1105
int width
Width of the final stream for presentation.
Definition avformat.h:1117
unsigned int metadata_index
Index of the metadata stream in the AVStreamGroup.
Definition avformat.h:1146
AVStreamGroupTileGrid holds information on how to combine several independent images on a single canv...
Definition avformat.h:975
int nb_coded_side_data
Amount of entries in coded_side_data.
Definition avformat.h:1083
int width
Width of the final image for presentation.
Definition avformat.h:1060
int height
Height of the final image for presentation.
Definition avformat.h:1070
int coded_width
Width of the canvas.
Definition avformat.h:990
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:983
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:1034
int horizontal
Offset in pixels from the left edge of the canvas where the tile should be placed.
Definition avformat.h:1019
unsigned int idx
Index of the stream in the group this tile references.
Definition avformat.h:1014
int coded_height
Width of the canvas.
Definition avformat.h:996
AVPacketSideData * coded_side_data
Additional data associated with the grid.
Definition avformat.h:1078
int vertical
Offset in pixels from the top edge of the canvas where the tile should be placed.
Definition avformat.h:1024
union AVStreamGroup::@166361102046003066253145020066347265153020354020 params
Group type-specific parameters.
enum AVStreamGroupParamsType type
Group type.
Definition avformat.h:1190
struct AVIAMFMixPresentation * iamf_mix_presentation
Definition avformat.h:1197
struct AVStreamGroupTileGrid * tile_grid
Definition avformat.h:1198
unsigned int nb_streams
Number of elements in AVStreamGroup.streams.
Definition avformat.h:1225
struct AVStreamGroupTREF * tref
Definition avformat.h:1207
AVDictionary * metadata
Metadata that applies to the whole group.
Definition avformat.h:1218
struct AVIAMFAudioElement * iamf_audio_element
Definition avformat.h:1196
int disposition
Stream group disposition - a combination of AV_DISPOSITION_* flags.
Definition avformat.h:1248
int64_t id
Group type-specific group ID.
Definition avformat.h:1182
AVStream ** streams
A list of streams in the group.
Definition avformat.h:1238
struct AVStreamGroupLayeredVideo * layered_video
Definition avformat.h:1199
Stream structure.
Definition avformat.h:768
AVCodecParameters * codecpar
Codec parameters associated with this stream.
Definition avformat.h:791
AVRational sample_aspect_ratio
sample aspect ratio (0 if unknown)
Definition avformat.h:846
int64_t nb_frames
number of frames in this stream if known or 0
Definition avformat.h:829
enum AVDiscard discard
Selects which packets can be discarded at will and do not need to be demuxed.
Definition avformat.h:839
int64_t duration
Decoding: duration of the stream, in stream time base.
Definition avformat.h:827
AVDictionary * metadata
Definition avformat.h:848
void * priv_data
Definition avformat.h:793
int id
Format-specific stream ID.
Definition avformat.h:780
int index
stream index in AVFormatContext
Definition avformat.h:774
int64_t start_time
Decoding: pts of the first frame of the stream in presentation order, in stream time base.
Definition avformat.h:817
AVPacket attached_pic
For streams with AV_DISPOSITION_ATTACHED_PIC disposition, this packet will contain the attached pictu...
Definition avformat.h:866
AVRational avg_frame_rate
Average framerate.
Definition avformat.h:857
AVRational time_base
This is the fundamental unit of time (in seconds) in terms of which frame timestamps are represented.
Definition avformat.h:807
AVRational r_frame_rate
Real base framerate of the stream.
Definition avformat.h:902
int disposition
Stream disposition - a combination of AV_DISPOSITION_* flags.
Definition avformat.h:837
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:87
uint32_t type
Definition mov.c:86
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:500
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
int num
Definition error.c:23
static int ref[MAX_W *MAX_W]
static char buffer[20]
Definition seek.c:32
#define height
Definition dsp.h:99
#define width
Definition dsp.h:99
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]