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
1921 item = &c->frag_index.item[index];
1922 item->headers_read = 0;
1923 item->current = 0;
1924 item->nb_stream_info = c->fc->nb_streams;
1925 item->moof_offset = offset;
1926 item->stream_info = frag_stream_info;
1927 c->frag_index.nb_items++;
1928
1929 return index;
1930}
1931
1932static void fix_frag_index_entries(MOVFragmentIndex *frag_index, int index,
1933 int id, int entries)
1934{
1935 int i;
1936 MOVFragmentStreamInfo * frag_stream_info;
1937
1938 if (index < 0)
1939 return;
1940 for (i = index; i < frag_index->nb_items; i++) {
1941 frag_stream_info = get_frag_stream_info(frag_index, i, id);
1942 if (frag_stream_info && frag_stream_info->index_entry >= 0)
1943 frag_stream_info->index_entry += entries;
1944 }
1945}
1946
1948{
1949 // Set by mov_read_tfhd(). mov_read_trun() will reject files missing tfhd.
1950 c->fragment.found_tfhd = 0;
1951
1952 if (!c->has_looked_for_mfra && c->use_mfra_for > 0) {
1953 c->has_looked_for_mfra = 1;
1954 if (pb->seekable & AVIO_SEEKABLE_NORMAL) {
1955 int ret;
1956 av_log(c->fc, AV_LOG_VERBOSE, "stream has moof boxes, will look "
1957 "for a mfra\n");
1958 if ((ret = mov_read_mfra(c, pb)) < 0) {
1959 av_log(c->fc, AV_LOG_VERBOSE, "found a moof box but failed to "
1960 "read the mfra (may be a live ismv)\n");
1961 }
1962 } else {
1963 av_log(c->fc, AV_LOG_VERBOSE, "found a moof box but stream is not "
1964 "seekable, can not look for mfra\n");
1965 }
1966 }
1967 c->fragment.moof_offset = c->fragment.implicit_offset = avio_tell(pb) - 8;
1968 av_log(c->fc, AV_LOG_TRACE, "moof offset %"PRIx64"\n", c->fragment.moof_offset);
1969 c->frag_index.current = update_frag_index(c, c->fragment.moof_offset);
1970 return mov_read_default(c, pb, atom);
1971}
1972
1974{
1975 int64_t time;
1976 if (version == 1) {
1977 time = avio_rb64(pb);
1978 avio_rb64(pb);
1979 if (time < 0) {
1980 av_log(c->fc, AV_LOG_DEBUG, "creation_time is negative\n");
1981 return;
1982 }
1983 } else {
1984 time = avio_rb32(pb);
1985 avio_rb32(pb); /* modification time */
1986 if (time > 0 && time < 2082844800) {
1987 av_log(c->fc, AV_LOG_WARNING, "Detected creation time before 1970, parsing as unix timestamp.\n");
1988 time += 2082844800;
1989 }
1990 }
1991 if (time) {
1992 time -= 2082844800; /* seconds between 1904-01-01 and Epoch */
1993
1994 if ((int64_t)(time * 1000000ULL) / 1000000 != time) {
1995 av_log(c->fc, AV_LOG_DEBUG, "creation_time is not representable\n");
1996 return;
1997 }
1998
1999 ff_dict_set_timestamp(metadata, "creation_time", time * 1000000);
2000 }
2001}
2002
2004{
2005 AVStream *st;
2006 MOVStreamContext *sc;
2007 int version;
2008 char language[4] = {0};
2009 unsigned lang;
2010
2011 if (c->fc->nb_streams < 1)
2012 return 0;
2013 st = c->fc->streams[c->fc->nb_streams-1];
2014 sc = st->priv_data;
2015
2016 if (sc->time_scale) {
2017 av_log(c->fc, AV_LOG_ERROR, "Multiple mdhd?\n");
2018 return AVERROR_INVALIDDATA;
2019 }
2020
2021 version = avio_r8(pb);
2022 if (version > 1) {
2023 avpriv_request_sample(c->fc, "Version %d", version);
2024 return AVERROR_PATCHWELCOME;
2025 }
2026 avio_rb24(pb); /* flags */
2028
2029 sc->time_scale = avio_rb32(pb);
2030 if (sc->time_scale <= 0) {
2031 av_log(c->fc, AV_LOG_ERROR, "Invalid mdhd time scale %d, defaulting to 1\n", sc->time_scale);
2032 sc->time_scale = 1;
2033 }
2034 st->duration = (version == 1) ? avio_rb64(pb) : avio_rb32(pb); /* duration */
2035
2036 if ((version == 1 && st->duration == UINT64_MAX) ||
2037 (version != 1 && st->duration == UINT32_MAX)) {
2038 st->duration = 0;
2039 }
2040
2041 lang = avio_rb16(pb); /* language */
2042 if (ff_mov_lang_to_iso639(lang, language))
2043 av_dict_set(&st->metadata, "language", language, 0);
2044 avio_rb16(pb); /* quality */
2045
2046 return 0;
2047}
2048
2050{
2051 int i;
2052 int version = avio_r8(pb); /* version */
2053 avio_rb24(pb); /* flags */
2054
2055 mov_metadata_creation_time(c, pb, &c->fc->metadata, version);
2056 c->time_scale = avio_rb32(pb); /* time scale */
2057 if (c->time_scale <= 0) {
2058 av_log(c->fc, AV_LOG_ERROR, "Invalid mvhd time scale %d, defaulting to 1\n", c->time_scale);
2059 c->time_scale = 1;
2060 }
2061 av_log(c->fc, AV_LOG_TRACE, "time scale = %i\n", c->time_scale);
2062
2063 c->duration = (version == 1) ? avio_rb64(pb) : avio_rb32(pb); /* duration */
2064 avio_rb32(pb); /* preferred scale */
2065
2066 avio_rb16(pb); /* preferred volume */
2067
2068 avio_skip(pb, 10); /* reserved */
2069
2070 /* movie display matrix, store it in main context and use it later on */
2071 for (i = 0; i < 3; i++) {
2072 c->movie_display_matrix[i][0] = avio_rb32(pb); // 16.16 fixed point
2073 c->movie_display_matrix[i][1] = avio_rb32(pb); // 16.16 fixed point
2074 c->movie_display_matrix[i][2] = avio_rb32(pb); // 2.30 fixed point
2075 }
2076
2077 avio_rb32(pb); /* preview time */
2078 avio_rb32(pb); /* preview duration */
2079 avio_rb32(pb); /* poster time */
2080 avio_rb32(pb); /* selection time */
2081 avio_rb32(pb); /* selection duration */
2082 avio_rb32(pb); /* current time */
2083 avio_rb32(pb); /* next track ID */
2084
2085 return 0;
2086}
2087
2089{
2090 AVStream *st;
2091
2092 if (fc->nb_streams < 1)
2093 return;
2094 st = fc->streams[fc->nb_streams-1];
2095
2096 switch (st->codecpar->codec_id) {
2099 break;
2102 break;
2105 break;
2108 break;
2111 break;
2112 default:
2113 break;
2114 }
2115}
2116
2118{
2119 int little_endian = avio_rb16(pb) & 0xFF;
2120 av_log(c->fc, AV_LOG_TRACE, "enda %d\n", little_endian);
2121 if (little_endian == 1)
2123 return 0;
2124}
2125
2127{
2128 int format_flags;
2129 int version, flags;
2130 int pcm_sample_size;
2131 AVFormatContext *fc = c->fc;
2132 AVStream *st;
2133 MOVStreamContext *sc;
2134
2135 if (atom.size < 6) {
2136 av_log(c->fc, AV_LOG_ERROR, "Empty pcmC box\n");
2137 return AVERROR_INVALIDDATA;
2138 }
2139
2140 version = avio_r8(pb);
2141 flags = avio_rb24(pb);
2142
2143 if (version != 0 || flags != 0) {
2144 av_log(c->fc, AV_LOG_ERROR,
2145 "Unsupported 'pcmC' box with version %d, flags: %x",
2146 version, flags);
2147 return AVERROR_INVALIDDATA;
2148 }
2149
2150 format_flags = avio_r8(pb);
2151 pcm_sample_size = avio_r8(pb);
2152
2153 if (fc->nb_streams < 1)
2154 return AVERROR_INVALIDDATA;
2155
2156 st = fc->streams[fc->nb_streams - 1];
2157 sc = st->priv_data;
2158
2159 if (sc->format == MOV_MP4_FPCM_TAG) {
2160 switch (pcm_sample_size) {
2161 case 32:
2163 break;
2164 case 64:
2166 break;
2167 default:
2168 av_log(fc, AV_LOG_ERROR, "invalid pcm_sample_size %d for %s\n",
2169 pcm_sample_size,
2170 av_fourcc2str(sc->format));
2171 return AVERROR_INVALIDDATA;
2172 }
2173 } else if (sc->format == MOV_MP4_IPCM_TAG) {
2174 switch (pcm_sample_size) {
2175 case 16:
2177 break;
2178 case 24:
2180 break;
2181 case 32:
2183 break;
2184 default:
2185 av_log(fc, AV_LOG_ERROR, "invalid pcm_sample_size %d for %s\n",
2186 pcm_sample_size,
2187 av_fourcc2str(sc->format));
2188 return AVERROR_INVALIDDATA;
2189 }
2190 } else {
2191 av_log(fc, AV_LOG_ERROR, "'pcmC' with invalid sample entry '%s'\n",
2192 av_fourcc2str(sc->format));
2193 return AVERROR_INVALIDDATA;
2194 }
2195
2196 if (format_flags & 1) // indicates little-endian format. If not present, big-endian format is used
2199
2200 return 0;
2201}
2202
2204{
2205 AVStream *st;
2206 HEIFItem *item = NULL;
2207 char color_parameter_type[5] = { 0 };
2208 uint16_t color_primaries, color_trc, color_matrix;
2209 int ret;
2210
2211 st = get_curr_st(c);
2212 if (!st) {
2213 item = get_heif_item(c, c->cur_item_id);
2214 if (!item)
2215 return 0;
2216 }
2217
2218 ret = ffio_read_size(pb, color_parameter_type, 4);
2219 if (ret < 0)
2220 return ret;
2221 if (strncmp(color_parameter_type, "nclx", 4) &&
2222 strncmp(color_parameter_type, "nclc", 4) &&
2223 strncmp(color_parameter_type, "prof", 4)) {
2224 av_log(c->fc, AV_LOG_WARNING, "unsupported color_parameter_type %s\n",
2225 color_parameter_type);
2226 return 0;
2227 }
2228
2229 if (!strncmp(color_parameter_type, "prof", 4)) {
2230 AVPacketSideData *sd;
2231 uint8_t *icc_profile;
2232 if (st) {
2236 atom.size - 4, 0);
2237 if (!sd)
2238 return AVERROR(ENOMEM);
2239 icc_profile = sd->data;
2240 } else {
2241 if (c->heif_icc_profile_items >= c->fc->max_streams) {
2242 av_log(c->fc, AV_LOG_WARNING,
2243 "HEIF ICC profile copies exceed cap %d; ignoring further items\n",
2244 c->fc->max_streams);
2245 return 0;
2246 }
2247 av_freep(&item->icc_profile);
2248 icc_profile = item->icc_profile = av_malloc(atom.size - 4);
2249 if (!icc_profile) {
2250 item->icc_profile_size = 0;
2251 return AVERROR(ENOMEM);
2252 }
2253 item->icc_profile_size = atom.size - 4;
2254 c->heif_icc_profile_items++;
2255 }
2256 ret = ffio_read_size(pb, icc_profile, atom.size - 4);
2257 if (ret < 0)
2258 return ret;
2259 } else if (st) {
2261 color_trc = avio_rb16(pb);
2262 color_matrix = avio_rb16(pb);
2263
2264 av_log(c->fc, AV_LOG_TRACE,
2265 "%s: pri %d trc %d matrix %d",
2266 color_parameter_type, color_primaries, color_trc, color_matrix);
2267
2268 if (!strncmp(color_parameter_type, "nclx", 4)) {
2269 uint8_t color_range = avio_r8(pb) >> 7;
2270 av_log(c->fc, AV_LOG_TRACE, " full %"PRIu8"", color_range);
2271 if (color_range)
2273 else
2275 }
2276
2279 if (!av_color_transfer_name(color_trc))
2280 color_trc = AVCOL_TRC_UNSPECIFIED;
2281 if (!av_color_space_name(color_matrix))
2282 color_matrix = AVCOL_SPC_UNSPECIFIED;
2283
2285 st->codecpar->color_trc = color_trc;
2286 st->codecpar->color_space = color_matrix;
2287 av_log(c->fc, AV_LOG_TRACE, "\n");
2288 }
2289 return 0;
2290}
2291
2293{
2294 AVStream *st;
2295 unsigned mov_field_order;
2296 enum AVFieldOrder decoded_field_order = AV_FIELD_UNKNOWN;
2297
2298 if (c->fc->nb_streams < 1) // will happen with jp2 files
2299 return 0;
2300 st = c->fc->streams[c->fc->nb_streams-1];
2301 if (atom.size < 2)
2302 return AVERROR_INVALIDDATA;
2303 mov_field_order = avio_rb16(pb);
2304 if ((mov_field_order & 0xFF00) == 0x0100)
2305 decoded_field_order = AV_FIELD_PROGRESSIVE;
2306 else if ((mov_field_order & 0xFF00) == 0x0200) {
2307 switch (mov_field_order & 0xFF) {
2308 case 0x01: decoded_field_order = AV_FIELD_TT;
2309 break;
2310 case 0x06: decoded_field_order = AV_FIELD_BB;
2311 break;
2312 case 0x09: decoded_field_order = AV_FIELD_TB;
2313 break;
2314 case 0x0E: decoded_field_order = AV_FIELD_BT;
2315 break;
2316 }
2317 }
2318 if (decoded_field_order == AV_FIELD_UNKNOWN && mov_field_order) {
2319 av_log(c->fc, AV_LOG_ERROR, "Unknown MOV field order 0x%04x\n", mov_field_order);
2320 }
2321 st->codecpar->field_order = decoded_field_order;
2322
2323 return 0;
2324}
2325
2327{
2328 int err = 0;
2329 uint64_t size = (uint64_t)par->extradata_size + atom.size + 8 + AV_INPUT_BUFFER_PADDING_SIZE;
2330 if (size > INT_MAX || (uint64_t)atom.size > INT_MAX)
2331 return AVERROR_INVALIDDATA;
2332 if ((err = av_reallocp(&par->extradata, size)) < 0) {
2333 par->extradata_size = 0;
2334 return err;
2335 }
2337 return 0;
2338}
2339
2340/* Read a whole atom into the extradata return the size of the atom read, possibly truncated if != atom.size */
2342 AVCodecParameters *par, uint8_t *buf)
2343{
2344 int64_t result = atom.size;
2345 int err;
2346
2347 AV_WB32(buf , atom.size + 8);
2348 AV_WL32(buf + 4, atom.type);
2349 err = ffio_read_size(pb, buf + 8, atom.size);
2350 if (err < 0) {
2351 par->extradata_size -= atom.size;
2352 return err;
2353 } else if (err < atom.size) {
2354 av_log(c->fc, AV_LOG_WARNING, "truncated extradata\n");
2355 par->extradata_size -= atom.size - err;
2356 result = err;
2357 }
2358 memset(buf + 8 + err, 0, AV_INPUT_BUFFER_PADDING_SIZE);
2359 return result;
2360}
2361
2362/* FIXME modify QDM2/SVQ3/H.264 decoders to take full atom as extradata */
2364 enum AVCodecID codec_id)
2365{
2366 AVStream *st;
2367 uint64_t original_size;
2368 int err;
2369
2370 if (c->fc->nb_streams < 1) // will happen with jp2 files
2371 return 0;
2372 st = c->fc->streams[c->fc->nb_streams-1];
2373
2374 if (st->codecpar->codec_id != codec_id)
2375 return 0; /* unexpected codec_id - don't mess with extradata */
2376
2377 original_size = st->codecpar->extradata_size;
2378 err = mov_realloc_extradata(st->codecpar, atom);
2379 if (err)
2380 return err;
2381
2382 err = mov_read_atom_into_extradata(c, pb, atom, st->codecpar, st->codecpar->extradata + original_size);
2383 if (err < 0)
2384 return err;
2385 return 0; // Note: this is the original behavior to ignore truncation.
2386}
2387
2388/* wrapper functions for reading ALAC/AVS/MJPEG/MJPEG2000 extradata atoms only for those codecs */
2390{
2391 return mov_read_extradata(c, pb, atom, AV_CODEC_ID_ALAC);
2392}
2393
2395{
2396 return mov_read_extradata(c, pb, atom, AV_CODEC_ID_CAVS);
2397}
2398
2400{
2401 return mov_read_extradata(c, pb, atom, AV_CODEC_ID_JPEG2000);
2402}
2403
2405{
2406 return mov_read_extradata(c, pb, atom, AV_CODEC_ID_R10K);
2407}
2408
2410{
2411 int ret = mov_read_extradata(c, pb, atom, AV_CODEC_ID_AVUI);
2412 if (!ret)
2413 ret = mov_read_extradata(c, pb, atom, AV_CODEC_ID_DNXHD);
2414 return ret;
2415}
2416
2418{
2419 int ret = mov_read_extradata(c, pb, atom, AV_CODEC_ID_TARGA_Y216);
2420
2421 if (!ret && c->fc->nb_streams >= 1) {
2422 AVCodecParameters *par = c->fc->streams[c->fc->nb_streams-1]->codecpar;
2423 if (par->extradata_size >= 40) {
2424 par->height = AV_RB16(&par->extradata[36]);
2425 par->width = AV_RB16(&par->extradata[38]);
2426 }
2427 }
2428 return ret;
2429}
2430
2432{
2433 if (c->fc->nb_streams >= 1) {
2434 AVStream *const st = c->fc->streams[c->fc->nb_streams - 1];
2435 FFStream *const sti = ffstream(st);
2436 AVCodecParameters *par = st->codecpar;
2437
2438 if (par->codec_tag == MKTAG('A', 'V', 'i', 'n') &&
2439 par->codec_id == AV_CODEC_ID_H264 &&
2440 atom.size > 11) {
2441 int cid;
2442 avio_skip(pb, 10);
2443 cid = avio_rb16(pb);
2444 /* For AVID AVCI50, force width of 1440 to be able to select the correct SPS and PPS */
2445 if (cid == 0xd4d || cid == 0xd4e)
2446 par->width = 1440;
2447 return 0;
2448 } else if ((par->codec_tag == MKTAG('A', 'V', 'd', '1') ||
2449 par->codec_tag == MKTAG('A', 'V', 'j', '2') ||
2450 par->codec_tag == MKTAG('A', 'V', 'd', 'n')) &&
2451 atom.size >= 24) {
2452 int num, den;
2453 avio_skip(pb, 12);
2454 num = avio_rb32(pb);
2455 den = avio_rb32(pb);
2456 if (num <= 0 || den <= 0)
2457 return 0;
2458 switch (avio_rb32(pb)) {
2459 case 2:
2460 if (den >= INT_MAX / 2)
2461 return 0;
2462 den *= 2;
2464 case 1:
2465 sti->display_aspect_ratio = (AVRational){ num, den };
2467 default:
2468 return 0;
2469 }
2470 }
2471 }
2472
2473 return mov_read_avid(c, pb, atom);
2474}
2475
2477{
2478 int ret = 0;
2479 int length = 0;
2480 uint64_t original_size;
2481 if (c->fc->nb_streams >= 1) {
2482 AVCodecParameters *par = c->fc->streams[c->fc->nb_streams-1]->codecpar;
2483 if (par->codec_id == AV_CODEC_ID_H264)
2484 return 0;
2485 if (atom.size == 16) {
2486 original_size = par->extradata_size;
2487 ret = mov_realloc_extradata(par, atom);
2488 if (!ret) {
2489 length = mov_read_atom_into_extradata(c, pb, atom, par, par->extradata + original_size);
2490 if (length == atom.size) {
2491 const uint8_t range_value = par->extradata[original_size + 19];
2492 switch (range_value) {
2493 case 1:
2495 break;
2496 case 2:
2498 break;
2499 default:
2500 av_log(c->fc, AV_LOG_WARNING, "ignored unknown aclr value (%d)\n", range_value);
2501 break;
2502 }
2503 ff_dlog(c->fc, "color_range: %d\n", par->color_range);
2504 } else {
2505 /* For some reason the whole atom was not added to the extradata */
2506 av_log(c->fc, AV_LOG_ERROR, "aclr not decoded - incomplete atom\n");
2507 }
2508 } else {
2509 av_log(c->fc, AV_LOG_ERROR, "aclr not decoded - unable to add atom to extradata\n");
2510 }
2511 } else {
2512 av_log(c->fc, AV_LOG_WARNING, "aclr not decoded - unexpected size %"PRId64"\n", atom.size);
2513 }
2514 }
2515
2516 return ret;
2517}
2518
2520{
2521 return mov_read_extradata(c, pb, atom, AV_CODEC_ID_SVQ3);
2522}
2523
2525{
2526 AVStream *st;
2527 int ret;
2528
2529 if (c->fc->nb_streams < 1)
2530 return 0;
2531 st = c->fc->streams[c->fc->nb_streams-1];
2532
2533 if ((uint64_t)atom.size > (1<<30))
2534 return AVERROR_INVALIDDATA;
2535
2536 if (st->codecpar->codec_id == AV_CODEC_ID_QDM2 ||
2539 // pass all frma atom to codec, needed at least for QDMC and QDM2
2540 ret = ff_get_extradata(c->fc, st->codecpar, pb, atom.size);
2541 if (ret < 0)
2542 return ret;
2543 } else if (atom.size > 8) { /* to read frma, esds atoms */
2544 if (st->codecpar->codec_id == AV_CODEC_ID_ALAC && atom.size >= 24) {
2545 uint64_t buffer;
2546 ret = ffio_ensure_seekback(pb, 8);
2547 if (ret < 0)
2548 return ret;
2549 buffer = avio_rb64(pb);
2550 atom.size -= 8;
2551 if ( (buffer & 0xFFFFFFFF) == MKBETAG('f','r','m','a')
2552 && buffer >> 32 <= atom.size
2553 && buffer >> 32 >= 8) {
2554 avio_skip(pb, -8);
2555 atom.size += 8;
2556 } else if (!st->codecpar->extradata_size) {
2557#define ALAC_EXTRADATA_SIZE 36
2559 if (!st->codecpar->extradata)
2560 return AVERROR(ENOMEM);
2563 AV_WB32(st->codecpar->extradata + 4, MKTAG('a','l','a','c'));
2564 AV_WB64(st->codecpar->extradata + 12, buffer);
2565 avio_read(pb, st->codecpar->extradata + 20, 16);
2566 avio_skip(pb, atom.size - 24);
2567 return 0;
2568 }
2569 }
2570 if ((ret = mov_read_default(c, pb, atom)) < 0)
2571 return ret;
2572 } else
2573 avio_skip(pb, atom.size);
2574 return 0;
2575}
2576
2577/**
2578 * This function reads atom content and puts data in extradata without tag
2579 * nor size unlike mov_read_extradata.
2580 */
2582{
2583 AVStream *st;
2584 int ret;
2585
2586 st = get_curr_st(c);
2587 if (!st)
2588 return 0;
2589
2590 if ((uint64_t)atom.size > (1<<30))
2591 return AVERROR_INVALIDDATA;
2592
2593 if (atom.type == MKTAG('v','v','c','C')) {
2594 avio_skip(pb, 4);
2595 atom.size -= 4;
2596 }
2597
2598 if (atom.size >= 10) {
2599 // Broken files created by legacy versions of libavformat will
2600 // wrap a whole fiel atom inside of a glbl atom.
2601 unsigned size = avio_rb32(pb);
2602 unsigned type = avio_rl32(pb);
2603 if (avio_feof(pb))
2604 return AVERROR_INVALIDDATA;
2605 avio_seek(pb, -8, SEEK_CUR);
2606 if (type == MKTAG('f','i','e','l') && size == atom.size)
2607 return mov_read_default(c, pb, atom);
2608 }
2609 if (st->codecpar->extradata_size > 1 && st->codecpar->extradata) {
2610 av_log(c->fc, AV_LOG_WARNING, "ignoring multiple glbl\n");
2611 return 0;
2612 }
2613 ret = ff_get_extradata(c->fc, st->codecpar, pb, atom.size);
2614 if (ret < 0)
2615 return ret;
2616 if (atom.type == MKTAG('h','v','c','C') && st->codecpar->codec_tag == MKTAG('d','v','h','1'))
2617 /* HEVC-based Dolby Vision derived from hvc1.
2618 Happens to match with an identifier
2619 previously utilized for DV. Thus, if we have
2620 the hvcC extradata box available as specified,
2621 set codec to HEVC */
2623
2624 return 0;
2625}
2626
2628{
2629 AVStream *st;
2630 uint8_t profile_level;
2631 int ret;
2632
2633 if (c->fc->nb_streams < 1)
2634 return 0;
2635 st = c->fc->streams[c->fc->nb_streams-1];
2636
2637 if (atom.size >= (1<<28) || atom.size < 7)
2638 return AVERROR_INVALIDDATA;
2639
2640 profile_level = avio_r8(pb);
2641 if ((profile_level & 0xf0) != 0xc0)
2642 return 0;
2643
2644 avio_seek(pb, 6, SEEK_CUR);
2645 ret = ff_get_extradata(c->fc, st->codecpar, pb, atom.size - 7);
2646 if (ret < 0)
2647 return ret;
2648
2649 return 0;
2650}
2651
2652static int mov_find_tref_id(const MovTref *tag, uint32_t id)
2653{
2654 for (int i = 0; i < tag->nb_id; i++) {
2655 if (tag->id[i] == id)
2656 return 1;
2657 }
2658 return 0;
2659}
2660
2661static int mov_add_tref_id(MovTref *tag, uint32_t id)
2662{
2663 int ret = mov_find_tref_id(tag, id);
2664
2665 if (!ret) {
2666 uint32_t *tmp = av_realloc_array(tag->id, tag->nb_id + 1, sizeof(*tag->id));
2667 if (!tmp)
2668 return AVERROR(ENOMEM);
2669 tag->id = tmp;
2670 tag->id[tag->nb_id++] = id;
2671 }
2672
2673 return 0;
2674}
2675
2677{
2678 for (int i = 0; i < sc->nb_tref_tags; i++) {
2679 MovTref *entry = &sc->tref_tags[i];
2680
2681 if (entry->name == name)
2682 return entry;
2683 }
2684 return NULL;
2685}
2686
2688{
2690
2691 if (!tag) {
2693 sizeof(*sc->tref_tags));
2694 if (!tmp)
2695 return NULL;
2696 sc->tref_tags = tmp;
2697 tag = &sc->tref_tags[sc->nb_tref_tags++];
2698 *tag = (MovTref){ .name = name };
2699 }
2700
2701 return tag;
2702}
2703
2705{
2706 AVStream* st;
2707 MOVStreamContext* sc;
2708
2709 if (c->fc->nb_streams < 1)
2710 return 0;
2711
2712 if (atom.size > 4) {
2713 av_log(c->fc, AV_LOG_ERROR, "Only a single tref of type cdsc/rndr is supported\n");
2714 return AVERROR_PATCHWELCOME;
2715 }
2716 if (atom.size < 4)
2717 return AVERROR_INVALIDDATA;
2718
2719 st = get_curr_st(c);
2720 if (!st)
2721 return AVERROR_INVALIDDATA;
2722 sc = st->priv_data;
2723
2724 MovTref *tag = mov_add_tref_tag(sc, atom.type);
2725 if (!tag)
2726 return AVERROR(ENOMEM);
2727
2728 int ret = mov_add_tref_id(tag, avio_rb32(pb));
2729 if (ret < 0)
2730 return ret;
2731
2732 return 0;
2733}
2734
2736{
2737 AVStream* st;
2738 MOVStreamContext* sc;
2739
2740 if (c->fc->nb_streams < 1)
2741 return 0;
2742
2743 /* For SBAS this should be fine - though beware if someone implements a
2744 * tref atom processor that doesn't drop down to default then this may
2745 * be lost. */
2746 if (atom.size > 4) {
2747 av_log(c->fc, AV_LOG_ERROR, "Only a single tref of type sbas is supported\n");
2748 return AVERROR_PATCHWELCOME;
2749 }
2750 if (atom.size < 4)
2751 return AVERROR_INVALIDDATA;
2752
2753 st = c->fc->streams[c->fc->nb_streams - 1];
2754 sc = st->priv_data;
2755
2756 MovTref *tag = mov_add_tref_tag(sc, atom.type);
2757 if (!tag)
2758 return AVERROR(ENOMEM);
2759
2760 int ret = mov_add_tref_id(tag, avio_rb32(pb));
2761 if (ret < 0)
2762 return ret;
2763
2764 return 0;
2765}
2766
2768{
2769 AVStream* st;
2770 MOVStreamContext* sc;
2771
2772 if (c->fc->nb_streams < 1)
2773 return 0;
2774
2775 if (atom.size > 4)
2776 av_log(c->fc, AV_LOG_WARNING, "More than one vdep reference is not supported.\n");
2777 if (atom.size < 4)
2778 return AVERROR_INVALIDDATA;
2779
2780 st = c->fc->streams[c->fc->nb_streams - 1];
2781 sc = st->priv_data;
2782
2783 MovTref *tag = mov_add_tref_tag(sc, atom.type);
2784 if (!tag)
2785 return AVERROR(ENOMEM);
2786
2787 int ret = mov_add_tref_id(tag, avio_rb32(pb));
2788 if (ret < 0)
2789 return ret;
2790
2791 return 0;
2792}
2793
2794/**
2795 * An strf atom is a BITMAPINFOHEADER struct. This struct is 40 bytes itself,
2796 * but can have extradata appended at the end after the 40 bytes belonging
2797 * to the struct.
2798 */
2800{
2801 AVStream *st;
2802 int ret;
2803
2804 if (c->fc->nb_streams < 1)
2805 return 0;
2806 if (atom.size <= 40)
2807 return 0;
2808 st = c->fc->streams[c->fc->nb_streams-1];
2809
2810 if ((uint64_t)atom.size > (1<<30))
2811 return AVERROR_INVALIDDATA;
2812
2813 avio_skip(pb, 40);
2814 ret = ff_get_extradata(c->fc, st->codecpar, pb, atom.size - 40);
2815 if (ret < 0)
2816 return ret;
2817
2818 return 0;
2819}
2820
2822{
2823 AVStream *st;
2824 MOVStreamContext *sc;
2825 unsigned int i, entries;
2826
2827 if (c->trak_index < 0) {
2828 av_log(c->fc, AV_LOG_WARNING, "STCO outside TRAK\n");
2829 return 0;
2830 }
2831 if (c->fc->nb_streams < 1)
2832 return 0;
2833 st = c->fc->streams[c->fc->nb_streams-1];
2834 sc = st->priv_data;
2835
2836 avio_r8(pb); /* version */
2837 avio_rb24(pb); /* flags */
2838
2839 // Clamp allocation size for `chunk_offsets` -- don't throw an error for an
2840 // invalid count since the EOF path doesn't throw either.
2841 entries = avio_rb32(pb);
2842 entries =
2843 FFMIN(entries,
2844 FFMAX(0, (atom.size - 8) /
2845 (atom.type == MKTAG('s', 't', 'c', 'o') ? 4 : 8)));
2846
2847 if (!entries)
2848 return 0;
2849
2850 if (sc->chunk_offsets) {
2851 av_log(c->fc, AV_LOG_WARNING, "Ignoring duplicated STCO atom\n");
2852 return 0;
2853 }
2854
2856 sc->chunk_count = 0;
2857 sc->chunk_offsets = av_malloc_array(entries, sizeof(*sc->chunk_offsets));
2858 if (!sc->chunk_offsets)
2859 return AVERROR(ENOMEM);
2860 sc->chunk_count = entries;
2861
2862 if (atom.type == MKTAG('s','t','c','o'))
2863 for (i = 0; i < entries && !pb->eof_reached; i++)
2864 sc->chunk_offsets[i] = avio_rb32(pb);
2865 else if (atom.type == MKTAG('c','o','6','4'))
2866 for (i = 0; i < entries && !pb->eof_reached; i++) {
2867 sc->chunk_offsets[i] = avio_rb64(pb);
2868 if (sc->chunk_offsets[i] < 0) {
2869 av_log(c->fc, AV_LOG_WARNING, "Impossible chunk_offset\n");
2870 sc->chunk_offsets[i] = 0;
2871 }
2872 }
2873 else
2874 return AVERROR_INVALIDDATA;
2875
2876 sc->chunk_count = i;
2877
2878 if (pb->eof_reached) {
2879 av_log(c->fc, AV_LOG_WARNING, "reached eof, corrupted STCO atom\n");
2880 return AVERROR_EOF;
2881 }
2882
2883 return 0;
2884}
2885
2886static int mov_codec_id(AVStream *st, uint32_t format)
2887{
2889
2890 if (id <= 0 &&
2891 ((format & 0xFFFF) == 'm' + ('s' << 8) ||
2892 (format & 0xFFFF) == 'T' + ('S' << 8)))
2894
2895 if (st->codecpar->codec_type != AVMEDIA_TYPE_VIDEO && id > 0) {
2897 } else if (st->codecpar->codec_type != AVMEDIA_TYPE_AUDIO &&
2898 /* skip old ASF MPEG-4 tag */
2899 format && format != MKTAG('m','p','4','s')) {
2901 if (id <= 0)
2903 if (id > 0)
2905 else if (st->codecpar->codec_type == AVMEDIA_TYPE_DATA ||
2909 if (id <= 0) {
2912 }
2913
2914 if (id > 0)
2916 else
2918 }
2919 }
2920
2921 st->codecpar->codec_tag = format;
2922
2923 return id;
2924}
2925
2927 AVStream *st, MOVStreamContext *sc)
2928{
2929 uint8_t codec_name[32] = { 0 };
2930 int64_t stsd_start;
2931 unsigned int len;
2932 uint32_t id = 0;
2933
2934 /* The first 16 bytes of the video sample description are already
2935 * read in ff_mov_read_stsd_entries() */
2936 stsd_start = avio_tell(pb) - 16;
2937
2938 if (c->isom) {
2939 avio_skip(pb, 2); /* pre_defined */
2940 avio_skip(pb, 2); /* reserved */
2941 avio_skip(pb, 12); /* pre_defined */
2942 } else {
2943 avio_rb16(pb); /* version */
2944 avio_rb16(pb); /* revision level */
2945 id = avio_rl32(pb); /* vendor */
2946 av_dict_set(&st->metadata, "vendor_id", av_fourcc2str(id), 0);
2947 avio_rb32(pb); /* temporal quality */
2948 avio_rb32(pb); /* spatial quality */
2949 }
2950
2951 st->codecpar->width = avio_rb16(pb); /* width */
2952 st->codecpar->height = avio_rb16(pb); /* height */
2953
2954 avio_rb32(pb); /* horiz resolution */
2955 avio_rb32(pb); /* vert resolution */
2956 avio_rb32(pb); /* data size, always 0 */
2957 avio_rb16(pb); /* frames per samples */
2958
2959 len = avio_r8(pb); /* codec name, pascal string */
2960 if (len > 31)
2961 len = 31;
2962 mov_read_mac_string(c, pb, len, codec_name, sizeof(codec_name));
2963 if (len < 31)
2964 avio_skip(pb, 31 - len);
2965
2966 if (codec_name[0])
2967 av_dict_set(&st->metadata, "encoder", codec_name, 0);
2968
2969 /* codec_tag YV12 triggers an UV swap in rawdec.c */
2970 if (!strncmp(codec_name, "Planar Y'CbCr 8-bit 4:2:0", 25)) {
2971 st->codecpar->codec_tag = MKTAG('I', '4', '2', '0');
2972 st->codecpar->width &= ~1;
2973 st->codecpar->height &= ~1;
2974 }
2975 /* Flash Media Server uses tag H.263 with Sorenson Spark */
2976 if (st->codecpar->codec_tag == MKTAG('H','2','6','3') &&
2977 !strncmp(codec_name, "Sorenson H263", 13))
2979
2980 st->codecpar->bits_per_coded_sample = avio_rb16(pb); /* depth */
2981
2982 avio_seek(pb, stsd_start, SEEK_SET);
2983
2984 if (ff_get_qtpalette(st->codecpar->codec_id, pb, sc->palette)) {
2985 st->codecpar->bits_per_coded_sample &= 0x1F;
2986 sc->has_palette = 1;
2987 }
2988}
2989
2991 AVStream *st, MOVStreamContext *sc)
2992{
2993 int bits_per_sample, flags;
2994 uint16_t version = avio_rb16(pb);
2995 uint32_t id = 0;
2996 AVDictionaryEntry *compatible_brands = av_dict_get(c->fc->metadata, "compatible_brands", NULL, AV_DICT_MATCH_CASE);
2997 int channel_count;
2998
2999 if (c->isom)
3000 avio_skip(pb, 6); /* reserved */
3001 else {
3002 avio_rb16(pb); /* revision level */
3003 id = avio_rl32(pb); /* vendor */
3004 av_dict_set(&st->metadata, "vendor_id", av_fourcc2str(id), 0);
3005 }
3006
3007 channel_count = avio_rb16(pb);
3008
3010 st->codecpar->ch_layout.nb_channels = channel_count;
3011 st->codecpar->bits_per_coded_sample = avio_rb16(pb); /* sample size */
3012 av_log(c->fc, AV_LOG_TRACE, "audio channels %d\n", channel_count);
3013
3014 sc->audio_cid = avio_rb16(pb);
3015 avio_rb16(pb); /* packet size = 0 */
3016
3017 st->codecpar->sample_rate = ((avio_rb32(pb) >> 16));
3018
3019 // Read QT version 1 fields. In version 0 these do not exist.
3020 av_log(c->fc, AV_LOG_TRACE, "version =%d, isom =%d\n", version, c->isom);
3021 if (!c->isom ||
3022 (compatible_brands && strstr(compatible_brands->value, "qt ")) ||
3023 (sc->stsd_version == 0 && version > 0)) {
3024 if (version == 1) {
3025 sc->samples_per_frame = avio_rb32(pb);
3026 avio_rb32(pb); /* bytes per packet */
3027 sc->bytes_per_frame = avio_rb32(pb);
3028 avio_rb32(pb); /* bytes per sample */
3029 } else if (version == 2) {
3030 avio_rb32(pb); /* sizeof struct only */
3032 channel_count = avio_rb32(pb);
3034 st->codecpar->ch_layout.nb_channels = channel_count;
3035 avio_rb32(pb); /* always 0x7F000000 */
3037
3038 flags = avio_rb32(pb); /* lpcm format specific flag */
3039 sc->bytes_per_frame = avio_rb32(pb);
3040 sc->samples_per_frame = avio_rb32(pb);
3041 if (st->codecpar->codec_tag == MKTAG('l','p','c','m'))
3042 st->codecpar->codec_id =
3044 flags);
3045 }
3046 if (version == 0 || (version == 1 && sc->audio_cid != -2)) {
3047 /* can't correctly handle variable sized packet as audio unit */
3048 switch (st->codecpar->codec_id) {
3049 case AV_CODEC_ID_MP2:
3050 case AV_CODEC_ID_MP3:
3052 break;
3053 }
3054 }
3055 }
3056
3057 if (sc->format == 0) {
3058 if (st->codecpar->bits_per_coded_sample == 8)
3059 st->codecpar->codec_id = mov_codec_id(st, MKTAG('r','a','w',' '));
3060 else if (st->codecpar->bits_per_coded_sample == 16)
3061 st->codecpar->codec_id = mov_codec_id(st, MKTAG('t','w','o','s'));
3062 }
3063
3064 switch (st->codecpar->codec_id) {
3065 case AV_CODEC_ID_PCM_S8:
3066 case AV_CODEC_ID_PCM_U8:
3067 if (st->codecpar->bits_per_coded_sample == 16)
3069 break;
3072 if (st->codecpar->bits_per_coded_sample == 8)
3074 else if (st->codecpar->bits_per_coded_sample == 24)
3075 st->codecpar->codec_id =
3078 else if (st->codecpar->bits_per_coded_sample == 32)
3079 st->codecpar->codec_id =
3082 break;
3083 /* set values for old format before stsd version 1 appeared */
3084 case AV_CODEC_ID_MACE3:
3085 sc->samples_per_frame = 6;
3087 break;
3088 case AV_CODEC_ID_MACE6:
3089 sc->samples_per_frame = 6;
3091 break;
3093 sc->samples_per_frame = 64;
3095 break;
3096 case AV_CODEC_ID_GSM:
3097 sc->samples_per_frame = 160;
3098 sc->bytes_per_frame = 33;
3099 break;
3100 default:
3101 break;
3102 }
3103
3104 bits_per_sample = av_get_bits_per_sample(st->codecpar->codec_id);
3105 if (bits_per_sample && (bits_per_sample >> 3) * (uint64_t)st->codecpar->ch_layout.nb_channels <= INT_MAX) {
3106 st->codecpar->bits_per_coded_sample = bits_per_sample;
3107 sc->sample_size = (bits_per_sample >> 3) * st->codecpar->ch_layout.nb_channels;
3108 }
3109}
3110
3112 AVStream *st, MOVStreamContext *sc,
3113 int64_t size)
3114{
3115 // ttxt stsd contains display flags, justification, background
3116 // color, fonts, and default styles, so fake an atom to read it
3117 MOVAtom fake_atom = { .size = size };
3118 // mp4s contains a regular esds atom, dfxp ISMV TTML has no content
3119 // in extradata unlike stpp MP4 TTML.
3120 if (st->codecpar->codec_tag != AV_RL32("mp4s") &&
3122 mov_read_glbl(c, pb, fake_atom);
3123 st->codecpar->width = sc->width;
3124 st->codecpar->height = sc->height;
3125}
3126
3128 AVStream *st, MOVStreamContext *sc,
3129 int64_t size)
3130{
3131 int ret;
3132
3133 if (st->codecpar->codec_tag == MKTAG('t','m','c','d')) {
3134 if ((int)size != size)
3135 return AVERROR(ENOMEM);
3136
3137 ret = ff_get_extradata(c->fc, st->codecpar, pb, size);
3138 if (ret < 0)
3139 return ret;
3140 if (size > 16) {
3141 MOVStreamContext *tmcd_ctx = st->priv_data;
3142 int val;
3143 val = AV_RB32(st->codecpar->extradata + 4);
3144 tmcd_ctx->tmcd_flags = val;
3145 st->avg_frame_rate.num = AV_RB32(st->codecpar->extradata + 8); /* timescale */
3146 st->avg_frame_rate.den = AV_RB32(st->codecpar->extradata + 12); /* frameDuration */
3147 tmcd_ctx->tmcd_nb_frames = st->codecpar->extradata[16]; /* number of frames */
3148 if (size > 30) {
3149 uint32_t len = AV_RB32(st->codecpar->extradata + 18); /* name atom length */
3150 uint32_t format = AV_RB32(st->codecpar->extradata + 22);
3151 if (format == AV_RB32("name") && (int64_t)size >= (int64_t)len + 18) {
3152 uint16_t str_size = AV_RB16(st->codecpar->extradata + 26); /* string length */
3153 if (str_size > 0 && size >= (int)str_size + 30 &&
3154 st->codecpar->extradata[30] /* Don't add empty string */) {
3155 char *reel_name = av_malloc(str_size + 1);
3156 if (!reel_name)
3157 return AVERROR(ENOMEM);
3158 memcpy(reel_name, st->codecpar->extradata + 30, str_size);
3159 reel_name[str_size] = 0; /* Add null terminator */
3160 av_dict_set(&st->metadata, "reel_name", reel_name,
3162 }
3163 }
3164 }
3165 }
3166 } else if (st->codecpar->codec_id == AV_CODEC_ID_ITUT_T35) {
3167 int t35_identifier_length = avio_r8(pb);
3168
3169 if (t35_identifier_length <= 0 || t35_identifier_length >= size)
3170 return AVERROR_INVALIDDATA;
3171
3172 ret = ff_get_extradata(c->fc, st->codecpar, pb, t35_identifier_length);
3173 if (ret < 0)
3174 return ret;
3175
3176 int hrsd_len = size - t35_identifier_length - 1;
3177 if (hrsd_len > 0) {
3178 uint8_t *hrsd_str = av_malloc(hrsd_len + 1);
3179 if (!hrsd_str)
3180 return AVERROR(ENOMEM);
3181
3182 ret = ffio_read_size(pb, hrsd_str, hrsd_len);
3183 if (ret < 0) {
3184 av_free(hrsd_str);
3185 return ret;
3186 }
3187 if (hrsd_str[0]) {
3188 hrsd_str[hrsd_len] = 0;
3189 ret = av_dict_set(&st->metadata, "description", hrsd_str, AV_DICT_DONT_OVERWRITE);
3190 }
3191 av_free(hrsd_str);
3192 }
3193 } else {
3194 /* other codec type, just skip (rtp, mp4s ...) */
3195 avio_skip(pb, size);
3196 }
3197 return 0;
3198}
3199
3201 AVStream *st, MOVStreamContext *sc)
3202{
3203 FFStream *const sti = ffstream(st);
3204
3206 !st->codecpar->sample_rate && sc->time_scale > 1)
3207 st->codecpar->sample_rate = sc->time_scale;
3208
3209 /* special codec parameters handling */
3210 switch (st->codecpar->codec_id) {
3211#if CONFIG_DV_DEMUXER
3213 if (c->dv_fctx) {
3214 avpriv_request_sample(c->fc, "multiple DV audio streams");
3215 return AVERROR(ENOSYS);
3216 }
3217
3218 c->dv_fctx = avformat_alloc_context();
3219 if (!c->dv_fctx) {
3220 av_log(c->fc, AV_LOG_ERROR, "dv demux context alloc error\n");
3221 return AVERROR(ENOMEM);
3222 }
3223 c->dv_demux = avpriv_dv_init_demux(c->dv_fctx);
3224 if (!c->dv_demux) {
3225 av_log(c->fc, AV_LOG_ERROR, "dv demux context init error\n");
3226 return AVERROR(ENOMEM);
3227 }
3228 sc->dv_audio_container = 1;
3230 break;
3231#endif
3232 /* no ifdef since parameters are always those */
3233 case AV_CODEC_ID_QCELP:
3236 // force sample rate for qcelp when not stored in mov
3237 if (st->codecpar->codec_tag != MKTAG('Q','c','l','p'))
3238 st->codecpar->sample_rate = 8000;
3239 // FIXME: Why is the following needed for some files?
3240 sc->samples_per_frame = 160;
3241 if (!sc->bytes_per_frame)
3242 sc->bytes_per_frame = 35;
3243 break;
3244 case AV_CODEC_ID_AMR_NB:
3247 /* force sample rate for amr, stsd in 3gp does not store sample rate */
3248 st->codecpar->sample_rate = 8000;
3249 break;
3250 case AV_CODEC_ID_AMR_WB:
3253 st->codecpar->sample_rate = 16000;
3254 break;
3255 case AV_CODEC_ID_MP2:
3256 case AV_CODEC_ID_MP3:
3257 /* force type after stsd for m1a hdlr */
3259 break;
3260 case AV_CODEC_ID_GSM:
3263 case AV_CODEC_ID_ILBC:
3264 case AV_CODEC_ID_MACE3:
3265 case AV_CODEC_ID_MACE6:
3266 case AV_CODEC_ID_QDM2:
3268 break;
3269 case AV_CODEC_ID_ALAC:
3270 if (st->codecpar->extradata_size == 36) {
3271 int channel_count = AV_RB8(st->codecpar->extradata + 21);
3272 if (st->codecpar->ch_layout.nb_channels != channel_count) {
3275 st->codecpar->ch_layout.nb_channels = channel_count;
3276 }
3277 st->codecpar->sample_rate = AV_RB32(st->codecpar->extradata + 32);
3278 }
3279 break;
3280 case AV_CODEC_ID_AC3:
3281 case AV_CODEC_ID_EAC3:
3283 case AV_CODEC_ID_VC1:
3284 case AV_CODEC_ID_VP8:
3285 case AV_CODEC_ID_VP9:
3287 break;
3289 case AV_CODEC_ID_PRORES:
3290 case AV_CODEC_ID_APV:
3291 case AV_CODEC_ID_EVC:
3292 case AV_CODEC_ID_LCEVC:
3293 case AV_CODEC_ID_AV1:
3294 /* field_order detection of H264 requires parsing */
3295 case AV_CODEC_ID_H264:
3297 break;
3298 default:
3299 break;
3300 }
3301 return 0;
3302}
3303
3305 int codec_tag, int format,
3306 int64_t size)
3307{
3308 if (codec_tag &&
3309 (codec_tag != format &&
3310 // AVID 1:1 samples with differing data format and codec tag exist
3311 (codec_tag != AV_RL32("AV1x") || format != AV_RL32("AVup")) &&
3312 // prores is allowed to have differing data format and codec tag
3313 codec_tag != AV_RL32("apcn") && codec_tag != AV_RL32("apch") &&
3314 // so is dv (sigh)
3315 codec_tag != AV_RL32("dvpp") && codec_tag != AV_RL32("dvcp") &&
3316 (c->fc->video_codec_id ? ff_codec_get_id(ff_codec_movvideo_tags, format) != c->fc->video_codec_id
3317 : codec_tag != MKTAG('j','p','e','g')))) {
3318 /* Multiple fourcc, we skip JPEG. This is not correct, we should
3319 * export it as a separate AVStream but this needs a few changes
3320 * in the MOV demuxer, patch welcome. */
3321
3322 av_log(c->fc, AV_LOG_WARNING, "multiple fourcc not supported\n");
3323 avio_skip(pb, size);
3324 return 1;
3325 }
3326
3327 return 0;
3328}
3329
3331{
3332 int ret;
3333
3334 /* special codec parameters handling */
3335 switch (st->codecpar->codec_id) {
3336 case AV_CODEC_ID_H264:
3337 // done for ai5q, ai52, ai55, ai1q, ai12 and ai15.
3340 if (ret < 0)
3341 return ret;
3342 }
3343 break;
3344 default:
3345 break;
3346 }
3347
3348 return 0;
3349}
3350
3352{
3353 AVStream *st;
3354 MOVStreamContext *sc;
3355 int pseudo_stream_id;
3356
3357 av_assert0 (c->fc->nb_streams >= 1);
3358 st = c->fc->streams[c->fc->nb_streams-1];
3359 sc = st->priv_data;
3360
3361 for (pseudo_stream_id = 0;
3362 pseudo_stream_id < entries && !pb->eof_reached;
3363 pseudo_stream_id++) {
3364 //Parsing Sample description table
3365 enum AVCodecID id;
3366 int ret, dref_id = 1;
3367 MOVAtom a = { AV_RL32("stsd") };
3368 int64_t start_pos = avio_tell(pb);
3369 int64_t size = avio_rb32(pb); /* size */
3370 uint32_t format = avio_rl32(pb); /* data format */
3371
3372 if (size >= 16) {
3373 avio_rb32(pb); /* reserved */
3374 avio_rb16(pb); /* reserved */
3375 dref_id = avio_rb16(pb);
3376 } else if (size <= 7) {
3377 av_log(c->fc, AV_LOG_ERROR,
3378 "invalid size %"PRId64" in stsd\n", size);
3379 return AVERROR_INVALIDDATA;
3380 }
3381
3383 size - (avio_tell(pb) - start_pos))) {
3384 sc->stsd_count++;
3385 continue;
3386 }
3387
3388 sc->pseudo_stream_id = st->codecpar->codec_tag ? -1 : pseudo_stream_id;
3389 sc->dref_id= dref_id;
3390 sc->format = format;
3391
3392 id = mov_codec_id(st, format);
3393
3394 av_log(c->fc, AV_LOG_TRACE,
3395 "size=%"PRId64" 4CC=%s codec_type=%d\n", size,
3397
3398 st->codecpar->codec_id = id;
3400 mov_parse_stsd_video(c, pb, st, sc);
3401 } else if (st->codecpar->codec_type==AVMEDIA_TYPE_AUDIO) {
3402 mov_parse_stsd_audio(c, pb, st, sc);
3403 if (st->codecpar->sample_rate < 0) {
3404 av_log(c->fc, AV_LOG_ERROR, "Invalid sample rate %d\n", st->codecpar->sample_rate);
3405 return AVERROR_INVALIDDATA;
3406 }
3407 if (st->codecpar->ch_layout.nb_channels < 0) {
3408 av_log(c->fc, AV_LOG_ERROR, "Invalid channels %d\n", st->codecpar->ch_layout.nb_channels);
3409 return AVERROR_INVALIDDATA;
3410 }
3411 } else if (st->codecpar->codec_type==AVMEDIA_TYPE_SUBTITLE){
3412 mov_parse_stsd_subtitle(c, pb, st, sc,
3413 size - (avio_tell(pb) - start_pos));
3414 } else {
3415 ret = mov_parse_stsd_data(c, pb, st, sc,
3416 size - (avio_tell(pb) - start_pos));
3417 if (ret < 0)
3418 return ret;
3419 }
3420 /* this will read extra atoms at the end (wave, alac, damr, avcC, hvcC, SMI ...) */
3421 a.size = size - (avio_tell(pb) - start_pos);
3422 if (a.size > 8) {
3423 if ((ret = mov_read_default(c, pb, a)) < 0)
3424 return ret;
3425 } else if (a.size > 0)
3426 avio_skip(pb, a.size);
3427
3428 ret = mov_finalize_stsd_entry(c, st);
3429 if (ret < 0)
3430 return ret;
3431
3432 if (sc->extradata && st->codecpar->extradata) {
3433 int extra_size = st->codecpar->extradata_size;
3434
3435 /* Move the current stream extradata to the stream context one. */
3436 sc->extradata_size[pseudo_stream_id] = extra_size;
3437 sc->extradata[pseudo_stream_id] = st->codecpar->extradata;
3438 st->codecpar->extradata = NULL;
3439 st->codecpar->extradata_size = 0;
3440 }
3441 sc->stsd_count++;
3442 }
3443
3444 if (pb->eof_reached) {
3445 av_log(c->fc, AV_LOG_WARNING, "reached eof, corrupted STSD atom\n");
3446 return AVERROR_EOF;
3447 }
3448
3449 return 0;
3450}
3451
3453{
3454 AVStream *st;
3455 MOVStreamContext *sc;
3456 int ret, entries;
3457
3458 if (c->fc->nb_streams < 1)
3459 return 0;
3460 st = c->fc->streams[c->fc->nb_streams - 1];
3461 sc = st->priv_data;
3462
3463 if (sc->extradata) {
3464 av_log(c->fc, AV_LOG_ERROR,
3465 "Duplicate stsd found in this track.\n");
3466 return AVERROR_INVALIDDATA;
3467 }
3468
3469 sc->stsd_version = avio_r8(pb);
3470 avio_rb24(pb); /* flags */
3471 entries = avio_rb32(pb);
3472
3473 /* Each entry contains a size (4 bytes) and format (4 bytes). */
3474 if (entries <= 0 || entries > atom.size / 8 || entries > 1024) {
3475 av_log(c->fc, AV_LOG_ERROR, "invalid STSD entries %d\n", entries);
3476 return AVERROR_INVALIDDATA;
3477 }
3478
3479 /* Prepare space for hosting multiple extradata. */
3480 sc->extradata = av_calloc(entries, sizeof(*sc->extradata));
3481 if (!sc->extradata)
3482 return AVERROR(ENOMEM);
3483
3484 sc->extradata_size = av_calloc(entries, sizeof(*sc->extradata_size));
3485 if (!sc->extradata_size) {
3486 ret = AVERROR(ENOMEM);
3487 goto fail;
3488 }
3489
3490 ret = ff_mov_read_stsd_entries(c, pb, entries);
3491 if (ret < 0)
3492 goto fail;
3493
3494 /* Restore back the primary extradata. */
3497 if (sc->extradata_size[0]) {
3499 if (!st->codecpar->extradata)
3500 return AVERROR(ENOMEM);
3501 memcpy(st->codecpar->extradata, sc->extradata[0], sc->extradata_size[0]);
3502 }
3503
3504 return mov_finalize_stsd_codec(c, pb, st, sc);
3505fail:
3506 if (sc->extradata) {
3507 int j;
3508 for (j = 0; j < sc->stsd_count; j++)
3509 av_freep(&sc->extradata[j]);
3510 }
3511
3512 sc->stsd_count = 0;
3513 av_freep(&sc->extradata);
3515 return ret;
3516}
3517
3519{
3520 AVStream *st;
3521 MOVStreamContext *sc;
3522 unsigned int i, entries;
3523
3524 if (c->trak_index < 0) {
3525 av_log(c->fc, AV_LOG_WARNING, "STSC outside TRAK\n");
3526 return 0;
3527 }
3528
3529 if (c->fc->nb_streams < 1)
3530 return 0;
3531 st = c->fc->streams[c->fc->nb_streams-1];
3532 sc = st->priv_data;
3533
3534 avio_r8(pb); /* version */
3535 avio_rb24(pb); /* flags */
3536
3537 entries = avio_rb32(pb);
3538 if ((uint64_t)entries * 12 + 4 > atom.size)
3539 return AVERROR_INVALIDDATA;
3540
3541 av_log(c->fc, AV_LOG_TRACE, "track[%u].stsc.entries = %u\n", c->fc->nb_streams - 1, entries);
3542
3543 if (!entries)
3544 return 0;
3545 if (sc->stsc_data) {
3546 av_log(c->fc, AV_LOG_WARNING, "Ignoring duplicated STSC atom\n");
3547 return 0;
3548 }
3549 av_free(sc->stsc_data);
3550 sc->stsc_count = 0;
3551 sc->stsc_data = av_malloc_array(entries, sizeof(*sc->stsc_data));
3552 if (!sc->stsc_data)
3553 return AVERROR(ENOMEM);
3554
3555 for (i = 0; i < entries && !pb->eof_reached; i++) {
3556 sc->stsc_data[i].first = avio_rb32(pb);
3557 sc->stsc_data[i].count = avio_rb32(pb);
3558 sc->stsc_data[i].id = avio_rb32(pb);
3559 }
3560
3561 sc->stsc_count = i;
3562 for (i = sc->stsc_count - 1; i < UINT_MAX; i--) {
3563 int64_t first_min = i + 1;
3564 if ((i+1 < sc->stsc_count && sc->stsc_data[i].first >= sc->stsc_data[i+1].first) ||
3565 (i > 0 && sc->stsc_data[i].first <= sc->stsc_data[i-1].first) ||
3566 sc->stsc_data[i].first < first_min ||
3567 sc->stsc_data[i].count < 1 ||
3568 sc->stsc_data[i].id < 1) {
3569 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);
3570 if (i+1 >= sc->stsc_count) {
3571 if (sc->stsc_data[i].count == 0 && i > 0) {
3572 sc->stsc_count --;
3573 continue;
3574 }
3575 sc->stsc_data[i].first = FFMAX(sc->stsc_data[i].first, first_min);
3576 if (i > 0 && sc->stsc_data[i].first <= sc->stsc_data[i-1].first)
3577 sc->stsc_data[i].first = FFMIN(sc->stsc_data[i-1].first + 1LL, INT_MAX);
3578 sc->stsc_data[i].count = FFMAX(sc->stsc_data[i].count, 1);
3579 sc->stsc_data[i].id = FFMAX(sc->stsc_data[i].id, 1);
3580 continue;
3581 }
3582 av_assert0(sc->stsc_data[i+1].first >= 2);
3583 // We replace this entry by the next valid
3584 sc->stsc_data[i].first = sc->stsc_data[i+1].first - 1;
3585 sc->stsc_data[i].count = sc->stsc_data[i+1].count;
3586 sc->stsc_data[i].id = sc->stsc_data[i+1].id;
3587 }
3588 }
3589
3590 if (pb->eof_reached) {
3591 av_log(c->fc, AV_LOG_WARNING, "reached eof, corrupted STSC atom\n");
3592 return AVERROR_EOF;
3593 }
3594
3595 return 0;
3596}
3597
3598static inline int mov_stsc_index_valid(unsigned int index, unsigned int count)
3599{
3600 return index < count - 1;
3601}
3602
3603/* Compute the samples value for the stsc entry at the given index. */
3604static inline int64_t mov_get_stsc_samples(MOVStreamContext *sc, unsigned int index)
3605{
3606 int chunk_count;
3607
3609 chunk_count = sc->stsc_data[index + 1].first - sc->stsc_data[index].first;
3610 else {
3611 // Validation for stsc / stco happens earlier in mov_read_stsc + mov_read_trak.
3613 chunk_count = sc->chunk_count - (sc->stsc_data[index].first - 1);
3614 }
3615
3616 return sc->stsc_data[index].count * (int64_t)chunk_count;
3617}
3618
3620{
3621 AVStream *st;
3622 MOVStreamContext *sc;
3623 unsigned i, entries;
3624
3625 if (c->trak_index < 0) {
3626 av_log(c->fc, AV_LOG_WARNING, "STPS outside TRAK\n");
3627 return 0;
3628 }
3629
3630 if (c->fc->nb_streams < 1)
3631 return 0;
3632 st = c->fc->streams[c->fc->nb_streams-1];
3633 sc = st->priv_data;
3634
3635 avio_rb32(pb); // version + flags
3636
3637 entries = avio_rb32(pb);
3638 if (sc->stps_data)
3639 av_log(c->fc, AV_LOG_WARNING, "Duplicated STPS atom\n");
3640 av_free(sc->stps_data);
3641 sc->stps_count = 0;
3642 sc->stps_data = av_malloc_array(entries, sizeof(*sc->stps_data));
3643 if (!sc->stps_data)
3644 return AVERROR(ENOMEM);
3645
3646 for (i = 0; i < entries && !pb->eof_reached; i++) {
3647 sc->stps_data[i] = avio_rb32(pb);
3648 }
3649
3650 sc->stps_count = i;
3651
3652 if (pb->eof_reached) {
3653 av_log(c->fc, AV_LOG_WARNING, "reached eof, corrupted STPS atom\n");
3654 return AVERROR_EOF;
3655 }
3656
3657 return 0;
3658}
3659
3661{
3662 AVStream *st;
3663 FFStream *sti;
3664 MOVStreamContext *sc;
3665 unsigned int i, entries;
3666
3667 if (c->trak_index < 0) {
3668 av_log(c->fc, AV_LOG_WARNING, "STSS outside TRAK\n");
3669 return 0;
3670 }
3671
3672 if (c->fc->nb_streams < 1)
3673 return 0;
3674 st = c->fc->streams[c->fc->nb_streams-1];
3675 sti = ffstream(st);
3676 sc = st->priv_data;
3677
3678 avio_r8(pb); /* version */
3679 avio_rb24(pb); /* flags */
3680
3681 entries = avio_rb32(pb);
3682
3683 av_log(c->fc, AV_LOG_TRACE, "keyframe_count = %u\n", entries);
3684
3685 if (!entries) {
3686 sc->keyframe_absent = 1;
3689 return 0;
3690 }
3691 if (sc->keyframes)
3692 av_log(c->fc, AV_LOG_WARNING, "Duplicated STSS atom\n");
3693 if (entries >= UINT_MAX / sizeof(int))
3694 return AVERROR_INVALIDDATA;
3695 av_freep(&sc->keyframes);
3696 sc->keyframe_count = 0;
3697 sc->keyframes = av_malloc_array(entries, sizeof(*sc->keyframes));
3698 if (!sc->keyframes)
3699 return AVERROR(ENOMEM);
3700
3701 for (i = 0; i < entries && !pb->eof_reached; i++) {
3702 sc->keyframes[i] = avio_rb32(pb);
3703 }
3704
3705 sc->keyframe_count = i;
3706
3707 if (pb->eof_reached) {
3708 av_log(c->fc, AV_LOG_WARNING, "reached eof, corrupted STSS atom\n");
3709 return AVERROR_EOF;
3710 }
3711
3712 return 0;
3713}
3714
3716{
3717 AVStream *st;
3718 MOVStreamContext *sc;
3719 unsigned int i, entries, sample_size, field_size, num_bytes;
3720 GetBitContext gb;
3721 unsigned char* buf;
3722 int ret;
3723
3724 if (c->trak_index < 0) {
3725 av_log(c->fc, AV_LOG_WARNING, "STSZ outside TRAK\n");
3726 return 0;
3727 }
3728
3729 if (c->fc->nb_streams < 1)
3730 return 0;
3731 st = c->fc->streams[c->fc->nb_streams-1];
3732 sc = st->priv_data;
3733
3734 avio_r8(pb); /* version */
3735 avio_rb24(pb); /* flags */
3736
3737 if (atom.type == MKTAG('s','t','s','z')) {
3738 sample_size = avio_rb32(pb);
3739 if (!sc->sample_size) /* do not overwrite value computed in stsd */
3740 sc->sample_size = sample_size;
3741 sc->stsz_sample_size = sample_size;
3742 field_size = 32;
3743 } else {
3744 sample_size = 0;
3745 avio_rb24(pb); /* reserved */
3746 field_size = avio_r8(pb);
3747 }
3748 entries = avio_rb32(pb);
3749
3750 av_log(c->fc, AV_LOG_TRACE, "sample_size = %u sample_count = %u\n", sc->sample_size, entries);
3751
3752 sc->sample_count = entries;
3753 if (sample_size)
3754 return 0;
3755
3756 if (field_size != 4 && field_size != 8 && field_size != 16 && field_size != 32) {
3757 av_log(c->fc, AV_LOG_ERROR, "Invalid sample field size %u\n", field_size);
3758 return AVERROR_INVALIDDATA;
3759 }
3760
3761 if (!entries)
3762 return 0;
3763 if (entries >= (INT_MAX - 4 - 8 * AV_INPUT_BUFFER_PADDING_SIZE) / field_size)
3764 return AVERROR_INVALIDDATA;
3765 if (sc->sample_sizes)
3766 av_log(c->fc, AV_LOG_WARNING, "Duplicated STSZ atom\n");
3767 av_free(sc->sample_sizes);
3768 sc->sample_count = 0;
3769 sc->sample_sizes = av_malloc_array(entries, sizeof(*sc->sample_sizes));
3770 if (!sc->sample_sizes)
3771 return AVERROR(ENOMEM);
3772
3773 num_bytes = (entries*field_size+4)>>3;
3774
3775 buf = av_malloc(num_bytes+AV_INPUT_BUFFER_PADDING_SIZE);
3776 if (!buf) {
3777 av_freep(&sc->sample_sizes);
3778 return AVERROR(ENOMEM);
3779 }
3780
3781 ret = ffio_read_size(pb, buf, num_bytes);
3782 if (ret < 0) {
3783 av_freep(&sc->sample_sizes);
3784 av_free(buf);
3785 av_log(c->fc, AV_LOG_WARNING, "STSZ atom truncated\n");
3786 return 0;
3787 }
3788
3789 init_get_bits(&gb, buf, 8*num_bytes);
3790
3791 for (i = 0; i < entries; i++) {
3792 sc->sample_sizes[i] = get_bits_long(&gb, field_size);
3793 if (sc->sample_sizes[i] > INT64_MAX - sc->data_size) {
3794 av_free(buf);
3795 av_log(c->fc, AV_LOG_ERROR, "Sample size overflow in STSZ\n");
3796 return AVERROR_INVALIDDATA;
3797 }
3798 sc->data_size += sc->sample_sizes[i];
3799 }
3800
3801 sc->sample_count = i;
3802
3803 av_free(buf);
3804
3805 return 0;
3806}
3807
3809{
3810 AVStream *st;
3811 MOVStreamContext *sc;
3812 unsigned int i, entries;
3813 int64_t duration = 0;
3814 int64_t total_sample_count = 0;
3815 int64_t current_dts = 0;
3816 int64_t corrected_dts = 0;
3817
3818 if (c->trak_index < 0) {
3819 av_log(c->fc, AV_LOG_WARNING, "STTS outside TRAK\n");
3820 return 0;
3821 }
3822
3823 if (c->fc->nb_streams < 1)
3824 return 0;
3825 st = c->fc->streams[c->fc->nb_streams-1];
3826 sc = st->priv_data;
3827
3828 avio_r8(pb); /* version */
3829 avio_rb24(pb); /* flags */
3830 entries = avio_rb32(pb);
3831
3832 av_log(c->fc, AV_LOG_TRACE, "track[%u].stts.entries = %u\n",
3833 c->fc->nb_streams-1, entries);
3834
3835 if (sc->stts_data)
3836 av_log(c->fc, AV_LOG_WARNING, "Duplicated STTS atom\n");
3837 av_freep(&sc->stts_data);
3838 sc->stts_count = 0;
3839 if (entries >= INT_MAX / sizeof(*sc->stts_data))
3840 return AVERROR(ENOMEM);
3841
3842 for (i = 0; i < entries && !pb->eof_reached; i++) {
3843 unsigned int sample_duration;
3844 unsigned int sample_count;
3845 unsigned int min_entries = FFMIN(FFMAX(i + 1, 1024 * 1024), entries);
3847 min_entries * sizeof(*sc->stts_data));
3848 if (!stts_data) {
3849 av_freep(&sc->stts_data);
3850 sc->stts_count = 0;
3851 return AVERROR(ENOMEM);
3852 }
3853 sc->stts_count = min_entries;
3854 sc->stts_data = stts_data;
3855
3856 sample_count = avio_rb32(pb);
3857 sample_duration = avio_rb32(pb);
3858
3859 sc->stts_data[i].count= sample_count;
3860 sc->stts_data[i].duration= sample_duration;
3861
3862 av_log(c->fc, AV_LOG_TRACE, "sample_count=%u, sample_duration=%u\n",
3863 sample_count, sample_duration);
3864
3865 /* STTS sample offsets are uint32 but some files store it as int32
3866 * with negative values used to correct DTS delays.
3867 There may be abnormally large values as well. */
3868 if (sample_duration > c->max_stts_delta) {
3869 // assume high delta is a correction if negative when cast as int32
3870 int32_t delta_magnitude = (int32_t)sample_duration;
3871 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",
3872 sample_duration, i, sample_count, st->index);
3873 sc->stts_data[i].duration = 1;
3874 corrected_dts = av_sat_add64(corrected_dts, (delta_magnitude < 0 ? (int64_t)delta_magnitude : 1) * sample_count);
3875 } else {
3876 corrected_dts += sample_duration * (uint64_t)sample_count;
3877 }
3878
3879 current_dts += sc->stts_data[i].duration * (uint64_t)sample_count;
3880
3881 if (current_dts > corrected_dts) {
3882 int64_t drift = av_sat_sub64(current_dts, corrected_dts) / FFMAX(sample_count, 1);
3883 uint32_t correction = (sc->stts_data[i].duration > drift) ? drift : sc->stts_data[i].duration - 1;
3884 current_dts -= correction * (uint64_t)sample_count;
3885 sc->stts_data[i].duration -= correction;
3886 }
3887
3888 duration+=(int64_t)sc->stts_data[i].duration*(uint64_t)sc->stts_data[i].count;
3889 total_sample_count+=sc->stts_data[i].count;
3890 }
3891
3892 sc->stts_count = i;
3893
3894 if (duration > 0 &&
3895 duration <= INT64_MAX - sc->duration_for_fps &&
3896 total_sample_count <= INT_MAX - sc->nb_frames_for_fps) {
3898 sc->nb_frames_for_fps += total_sample_count;
3899 }
3900
3901 if (pb->eof_reached) {
3902 av_log(c->fc, AV_LOG_WARNING, "reached eof, corrupted STTS atom\n");
3903 return AVERROR_EOF;
3904 }
3905
3906 st->nb_frames= total_sample_count;
3907 if (duration)
3908 st->duration= FFMIN(st->duration, duration);
3909
3910 // All samples have zero duration. They have higher chance be chose by
3911 // mov_find_next_sample, which leads to seek again and again.
3912 //
3913 // It's AVERROR_INVALIDDATA actually, but such files exist in the wild.
3914 // So only mark data stream as discarded for safety.
3915 if (!duration && sc->stts_count &&
3917 av_log(c->fc, AV_LOG_WARNING,
3918 "All samples in data stream index:id [%d:%d] have zero "
3919 "duration, stream set to be discarded by default. Override "
3920 "using AVStream->discard or -discard for ffmpeg command.\n",
3921 st->index, sc->id);
3922 st->discard = AVDISCARD_ALL;
3923 }
3924 sc->track_end = duration;
3925 return 0;
3926}
3927
3929{
3930 AVStream *st;
3931 MOVStreamContext *sc;
3932 unsigned int i;
3933 int64_t entries;
3934
3935 if (c->fc->nb_streams < 1)
3936 return 0;
3937 st = c->fc->streams[c->fc->nb_streams - 1];
3938 sc = st->priv_data;
3939
3940 avio_r8(pb); /* version */
3941 avio_rb24(pb); /* flags */
3942 entries = atom.size - 4;
3943
3944 av_log(c->fc, AV_LOG_TRACE, "track[%u].sdtp.entries = %" PRId64 "\n",
3945 c->fc->nb_streams - 1, entries);
3946
3947 if (sc->sdtp_data)
3948 av_log(c->fc, AV_LOG_WARNING, "Duplicated SDTP atom\n");
3949 av_freep(&sc->sdtp_data);
3950 sc->sdtp_count = 0;
3951
3952 if (entries < 0 || entries > UINT_MAX)
3953 return AVERROR(ERANGE);
3954
3955 sc->sdtp_data = av_malloc(entries);
3956 if (!sc->sdtp_data)
3957 return AVERROR(ENOMEM);
3958
3959 for (i = 0; i < entries && !pb->eof_reached; i++)
3960 sc->sdtp_data[i] = avio_r8(pb);
3961 sc->sdtp_count = i;
3962
3963 return 0;
3964}
3965
3966static void mov_update_dts_shift(MOVStreamContext *sc, int duration, void *logctx)
3967{
3968 if (duration < 0) {
3969 if (duration == INT_MIN) {
3970 av_log(logctx, AV_LOG_WARNING, "mov_update_dts_shift(): dts_shift set to %d\n", INT_MAX);
3971 duration++;
3972 }
3973 sc->dts_shift = FFMAX(sc->dts_shift, -duration);
3974 }
3975}
3976
3978{
3979 AVStream *st;
3980 MOVStreamContext *sc;
3981 unsigned int i, entries, ctts_count = 0;
3982
3983 if (c->trak_index < 0) {
3984 av_log(c->fc, AV_LOG_WARNING, "CTTS outside TRAK\n");
3985 return 0;
3986 }
3987
3988 if (c->fc->nb_streams < 1)
3989 return 0;
3990 st = c->fc->streams[c->fc->nb_streams-1];
3991 sc = st->priv_data;
3992
3993 avio_r8(pb); /* version */
3994 avio_rb24(pb); /* flags */
3995 entries = avio_rb32(pb);
3996
3997 av_log(c->fc, AV_LOG_TRACE, "track[%u].ctts.entries = %u\n", c->fc->nb_streams - 1, entries);
3998
3999 if (!entries)
4000 return 0;
4001 if (entries >= UINT_MAX / sizeof(*sc->ctts_data))
4002 return AVERROR_INVALIDDATA;
4003 av_freep(&sc->ctts_data);
4004 sc->ctts_data = av_fast_realloc(NULL, &sc->ctts_allocated_size, entries * sizeof(*sc->ctts_data));
4005 if (!sc->ctts_data)
4006 return AVERROR(ENOMEM);
4007
4008 for (i = 0; i < entries && !pb->eof_reached; i++) {
4009 MOVCtts *ctts_data;
4010 const size_t min_size_needed = (ctts_count + 1) * sizeof(MOVCtts);
4011 const size_t requested_size =
4012 min_size_needed > sc->ctts_allocated_size ?
4013 FFMAX(min_size_needed, 2 * sc->ctts_allocated_size) :
4014 min_size_needed;
4015 int count = avio_rb32(pb);
4016 int duration = avio_rb32(pb);
4017
4018 if (count <= 0) {
4019 av_log(c->fc, AV_LOG_TRACE,
4020 "ignoring CTTS entry with count=%d duration=%d\n",
4021 count, duration);
4022 continue;
4023 }
4024
4025 if (ctts_count >= UINT_MAX / sizeof(MOVCtts) - 1)
4026 return AVERROR(ENOMEM);
4027
4028 ctts_data = av_fast_realloc(sc->ctts_data, &sc->ctts_allocated_size, requested_size);
4029
4030 if (!ctts_data)
4031 return AVERROR(ENOMEM);
4032
4033 sc->ctts_data = ctts_data;
4034
4035 ctts_data[ctts_count].count = count;
4036 ctts_data[ctts_count].offset = duration;
4037 ctts_count++;
4038
4039 av_log(c->fc, AV_LOG_TRACE, "count=%d, duration=%d\n",
4040 count, duration);
4041
4042 if (i+2<entries)
4044 }
4045
4046 sc->ctts_count = ctts_count;
4047
4048 if (pb->eof_reached) {
4049 av_log(c->fc, AV_LOG_WARNING, "reached eof, corrupted CTTS atom\n");
4050 return AVERROR_EOF;
4051 }
4052
4053 av_log(c->fc, AV_LOG_TRACE, "dts shift %d\n", sc->dts_shift);
4054
4055 return 0;
4056}
4057
4059{
4060 AVStream *st;
4061 MOVStreamContext *sc;
4062 uint8_t version;
4063 uint32_t grouping_type;
4064 uint32_t default_length;
4065 av_unused uint32_t default_group_description_index;
4066 uint32_t entry_count;
4067
4068 if (c->fc->nb_streams < 1)
4069 return 0;
4070 st = c->fc->streams[c->fc->nb_streams - 1];
4071 sc = st->priv_data;
4072
4073 version = avio_r8(pb); /* version */
4074 avio_rb24(pb); /* flags */
4075 grouping_type = avio_rl32(pb);
4076
4077 /*
4078 * This function only supports "sync" boxes, but the code is able to parse
4079 * other boxes (such as "tscl", "tsas" and "stsa")
4080 */
4081 if (grouping_type != MKTAG('s','y','n','c'))
4082 return 0;
4083
4084 default_length = version >= 1 ? avio_rb32(pb) : 0;
4085 default_group_description_index = version >= 2 ? avio_rb32(pb) : 0;
4086 entry_count = avio_rb32(pb);
4087
4088 if (entry_count > atom.size)
4089 return AVERROR_INVALIDDATA;
4090
4091 av_freep(&sc->sgpd_sync);
4092 sc->sgpd_sync_count = entry_count;
4093 sc->sgpd_sync = av_calloc(entry_count, sizeof(*sc->sgpd_sync));
4094 if (!sc->sgpd_sync)
4095 return AVERROR(ENOMEM);
4096
4097 for (uint32_t i = 0; i < entry_count && !pb->eof_reached; i++) {
4098 uint32_t description_length = default_length;
4099 if (version >= 1 && default_length == 0)
4100 description_length = avio_rb32(pb);
4101 if (grouping_type == MKTAG('s','y','n','c')) {
4102 const uint8_t nal_unit_type = avio_r8(pb) & 0x3f;
4103 sc->sgpd_sync[i] = nal_unit_type;
4104 description_length -= 1;
4105 }
4106 avio_skip(pb, description_length);
4107 }
4108
4109 if (pb->eof_reached) {
4110 av_log(c->fc, AV_LOG_WARNING, "reached eof, corrupted SGPD atom\n");
4111 return AVERROR_EOF;
4112 }
4113
4114 return 0;
4115}
4116
4118{
4119 AVStream *st;
4120 MOVStreamContext *sc;
4121 unsigned int i, entries;
4122 uint8_t version;
4123 uint32_t grouping_type;
4124 MOVSbgp *table, **tablep;
4125 int *table_count;
4126
4127 if (c->fc->nb_streams < 1)
4128 return 0;
4129 st = c->fc->streams[c->fc->nb_streams-1];
4130 sc = st->priv_data;
4131
4132 version = avio_r8(pb); /* version */
4133 avio_rb24(pb); /* flags */
4134 grouping_type = avio_rl32(pb);
4135
4136 if (grouping_type == MKTAG('r','a','p',' ')) {
4137 tablep = &sc->rap_group;
4138 table_count = &sc->rap_group_count;
4139 } else if (grouping_type == MKTAG('s','y','n','c')) {
4140 tablep = &sc->sync_group;
4141 table_count = &sc->sync_group_count;
4142 } else {
4143 return 0;
4144 }
4145
4146 if (version == 1)
4147 avio_rb32(pb); /* grouping_type_parameter */
4148
4149 entries = avio_rb32(pb);
4150 if (!entries)
4151 return 0;
4152 if (*tablep)
4153 av_log(c->fc, AV_LOG_WARNING, "Duplicated SBGP %s atom\n", av_fourcc2str(grouping_type));
4154 av_freep(tablep);
4155 table = av_malloc_array(entries, sizeof(*table));
4156 if (!table)
4157 return AVERROR(ENOMEM);
4158 *tablep = table;
4159
4160 for (i = 0; i < entries && !pb->eof_reached; i++) {
4161 table[i].count = avio_rb32(pb); /* sample_count */
4162 table[i].index = avio_rb32(pb); /* group_description_index */
4163 }
4164
4165 *table_count = i;
4166
4167 if (pb->eof_reached) {
4168 av_log(c->fc, AV_LOG_WARNING, "reached eof, corrupted SBGP atom\n");
4169 return AVERROR_EOF;
4170 }
4171
4172 return 0;
4173}
4174
4175/**
4176 * Get ith edit list entry (media time, duration).
4177 */
4179 const MOVStreamContext *msc,
4180 unsigned int edit_list_index,
4181 int64_t *edit_list_media_time,
4182 int64_t *edit_list_duration,
4183 int64_t global_timescale)
4184{
4185 if (edit_list_index == msc->elst_count) {
4186 return 0;
4187 }
4188 *edit_list_media_time = msc->elst_data[edit_list_index].time;
4189 *edit_list_duration = msc->elst_data[edit_list_index].duration;
4190
4191 /* duration is in global timescale units;convert to msc timescale */
4192 if (global_timescale == 0) {
4193 avpriv_request_sample(mov->fc, "Support for mvhd.timescale = 0 with editlists");
4194 return 0;
4195 }
4196 *edit_list_duration = av_rescale(*edit_list_duration, msc->time_scale,
4197 global_timescale);
4198
4199 if (*edit_list_duration + (uint64_t)*edit_list_media_time > INT64_MAX)
4200 *edit_list_duration = 0;
4201
4202 return 1;
4203}
4204
4205/**
4206 * Find the closest previous frame to the timestamp_pts, in e_old index
4207 * entries. Searching for just any frame / just key frames can be controlled by
4208 * last argument 'flag'.
4209 * Note that if ctts_data is not NULL, we will always search for a key frame
4210 * irrespective of the value of 'flag'. If we don't find any keyframe, we will
4211 * return the first frame of the video.
4212 *
4213 * Here the timestamp_pts is considered to be a presentation timestamp and
4214 * the timestamp of index entries are considered to be decoding timestamps.
4215 *
4216 * Returns 0 if successful in finding a frame, else returns -1.
4217 * Places the found index corresponding output arg.
4218 *
4219 * If ctts_old is not NULL, then refines the searched entry by searching
4220 * backwards from the found timestamp, to find the frame with correct PTS.
4221 *
4222 * Places the found ctts_index and ctts_sample in corresponding output args.
4223 */
4225 AVIndexEntry *e_old,
4226 int nb_old,
4227 MOVTimeToSample *tts_data,
4228 int64_t tts_count,
4229 int64_t timestamp_pts,
4230 int flag,
4231 int64_t* index,
4232 int64_t* tts_index,
4233 int64_t* tts_sample)
4234{
4235 MOVStreamContext *msc = st->priv_data;
4236 FFStream *const sti = ffstream(st);
4237 AVIndexEntry *e_keep = sti->index_entries;
4238 int nb_keep = sti->nb_index_entries;
4239 int64_t i = 0;
4240
4242
4243 // If dts_shift > 0, then all the index timestamps will have to be offset by
4244 // at least dts_shift amount to obtain PTS.
4245 // Hence we decrement the searched timestamp_pts by dts_shift to find the closest index element.
4246 if (msc->dts_shift > 0) {
4247 timestamp_pts -= msc->dts_shift;
4248 }
4249
4250 sti->index_entries = e_old;
4251 sti->nb_index_entries = nb_old;
4253
4254 // Keep going backwards in the index entries until the timestamp is the same.
4255 if (*index >= 0) {
4256 for (i = *index; i > 0 && e_old[i].timestamp == e_old[i - 1].timestamp;
4257 i--) {
4258 if ((flag & AVSEEK_FLAG_ANY) ||
4259 (e_old[i - 1].flags & AVINDEX_KEYFRAME)) {
4260 *index = i - 1;
4261 }
4262 }
4263 }
4264
4265 // If we have CTTS then refine the search, by searching backwards over PTS
4266 // computed by adding corresponding CTTS durations to index timestamps.
4267 if (msc->ctts_count && *index >= 0) {
4268 av_assert0(tts_index);
4269 av_assert0(tts_sample);
4270 // Find out the ctts_index for the found frame.
4271 *tts_index = 0;
4272 *tts_sample = 0;
4273 for (int64_t index_tts_count = 0; index_tts_count < *index; index_tts_count++) {
4274 if (*tts_index < tts_count) {
4275 (*tts_sample)++;
4276 if (tts_data[*tts_index].count == *tts_sample) {
4277 (*tts_index)++;
4278 *tts_sample = 0;
4279 }
4280 }
4281 }
4282
4283 while (*index >= 0 && (*tts_index) >= 0 && (*tts_index) < tts_count) {
4284 // Find a "key frame" with PTS <= timestamp_pts (So that we can decode B-frames correctly).
4285 // No need to add dts_shift to the timestamp here because timestamp_pts has already been
4286 // compensated by dts_shift above.
4287 if ((e_old[*index].timestamp + tts_data[*tts_index].offset) <= timestamp_pts &&
4288 (e_old[*index].flags & AVINDEX_KEYFRAME)) {
4289 break;
4290 }
4291
4292 (*index)--;
4293 if (*tts_sample == 0) {
4294 (*tts_index)--;
4295 if (*tts_index >= 0)
4296 *tts_sample = tts_data[*tts_index].count - 1;
4297 } else {
4298 (*tts_sample)--;
4299 }
4300 }
4301 }
4302
4303 /* restore AVStream state*/
4304 sti->index_entries = e_keep;
4305 sti->nb_index_entries = nb_keep;
4306 return *index >= 0 ? 0 : -1;
4307}
4308
4309/**
4310 * Add index entry with the given values, to the end of ffstream(st)->index_entries.
4311 * Returns the new size ffstream(st)->index_entries if successful, else returns -1.
4312 *
4313 * This function is similar to ff_add_index_entry in libavformat/utils.c
4314 * except that here we are always unconditionally adding an index entry to
4315 * the end, instead of searching the entries list and skipping the add if
4316 * there is an existing entry with the same timestamp.
4317 * This is needed because the mov_fix_index calls this func with the same
4318 * unincremented timestamp for successive discarded frames.
4319 */
4321 int size, int distance, int flags)
4322{
4323 FFStream *const sti = ffstream(st);
4324 AVIndexEntry *entries, *ie;
4325 int64_t index = -1;
4326 const size_t min_size_needed = (sti->nb_index_entries + 1) * sizeof(AVIndexEntry);
4327
4328 // Double the allocation each time, to lower memory fragmentation.
4329 // Another difference from ff_add_index_entry function.
4330 const size_t requested_size =
4331 min_size_needed > sti->index_entries_allocated_size ?
4332 FFMAX(min_size_needed, 2 * sti->index_entries_allocated_size) :
4333 min_size_needed;
4334
4335 if (sti->nb_index_entries + 1U >= UINT_MAX / sizeof(AVIndexEntry))
4336 return -1;
4337
4338 entries = av_fast_realloc(sti->index_entries,
4340 requested_size);
4341 if (!entries)
4342 return -1;
4343
4344 sti->index_entries = entries;
4345
4346 index = sti->nb_index_entries++;
4347 ie= &entries[index];
4348
4349 ie->pos = pos;
4350 ie->timestamp = timestamp;
4352 ie->size= size;
4353 ie->flags = flags;
4354 return index;
4355}
4356
4357/**
4358 * Rewrite timestamps of index entries in the range [end_index - frame_duration_buffer_size, end_index)
4359 * by subtracting end_ts successively by the amounts given in frame_duration_buffer.
4360 */
4361static void fix_index_entry_timestamps(AVStream* st, int end_index, int64_t end_ts,
4362 int64_t* frame_duration_buffer,
4363 int frame_duration_buffer_size) {
4364 FFStream *const sti = ffstream(st);
4365 int i = 0;
4366 av_assert0(end_index >= 0 && end_index <= sti->nb_index_entries);
4367 for (i = 0; i < frame_duration_buffer_size; i++) {
4368 end_ts -= frame_duration_buffer[frame_duration_buffer_size - 1 - i];
4369 sti->index_entries[end_index - 1 - i].timestamp = end_ts;
4370 }
4371}
4372
4373static int add_tts_entry(MOVTimeToSample **tts_data, unsigned int *tts_count, unsigned int *allocated_size,
4374 int count, int offset, unsigned int duration)
4375{
4376 MOVTimeToSample *tts_buf_new;
4377 const size_t min_size_needed = (*tts_count + 1) * sizeof(MOVTimeToSample);
4378 const size_t requested_size =
4379 min_size_needed > *allocated_size ?
4380 FFMAX(min_size_needed, 2 * (*allocated_size)) :
4381 min_size_needed;
4382
4383 if ((unsigned)(*tts_count) >= UINT_MAX / sizeof(MOVTimeToSample) - 1)
4384 return -1;
4385
4386 tts_buf_new = av_fast_realloc(*tts_data, allocated_size, requested_size);
4387
4388 if (!tts_buf_new)
4389 return -1;
4390
4391 *tts_data = tts_buf_new;
4392
4393 tts_buf_new[*tts_count].count = count;
4394 tts_buf_new[*tts_count].offset = offset;
4395 tts_buf_new[*tts_count].duration = duration;
4396
4397 *tts_count = (*tts_count) + 1;
4398 return 0;
4399}
4400
4401#define MAX_REORDER_DELAY 16
4403{
4404 MOVStreamContext *msc = st->priv_data;
4405 FFStream *const sti = ffstream(st);
4406 int ctts_ind = 0;
4407 int ctts_sample = 0;
4408 int64_t pts_buf[MAX_REORDER_DELAY + 1]; // Circular buffer to sort pts.
4409 int buf_start = 0;
4410 int j, r, num_swaps;
4411
4412 for (j = 0; j < MAX_REORDER_DELAY + 1; j++)
4413 pts_buf[j] = INT64_MIN;
4414
4415 if (st->codecpar->video_delay <= 0 && msc->ctts_count &&
4417 st->codecpar->video_delay = 0;
4418 for (int ind = 0; ind < sti->nb_index_entries && ctts_ind < msc->tts_count; ++ind) {
4419 // Point j to the last elem of the buffer and insert the current pts there.
4420 j = buf_start;
4421 buf_start = (buf_start + 1);
4422 if (buf_start == MAX_REORDER_DELAY + 1)
4423 buf_start = 0;
4424
4425 pts_buf[j] = sti->index_entries[ind].timestamp + msc->tts_data[ctts_ind].offset;
4426
4427 // The timestamps that are already in the sorted buffer, and are greater than the
4428 // current pts, are exactly the timestamps that need to be buffered to output PTS
4429 // in correct sorted order.
4430 // Hence the video delay (which is the buffer size used to sort DTS and output PTS),
4431 // can be computed as the maximum no. of swaps any particular timestamp needs to
4432 // go through, to keep this buffer in sorted order.
4433 num_swaps = 0;
4434 while (j != buf_start) {
4435 r = j - 1;
4436 if (r < 0) r = MAX_REORDER_DELAY;
4437 if (pts_buf[j] < pts_buf[r]) {
4438 FFSWAP(int64_t, pts_buf[j], pts_buf[r]);
4439 ++num_swaps;
4440 } else {
4441 break;
4442 }
4443 j = r;
4444 }
4445 st->codecpar->video_delay = FFMAX(st->codecpar->video_delay, num_swaps);
4446
4447 ctts_sample++;
4448 if (ctts_sample == msc->tts_data[ctts_ind].count) {
4449 ctts_ind++;
4450 ctts_sample = 0;
4451 }
4452 }
4453 av_log(c->fc, AV_LOG_DEBUG, "Setting codecpar->delay to %d for stream st: %d\n",
4454 st->codecpar->video_delay, st->index);
4455 }
4456}
4457
4459{
4460 sc->current_sample++;
4461 sc->current_index++;
4462 if (sc->index_ranges &&
4464 sc->current_index_range->end) {
4465 sc->current_index_range++;
4467 }
4468}
4469
4471{
4472 sc->current_sample--;
4473 sc->current_index--;
4474 if (sc->index_ranges &&
4477 sc->current_index_range--;
4478 sc->current_index = sc->current_index_range->end - 1;
4479 }
4480}
4481
4482static void mov_current_sample_set(MOVStreamContext *sc, int current_sample)
4483{
4484 int64_t range_size;
4485
4486 sc->current_sample = current_sample;
4487 sc->current_index = current_sample;
4488 if (!sc->index_ranges) {
4489 return;
4490 }
4491
4492 for (sc->current_index_range = sc->index_ranges;
4494 sc->current_index_range++) {
4495 range_size = sc->current_index_range->end - sc->current_index_range->start;
4496 if (range_size > current_sample) {
4497 sc->current_index = sc->current_index_range->start + current_sample;
4498 break;
4499 }
4500 current_sample -= range_size;
4501 }
4502}
4503
4504/**
4505 * Fix ffstream(st)->index_entries, so that it contains only the entries (and the entries
4506 * which are needed to decode them) that fall in the edit list time ranges.
4507 * Also fixes the timestamps of the index entries to match the timeline
4508 * specified the edit lists.
4509 */
4510static void mov_fix_index(MOVContext *mov, AVStream *st)
4511{
4512 MOVStreamContext *msc = st->priv_data;
4513 FFStream *const sti = ffstream(st);
4514 AVIndexEntry *e_old = sti->index_entries;
4515 int nb_old = sti->nb_index_entries;
4516 const AVIndexEntry *e_old_end = e_old + nb_old;
4517 const AVIndexEntry *current = NULL;
4518 MOVTimeToSample *tts_data_old = msc->tts_data;
4519 int64_t tts_index_old = 0;
4520 int64_t tts_sample_old = 0;
4521 int64_t tts_count_old = msc->tts_count;
4522 int64_t edit_list_media_time = 0;
4523 int64_t edit_list_duration = 0;
4524 int64_t frame_duration = 0;
4525 int64_t edit_list_dts_counter = 0;
4526 int64_t edit_list_dts_entry_end = 0;
4527 int64_t edit_list_start_tts_sample = 0;
4528 int64_t curr_cts;
4529 int64_t curr_ctts = 0;
4530 int64_t empty_edits_sum_duration = 0;
4531 int64_t edit_list_index = 0;
4532 int64_t index;
4533 int flags;
4534 int64_t start_dts = 0;
4535 int64_t edit_list_start_encountered = 0;
4536 int64_t search_timestamp = 0;
4537 int64_t* frame_duration_buffer = NULL;
4538 int num_discarded_begin = 0;
4539 int first_non_zero_audio_edit = -1;
4540 int packet_skip_samples = 0;
4541 MOVIndexRange *current_index_range = NULL;
4542 int found_keyframe_after_edit = 0;
4543 int found_non_empty_edit = 0;
4544
4545 if (!msc->elst_data || msc->elst_count <= 0 || nb_old <= 0) {
4546 return;
4547 }
4548
4549 // allocate the index ranges array
4550 msc->index_ranges = av_malloc_array(msc->elst_count + 1,
4551 sizeof(msc->index_ranges[0]));
4552 if (!msc->index_ranges) {
4553 av_log(mov->fc, AV_LOG_ERROR, "Cannot allocate index ranges buffer\n");
4554 return;
4555 }
4557
4558 // Clean AVStream from traces of old index
4559 sti->index_entries = NULL;
4561 sti->nb_index_entries = 0;
4562
4563 // Clean time to sample fields of MOVStreamContext
4564 msc->tts_data = NULL;
4565 msc->tts_count = 0;
4566 msc->tts_index = 0;
4567 msc->tts_sample = 0;
4568 msc->tts_allocated_size = 0;
4569
4570 // Reinitialize min_corrected_pts so that it can be computed again.
4571 msc->min_corrected_pts = -1;
4572
4573 // If the dts_shift is positive (in case of negative ctts values in mov),
4574 // then negate the DTS by dts_shift
4575 if (msc->dts_shift > 0) {
4576 edit_list_dts_entry_end -= msc->dts_shift;
4577 av_log(mov->fc, AV_LOG_DEBUG, "Shifting DTS by %d because of negative CTTS.\n", msc->dts_shift);
4578 }
4579
4580 start_dts = edit_list_dts_entry_end;
4581
4582 while (get_edit_list_entry(mov, msc, edit_list_index, &edit_list_media_time,
4583 &edit_list_duration, mov->time_scale)) {
4584 av_log(mov->fc, AV_LOG_DEBUG, "Processing st: %d, edit list %"PRId64" - media time: %"PRId64", duration: %"PRId64"\n",
4585 st->index, edit_list_index, edit_list_media_time, edit_list_duration);
4586 edit_list_index++;
4587 edit_list_dts_counter = edit_list_dts_entry_end;
4588 edit_list_dts_entry_end = av_sat_add64(edit_list_dts_entry_end, edit_list_duration);
4589 if (edit_list_dts_entry_end == INT64_MAX) {
4590 av_log(mov->fc, AV_LOG_ERROR, "Cannot calculate dts entry length with duration %"PRId64"\n",
4591 edit_list_duration);
4592 break;
4593 }
4594 num_discarded_begin = 0;
4595 if (!found_non_empty_edit && edit_list_media_time == -1) {
4596 empty_edits_sum_duration += edit_list_duration;
4597 continue;
4598 }
4599 found_non_empty_edit = 1;
4600
4601 // If we encounter a non-negative edit list reset the skip_samples/initial_padding fields and set them
4602 // according to the edit list below.
4604 if (first_non_zero_audio_edit < 0) {
4605 first_non_zero_audio_edit = 1;
4606 } else {
4607 first_non_zero_audio_edit = 0;
4608 }
4609
4610 if (first_non_zero_audio_edit > 0)
4611 sti->skip_samples = st->codecpar->initial_padding = 0;
4612 }
4613
4614 // While reordering frame index according to edit list we must handle properly
4615 // the scenario when edit list entry starts from none key frame.
4616 // We find closest previous key frame and preserve it and consequent frames in index.
4617 // All frames which are outside edit list entry time boundaries will be dropped after decoding.
4618 search_timestamp = edit_list_media_time;
4620 // Audio decoders like AAC need need a decoder delay samples previous to the current sample,
4621 // to correctly decode this frame. Hence for audio we seek to a frame 1 sec. before the
4622 // edit_list_media_time to cover the decoder delay.
4623 search_timestamp = FFMAX(search_timestamp - msc->time_scale, e_old[0].timestamp);
4624 }
4625
4626 if (find_prev_closest_index(st, e_old, nb_old, tts_data_old, tts_count_old, search_timestamp, 0,
4627 &index, &tts_index_old, &tts_sample_old) < 0) {
4628 av_log(mov->fc, AV_LOG_WARNING,
4629 "st: %d edit list: %"PRId64" Missing key frame while searching for timestamp: %"PRId64"\n",
4630 st->index, edit_list_index, search_timestamp);
4631 if (find_prev_closest_index(st, e_old, nb_old, tts_data_old, tts_count_old, search_timestamp, AVSEEK_FLAG_ANY,
4632 &index, &tts_index_old, &tts_sample_old) < 0) {
4633 av_log(mov->fc, AV_LOG_WARNING,
4634 "st: %d edit list %"PRId64" Cannot find an index entry before timestamp: %"PRId64".\n",
4635 st->index, edit_list_index, search_timestamp);
4636 index = 0;
4637 tts_index_old = 0;
4638 tts_sample_old = 0;
4639 }
4640 }
4641 current = e_old + index;
4642 edit_list_start_tts_sample = tts_sample_old;
4643
4644 // Iterate over index and arrange it according to edit list
4645 edit_list_start_encountered = 0;
4646 found_keyframe_after_edit = 0;
4647 for (; current < e_old_end; current++, index++) {
4648 // check if frame outside edit list mark it for discard
4649 frame_duration = (current + 1 < e_old_end) ?
4650 ((current + 1)->timestamp - current->timestamp) : edit_list_duration;
4651
4652 flags = current->flags;
4653
4654 // frames (pts) before or after edit list
4655 curr_cts = current->timestamp + msc->dts_shift;
4656 curr_ctts = 0;
4657
4658 if (tts_data_old && tts_index_old < tts_count_old) {
4659 curr_ctts = tts_data_old[tts_index_old].offset;
4660 av_log(mov->fc, AV_LOG_TRACE, "stts: %"PRId64" ctts: %"PRId64", tts_index: %"PRId64", tts_count: %"PRId64"\n",
4661 curr_cts, curr_ctts, tts_index_old, tts_count_old);
4662 curr_cts += curr_ctts;
4663 tts_sample_old++;
4664 if (tts_sample_old == tts_data_old[tts_index_old].count) {
4665 if (add_tts_entry(&msc->tts_data, &msc->tts_count,
4666 &msc->tts_allocated_size,
4667 tts_data_old[tts_index_old].count - edit_list_start_tts_sample,
4668 tts_data_old[tts_index_old].offset, tts_data_old[tts_index_old].duration) == -1) {
4669 av_log(mov->fc, AV_LOG_ERROR, "Cannot add Time To Sample entry %"PRId64" - {%"PRId64", %d}\n",
4670 tts_index_old,
4671 tts_data_old[tts_index_old].count - edit_list_start_tts_sample,
4672 tts_data_old[tts_index_old].offset);
4673 break;
4674 }
4675 tts_index_old++;
4676 tts_sample_old = 0;
4677 edit_list_start_tts_sample = 0;
4678 }
4679 }
4680
4681 if (curr_cts < edit_list_media_time || curr_cts >= (edit_list_duration + edit_list_media_time)) {
4683 curr_cts < edit_list_media_time && curr_cts + frame_duration > edit_list_media_time &&
4684 first_non_zero_audio_edit > 0) {
4685 packet_skip_samples = edit_list_media_time - curr_cts;
4686 sti->skip_samples += packet_skip_samples;
4687
4688 // Shift the index entry timestamp by packet_skip_samples to be correct.
4689 edit_list_dts_counter -= packet_skip_samples;
4690 if (edit_list_start_encountered == 0) {
4691 edit_list_start_encountered = 1;
4692 // Make timestamps strictly monotonically increasing for audio, by rewriting timestamps for
4693 // discarded packets.
4694 if (frame_duration_buffer) {
4695 fix_index_entry_timestamps(st, sti->nb_index_entries, edit_list_dts_counter,
4696 frame_duration_buffer, num_discarded_begin);
4697 av_freep(&frame_duration_buffer);
4698 }
4699 }
4700
4701 av_log(mov->fc, AV_LOG_DEBUG, "skip %d audio samples from curr_cts: %"PRId64"\n", packet_skip_samples, curr_cts);
4702 } else {
4704 av_log(mov->fc, AV_LOG_DEBUG, "drop a frame at curr_cts: %"PRId64" @ %"PRId64"\n", curr_cts, index);
4705
4706 if (edit_list_start_encountered == 0) {
4707 num_discarded_begin++;
4708 if (av_reallocp_array(&frame_duration_buffer, num_discarded_begin,
4709 sizeof(*frame_duration_buffer)) < 0) {
4710 av_log(mov->fc, AV_LOG_ERROR, "Cannot reallocate frame duration buffer\n");
4711 break;
4712 }
4713 frame_duration_buffer[num_discarded_begin - 1] = frame_duration;
4714
4715 // Increment skip_samples for the first non-zero audio edit list
4717 first_non_zero_audio_edit > 0 && st->codecpar->codec_id != AV_CODEC_ID_VORBIS) {
4718 sti->skip_samples += frame_duration;
4719 }
4720 }
4721 }
4722 } else {
4723 if (msc->min_corrected_pts < 0) {
4724 msc->min_corrected_pts = edit_list_dts_counter + curr_ctts + msc->dts_shift;
4725 } else {
4726 msc->min_corrected_pts = FFMIN(msc->min_corrected_pts, edit_list_dts_counter + curr_ctts + msc->dts_shift);
4727 }
4728 if (edit_list_start_encountered == 0) {
4729 edit_list_start_encountered = 1;
4730 // Make timestamps strictly monotonically increasing by rewriting timestamps for
4731 // discarded packets.
4732 if (frame_duration_buffer) {
4733 fix_index_entry_timestamps(st, sti->nb_index_entries, edit_list_dts_counter,
4734 frame_duration_buffer, num_discarded_begin);
4735 av_freep(&frame_duration_buffer);
4736 }
4737 }
4738 }
4739
4740 if (add_index_entry(st, current->pos, edit_list_dts_counter, current->size,
4741 current->min_distance, flags) == -1) {
4742 av_log(mov->fc, AV_LOG_ERROR, "Cannot add index entry\n");
4743 break;
4744 }
4745
4746 // Update the index ranges array
4747 if (!current_index_range || index != current_index_range->end) {
4748 current_index_range = current_index_range ? current_index_range + 1
4749 : msc->index_ranges;
4750 current_index_range->start = index;
4751 }
4752 current_index_range->end = index + 1;
4753
4754 // Only start incrementing DTS in frame_duration amounts, when we encounter a frame in edit list.
4755 if (edit_list_start_encountered > 0) {
4756 edit_list_dts_counter = edit_list_dts_counter + frame_duration;
4757 }
4758
4759 // Break when found first key frame after edit entry completion
4760 if ((curr_cts + frame_duration >= (edit_list_duration + edit_list_media_time)) &&
4762 if (msc->ctts_count) {
4763 // If we have CTTS and this is the first keyframe after edit elist,
4764 // wait for one more, because there might be trailing B-frames after this I-frame
4765 // that do belong to the edit.
4766 if (st->codecpar->codec_type != AVMEDIA_TYPE_AUDIO && found_keyframe_after_edit == 0) {
4767 found_keyframe_after_edit = 1;
4768 continue;
4769 }
4770 if (tts_sample_old != 0) {
4771 if (add_tts_entry(&msc->tts_data, &msc->tts_count,
4772 &msc->tts_allocated_size,
4773 tts_sample_old - edit_list_start_tts_sample,
4774 tts_data_old[tts_index_old].offset, tts_data_old[tts_index_old].duration) == -1) {
4775 av_log(mov->fc, AV_LOG_ERROR, "Cannot add Time To Sample entry %"PRId64" - {%"PRId64", %d}\n",
4776 tts_index_old, tts_sample_old - edit_list_start_tts_sample,
4777 tts_data_old[tts_index_old].offset);
4778 break;
4779 }
4780 }
4781 }
4782 break;
4783 }
4784 }
4785 }
4786 // If there are empty edits, then msc->min_corrected_pts might be positive
4787 // intentionally. So we subtract the sum duration of empty edits here.
4788 msc->min_corrected_pts -= empty_edits_sum_duration;
4789
4790 // If the minimum pts turns out to be greater than zero after fixing the index, then we subtract the
4791 // dts by that amount to make the first pts zero.
4793 if (msc->min_corrected_pts > 0) {
4794 av_log(mov->fc, AV_LOG_DEBUG, "Offset DTS by %"PRId64" to make first pts zero.\n", msc->min_corrected_pts);
4795 for (int i = 0; i < sti->nb_index_entries; ++i)
4797 }
4798 }
4799 // Start time should be equal to zero or the duration of any empty edits.
4800 st->start_time = empty_edits_sum_duration;
4801
4802 // Update av stream length, if it ends up shorter than the track's media duration
4803 st->duration = FFMIN(st->duration, edit_list_dts_entry_end - start_dts);
4805
4806 // Free the old index and the old CTTS structures
4807 av_free(e_old);
4808 av_free(tts_data_old);
4809 av_freep(&frame_duration_buffer);
4810
4811 // Null terminate the index ranges array
4812 current_index_range = current_index_range ? current_index_range + 1
4813 : msc->index_ranges;
4814 current_index_range->start = 0;
4815 current_index_range->end = 0;
4816 msc->current_index = msc->index_ranges[0].start;
4817}
4818
4819static uint32_t get_sgpd_sync_index(const MOVStreamContext *sc, int nal_unit_type)
4820{
4821 for (uint32_t i = 0; i < sc->sgpd_sync_count; i++)
4822 if (sc->sgpd_sync[i] == nal_unit_type)
4823 return i + 1;
4824 return 0;
4825}
4826
4828{
4829 int k;
4830 int sample_id = 0;
4831 uint32_t cra_index;
4832 MOVStreamContext *sc = st->priv_data;
4833
4835 return 0;
4836
4837 /* Build an unrolled index of the samples */
4838 sc->sample_offsets_count = 0;
4839 for (uint32_t i = 0; i < sc->ctts_count; i++) {
4840 if (sc->ctts_data[i].count > INT_MAX - sc->sample_offsets_count)
4841 return AVERROR(ENOMEM);
4843 }
4846 if (!sc->sample_offsets)
4847 return AVERROR(ENOMEM);
4848 k = 0;
4849 for (uint32_t i = 0; i < sc->ctts_count; i++)
4850 for (int j = 0; j < sc->ctts_data[i].count; j++)
4851 sc->sample_offsets[k++] = sc->ctts_data[i].offset;
4852
4853 /* The following HEVC NAL type reveal the use of open GOP sync points
4854 * (TODO: BLA types may also be concerned) */
4855 cra_index = get_sgpd_sync_index(sc, HEVC_NAL_CRA_NUT); /* Clean Random Access */
4856 if (!cra_index)
4857 return 0;
4858
4859 /* Build a list of open-GOP key samples */
4860 sc->open_key_samples_count = 0;
4861 for (uint32_t i = 0; i < sc->sync_group_count; i++)
4862 if (sc->sync_group[i].index == cra_index) {
4863 if (sc->sync_group[i].count > INT_MAX - sc->open_key_samples_count)
4864 return AVERROR(ENOMEM);
4866 }
4869 if (!sc->open_key_samples)
4870 return AVERROR(ENOMEM);
4871 k = 0;
4872 for (uint32_t i = 0; i < sc->sync_group_count; i++) {
4873 const MOVSbgp *sg = &sc->sync_group[i];
4874 if (sg->index == cra_index)
4875 for (uint32_t j = 0; j < sg->count; j++)
4876 sc->open_key_samples[k++] = sample_id;
4877 if (sg->count > INT_MAX - sample_id)
4878 return AVERROR_PATCHWELCOME;
4879 sample_id += sg->count;
4880 }
4881
4882 /* Identify the minimal time step between samples */
4883 sc->min_sample_duration = UINT_MAX;
4884 for (uint32_t i = 0; i < sc->stts_count; i++)
4886
4887 return 0;
4888}
4889
4890#define MOV_MERGE_CTTS 1
4891#define MOV_MERGE_STTS 2
4892/*
4893 * Merge stts and ctts arrays into a new combined array.
4894 * stts_count and ctts_count may be left untouched as they will be
4895 * used to check for the presence of either of them.
4896 */
4898{
4899 MOVStreamContext *sc = st->priv_data;
4900 int ctts = sc->ctts_data && (flags & MOV_MERGE_CTTS);
4901 int stts = sc->stts_data && (flags & MOV_MERGE_STTS);
4902 int idx = 0;
4903
4904 if (!sc->ctts_data && !sc->stts_data)
4905 return 0;
4906 // Expand time to sample entries such that we have a 1-1 mapping with samples
4907 if (!sc->sample_count || sc->sample_count >= UINT_MAX / sizeof(*sc->tts_data))
4908 return -1;
4909
4910 if (ctts) {
4912 sc->sample_count * sizeof(*sc->tts_data));
4913 if (!sc->tts_data)
4914 return -1;
4915
4916 memset(sc->tts_data, 0, sc->tts_allocated_size);
4917
4918 for (int i = 0; i < sc->ctts_count &&
4919 idx < sc->sample_count; i++)
4920 for (int j = 0; j < sc->ctts_data[i].count &&
4921 idx < sc->sample_count; j++) {
4922 sc->tts_data[idx].offset = sc->ctts_data[i].offset;
4923 sc->tts_data[idx++].count = 1;
4924 }
4925
4926 sc->tts_count = idx;
4927 } else
4928 sc->ctts_count = 0;
4929 av_freep(&sc->ctts_data);
4930 sc->ctts_allocated_size = 0;
4931
4932 idx = 0;
4933 if (stts) {
4935 sc->sample_count * sizeof(*sc->tts_data));
4936 if (!tts_data)
4937 return -1;
4938
4939 if (!sc->tts_data)
4940 memset(tts_data, 0, sc->tts_allocated_size);
4941 sc->tts_data = tts_data;
4942
4943 for (int i = 0; i < sc->stts_count &&
4944 idx < sc->sample_count; i++)
4945 for (int j = 0; j < sc->stts_data[i].count &&
4946 idx < sc->sample_count; j++) {
4947 sc->tts_data[idx].duration = sc->stts_data[i].duration;
4948 sc->tts_data[idx++].count = 1;
4949 }
4950
4951 sc->tts_count = FFMAX(sc->tts_count, idx);
4952 } else
4953 sc->stts_count = 0;
4954 av_freep(&sc->stts_data);
4955 sc->stts_allocated_size = 0;
4956
4957 return 0;
4958}
4959
4961{
4962 MOVStreamContext *sc = st->priv_data;
4963 FFStream *const sti = ffstream(st);
4964 int64_t current_offset;
4965 int64_t current_dts = 0;
4966 unsigned int stts_index = 0;
4967 unsigned int stsc_index = 0;
4968 unsigned int stss_index = 0;
4969 unsigned int stps_index = 0;
4970 unsigned int i, j;
4971 uint64_t stream_size = 0;
4972
4973 int ret = build_open_gop_key_points(st);
4974 if (ret < 0)
4975 return;
4976
4977 if (sc->elst_count) {
4978 int i, edit_start_index = 0, multiple_edits = 0;
4979 int64_t empty_duration = 0; // empty duration of the first edit list entry
4980 int64_t start_time = 0; // start time of the media
4981
4982 for (i = 0; i < sc->elst_count; i++) {
4983 const MOVElst *e = &sc->elst_data[i];
4984 if (i == 0 && e->time == -1) {
4985 /* if empty, the first entry is the start time of the stream
4986 * relative to the presentation itself */
4987 empty_duration = e->duration;
4988 edit_start_index = 1;
4989 } else if (i == edit_start_index && e->time >= 0) {
4990 start_time = e->time;
4991 } else {
4992 multiple_edits = 1;
4993 }
4994 }
4995
4996 if (multiple_edits && !mov->advanced_editlist) {
4998 av_log(mov->fc, AV_LOG_WARNING, "multiple edit list entries, "
4999 "not supported in fragmented MP4 files\n");
5000 else
5001 av_log(mov->fc, AV_LOG_WARNING, "multiple edit list entries, "
5002 "Use -advanced_editlist to correctly decode otherwise "
5003 "a/v desync might occur\n");
5004 }
5005
5006 /* adjust first dts according to edit list */
5007 if ((empty_duration || start_time) && mov->time_scale > 0) {
5008 if (empty_duration)
5009 empty_duration = av_rescale(empty_duration, sc->time_scale, mov->time_scale);
5010
5011 if (av_sat_sub64(start_time, empty_duration) != start_time - (uint64_t)empty_duration)
5012 av_log(mov->fc, AV_LOG_WARNING, "start_time - empty_duration is not representable\n");
5013
5014 sc->time_offset = start_time - (uint64_t)empty_duration;
5016 if (!mov->advanced_editlist)
5017 current_dts = -av_clip64(sc->time_offset, -INT64_MAX, INT64_MAX);
5018 }
5019
5020 if (!multiple_edits && !mov->advanced_editlist &&
5023 (AVRational){1, st->codecpar->sample_rate});
5024 }
5025
5026 /* only use old uncompressed audio chunk demuxing when stts specifies it */
5027 if (!(st->codecpar->codec_type == AVMEDIA_TYPE_AUDIO &&
5028 sc->stts_count == 1 && sc->stts_data && sc->stts_data[0].duration == 1)) {
5029 unsigned int current_sample = 0;
5030 unsigned int stts_sample = 0;
5031 unsigned int sample_size;
5032 unsigned int distance = 0;
5033 unsigned int rap_group_index = 0;
5034 unsigned int rap_group_sample = 0;
5035 int rap_group_present = sc->rap_group_count && sc->rap_group;
5036 int key_off = (sc->keyframe_count && sc->keyframes[0] > 0) || (sc->stps_count && sc->stps_data[0] > 0);
5037
5038 av_assert0(sc->dts_shift >= 0);
5039 if (current_dts < INT64_MIN + sc->dts_shift)
5040 return;
5041 current_dts -= sc->dts_shift;
5042 if (!sc->sample_count || sti->nb_index_entries || sc->tts_count)
5043 return;
5044 if (sc->sample_count >= UINT_MAX / sizeof(*sti->index_entries) - sti->nb_index_entries)
5045 return;
5047 sti->nb_index_entries + sc->sample_count,
5048 sizeof(*sti->index_entries)) < 0) {
5049 sti->nb_index_entries = 0;
5050 return;
5051 }
5052 sti->index_entries_allocated_size = (sti->nb_index_entries + sc->sample_count) * sizeof(*sti->index_entries);
5053
5055 if (ret < 0)
5056 return;
5057
5058 for (i = 0; i < sc->chunk_count; i++) {
5059 int64_t next_offset = i+1 < sc->chunk_count ? sc->chunk_offsets[i+1] : INT64_MAX;
5060 current_offset = sc->chunk_offsets[i];
5061 while (mov_stsc_index_valid(stsc_index, sc->stsc_count) &&
5062 i + 1 == sc->stsc_data[stsc_index + 1].first)
5063 stsc_index++;
5064
5065 if (next_offset > current_offset && sc->sample_size>0 && sc->sample_size < sc->stsz_sample_size &&
5066 sc->stsc_data[stsc_index].count * (int64_t)sc->stsz_sample_size > next_offset - current_offset) {
5067 av_log(mov->fc, AV_LOG_WARNING, "STSZ sample size %d invalid (too large), ignoring\n", sc->stsz_sample_size);
5068 sc->stsz_sample_size = sc->sample_size;
5069 }
5070 if (sc->stsz_sample_size>0 && sc->stsz_sample_size < sc->sample_size) {
5071 av_log(mov->fc, AV_LOG_WARNING, "STSZ sample size %d invalid (too small), ignoring\n", sc->stsz_sample_size);
5072 sc->stsz_sample_size = sc->sample_size;
5073 }
5074
5075 for (j = 0; j < sc->stsc_data[stsc_index].count; j++) {
5076 int keyframe = 0;
5077 if (current_sample >= sc->sample_count) {
5078 av_log(mov->fc, AV_LOG_ERROR, "wrong sample count\n");
5079 return;
5080 }
5081
5082 if (!sc->keyframe_absent && (!sc->keyframe_count || current_sample+key_off == sc->keyframes[stss_index])) {
5083 keyframe = 1;
5084 if (stss_index + 1 < sc->keyframe_count)
5085 stss_index++;
5086 } else if (sc->stps_count && current_sample+key_off == sc->stps_data[stps_index]) {
5087 keyframe = 1;
5088 if (stps_index + 1 < sc->stps_count)
5089 stps_index++;
5090 }
5091 if (rap_group_present && rap_group_index < sc->rap_group_count) {
5092 if (sc->rap_group[rap_group_index].index > 0)
5093 keyframe = 1;
5094 if (++rap_group_sample == sc->rap_group[rap_group_index].count) {
5095 rap_group_sample = 0;
5096 rap_group_index++;
5097 }
5098 }
5099 if (sc->keyframe_absent
5100 && !sc->stps_count
5101 && !rap_group_present
5102 && (st->codecpar->codec_type == AVMEDIA_TYPE_AUDIO || (i==0 && j==0)))
5103 keyframe = 1;
5104 if (keyframe)
5105 distance = 0;
5106 sample_size = sc->stsz_sample_size > 0 ? sc->stsz_sample_size : sc->sample_sizes[current_sample];
5107 if (current_offset > INT64_MAX - sample_size) {
5108 av_log(mov->fc, AV_LOG_ERROR, "Current offset %"PRId64" or sample size %u is too large\n",
5109 current_offset,
5110 sample_size);
5111 return;
5112 }
5113
5114 if (sc->pseudo_stream_id == -1 ||
5115 sc->stsc_data[stsc_index].id - 1 == sc->pseudo_stream_id) {
5116 AVIndexEntry *e;
5117 if (sample_size > 0x3FFFFFFF) {
5118 av_log(mov->fc, AV_LOG_ERROR, "Sample size %u is too large\n", sample_size);
5119 return;
5120 }
5121 e = &sti->index_entries[sti->nb_index_entries++];
5122 e->pos = current_offset;
5123 e->timestamp = current_dts;
5124 e->size = sample_size;
5126 e->flags = keyframe ? AVINDEX_KEYFRAME : 0;
5127 av_log(mov->fc, AV_LOG_TRACE, "AVIndex stream %d, sample %u, offset %"PRIx64", dts %"PRId64", "
5128 "size %u, distance %u, keyframe %d\n", st->index, current_sample,
5129 current_offset, current_dts, sample_size, distance, keyframe);
5130 if (st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO && sti->nb_index_entries < 100)
5131 ff_rfps_add_frame(mov->fc, st, current_dts);
5132 }
5133
5134 current_offset += sample_size;
5135 stream_size += sample_size;
5136
5137 if (current_dts > INT64_MAX - sc->tts_data[stts_index].duration)
5138 return;
5139 current_dts += sc->tts_data[stts_index].duration;
5140
5141 distance++;
5142 stts_sample++;
5143 current_sample++;
5144 if (stts_index + 1 < sc->tts_count && stts_sample == sc->tts_data[stts_index].count) {
5145 stts_sample = 0;
5146 stts_index++;
5147 }
5148 }
5149 }
5150 if (st->duration > 0)
5151 st->codecpar->bit_rate = stream_size*8*sc->time_scale/st->duration;
5152 } else {
5153 unsigned chunk_samples, total = 0;
5154
5155 if (!sc->chunk_count || sc->tts_count)
5156 return;
5157
5158 // compute total chunk count
5159 for (i = 0; i < sc->stsc_count; i++) {
5160 unsigned count, chunk_count;
5161
5162 chunk_samples = sc->stsc_data[i].count;
5163 if (i != sc->stsc_count - 1 &&
5164 sc->samples_per_frame && chunk_samples % sc->samples_per_frame) {
5165 av_log(mov->fc, AV_LOG_ERROR, "error unaligned chunk\n");
5166 return;
5167 }
5168
5169 if (sc->samples_per_frame >= 160) { // gsm
5170 count = chunk_samples / sc->samples_per_frame;
5171 } else if (sc->samples_per_frame > 1) {
5172 unsigned samples = (1024/sc->samples_per_frame)*sc->samples_per_frame;
5173 count = (chunk_samples+samples-1) / samples;
5174 } else {
5175 count = (chunk_samples+1023) / 1024;
5176 }
5177
5179 chunk_count = sc->stsc_data[i+1].first - sc->stsc_data[i].first;
5180 else
5181 chunk_count = sc->chunk_count - (sc->stsc_data[i].first - 1);
5182 total += chunk_count * count;
5183 }
5184
5185 av_log(mov->fc, AV_LOG_TRACE, "chunk count %u\n", total);
5186 if (total >= UINT_MAX / sizeof(*sti->index_entries) - sti->nb_index_entries)
5187 return;
5189 sti->nb_index_entries + total,
5190 sizeof(*sti->index_entries)) < 0) {
5191 sti->nb_index_entries = 0;
5192 return;
5193 }
5194 sti->index_entries_allocated_size = (sti->nb_index_entries + total) * sizeof(*sti->index_entries);
5195
5196 // populate index
5197 for (i = 0; i < sc->chunk_count; i++) {
5198 current_offset = sc->chunk_offsets[i];
5199 if (mov_stsc_index_valid(stsc_index, sc->stsc_count) &&
5200 i + 1 == sc->stsc_data[stsc_index + 1].first)
5201 stsc_index++;
5202 chunk_samples = sc->stsc_data[stsc_index].count;
5203
5204 while (chunk_samples > 0) {
5205 AVIndexEntry *e;
5206 unsigned size, samples;
5207
5208 if (sc->samples_per_frame > 1 && !sc->bytes_per_frame) {
5210 "Zero bytes per frame, but %d samples per frame",
5211 sc->samples_per_frame);
5212 return;
5213 }
5214
5215 if (sc->samples_per_frame >= 160) { // gsm
5216 samples = sc->samples_per_frame;
5217 size = sc->bytes_per_frame;
5218 } else {
5219 if (sc->samples_per_frame > 1) {
5220 samples = FFMIN((1024 / sc->samples_per_frame)*
5221 sc->samples_per_frame, chunk_samples);
5222 size = (samples / sc->samples_per_frame) * sc->bytes_per_frame;
5223 } else {
5224 samples = FFMIN(1024, chunk_samples);
5225 size = samples * sc->sample_size;
5226 }
5227 }
5228
5229 if (sti->nb_index_entries >= total) {
5230 av_log(mov->fc, AV_LOG_ERROR, "wrong chunk count %u\n", total);
5231 return;
5232 }
5233 if (size > 0x3FFFFFFF) {
5234 av_log(mov->fc, AV_LOG_ERROR, "Sample size %u is too large\n", size);
5235 return;
5236 }
5237 e = &sti->index_entries[sti->nb_index_entries++];
5238 e->pos = current_offset;
5239 e->timestamp = current_dts;
5240 e->size = size;
5241 e->min_distance = 0;
5243 av_log(mov->fc, AV_LOG_TRACE, "AVIndex stream %d, chunk %u, offset %"PRIx64", dts %"PRId64", "
5244 "size %u, duration %u\n", st->index, i, current_offset, current_dts,
5245 size, samples);
5246
5247 current_offset += size;
5248 if (current_dts > INT64_MAX - samples)
5249 return;
5250 current_dts += samples;
5251 chunk_samples -= samples;
5252 }
5253 }
5254
5255 ret = mov_merge_tts_data(mov, st, MOV_MERGE_CTTS);
5256 if (ret < 0)
5257 return;
5258 }
5259
5260 if (!mov->ignore_editlist && mov->advanced_editlist) {
5261 // Fix index according to edit lists.
5262 mov_fix_index(mov, st);
5263 }
5264
5265 // Update start time of the stream.
5268 if (sc->tts_data) {
5270 }
5271 }
5272
5273 mov_estimate_video_delay(mov, st);
5274}
5275
5280
5281static int mov_compare_presentation_samples(const void *a, const void *b)
5282{
5283 const MOVPresentationSample *sa = a;
5284 const MOVPresentationSample *sb = b;
5285
5286 if (sa->pts != sb->pts)
5287 return (sa->pts > sb->pts) - (sa->pts < sb->pts);
5288 return (sa->index > sb->index) - (sa->index < sb->index);
5289}
5290
5291/*
5292 * Set sample durations from adjacent presentation timestamps.
5293 */
5295{
5296 MOVStreamContext *sc = st->priv_data;
5297 FFStream *const sti = ffstream(st);
5298 MOVPresentationSample *samples = NULL;
5299 MOVTimeToSample *tts_data = NULL;
5300 unsigned int tts_index = 0, tts_sample = 0;
5301 int count = sti->nb_index_entries;
5302
5303 /* A single STTS entry describes a fixed sample delta. */
5305 !sc->ctts_count || sc->stts_count < 2 ||
5306 !sc->tts_data || count < 2 ||
5307 count >= UINT_MAX / sizeof(*tts_data))
5308 return;
5309
5310 samples = av_malloc_array(count, sizeof(*samples));
5311 tts_data = av_malloc_array(count, sizeof(*tts_data));
5312 if (!samples || !tts_data)
5313 goto fail;
5314
5315 for (int i = 0; i < count; i++) {
5316 int64_t dts, offset;
5317
5318 if (tts_index >= sc->tts_count || !sc->tts_data[tts_index].count)
5319 goto fail;
5320
5321 tts_data[i] = sc->tts_data[tts_index];
5322 tts_data[i].count = 1;
5323
5324 dts = sti->index_entries[i].timestamp;
5325 offset = (int64_t)sc->dts_shift + tts_data[i].offset;
5326 if (dts == AV_NOPTS_VALUE ||
5327 (offset > 0 && dts > INT64_MAX - offset) ||
5328 (offset < 0 && dts < INT64_MIN - offset))
5329 goto fail;
5330
5331 samples[i].index = i;
5332 samples[i].pts = dts + offset;
5333
5334 if (++tts_sample == sc->tts_data[tts_index].count) {
5335 tts_index++;
5336 tts_sample = 0;
5337 }
5338 }
5339 if (tts_index != sc->tts_count || tts_sample)
5340 goto fail;
5341
5342 qsort(samples, count, sizeof(*samples), mov_compare_presentation_samples);
5343
5344 for (int i = 0; i + 1 < count; i++) {
5345 uint64_t duration;
5346
5347 if (samples[i].pts >= samples[i + 1].pts)
5348 goto fail;
5349
5350 /*
5351 * In VFR streams with reordered frames, STTS deltas follow decode
5352 * order while AVPacket.duration follows presentation order. CTTS
5353 * may produce presentation intervals that cannot be obtained by
5354 * merely permuting the STTS deltas, so derive each known duration
5355 * from adjacent PTS.
5356 */
5357 duration = (uint64_t)samples[i + 1].pts - samples[i].pts;
5358 if (!duration || duration > UINT_MAX)
5359 goto fail;
5360
5361 tts_data[samples[i].index].duration = (unsigned int)duration;
5362 }
5363
5364 av_log(mov->fc, AV_LOG_DEBUG,
5365 "Updated sample durations in presentation order for stream %d\n",
5366 st->index);
5367
5368 av_freep(&sc->tts_data);
5369 sc->tts_data = tts_data;
5370 sc->tts_count = count;
5371 sc->tts_allocated_size = count * sizeof(*tts_data);
5372 tts_data = NULL;
5373
5374fail:
5375 av_free(samples);
5376 av_free(tts_data);
5377}
5378
5379static int test_same_origin(const char *src, const char *ref) {
5380 char src_proto[64];
5381 char ref_proto[64];
5382 char src_auth[256];
5383 char ref_auth[256];
5384 char src_host[256];
5385 char ref_host[256];
5386 int src_port=-1;
5387 int ref_port=-1;
5388
5389 av_url_split(src_proto, sizeof(src_proto), src_auth, sizeof(src_auth), src_host, sizeof(src_host), &src_port, NULL, 0, src);
5390 av_url_split(ref_proto, sizeof(ref_proto), ref_auth, sizeof(ref_auth), ref_host, sizeof(ref_host), &ref_port, NULL, 0, ref);
5391
5392 if (strlen(src) == 0) {
5393 return -1;
5394 } else if (strlen(src_auth) + 1 >= sizeof(src_auth) ||
5395 strlen(ref_auth) + 1 >= sizeof(ref_auth) ||
5396 strlen(src_host) + 1 >= sizeof(src_host) ||
5397 strlen(ref_host) + 1 >= sizeof(ref_host)) {
5398 return 0;
5399 } else if (strcmp(src_proto, ref_proto) ||
5400 strcmp(src_auth, ref_auth) ||
5401 strcmp(src_host, ref_host) ||
5402 src_port != ref_port) {
5403 return 0;
5404 } else
5405 return 1;
5406}
5407
5408static int mov_open_dref(MOVContext *c, AVIOContext **pb, const char *src, MOVDref *ref)
5409{
5410 /* try relative path, we do not try the absolute because it can leak information about our
5411 system to an attacker */
5412 if (ref->nlvl_to > 0 && ref->nlvl_from > 0) {
5413 char filename[1025];
5414 const char *src_path;
5415 int i, l;
5416
5417 /* find a source dir */
5418 src_path = strrchr(src, '/');
5419 if (src_path)
5420 src_path++;
5421 else
5422 src_path = src;
5423
5424 /* find a next level down to target */
5425 for (i = 0, l = strlen(ref->path) - 1; l >= 0; l--)
5426 if (ref->path[l] == '/') {
5427 if (i == ref->nlvl_to - 1)
5428 break;
5429 else
5430 i++;
5431 }
5432
5433 /* compose filename if next level down to target was found */
5434 if (i == ref->nlvl_to - 1 && src_path - src < sizeof(filename)) {
5435 memcpy(filename, src, src_path - src);
5436 filename[src_path - src] = 0;
5437
5438 for (i = 1; i < ref->nlvl_from; i++)
5439 av_strlcat(filename, "../", sizeof(filename));
5440
5441 av_strlcat(filename, ref->path + l + 1, sizeof(filename));
5442 if (!c->use_absolute_path) {
5443 int same_origin = test_same_origin(src, filename);
5444
5445 if (!same_origin) {
5446 av_log(c->fc, AV_LOG_ERROR,
5447 "Reference with mismatching origin, %s not tried for security reasons, "
5448 "set demuxer option use_absolute_path to allow it anyway\n",
5449 ref->path);
5450 return AVERROR(ENOENT);
5451 }
5452
5453 if (strstr(ref->path + l + 1, "..") ||
5454 strstr(ref->path + l + 1, ":") ||
5455 (ref->nlvl_from > 1 && same_origin < 0) ||
5456 (filename[0] == '/' && src_path == src))
5457 return AVERROR(ENOENT);
5458 }
5459
5460 if (strlen(filename) + 1 == sizeof(filename))
5461 return AVERROR(ENOENT);
5462 if (!c->fc->io_open(c->fc, pb, filename, AVIO_FLAG_READ, NULL))
5463 return 0;
5464 }
5465 } else if (c->use_absolute_path) {
5466 av_log(c->fc, AV_LOG_WARNING, "Using absolute path on user request, "
5467 "this is a possible security issue\n");
5468 if (!c->fc->io_open(c->fc, pb, ref->path, AVIO_FLAG_READ, NULL))
5469 return 0;
5470 } else {
5471 av_log(c->fc, AV_LOG_ERROR,
5472 "Absolute path %s not tried for security reasons, "
5473 "set demuxer option use_absolute_path to allow absolute paths\n",
5474 ref->path);
5475 }
5476
5477 return AVERROR(ENOENT);
5478}
5479
5481{
5482 if (sc->time_scale <= 0) {
5483 av_log(c->fc, AV_LOG_WARNING, "stream %d, timescale not set\n", sc->ffindex);
5484 sc->time_scale = c->time_scale;
5485 if (sc->time_scale <= 0)
5486 sc->time_scale = 1;
5487 }
5488}
5489
5490#if CONFIG_IAMFDEC
5491static int mov_update_iamf_streams(MOVContext *c, const AVStream *st)
5492{
5493 const MOVStreamContext *sc = st->priv_data;
5494 const IAMFContext *iamf = &sc->iamf->iamf;
5495
5496 for (int i = 0; i < iamf->nb_audio_elements; i++) {
5497 const AVStreamGroup *stg = NULL;
5498
5499 for (int j = 0; j < c->fc->nb_stream_groups; j++)
5500 if (c->fc->stream_groups[j]->id == iamf->audio_elements[i]->audio_element_id)
5501 stg = c->fc->stream_groups[j];
5502 av_assert0(stg);
5503
5504 for (int j = 0; j < stg->nb_streams; j++) {
5505 const FFStream *sti = cffstream(st);
5506 AVStream *out = stg->streams[j];
5507 FFStream *out_sti = ffstream(stg->streams[j]);
5508
5509 out->codecpar->bit_rate = 0;
5510
5511 if (out == st)
5512 continue;
5513
5514 out->time_base = st->time_base;
5515 out->start_time = st->start_time;
5516 out->duration = st->duration;
5517 out->nb_frames = st->nb_frames;
5518 out->discard = st->discard;
5519
5520 av_assert0(!out_sti->index_entries);
5522 if (!out_sti->index_entries)
5523 return AVERROR(ENOMEM);
5524
5526 out_sti->nb_index_entries = sti->nb_index_entries;
5527 out_sti->skip_samples = sti->skip_samples;
5528 memcpy(out_sti->index_entries, sti->index_entries, sti->index_entries_allocated_size);
5529 }
5530 }
5531
5532 return 0;
5533}
5534#endif
5535
5536static int sanity_checks(void *log_obj, MOVStreamContext *sc, int index)
5537{
5538 if ((sc->chunk_count && (!sc->stts_count || !sc->stsc_count ||
5539 (!sc->sample_size && !sc->sample_count))) ||
5540 (sc->sample_count && (!sc->chunk_count ||
5541 (!sc->sample_size && !sc->sample_sizes)))) {
5542 av_log(log_obj, AV_LOG_ERROR, "stream %d, missing mandatory atoms, broken header\n",
5543 index);
5544 return 1;
5545 }
5546
5547 if (sc->stsc_count && sc->stsc_data[ sc->stsc_count - 1 ].first > sc->chunk_count) {
5548 av_log(log_obj, AV_LOG_ERROR, "stream %d, contradictionary STSC and STCO\n",
5549 index);
5550 return 2;
5551 }
5552 return 0;
5553}
5554
5556{
5557 AVStream *st;
5558 MOVStreamContext *sc;
5559 int ret;
5560
5561 st = avformat_new_stream(c->fc, NULL);
5562 if (!st) return AVERROR(ENOMEM);
5563 st->id = -1;
5564 sc = av_mallocz(sizeof(MOVStreamContext));
5565 if (!sc) return AVERROR(ENOMEM);
5566
5567 st->priv_data = sc;
5569 sc->ffindex = st->index;
5570 c->trak_index = st->index;
5571 sc->refcount = 1;
5572
5573 if ((ret = mov_read_default(c, pb, atom)) < 0)
5574 return ret;
5575
5576 c->trak_index = -1;
5577
5578 // Here stsc refers to a chunk not described in stco. This is technically invalid,
5579 // but we can overlook it (clearing stsc) whenever stts_count == 0 (indicating no samples).
5580 if (!sc->chunk_count && !sc->stts_count && sc->stsc_count) {
5581 sc->stsc_count = 0;
5582 av_freep(&sc->stsc_data);
5583 }
5584
5585 ret = sanity_checks(c->fc, sc, st->index);
5586 if (ret)
5587 return ret > 1 ? AVERROR_INVALIDDATA : 0;
5588
5589 fix_timescale(c, sc);
5590
5591 avpriv_set_pts_info(st, 64, 1, sc->time_scale);
5592
5593 /*
5594 * Advanced edit list support does not work with fragemented MP4s, which
5595 * have stsc, stsz, stco, and stts with zero entries in the moov atom.
5596 * In these files, trun atoms may be streamed in.
5597 */
5598 if (!sc->stts_count && c->advanced_editlist) {
5599
5600 av_log(c->fc, AV_LOG_VERBOSE, "advanced_editlist does not work with fragmented "
5601 "MP4. disabling.\n");
5602 c->advanced_editlist = 0;
5603 c->advanced_editlist_autodisabled = 1;
5604 }
5605
5606 mov_build_index(c, st);
5607 /*
5608 * Fragment samples are appended later by mov_read_trun() and are not
5609 * covered by this non-fragmented track update.
5610 */
5612
5613#if CONFIG_IAMFDEC
5614 if (sc->iamf) {
5615 ret = mov_update_iamf_streams(c, st);
5616 if (ret < 0)
5617 return ret;
5618 }
5619#endif
5620
5621 if (sc->dref_id-1 < sc->drefs_count && sc->drefs[sc->dref_id-1].path) {
5622 MOVDref *dref = &sc->drefs[sc->dref_id - 1];
5623 if (c->enable_drefs) {
5624 if (mov_open_dref(c, &sc->pb, c->fc->url, dref) < 0)
5625 av_log(c->fc, AV_LOG_ERROR,
5626 "stream %d, error opening alias: path='%s', dir='%s', "
5627 "filename='%s', volume='%s', nlvl_from=%d, nlvl_to=%d\n",
5628 st->index, dref->path, dref->dir, dref->filename,
5629 dref->volume, dref->nlvl_from, dref->nlvl_to);
5630 } else {
5631 av_log(c->fc, AV_LOG_WARNING,
5632 "Skipped opening external track: "
5633 "stream %d, alias: path='%s', dir='%s', "
5634 "filename='%s', volume='%s', nlvl_from=%d, nlvl_to=%d."
5635 "Set enable_drefs to allow this.\n",
5636 st->index, dref->path, dref->dir, dref->filename,
5637 dref->volume, dref->nlvl_from, dref->nlvl_to);
5638 }
5639 } else {
5640 sc->pb = c->fc->pb;
5641 sc->pb_is_copied = 1;
5642 }
5643
5645 int stts_constant = sc->stts_count && sc->tts_count;
5646 if (sc->h_spacing && sc->v_spacing)
5648 sc->h_spacing, sc->v_spacing, INT_MAX);
5649 if (!st->sample_aspect_ratio.num && st->codecpar->width && st->codecpar->height &&
5650 sc->height && sc->width &&
5651 (st->codecpar->width != sc->width || st->codecpar->height != sc->height)) {
5653 (int64_t)st->codecpar->height * sc->width,
5654 (int64_t)st->codecpar->width * sc->height, INT_MAX);
5655 }
5656
5657#if FF_API_R_FRAME_RATE
5658 for (unsigned int i = 1; sc->stts_count && i + 1 < sc->tts_count; i++) {
5659 if (sc->tts_data[i].duration == sc->tts_data[0].duration)
5660 continue;
5661 stts_constant = 0;
5662 }
5663 if (stts_constant)
5665 sc->time_scale, sc->tts_data[0].duration, INT_MAX);
5666#endif
5667 }
5668
5669#if CONFIG_H261_DECODER || CONFIG_H263_DECODER || CONFIG_MPEG4_DECODER
5670 switch (st->codecpar->codec_id) {
5671#if CONFIG_H261_DECODER
5672 case AV_CODEC_ID_H261:
5673#endif
5674#if CONFIG_H263_DECODER
5675 case AV_CODEC_ID_H263:
5676#endif
5677#if CONFIG_MPEG4_DECODER
5678 case AV_CODEC_ID_MPEG4:
5679#endif
5680 st->codecpar->width = 0; /* let decoder init width/height */
5681 st->codecpar->height= 0;
5682 break;
5683 }
5684#endif
5685
5686 // If the duration of the mp3 packets is not constant, then they could need a parser
5688 && sc->time_scale == st->codecpar->sample_rate) {
5689 int stts_constant = 1;
5690 for (int i = 1; sc->stts_count && i < sc->tts_count; i++) {
5691 if (sc->tts_data[i].duration == sc->tts_data[0].duration)
5692 continue;
5693 stts_constant = 0;
5694 }
5695 if (!stts_constant)
5697 }
5698 /* Do not need those anymore. */
5699 av_freep(&sc->chunk_offsets);
5700 av_freep(&sc->sample_sizes);
5701 av_freep(&sc->keyframes);
5702 av_freep(&sc->stps_data);
5703 av_freep(&sc->elst_data);
5704 av_freep(&sc->rap_group);
5705 av_freep(&sc->sync_group);
5706 av_freep(&sc->sgpd_sync);
5707
5708 return 0;
5709}
5710
5712{
5713 int ret;
5714 c->itunes_metadata = 1;
5715 ret = mov_read_default(c, pb, atom);
5716 c->itunes_metadata = 0;
5717 return ret;
5718}
5719
5721{
5722 uint32_t count;
5723 uint32_t i;
5724
5725 if (atom.size < 8)
5726 return 0;
5727
5728 avio_skip(pb, 4);
5729 count = avio_rb32(pb);
5730 atom.size -= 8;
5731 if (count > atom.size / 8 || count >= UINT_MAX / sizeof(*c->meta_keys)) {
5732 av_log(c->fc, AV_LOG_ERROR,
5733 "The 'keys' atom with the invalid key count: %"PRIu32"\n", count);
5734 return AVERROR_INVALIDDATA;
5735 }
5736
5737 c->meta_keys = av_malloc_array(count + 1, sizeof(*c->meta_keys));
5738 if (!c->meta_keys)
5739 return AVERROR(ENOMEM);
5740
5741 c->meta_keys[0] = NULL;
5742 c->meta_keys_count = 1;
5743 for (i = 1; i <= count; ++i) {
5744 uint32_t key_size = avio_rb32(pb);
5745 uint32_t type = avio_rl32(pb);
5746 c->meta_keys[i] = NULL;
5747 c->meta_keys_count = i + 1;
5748 if (key_size < 8 || key_size > atom.size) {
5749 av_log(c->fc, AV_LOG_ERROR,
5750 "The key# %"PRIu32" in meta has invalid size:"
5751 "%"PRIu32"\n", i, key_size);
5752 return AVERROR_INVALIDDATA;
5753 }
5754 atom.size -= key_size;
5755 key_size -= 8;
5756 if (type != MKTAG('m','d','t','a')) {
5757 avio_skip(pb, key_size);
5758 continue;
5759 }
5760 c->meta_keys[i] = av_malloc(key_size + 1);
5761 if (!c->meta_keys[i])
5762 return AVERROR(ENOMEM);
5763 int ret = ffio_read_size(pb, c->meta_keys[i], key_size);
5764 if (ret < 0)
5765 return ret;
5766 c->meta_keys[i][key_size] = 0;
5767 }
5768
5769 return 0;
5770}
5771
5773{
5774 int64_t end = av_sat_add64(avio_tell(pb), atom.size);
5775 uint8_t *key = NULL, *val = NULL, *mean = NULL;
5776 int i;
5777 int ret = 0;
5778 AVStream *st;
5779
5780 if (c->fc->nb_streams < 1)
5781 return 0;
5782 st = c->fc->streams[c->fc->nb_streams-1];
5783
5784 for (i = 0; i < 3; i++) {
5785 uint8_t **p;
5786 uint32_t len, tag;
5787
5788 if (end - avio_tell(pb) <= 12)
5789 break;
5790
5791 len = avio_rb32(pb);
5792 tag = avio_rl32(pb);
5793 avio_skip(pb, 4); // flags
5794
5795 if (len < 12 || len - 12 > end - avio_tell(pb))
5796 break;
5797 len -= 12;
5798
5799 if (tag == MKTAG('m', 'e', 'a', 'n'))
5800 p = &mean;
5801 else if (tag == MKTAG('n', 'a', 'm', 'e'))
5802 p = &key;
5803 else if (tag == MKTAG('d', 'a', 't', 'a') && len > 4) {
5804 avio_skip(pb, 4);
5805 len -= 4;
5806 p = &val;
5807 } else
5808 break;
5809
5810 if (*p)
5811 break;
5812
5813 *p = av_malloc(len + 1);
5814 if (!*p) {
5815 ret = AVERROR(ENOMEM);
5816 break;
5817 }
5818 ret = ffio_read_size(pb, *p, len);
5819 if (ret < 0) {
5820 av_freep(p);
5821 break;
5822 }
5823 (*p)[len] = 0;
5824 }
5825
5826 if (mean && key && val) {
5827 if (strcmp(key, "iTunSMPB") == 0) {
5828 int64_t priming, remainder, samples;
5829 if (ff_itunes_parse_smpb(val, &priming, &remainder, &samples) >= 0) {
5830 if(priming>0 && priming<16384)
5831 st->codecpar->initial_padding = priming = av_rescale_q(priming, st->time_base,
5832 (AVRational){ 1, st->codecpar->sample_rate });
5833 if (remainder > 0) {
5835 (AVRational){ 1, st->codecpar->sample_rate });
5836 remainder = av_rescale_q(remainder, st->time_base,
5837 (AVRational){ 1, st->codecpar->sample_rate });
5838 samples = av_rescale_q(samples, st->time_base,
5839 (AVRational){ 1, st->codecpar->sample_rate });
5840 if (duration > remainder && duration > samples) {
5841 ffstream(st)->first_discard_sample = duration - remainder;
5843 }
5844 }
5845 av_log(c->fc, AV_LOG_DEBUG, "Parsed iTunSMPB: priming %"PRId64", "
5846 "remainder %"PRId64" samples %"PRId64"\n",
5847 priming, remainder, samples);
5848 }
5849 }
5850 if (strcmp(mean, "com.apple.iTunes") == 0 &&
5851 strcmp(key, "DISCSUBTITLE") == 0) {
5852 av_dict_set(&c->fc->metadata, "disc_subtitle", val,
5854 val = NULL;
5855 }
5856 if (strcmp(key, "cdec") != 0) {
5857 av_dict_set(&c->fc->metadata, key, val,
5859 key = val = NULL;
5860 }
5861 } else {
5862 av_log(c->fc, AV_LOG_VERBOSE,
5863 "Unhandled or malformed custom metadata of size %"PRId64"\n", atom.size);
5864 }
5865
5866 avio_seek(pb, end, SEEK_SET);
5867 av_freep(&key);
5868 av_freep(&val);
5869 av_freep(&mean);
5870 return ret;
5871}
5872
5874{
5875 MOVStreamContext *sc;
5876 AVStream *st;
5877
5878 st = avformat_new_stream(c->fc, NULL);
5879 if (!st)
5880 return AVERROR(ENOMEM);
5881 sc = av_mallocz(sizeof(MOVStreamContext));
5882 if (!sc)
5883 goto fail;
5884
5885 item->st = st;
5886 st->id = item->item_id;
5887 st->priv_data = sc;
5889 st->codecpar->codec_id = mov_codec_id(st, item->type);
5890 sc->id = st->id;
5891 sc->ffindex = st->index;
5892 st->avg_frame_rate.num = st->avg_frame_rate.den = 1;
5893 st->time_base.num = st->time_base.den = 1;
5894 st->nb_frames = 1;
5895 sc->time_scale = 1;
5896 sc->pb = c->fc->pb;
5897 sc->pb_is_copied = 1;
5898 sc->refcount = 1;
5899
5900 if (item->name)
5901 av_dict_set(&st->metadata, "title", item->name, 0);
5902
5903 // Populate the necessary fields used by mov_build_index.
5904 sc->stsc_data = av_malloc_array(1, sizeof(*sc->stsc_data));
5905 if (!sc->stsc_data)
5906 goto fail;
5907 sc->stsc_count = 1;
5908 sc->stsc_data[0].first = 1;
5909 sc->stsc_data[0].count = 1;
5910 sc->stsc_data[0].id = 1;
5911 sc->chunk_offsets = av_malloc_array(1, sizeof(*sc->chunk_offsets));
5912 if (!sc->chunk_offsets)
5913 goto fail;
5914 sc->chunk_count = 1;
5915 sc->stts_data = av_malloc_array(1, sizeof(*sc->stts_data));
5916 if (!sc->stts_data)
5917 goto fail;
5918 sc->stts_count = 1;
5919 sc->stts_data[0].count = 1;
5920 // Not used for still images. But needed by mov_build_index.
5921 sc->stts_data[0].duration = 0;
5922
5923 return 0;
5924fail:
5925 mov_free_stream_context(c->fc, st);
5926 ff_remove_stream(c->fc, st);
5927 item->st = NULL;
5928
5929 return AVERROR(ENOMEM);
5930}
5931
5933{
5934 while (atom.size > 8) {
5935 uint32_t tag;
5936 if (avio_feof(pb))
5937 return AVERROR_EOF;
5938 tag = avio_rl32(pb);
5939 atom.size -= 4;
5940 if (tag == MKTAG('h','d','l','r')) {
5941 avio_seek(pb, -8, SEEK_CUR);
5942 atom.size += 8;
5943 return mov_read_default(c, pb, atom);
5944 }
5945 }
5946 return 0;
5947}
5948
5949// return 1 when matrix is identity, 0 otherwise
5950#define IS_MATRIX_IDENT(matrix) \
5951 ( (matrix)[0][0] == (1 << 16) && \
5952 (matrix)[1][1] == (1 << 16) && \
5953 (matrix)[2][2] == (1 << 30) && \
5954 !(matrix)[0][1] && !(matrix)[0][2] && \
5955 !(matrix)[1][0] && !(matrix)[1][2] && \
5956 !(matrix)[2][0] && !(matrix)[2][1])
5957
5959{
5960 int i, j, e;
5961 int width;
5962 int height;
5963 int display_matrix[3][3];
5964 int res_display_matrix[3][3] = { { 0 } };
5965 AVStream *st;
5966 MOVStreamContext *sc;
5967 int version;
5968 int flags;
5969
5970 if (c->fc->nb_streams < 1)
5971 return 0;
5972 st = c->fc->streams[c->fc->nb_streams-1];
5973 sc = st->priv_data;
5974
5975 // Each stream (trak) should have exactly 1 tkhd. This catches bad files and
5976 // avoids corrupting AVStreams mapped to an earlier tkhd.
5977 if (st->id != -1)
5978 return AVERROR_INVALIDDATA;
5979
5980 version = avio_r8(pb);
5981 flags = avio_rb24(pb);
5983
5984 if (version == 1) {
5985 avio_rb64(pb);
5986 avio_rb64(pb);
5987 } else {
5988 avio_rb32(pb); /* creation time */
5989 avio_rb32(pb); /* modification time */
5990 }
5991 st->id = (int)avio_rb32(pb); /* track id (NOT 0 !)*/
5992 sc->id = st->id;
5993 avio_rb32(pb); /* reserved */
5994
5995 /* highlevel (considering edits) duration in movie timebase */
5996 (version == 1) ? avio_rb64(pb) : avio_rb32(pb);
5997 avio_rb32(pb); /* reserved */
5998 avio_rb32(pb); /* reserved */
5999
6000 avio_rb16(pb); /* layer */
6001 avio_rb16(pb); /* alternate group */
6002 avio_rb16(pb); /* volume */
6003 avio_rb16(pb); /* reserved */
6004
6005 //read in the display matrix (outlined in ISO 14496-12, Section 6.2.2)
6006 // they're kept in fixed point format through all calculations
6007 // save u,v,z to store the whole matrix in the AV_PKT_DATA_DISPLAYMATRIX
6008 // side data, but the scale factor is not needed to calculate aspect ratio
6009 for (i = 0; i < 3; i++) {
6010 display_matrix[i][0] = avio_rb32(pb); // 16.16 fixed point
6011 display_matrix[i][1] = avio_rb32(pb); // 16.16 fixed point
6012 display_matrix[i][2] = avio_rb32(pb); // 2.30 fixed point
6013 }
6014
6015 width = avio_rb32(pb); // 16.16 fixed point track width
6016 height = avio_rb32(pb); // 16.16 fixed point track height
6017 sc->width = width >> 16;
6018 sc->height = height >> 16;
6019
6020 // apply the moov display matrix (after the tkhd one)
6021 for (i = 0; i < 3; i++) {
6022 const int sh[3] = { 16, 16, 30 };
6023 for (j = 0; j < 3; j++) {
6024 for (e = 0; e < 3; e++) {
6025 res_display_matrix[i][j] +=
6026 ((int64_t) display_matrix[i][e] *
6027 c->movie_display_matrix[e][j]) >> sh[e];
6028 }
6029 }
6030 }
6031
6032 // save the matrix when it is not the default identity
6033 if (!IS_MATRIX_IDENT(res_display_matrix)) {
6035 sc->display_matrix = av_malloc(sizeof(int32_t) * 9);
6036 if (!sc->display_matrix)
6037 return AVERROR(ENOMEM);
6038
6039 for (i = 0; i < 3; i++)
6040 for (j = 0; j < 3; j++)
6041 sc->display_matrix[i * 3 + j] = res_display_matrix[i][j];
6042 }
6043
6044 // transform the display width/height according to the matrix
6045 // to keep the same scale, use [width height 1<<16]
6046 if (width && height && sc->display_matrix) {
6047 double disp_transform[2];
6048
6049 for (i = 0; i < 2; i++)
6050 disp_transform[i] = hypot(sc->display_matrix[0 + i],
6051 sc->display_matrix[3 + i]);
6052
6053 if (disp_transform[0] > 1 && disp_transform[1] > 1 &&
6054 disp_transform[0] < (1<<24) && disp_transform[1] < (1<<24) &&
6055 fabs((disp_transform[0] / disp_transform[1]) - 1.0) > 0.01)
6057 disp_transform[0] / disp_transform[1],
6058 INT_MAX);
6059 }
6060 return 0;
6061}
6062
6064{
6065 MOVFragment *frag = &c->fragment;
6066 MOVTrackExt *trex = NULL;
6067 int flags, track_id, i;
6068 MOVFragmentStreamInfo * frag_stream_info;
6069
6070 avio_r8(pb); /* version */
6071 flags = avio_rb24(pb);
6072
6073 track_id = avio_rb32(pb);
6074 if (!track_id)
6075 return AVERROR_INVALIDDATA;
6076 for (i = 0; i < c->trex_count; i++)
6077 if (c->trex_data[i].track_id == track_id) {
6078 trex = &c->trex_data[i];
6079 break;
6080 }
6081 if (!trex) {
6082 av_log(c->fc, AV_LOG_WARNING, "could not find corresponding trex (id %u)\n", track_id);
6083 return 0;
6084 }
6085 c->fragment.found_tfhd = 1;
6086 frag->track_id = track_id;
6087 set_frag_stream(&c->frag_index, track_id);
6088
6091 frag->moof_offset : frag->implicit_offset;
6092 frag->stsd_id = flags & MOV_TFHD_STSD_ID ? avio_rb32(pb) : trex->stsd_id;
6093
6095 avio_rb32(pb) : trex->duration;
6096 frag->size = flags & MOV_TFHD_DEFAULT_SIZE ?
6097 avio_rb32(pb) : trex->size;
6099 avio_rb32(pb) : trex->flags;
6100 av_log(c->fc, AV_LOG_TRACE, "frag flags 0x%x\n", frag->flags);
6101
6102 frag_stream_info = get_current_frag_stream_info(&c->frag_index);
6103 if (frag_stream_info) {
6104 frag_stream_info->next_trun_dts = AV_NOPTS_VALUE;
6105 frag_stream_info->stsd_id = frag->stsd_id;
6106 }
6107 return 0;
6108}
6109
6111{
6112 unsigned i, num;
6113 void *new_tracks;
6114
6115 num = atom.size / 4;
6116 if (!(new_tracks = av_malloc_array(num, sizeof(int))))
6117 return AVERROR(ENOMEM);
6118
6119 av_free(c->chapter_tracks);
6120 c->chapter_tracks = new_tracks;
6121 c->nb_chapter_tracks = num;
6122
6123 for (i = 0; i < num && !pb->eof_reached; i++)
6124 c->chapter_tracks[i] = avio_rb32(pb);
6125
6126 c->nb_chapter_tracks = i;
6127
6128 return 0;
6129}
6130
6132{
6133 MOVTrackExt *trex;
6134 int err;
6135
6136 if ((uint64_t)c->trex_count+1 >= UINT_MAX / sizeof(*c->trex_data))
6137 return AVERROR_INVALIDDATA;
6138 if ((err = av_reallocp_array(&c->trex_data, c->trex_count + 1,
6139 sizeof(*c->trex_data))) < 0) {
6140 c->trex_count = 0;
6141 return err;
6142 }
6143
6144 c->fc->duration = AV_NOPTS_VALUE; // the duration from mvhd is not representing the whole file when fragments are used.
6145
6146 trex = &c->trex_data[c->trex_count++];
6147 avio_r8(pb); /* version */
6148 avio_rb24(pb); /* flags */
6149 trex->track_id = avio_rb32(pb);
6150 trex->stsd_id = avio_rb32(pb);
6151 trex->duration = avio_rb32(pb);
6152 trex->size = avio_rb32(pb);
6153 trex->flags = avio_rb32(pb);
6154 return 0;
6155}
6156
6158{
6159 MOVFragment *frag = &c->fragment;
6160 AVStream *st = NULL;
6161 MOVStreamContext *sc;
6162 int version, i;
6163 MOVFragmentStreamInfo * frag_stream_info;
6164 int64_t base_media_decode_time;
6165
6166 for (i = 0; i < c->fc->nb_streams; i++) {
6167 sc = c->fc->streams[i]->priv_data;
6168 if (sc->id == frag->track_id) {
6169 st = c->fc->streams[i];
6170 break;
6171 }
6172 }
6173 if (!st) {
6174 av_log(c->fc, AV_LOG_WARNING, "could not find corresponding track id %u\n", frag->track_id);
6175 return 0;
6176 }
6177 sc = st->priv_data;
6178 if (sc->pseudo_stream_id + 1 != frag->stsd_id && sc->pseudo_stream_id != -1)
6179 return 0;
6180 version = avio_r8(pb);
6181 avio_rb24(pb); /* flags */
6182 if (version) {
6183 base_media_decode_time = avio_rb64(pb);
6184 } else {
6185 base_media_decode_time = avio_rb32(pb);
6186 }
6187
6188 frag_stream_info = get_current_frag_stream_info(&c->frag_index);
6189 if (frag_stream_info)
6190 frag_stream_info->tfdt_dts = base_media_decode_time;
6191 sc->track_end = base_media_decode_time;
6192
6193 return 0;
6194}
6195
6197{
6198 MOVFragment *frag = &c->fragment;
6199 AVStream *st = NULL;
6200 FFStream *sti = NULL;
6201 MOVStreamContext *sc;
6202 MOVTimeToSample *tts_data;
6203 uint64_t offset;
6204 int64_t dts, pts = AV_NOPTS_VALUE;
6205 int data_offset = 0;
6206 unsigned entries, first_sample_flags = frag->flags;
6207 int flags, distance, i;
6208 int64_t prev_dts = AV_NOPTS_VALUE;
6209 int next_frag_index = -1, index_entry_pos;
6210 size_t requested_size;
6211 size_t old_allocated_size;
6212 AVIndexEntry *new_entries;
6213 MOVFragmentStreamInfo * frag_stream_info;
6214
6215 if (!frag->found_tfhd) {
6216 av_log(c->fc, AV_LOG_ERROR, "trun track id unknown, no tfhd was found\n");
6217 return AVERROR_INVALIDDATA;
6218 }
6219
6220 for (i = 0; i < c->fc->nb_streams; i++) {
6221 sc = c->fc->streams[i]->priv_data;
6222 if (sc->id == frag->track_id) {
6223 st = c->fc->streams[i];
6224 sti = ffstream(st);
6225 break;
6226 }
6227 }
6228 if (!st) {
6229 av_log(c->fc, AV_LOG_WARNING, "could not find corresponding track id %u\n", frag->track_id);
6230 return 0;
6231 }
6232 sc = st->priv_data;
6233 if (sc->pseudo_stream_id+1 != frag->stsd_id && sc->pseudo_stream_id != -1)
6234 return 0;
6235
6236 // Find the next frag_index index that has a valid index_entry for
6237 // the current track_id.
6238 //
6239 // A valid index_entry means the trun for the fragment was read
6240 // and it's samples are in index_entries at the given position.
6241 // New index entries will be inserted before the index_entry found.
6242 index_entry_pos = sti->nb_index_entries;
6243 for (i = c->frag_index.current + 1; i < c->frag_index.nb_items; i++) {
6244 frag_stream_info = get_frag_stream_info(&c->frag_index, i, frag->track_id);
6245 if (frag_stream_info && frag_stream_info->index_entry >= 0) {
6246 next_frag_index = i;
6247 index_entry_pos = frag_stream_info->index_entry;
6248 break;
6249 }
6250 }
6251 av_assert0(index_entry_pos <= sti->nb_index_entries);
6252
6253 avio_r8(pb); /* version */
6254 flags = avio_rb24(pb);
6255 entries = avio_rb32(pb);
6256 av_log(c->fc, AV_LOG_TRACE, "flags 0x%x entries %u\n", flags, entries);
6257
6258 /* Explicit zero sizes are bounded by the trun payload. Reject a zero
6259 * default size before allocating or updating the sample index. */
6260 if (entries && !frag->size && !(flags & MOV_TRUN_SAMPLE_SIZE))
6261 return AVERROR_INVALIDDATA;
6262
6263 if ((uint64_t)entries+sc->tts_count >= UINT_MAX/sizeof(*sc->tts_data))
6264 return AVERROR_INVALIDDATA;
6265 if (flags & MOV_TRUN_DATA_OFFSET) data_offset = avio_rb32(pb);
6266 if (flags & MOV_TRUN_FIRST_SAMPLE_FLAGS) first_sample_flags = avio_rb32(pb);
6267
6268 int entry_size = !!(flags & MOV_TRUN_SAMPLE_DURATION) * 4
6269 + !!(flags & MOV_TRUN_SAMPLE_SIZE) * 4
6270 + !!(flags & MOV_TRUN_SAMPLE_FLAGS) * 4
6271 + !!(flags & MOV_TRUN_SAMPLE_CTS) * 4;
6272 int64_t sample_data_size = avio_size(sc->pb);
6273 int64_t max_entries = INT64_MAX;
6274
6275 if (sample_data_size > 0)
6276 max_entries = sample_data_size - sti->nb_index_entries;
6277 if (entry_size) {
6278 int64_t size = sc->pb == pb ? sample_data_size : avio_size(pb);
6279 int64_t pos = avio_tell(pb);
6280 int64_t left = atom.size - 8 - !!(flags & MOV_TRUN_DATA_OFFSET) * 4
6282
6283 if (pos >= 0 && size >= pos)
6284 left = FFMIN(left, size - pos);
6285 max_entries = FFMIN(max_entries, left / entry_size);
6286 }
6287 if (entries > max_entries) {
6288 av_log(c->fc, AV_LOG_ERROR, "trun sample count %u exceeds the %"PRId64" "
6289 "samples the input can hold\n", entries, max_entries);
6290 return AVERROR_INVALIDDATA;
6291 }
6292
6293 frag_stream_info = get_current_frag_stream_info(&c->frag_index);
6294 if (frag_stream_info) {
6295 if (frag_stream_info->next_trun_dts != AV_NOPTS_VALUE) {
6296 dts = frag_stream_info->next_trun_dts - sc->time_offset;
6297 } else if (frag_stream_info->first_tfra_pts != AV_NOPTS_VALUE &&
6298 c->use_mfra_for == FF_MOV_FLAG_MFRA_PTS) {
6299 pts = frag_stream_info->first_tfra_pts;
6300 av_log(c->fc, AV_LOG_DEBUG, "found mfra time %"PRId64
6301 ", using it for pts\n", pts);
6302 } else if (frag_stream_info->first_tfra_pts != AV_NOPTS_VALUE &&
6303 c->use_mfra_for == FF_MOV_FLAG_MFRA_DTS) {
6304 dts = frag_stream_info->first_tfra_pts;
6305 av_log(c->fc, AV_LOG_DEBUG, "found mfra time %"PRId64
6306 ", using it for dts\n", pts);
6307 } else {
6308 int has_tfdt = frag_stream_info->tfdt_dts != AV_NOPTS_VALUE;
6309 int has_sidx = frag_stream_info->sidx_pts != AV_NOPTS_VALUE;
6310 int fallback_tfdt = !c->use_tfdt && !has_sidx && has_tfdt;
6311 int fallback_sidx = c->use_tfdt && !has_tfdt && has_sidx;
6312
6313 if (fallback_sidx) {
6314 av_log(c->fc, AV_LOG_DEBUG, "use_tfdt set but no tfdt found, using sidx instead\n");
6315 }
6316 if (fallback_tfdt) {
6317 av_log(c->fc, AV_LOG_DEBUG, "use_tfdt not set but no sidx found, using tfdt instead\n");
6318 }
6319
6320 if (has_tfdt && c->use_tfdt || fallback_tfdt) {
6321 dts = frag_stream_info->tfdt_dts - sc->time_offset;
6322 av_log(c->fc, AV_LOG_DEBUG, "found tfdt time %"PRId64
6323 ", using it for dts\n", dts);
6324 } else if (has_sidx && !c->use_tfdt || fallback_sidx) {
6325 // FIXME: sidx earliest_presentation_time is *PTS*, s.b.
6326 // pts = frag_stream_info->sidx_pts;
6327 dts = frag_stream_info->sidx_pts;
6328 av_log(c->fc, AV_LOG_DEBUG, "found sidx time %"PRId64
6329 ", using it for dts\n", frag_stream_info->sidx_pts);
6330 } else {
6331 dts = sc->track_end - sc->time_offset;
6332 av_log(c->fc, AV_LOG_DEBUG, "found track end time %"PRId64
6333 ", using it for dts\n", dts);
6334 }
6335 }
6336 } else {
6337 dts = sc->track_end - sc->time_offset;
6338 av_log(c->fc, AV_LOG_DEBUG, "found track end time %"PRId64
6339 ", using it for dts\n", dts);
6340 }
6341 offset = frag->base_data_offset + data_offset;
6342 distance = 0;
6343 av_log(c->fc, AV_LOG_TRACE, "first sample flags 0x%x\n", first_sample_flags);
6344
6345 // realloc space for new index entries
6346 if ((uint64_t)sti->nb_index_entries + entries >= UINT_MAX / sizeof(AVIndexEntry)) {
6347 entries = UINT_MAX / sizeof(AVIndexEntry) - sti->nb_index_entries;
6348 av_log(c->fc, AV_LOG_ERROR, "Failed to add index entry\n");
6349 }
6350 if (entries == 0)
6351 return 0;
6352
6353 requested_size = (sti->nb_index_entries + entries) * sizeof(AVIndexEntry);
6354 new_entries = av_fast_realloc(sti->index_entries,
6356 requested_size);
6357 if (!new_entries)
6358 return AVERROR(ENOMEM);
6359 sti->index_entries= new_entries;
6360
6361 requested_size = (sti->nb_index_entries + entries) * sizeof(*sc->tts_data);
6362 old_allocated_size = sc->tts_allocated_size;
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 memset((uint8_t*)(sc->tts_data) + old_allocated_size, 0,
6373 sc->tts_allocated_size - old_allocated_size);
6374
6375 if (index_entry_pos < sti->nb_index_entries) {
6376 // Make hole in index_entries and tts_data for new samples
6377 memmove(sti->index_entries + index_entry_pos + entries,
6378 sti->index_entries + index_entry_pos,
6379 sizeof(*sti->index_entries) *
6380 (sti->nb_index_entries - index_entry_pos));
6381 memmove(sc->tts_data + index_entry_pos + entries,
6382 sc->tts_data + index_entry_pos,
6383 sizeof(*sc->tts_data) * (sc->tts_count - index_entry_pos));
6384 if (index_entry_pos < sc->current_sample) {
6385 sc->current_sample += entries;
6386 }
6387 }
6388
6389 sti->nb_index_entries += entries;
6390 sc->tts_count = sti->nb_index_entries;
6391 sc->stts_count = sti->nb_index_entries;
6393 sc->ctts_count = sti->nb_index_entries;
6394
6395 // Record the index_entry position in frag_index of this fragment
6396 if (frag_stream_info) {
6397 frag_stream_info->index_entry = index_entry_pos;
6398 if (frag_stream_info->index_base < 0)
6399 frag_stream_info->index_base = index_entry_pos;
6400 }
6401
6402 if (index_entry_pos > 0)
6403 prev_dts = sti->index_entries[index_entry_pos-1].timestamp;
6404
6405 for (i = 0; i < entries && !pb->eof_reached; i++) {
6406 unsigned sample_size = frag->size;
6407 int sample_flags = i ? frag->flags : first_sample_flags;
6408 unsigned sample_duration = frag->duration;
6409 unsigned ctts_duration = 0;
6410 int keyframe = 0;
6411 int index_entry_flags = 0;
6412
6413 if (flags & MOV_TRUN_SAMPLE_DURATION) sample_duration = avio_rb32(pb);
6414 if (flags & MOV_TRUN_SAMPLE_SIZE) sample_size = avio_rb32(pb);
6415 if (flags & MOV_TRUN_SAMPLE_FLAGS) sample_flags = avio_rb32(pb);
6416 if (flags & MOV_TRUN_SAMPLE_CTS) ctts_duration = avio_rb32(pb);
6417
6418 if (sample_duration > c->max_stts_delta) {
6419 av_log(c->fc, AV_LOG_WARNING,
6420 "Too large sample duration %u in trun entry %u in st:%d. Clipping to 1.\n",
6421 sample_duration, i, st->index);
6422 sample_duration = 1;
6423 }
6424
6425 mov_update_dts_shift(sc, ctts_duration, c->fc);
6426 if (pts != AV_NOPTS_VALUE) {
6427 dts = pts - sc->dts_shift;
6428 if (flags & MOV_TRUN_SAMPLE_CTS) {
6429 dts -= ctts_duration;
6430 } else {
6431 dts -= sc->time_offset;
6432 }
6433 av_log(c->fc, AV_LOG_DEBUG,
6434 "pts %"PRId64" calculated dts %"PRId64
6435 " sc->dts_shift %d ctts.duration %d"
6436 " sc->time_offset %"PRId64
6437 " flags & MOV_TRUN_SAMPLE_CTS %d\n",
6438 pts, dts,
6439 sc->dts_shift, ctts_duration,
6442 }
6443
6444 keyframe =
6445 !(sample_flags & (MOV_FRAG_SAMPLE_FLAG_IS_NON_SYNC |
6447 if (keyframe) {
6448 distance = 0;
6449 index_entry_flags |= AVINDEX_KEYFRAME;
6450 }
6451 // Fragments can overlap in time. Discard overlapping frames after
6452 // decoding.
6453 if (prev_dts >= dts)
6454 index_entry_flags |= AVINDEX_DISCARD_FRAME;
6455
6456 sti->index_entries[index_entry_pos].pos = offset;
6457 sti->index_entries[index_entry_pos].timestamp = dts;
6458 sti->index_entries[index_entry_pos].size = sample_size;
6459 sti->index_entries[index_entry_pos].min_distance = distance;
6460 sti->index_entries[index_entry_pos].flags = index_entry_flags;
6461
6462 sc->tts_data[index_entry_pos].count = 1;
6463 sc->tts_data[index_entry_pos].offset = ctts_duration;
6464 sc->tts_data[index_entry_pos].duration = sample_duration;
6465 index_entry_pos++;
6466
6467 av_log(c->fc, AV_LOG_TRACE, "AVIndex stream %d, sample %d, offset %"PRIx64", dts %"PRId64", "
6468 "size %u, distance %d, keyframe %d\n", st->index,
6469 index_entry_pos, offset, dts, sample_size, distance, keyframe);
6470 distance++;
6471 if (av_sat_add64(dts, sample_duration) != dts + (uint64_t)sample_duration)
6472 return AVERROR_INVALIDDATA;
6473 dts += sample_duration;
6474 offset += sample_size;
6475 sc->data_size += sample_size;
6476
6477 if (sample_duration <= INT64_MAX - sc->duration_for_fps &&
6478 1 <= INT_MAX - sc->nb_frames_for_fps
6479 ) {
6480 sc->duration_for_fps += sample_duration;
6481 sc->nb_frames_for_fps ++;
6482 }
6483 }
6484 if (frag_stream_info)
6485 frag_stream_info->next_trun_dts = dts + sc->time_offset;
6486 if (i < entries) {
6487 // EOF found before reading all entries. Fix the hole this would
6488 // leave in index_entries and tts_data
6489 int gap = entries - i;
6490 memmove(sti->index_entries + index_entry_pos,
6491 sti->index_entries + index_entry_pos + gap,
6492 sizeof(*sti->index_entries) *
6493 (sti->nb_index_entries - (index_entry_pos + gap)));
6494 memmove(sc->tts_data + index_entry_pos,
6495 sc->tts_data + index_entry_pos + gap,
6496 sizeof(*sc->tts_data) *
6497 (sc->tts_count - (index_entry_pos + gap)));
6498
6499 sti->nb_index_entries -= gap;
6500 sc->tts_count -= gap;
6501 if (index_entry_pos < sc->current_sample) {
6502 sc->current_sample -= gap;
6503 }
6504 entries = i;
6505 }
6506
6507 // The end of this new fragment may overlap in time with the start
6508 // of the next fragment in index_entries. Mark the samples in the next
6509 // fragment that overlap with AVINDEX_DISCARD_FRAME
6510 prev_dts = AV_NOPTS_VALUE;
6511 if (index_entry_pos > 0)
6512 prev_dts = sti->index_entries[index_entry_pos-1].timestamp;
6513 for (int i = index_entry_pos; i < sti->nb_index_entries; i++) {
6514 if (prev_dts < sti->index_entries[i].timestamp)
6515 break;
6517 }
6518
6519 // If a hole was created to insert the new index_entries into,
6520 // the index_entry recorded for all subsequent moof must
6521 // be incremented by the number of entries inserted.
6522 fix_frag_index_entries(&c->frag_index, next_frag_index,
6523 frag->track_id, entries);
6524
6525 if (pb->eof_reached) {
6526 av_log(c->fc, AV_LOG_WARNING, "reached eof, corrupted TRUN atom\n");
6527 return AVERROR_EOF;
6528 }
6529
6530 frag->implicit_offset = offset;
6531
6532 sc->track_end = dts + sc->time_offset;
6533 if (st->duration < sc->track_end)
6534 st->duration = sc->track_end;
6535
6536 return 0;
6537}
6538
6540{
6541 int64_t stream_size = avio_size(pb);
6542 int64_t offset = av_sat_add64(avio_tell(pb), atom.size), pts, timestamp;
6543 uint8_t version, is_complete;
6544 int64_t offadd;
6545 unsigned i, j, track_id, item_count;
6546 AVStream *st = NULL;
6547 AVStream *ref_st = NULL;
6548 MOVStreamContext *sc, *ref_sc = NULL;
6549 AVRational timescale;
6550
6551 version = avio_r8(pb);
6552 if (version > 1) {
6553 avpriv_request_sample(c->fc, "sidx version %u", version);
6554 return 0;
6555 }
6556
6557 avio_rb24(pb); // flags
6558
6559 track_id = avio_rb32(pb); // Reference ID
6560 for (i = 0; i < c->fc->nb_streams; i++) {
6561 sc = c->fc->streams[i]->priv_data;
6562 if (sc->id == track_id) {
6563 st = c->fc->streams[i];
6564 break;
6565 }
6566 }
6567 if (!st) {
6568 av_log(c->fc, AV_LOG_WARNING, "could not find corresponding track id %d\n", track_id);
6569 return 0;
6570 }
6571
6572 sc = st->priv_data;
6573
6574 timescale = av_make_q(1, avio_rb32(pb));
6575
6576 if (timescale.den <= 0) {
6577 av_log(c->fc, AV_LOG_ERROR, "Invalid sidx timescale 1/%d\n", timescale.den);
6578 return AVERROR_INVALIDDATA;
6579 }
6580
6581 if (version == 0) {
6582 pts = avio_rb32(pb);
6583 offadd= avio_rb32(pb);
6584 } else {
6585 pts = avio_rb64(pb);
6586 offadd= avio_rb64(pb);
6587 }
6588 if (av_sat_add64(offset, offadd) != offset + (uint64_t)offadd)
6589 return AVERROR_INVALIDDATA;
6590
6591 offset += (uint64_t)offadd;
6592
6593 avio_rb16(pb); // reserved
6594
6595 item_count = avio_rb16(pb);
6596 if (item_count == 0)
6597 return AVERROR_INVALIDDATA;
6598
6599 for (i = 0; i < item_count; i++) {
6600 int index;
6601 MOVFragmentStreamInfo * frag_stream_info;
6602 uint32_t size = avio_rb32(pb);
6603 uint32_t duration = avio_rb32(pb);
6604 if (size & 0x80000000) {
6605 avpriv_request_sample(c->fc, "sidx reference_type 1");
6606 return AVERROR_PATCHWELCOME;
6607 }
6608 avio_rb32(pb); // sap_flags
6609 timestamp = av_rescale_q(pts, timescale, st->time_base);
6610
6612 frag_stream_info = get_frag_stream_info(&c->frag_index, index, track_id);
6613 if (frag_stream_info)
6614 frag_stream_info->sidx_pts = timestamp;
6615
6616 if (av_sat_add64(offset, size) != offset + (uint64_t)size ||
6617 av_sat_add64(pts, duration) != pts + (uint64_t)duration
6618 )
6619 return AVERROR_INVALIDDATA;
6620 offset += size;
6621 pts += duration;
6622 }
6623
6624 st->duration = sc->track_end = pts;
6625
6626 sc->has_sidx = 1;
6627
6628 // See if the remaining bytes are just an mfra which we can ignore.
6629 is_complete = offset == stream_size;
6630 if (!is_complete && (pb->seekable & AVIO_SEEKABLE_NORMAL) && stream_size > 0 ) {
6631 int64_t ret;
6632 int64_t original_pos = avio_tell(pb);
6633 if (!c->have_read_mfra_size) {
6634 if ((ret = avio_seek(pb, stream_size - 4, SEEK_SET)) < 0)
6635 return ret;
6636 c->mfra_size = avio_rb32(pb);
6637 c->have_read_mfra_size = 1;
6638 if ((ret = avio_seek(pb, original_pos, SEEK_SET)) < 0)
6639 return ret;
6640 }
6641 if (offset == stream_size - c->mfra_size)
6642 is_complete = 1;
6643 }
6644
6645 if (is_complete) {
6646 // Find first entry in fragment index that came from an sidx.
6647 // This will pretty much always be the first entry.
6648 for (i = 0; i < c->frag_index.nb_items; i++) {
6649 MOVFragmentIndexItem * item = &c->frag_index.item[i];
6650 for (j = 0; ref_st == NULL && j < item->nb_stream_info; j++) {
6652 si = &item->stream_info[j];
6653 if (si->sidx_pts != AV_NOPTS_VALUE) {
6654 ref_st = c->fc->streams[j];
6655 ref_sc = ref_st->priv_data;
6656 break;
6657 }
6658 }
6659 }
6660 if (ref_st) for (i = 0; i < c->fc->nb_streams; i++) {
6661 st = c->fc->streams[i];
6662 sc = st->priv_data;
6663 if (!sc->has_sidx) {
6664 st->duration = sc->track_end = av_rescale(ref_st->duration, sc->time_scale, ref_sc->time_scale);
6665 }
6666 }
6667
6668 if (offadd == 0)
6669 c->frag_index.complete = 1;
6670 }
6671
6672 return 0;
6673}
6674
6675/* this atom should be null (from specs), but some buggy files put the 'moov' atom inside it... */
6676/* like the files created with Adobe Premiere 5.0, for samples see */
6677/* http://graphics.tudelft.nl/~wouter/publications/soundtests/ */
6679{
6680 int err;
6681
6682 if (atom.size < 8)
6683 return 0; /* continue */
6684 if (avio_rb32(pb) != 0) { /* 0 sized mdat atom... use the 'wide' atom size */
6685 avio_skip(pb, atom.size - 4);
6686 return 0;
6687 }
6688 atom.type = avio_rl32(pb);
6689 atom.size -= 8;
6690 if (atom.type != MKTAG('m','d','a','t')) {
6691 avio_skip(pb, atom.size);
6692 return 0;
6693 }
6694 err = mov_read_mdat(c, pb, atom);
6695 return err;
6696}
6697
6699{
6700#if CONFIG_ZLIB
6702 uint8_t *cmov_data;
6703 uint8_t *moov_data; /* uncompressed data */
6704 long cmov_len, moov_len;
6705 int ret = -1;
6706
6707 avio_rb32(pb); /* dcom atom */
6708 if (avio_rl32(pb) != MKTAG('d','c','o','m'))
6709 return AVERROR_INVALIDDATA;
6710 if (avio_rl32(pb) != MKTAG('z','l','i','b')) {
6711 av_log(c->fc, AV_LOG_ERROR, "unknown compression for cmov atom !\n");
6712 return AVERROR_INVALIDDATA;
6713 }
6714 avio_rb32(pb); /* cmvd atom */
6715 if (avio_rl32(pb) != MKTAG('c','m','v','d'))
6716 return AVERROR_INVALIDDATA;
6717 moov_len = avio_rb32(pb); /* uncompressed size */
6718 cmov_len = atom.size - 6 * 4;
6719
6720 cmov_data = av_malloc(cmov_len);
6721 if (!cmov_data)
6722 return AVERROR(ENOMEM);
6723 moov_data = av_malloc(moov_len);
6724 if (!moov_data) {
6725 av_free(cmov_data);
6726 return AVERROR(ENOMEM);
6727 }
6728 ret = ffio_read_size(pb, cmov_data, cmov_len);
6729 if (ret < 0)
6730 goto free_and_return;
6731
6732 ret = AVERROR_INVALIDDATA;
6733 if (uncompress (moov_data, (uLongf *) &moov_len, (const Bytef *)cmov_data, cmov_len) != Z_OK)
6734 goto free_and_return;
6735 ffio_init_read_context(&ctx, moov_data, moov_len);
6736 ctx.pub.seekable = AVIO_SEEKABLE_NORMAL;
6737 atom.type = MKTAG('m','o','o','v');
6738 atom.size = moov_len;
6739 ret = mov_read_default(c, &ctx.pub, atom);
6740free_and_return:
6741 av_free(moov_data);
6742 av_free(cmov_data);
6743 return ret;
6744#else
6745 av_log(c->fc, AV_LOG_ERROR, "this file requires zlib support compiled in\n");
6746 return AVERROR(ENOSYS);
6747#endif
6748}
6749
6750/* edit list atom */
6752{
6753 MOVStreamContext *sc;
6754 int i, edit_count, version;
6755 int64_t elst_entry_size;
6756
6757 if (c->fc->nb_streams < 1 || c->ignore_editlist)
6758 return 0;
6759 sc = c->fc->streams[c->fc->nb_streams-1]->priv_data;
6760
6761 version = avio_r8(pb); /* version */
6762 avio_rb24(pb); /* flags */
6763 edit_count = avio_rb32(pb); /* entries */
6764 atom.size -= 8;
6765
6766 elst_entry_size = version == 1 ? 20 : 12;
6767 if (atom.size != edit_count * elst_entry_size) {
6768 if (c->fc->strict_std_compliance >= FF_COMPLIANCE_STRICT) {
6769 av_log(c->fc, AV_LOG_ERROR, "Invalid edit list entry_count: %d for elst atom of size: %"PRId64" bytes.\n",
6770 edit_count, atom.size + 8);
6771 return AVERROR_INVALIDDATA;
6772 } else {
6773 edit_count = atom.size / elst_entry_size;
6774 if (edit_count * elst_entry_size != atom.size) {
6775 av_log(c->fc, AV_LOG_WARNING, "ELST atom of %"PRId64" bytes, bigger than %d entries.\n", atom.size, edit_count);
6776 }
6777 }
6778 }
6779
6780 if (!edit_count)
6781 return 0;
6782 if (sc->elst_data)
6783 av_log(c->fc, AV_LOG_WARNING, "Duplicated ELST atom\n");
6784 av_free(sc->elst_data);
6785 sc->elst_count = 0;
6786 sc->elst_data = av_malloc_array(edit_count, sizeof(*sc->elst_data));
6787 if (!sc->elst_data)
6788 return AVERROR(ENOMEM);
6789
6790 av_log(c->fc, AV_LOG_TRACE, "track[%u].edit_count = %i\n", c->fc->nb_streams - 1, edit_count);
6791 for (i = 0; i < edit_count && atom.size > 0 && !pb->eof_reached; i++) {
6792 MOVElst *e = &sc->elst_data[i];
6793
6794 if (version == 1) {
6795 e->duration = avio_rb64(pb);
6796 e->time = avio_rb64(pb);
6797 atom.size -= 16;
6798 } else {
6799 e->duration = avio_rb32(pb); /* segment duration */
6800 e->time = (int32_t)avio_rb32(pb); /* media time */
6801 atom.size -= 8;
6802 }
6803 e->rate = avio_rb32(pb) / 65536.0;
6804 atom.size -= 4;
6805 av_log(c->fc, AV_LOG_TRACE, "duration=%"PRId64" time=%"PRId64" rate=%f\n",
6806 e->duration, e->time, e->rate);
6807
6808 if (e->time < 0 && e->time != -1 &&
6809 c->fc->strict_std_compliance >= FF_COMPLIANCE_STRICT) {
6810 av_log(c->fc, AV_LOG_ERROR, "Track %d, edit %d: Invalid edit list media time=%"PRId64"\n",
6811 c->fc->nb_streams-1, i, e->time);
6812 return AVERROR_INVALIDDATA;
6813 }
6814 if (e->duration < 0) {
6815 av_log(c->fc, AV_LOG_ERROR, "Track %d, edit %d: Invalid edit list duration=%"PRId64"\n",
6816 c->fc->nb_streams-1, i, e->duration);
6817 return AVERROR_INVALIDDATA;
6818 }
6819 }
6820 sc->elst_count = i;
6821
6822 return 0;
6823}
6824
6826{
6827 MOVStreamContext *sc;
6828 int err;
6829
6830 if (c->fc->nb_streams < 1)
6831 return AVERROR_INVALIDDATA;
6832 sc = c->fc->streams[c->fc->nb_streams - 1]->priv_data;
6833
6834 if (atom.size % sizeof(uint32_t))
6835 return AVERROR_INVALIDDATA;
6836
6837 MovTref *tag = mov_add_tref_tag(sc, atom.type);
6838 if (!tag)
6839 return AVERROR(ENOMEM);
6840
6841 int nb_timecode_track = atom.size >> 2;
6842 for (int i = 0; i < nb_timecode_track; i++) {
6843 if (avio_feof(pb))
6844 return AVERROR_INVALIDDATA;
6845 err = mov_add_tref_id(tag, avio_rb32(pb));
6846 if (err < 0)
6847 return err;
6848 }
6849
6850 return 0;
6851}
6852
6854{
6855 AVStream *st;
6856 int version, color_range, color_primaries, color_trc, color_space;
6857
6858 if (c->fc->nb_streams < 1)
6859 return 0;
6860 st = c->fc->streams[c->fc->nb_streams - 1];
6861
6862 if (atom.size < 5) {
6863 av_log(c->fc, AV_LOG_ERROR, "Empty VP Codec Configuration box\n");
6864 return AVERROR_INVALIDDATA;
6865 }
6866
6867 version = avio_r8(pb);
6868 if (version != 1) {
6869 av_log(c->fc, AV_LOG_WARNING, "Unsupported VP Codec Configuration box version %d\n", version);
6870 return 0;
6871 }
6872 avio_skip(pb, 3); /* flags */
6873
6874 avio_skip(pb, 2); /* profile + level */
6875 color_range = avio_r8(pb); /* bitDepth, chromaSubsampling, videoFullRangeFlag */
6877 color_trc = avio_r8(pb);
6878 color_space = avio_r8(pb);
6879 if (avio_rb16(pb)) /* codecIntializationDataSize */
6880 return AVERROR_INVALIDDATA;
6881
6884 if (!av_color_transfer_name(color_trc))
6885 color_trc = AVCOL_TRC_UNSPECIFIED;
6886 if (!av_color_space_name(color_space))
6887 color_space = AVCOL_SPC_UNSPECIFIED;
6888
6891 st->codecpar->color_trc = color_trc;
6892 st->codecpar->color_space = color_space;
6893
6894 return 0;
6895}
6896
6898{
6899 MOVStreamContext *sc;
6900 int i, version;
6901
6902 if (c->fc->nb_streams < 1)
6903 return AVERROR_INVALIDDATA;
6904
6905 sc = c->fc->streams[c->fc->nb_streams - 1]->priv_data;
6906
6907 if (atom.size < 5) {
6908 av_log(c->fc, AV_LOG_ERROR, "Empty Mastering Display Metadata box\n");
6909 return AVERROR_INVALIDDATA;
6910 }
6911
6912 version = avio_r8(pb);
6913 if (version) {
6914 av_log(c->fc, AV_LOG_WARNING, "Unsupported Mastering Display Metadata box version %d\n", version);
6915 return 0;
6916 }
6917 if (sc->mastering) {
6918 av_log(c->fc, AV_LOG_WARNING, "Ignoring duplicate Mastering Display Metadata\n");
6919 return 0;
6920 }
6921
6922 avio_skip(pb, 3); /* flags */
6923
6925 if (!sc->mastering)
6926 return AVERROR(ENOMEM);
6927
6928 for (i = 0; i < 3; i++) {
6929 sc->mastering->display_primaries[i][0] = av_make_q(avio_rb16(pb), 1 << 16);
6930 sc->mastering->display_primaries[i][1] = av_make_q(avio_rb16(pb), 1 << 16);
6931 }
6932 sc->mastering->white_point[0] = av_make_q(avio_rb16(pb), 1 << 16);
6933 sc->mastering->white_point[1] = av_make_q(avio_rb16(pb), 1 << 16);
6934
6935 sc->mastering->max_luminance = av_make_q(avio_rb32(pb), 1 << 8);
6936 sc->mastering->min_luminance = av_make_q(avio_rb32(pb), 1 << 14);
6937
6938 sc->mastering->has_primaries = 1;
6939 sc->mastering->has_luminance = 1;
6940
6941 return 0;
6942}
6943
6945{
6946 MOVStreamContext *sc;
6947 const int mapping[3] = {1, 2, 0};
6948 const int chroma_den = 50000;
6949 const int luma_den = 10000;
6950 int i;
6951
6952 if (c->fc->nb_streams < 1)
6953 return AVERROR_INVALIDDATA;
6954
6955 sc = c->fc->streams[c->fc->nb_streams - 1]->priv_data;
6956
6957 if (atom.size < 24) {
6958 av_log(c->fc, AV_LOG_ERROR, "Invalid Mastering Display Color Volume box\n");
6959 return AVERROR_INVALIDDATA;
6960 }
6961
6962 if (sc->mastering) {
6963 av_log(c->fc, AV_LOG_WARNING, "Ignoring duplicate Mastering Display Color Volume\n");
6964 return 0;
6965 }
6966
6968 if (!sc->mastering)
6969 return AVERROR(ENOMEM);
6970
6971 for (i = 0; i < 3; i++) {
6972 const int j = mapping[i];
6973 sc->mastering->display_primaries[j][0] = av_make_q(avio_rb16(pb), chroma_den);
6974 sc->mastering->display_primaries[j][1] = av_make_q(avio_rb16(pb), chroma_den);
6975 }
6976 sc->mastering->white_point[0] = av_make_q(avio_rb16(pb), chroma_den);
6977 sc->mastering->white_point[1] = av_make_q(avio_rb16(pb), chroma_den);
6978
6979 sc->mastering->max_luminance = av_make_q(avio_rb32(pb), luma_den);
6980 sc->mastering->min_luminance = av_make_q(avio_rb32(pb), luma_den);
6981
6982 sc->mastering->has_luminance = 1;
6983 sc->mastering->has_primaries = 1;
6984
6985 return 0;
6986}
6987
6989{
6990 MOVStreamContext *sc;
6991 int version;
6992
6993 if (c->fc->nb_streams < 1)
6994 return AVERROR_INVALIDDATA;
6995
6996 sc = c->fc->streams[c->fc->nb_streams - 1]->priv_data;
6997
6998 if (atom.size < 5) {
6999 av_log(c->fc, AV_LOG_ERROR, "Empty Content Light Level box\n");
7000 return AVERROR_INVALIDDATA;
7001 }
7002
7003 version = avio_r8(pb);
7004 if (version) {
7005 av_log(c->fc, AV_LOG_WARNING, "Unsupported Content Light Level box version %d\n", version);
7006 return 0;
7007 }
7008 avio_skip(pb, 3); /* flags */
7009
7010 if (sc->coll){
7011 av_log(c->fc, AV_LOG_WARNING, "Ignoring duplicate COLL\n");
7012 return 0;
7013 }
7014
7016 if (!sc->coll)
7017 return AVERROR(ENOMEM);
7018
7019 sc->coll->MaxCLL = avio_rb16(pb);
7020 sc->coll->MaxFALL = avio_rb16(pb);
7021
7022 return 0;
7023}
7024
7026{
7027 MOVStreamContext *sc;
7028
7029 if (c->fc->nb_streams < 1)
7030 return AVERROR_INVALIDDATA;
7031
7032 sc = c->fc->streams[c->fc->nb_streams - 1]->priv_data;
7033
7034 if (atom.size < 4) {
7035 av_log(c->fc, AV_LOG_ERROR, "Empty Content Light Level Info box\n");
7036 return AVERROR_INVALIDDATA;
7037 }
7038
7039 if (sc->coll){
7040 av_log(c->fc, AV_LOG_WARNING, "Ignoring duplicate CLLI/COLL\n");
7041 return 0;
7042 }
7043
7045 if (!sc->coll)
7046 return AVERROR(ENOMEM);
7047
7048 sc->coll->MaxCLL = avio_rb16(pb);
7049 sc->coll->MaxFALL = avio_rb16(pb);
7050
7051 return 0;
7052}
7053
7055{
7056 MOVStreamContext *sc;
7057 const int illuminance_den = 10000;
7058 const int ambient_den = 50000;
7059 if (c->fc->nb_streams < 1)
7060 return AVERROR_INVALIDDATA;
7061 sc = c->fc->streams[c->fc->nb_streams - 1]->priv_data;
7062 if (atom.size < 6) {
7063 av_log(c->fc, AV_LOG_ERROR, "Empty Ambient Viewing Environment Info box\n");
7064 return AVERROR_INVALIDDATA;
7065 }
7066 if (sc->ambient){
7067 av_log(c->fc, AV_LOG_WARNING, "Ignoring duplicate AMVE\n");
7068 return 0;
7069 }
7071 if (!sc->ambient)
7072 return AVERROR(ENOMEM);
7073 sc->ambient->ambient_illuminance = av_make_q(avio_rb32(pb), illuminance_den);
7074 sc->ambient->ambient_light_x = av_make_q(avio_rb16(pb), ambient_den);
7075 sc->ambient->ambient_light_y = av_make_q(avio_rb16(pb), ambient_den);
7076 return 0;
7077}
7078
7080{
7081 AVStream *st;
7082 MOVStreamContext *sc;
7083 enum AVStereo3DType type;
7084 int mode;
7085
7086 if (c->fc->nb_streams < 1)
7087 return 0;
7088
7089 st = c->fc->streams[c->fc->nb_streams - 1];
7090 sc = st->priv_data;
7091
7092 if (atom.size < 5) {
7093 av_log(c->fc, AV_LOG_ERROR, "Empty stereoscopic video box\n");
7094 return AVERROR_INVALIDDATA;
7095 }
7096
7097 if (sc->stereo3d)
7098 return AVERROR_INVALIDDATA;
7099
7100 avio_skip(pb, 4); /* version + flags */
7101
7102 mode = avio_r8(pb);
7103 switch (mode) {
7104 case 0:
7106 break;
7107 case 1:
7109 break;
7110 case 2:
7112 break;
7113 default:
7114 av_log(c->fc, AV_LOG_WARNING, "Unknown st3d mode value %d\n", mode);
7115 return 0;
7116 }
7117
7119 if (!sc->stereo3d)
7120 return AVERROR(ENOMEM);
7121
7122 sc->stereo3d->type = type;
7123 return 0;
7124}
7125
7127{
7128 AVStream *st;
7129 MOVStreamContext *sc;
7130 int size = 0;
7131 int64_t remaining;
7132 uint32_t tag = 0;
7134
7135 if (c->fc->nb_streams < 1)
7136 return 0;
7137
7138 st = c->fc->streams[c->fc->nb_streams - 1];
7139 sc = st->priv_data;
7140
7141 remaining = atom.size;
7142 while (remaining > 0) {
7143 size = avio_rb32(pb);
7144 if (size < 8 || size > remaining ) {
7145 av_log(c->fc, AV_LOG_ERROR, "Invalid child size in pack box\n");
7146 return AVERROR_INVALIDDATA;
7147 }
7148
7149 tag = avio_rl32(pb);
7150 switch (tag) {
7151 case MKTAG('p','k','i','n'): {
7152 if (size != 16) {
7153 av_log(c->fc, AV_LOG_ERROR, "Invalid size of pkin box: %d\n", size);
7154 return AVERROR_INVALIDDATA;
7155 }
7156 avio_skip(pb, 1); // version
7157 avio_skip(pb, 3); // flags
7158
7159 tag = avio_rl32(pb);
7160 switch (tag) {
7161 case MKTAG('s','i','d','e'):
7163 break;
7164 case MKTAG('o','v','e','r'):
7166 break;
7167 case 0:
7168 // This means value will be set in another layer
7169 break;
7170 default:
7171 av_log(c->fc, AV_LOG_WARNING, "Unknown tag in pkin: %s\n",
7173 avio_skip(pb, size - 8);
7174 break;
7175 }
7176
7177 break;
7178 }
7179 default:
7180 av_log(c->fc, AV_LOG_WARNING, "Unknown tag in pack: %s\n",
7182 avio_skip(pb, size - 8);
7183 break;
7184 }
7185 remaining -= size;
7186 }
7187
7188 if (remaining != 0) {
7189 av_log(c->fc, AV_LOG_ERROR, "Broken pack box\n");
7190 return AVERROR_INVALIDDATA;
7191 }
7192
7193 if (type == AV_STEREO3D_2D)
7194 return 0;
7195
7196 if (!sc->stereo3d) {
7198 if (!sc->stereo3d)
7199 return AVERROR(ENOMEM);
7200 }
7201
7202 sc->stereo3d->type = type;
7203
7204 return 0;
7205}
7206
7208{
7209 AVStream *st;
7210 MOVStreamContext *sc;
7211 int size, version, layout;
7212 int32_t yaw, pitch, roll;
7213 uint32_t l = 0, t = 0, r = 0, b = 0;
7214 uint32_t tag, padding = 0;
7215 enum AVSphericalProjection projection;
7216
7217 if (c->fc->nb_streams < 1)
7218 return 0;
7219
7220 st = c->fc->streams[c->fc->nb_streams - 1];
7221 sc = st->priv_data;
7222
7223 if (atom.size < 8) {
7224 av_log(c->fc, AV_LOG_ERROR, "Empty spherical video box\n");
7225 return AVERROR_INVALIDDATA;
7226 }
7227
7228 size = avio_rb32(pb);
7229 if (size <= 12 || size > atom.size)
7230 return AVERROR_INVALIDDATA;
7231
7232 tag = avio_rl32(pb);
7233 if (tag != MKTAG('s','v','h','d')) {
7234 av_log(c->fc, AV_LOG_ERROR, "Missing spherical video header\n");
7235 return 0;
7236 }
7237 version = avio_r8(pb);
7238 if (version != 0) {
7239 av_log(c->fc, AV_LOG_WARNING, "Unknown spherical version %d\n",
7240 version);
7241 return 0;
7242 }
7243 avio_skip(pb, 3); /* flags */
7244 avio_skip(pb, size - 12); /* metadata_source */
7245
7246 size = avio_rb32(pb);
7247 if (size > atom.size)
7248 return AVERROR_INVALIDDATA;
7249
7250 tag = avio_rl32(pb);
7251 if (tag != MKTAG('p','r','o','j')) {
7252 av_log(c->fc, AV_LOG_ERROR, "Missing projection box\n");
7253 return 0;
7254 }
7255
7256 size = avio_rb32(pb);
7257 if (size > atom.size)
7258 return AVERROR_INVALIDDATA;
7259
7260 tag = avio_rl32(pb);
7261 if (tag != MKTAG('p','r','h','d')) {
7262 av_log(c->fc, AV_LOG_ERROR, "Missing projection header box\n");
7263 return 0;
7264 }
7265 version = avio_r8(pb);
7266 if (version != 0) {
7267 av_log(c->fc, AV_LOG_WARNING, "Unknown spherical version %d\n",
7268 version);
7269 return 0;
7270 }
7271 avio_skip(pb, 3); /* flags */
7272
7273 /* 16.16 fixed point */
7274 yaw = avio_rb32(pb);
7275 pitch = avio_rb32(pb);
7276 roll = avio_rb32(pb);
7277
7278 size = avio_rb32(pb);
7279 if (size > atom.size)
7280 return AVERROR_INVALIDDATA;
7281
7282 tag = avio_rl32(pb);
7283 version = avio_r8(pb);
7284 if (version != 0) {
7285 av_log(c->fc, AV_LOG_WARNING, "Unknown spherical version %d\n",
7286 version);
7287 return 0;
7288 }
7289 avio_skip(pb, 3); /* flags */
7290 switch (tag) {
7291 case MKTAG('c','b','m','p'):
7292 layout = avio_rb32(pb);
7293 if (layout) {
7294 av_log(c->fc, AV_LOG_WARNING,
7295 "Unsupported cubemap layout %d\n", layout);
7296 return 0;
7297 }
7298 projection = AV_SPHERICAL_CUBEMAP;
7299 padding = avio_rb32(pb);
7300 break;
7301 case MKTAG('e','q','u','i'):
7302 t = avio_rb32(pb);
7303 b = avio_rb32(pb);
7304 l = avio_rb32(pb);
7305 r = avio_rb32(pb);
7306
7307 if (b >= UINT_MAX - t || r >= UINT_MAX - l) {
7308 av_log(c->fc, AV_LOG_ERROR,
7309 "Invalid bounding rectangle coordinates "
7310 "%"PRIu32",%"PRIu32",%"PRIu32",%"PRIu32"\n", l, t, r, b);
7311 return AVERROR_INVALIDDATA;
7312 }
7313
7314 if (l || t || r || b)
7316 else
7317 projection = AV_SPHERICAL_EQUIRECTANGULAR;
7318 break;
7319 default:
7320 av_log(c->fc, AV_LOG_ERROR, "Unknown projection type: %s\n", av_fourcc2str(tag));
7321 return 0;
7322 }
7323
7325 if (!sc->spherical)
7326 return AVERROR(ENOMEM);
7327
7328 sc->spherical->projection = projection;
7329
7330 sc->spherical->yaw = yaw;
7331 sc->spherical->pitch = pitch;
7332 sc->spherical->roll = roll;
7333
7334 sc->spherical->padding = padding;
7335
7336 sc->spherical->bound_left = l;
7337 sc->spherical->bound_top = t;
7338 sc->spherical->bound_right = r;
7339 sc->spherical->bound_bottom = b;
7340
7341 return 0;
7342}
7343
7345{
7346 AVStream *st;
7347 MOVStreamContext *sc;
7348 int size;
7349 uint32_t tag;
7350 enum AVSphericalProjection projection;
7351
7352 if (c->fc->nb_streams < 1)
7353 return 0;
7354
7355 st = c->fc->streams[c->fc->nb_streams - 1];
7356 sc = st->priv_data;
7357
7358 if (atom.size < 16) {
7359 av_log(c->fc, AV_LOG_ERROR, "Invalid size for proj box: %"PRIu64"\n", atom.size);
7360 return AVERROR_INVALIDDATA;
7361 }
7362
7363 size = avio_rb32(pb);
7364 if (size < 16) {
7365 av_log(c->fc, AV_LOG_ERROR, "Invalid size for prji box: %d\n", size);
7366 return AVERROR_INVALIDDATA;
7367 } else if (size > 16) {
7368 av_log(c->fc, AV_LOG_WARNING, "Box has more bytes (%d) than prji box required (16) \n", size);
7369 }
7370
7371 tag = avio_rl32(pb);
7372 if (tag != MKTAG('p','r','j','i')) {
7373 av_log(c->fc, AV_LOG_ERROR, "Invalid child box of proj box: %s\n",
7375 return AVERROR_INVALIDDATA;
7376 }
7377
7378 // version and flags, only support (0, 0)
7379 unsigned n = avio_rl32(pb);
7380 if (n != 0) {
7381 av_log(c->fc, AV_LOG_ERROR, "prji version %u, flag %u are not supported\n",
7382 n & 0xFF, n >> 8);
7383 return AVERROR_PATCHWELCOME;
7384 }
7385
7386 tag = avio_rl32(pb);
7387 switch (tag) {
7388 case MKTAG('r','e','c','t'):
7389 projection = AV_SPHERICAL_RECTILINEAR;
7390 break;
7391 case MKTAG('e','q','u','i'):
7392 projection = AV_SPHERICAL_EQUIRECTANGULAR;
7393 break;
7394 case MKTAG('h','e','q','u'):
7396 break;
7397 case MKTAG('f','i','s','h'):
7398 projection = AV_SPHERICAL_FISHEYE;
7399 break;
7400 case MKTAG('p','r','i','m'):
7402 break;
7403 default:
7404 av_log(c->fc, AV_LOG_ERROR, "Invalid projection type in prji box: %s\n", av_fourcc2str(tag));
7405 return AVERROR_INVALIDDATA;
7406 }
7407
7409 if (!sc->spherical)
7410 return AVERROR(ENOMEM);
7411
7412 sc->spherical->projection = projection;
7413
7414 return 0;
7415}
7416
7418{
7419 AVStream *st;
7420 MOVStreamContext *sc;
7421 int size, flags = 0;
7422 int64_t remaining;
7423 uint32_t tag, baseline = 0;
7426 enum AVStereo3DPrimaryEye primary_eye = AV_PRIMARY_EYE_NONE;
7427 AVRational horizontal_disparity_adjustment = { 0, 1 };
7428
7429 if (c->fc->nb_streams < 1)
7430 return 0;
7431
7432 st = c->fc->streams[c->fc->nb_streams - 1];
7433 sc = st->priv_data;
7434
7435 remaining = atom.size;
7436 while (remaining > 0) {
7437 size = avio_rb32(pb);
7438 if (size < 8 || size > remaining ) {
7439 av_log(c->fc, AV_LOG_ERROR, "Invalid child size in eyes box\n");
7440 return AVERROR_INVALIDDATA;
7441 }
7442
7443 tag = avio_rl32(pb);
7444 switch (tag) {
7445 case MKTAG('s','t','r','i'): {
7446 int has_right, has_left;
7447 uint8_t tmp;
7448 if (size != 13) {
7449 av_log(c->fc, AV_LOG_ERROR, "Invalid size of stri box: %d\n", size);
7450 return AVERROR_INVALIDDATA;
7451 }
7452 avio_skip(pb, 1); // version
7453 avio_skip(pb, 3); // flags
7454
7455 tmp = avio_r8(pb);
7456
7457 // eye_views_reversed
7458 if (tmp & 8) {
7460 }
7461 // has_additional_views
7462 if (tmp & 4) {
7463 // skip...
7464 }
7465
7466 has_right = tmp & 2; // has_right_eye_view
7467 has_left = tmp & 1; // has_left_eye_view
7468
7469 if (has_left && has_right)
7471 else if (has_left)
7472 view = AV_STEREO3D_VIEW_LEFT;
7473 else if (has_right)
7475 if (has_left || has_right)
7477
7478 break;
7479 }
7480 case MKTAG('h','e','r','o'): {
7481 int tmp;
7482 if (size != 13) {
7483 av_log(c->fc, AV_LOG_ERROR, "Invalid size of hero box: %d\n", size);
7484 return AVERROR_INVALIDDATA;
7485 }
7486 avio_skip(pb, 1); // version
7487 avio_skip(pb, 3); // flags
7488
7489 tmp = avio_r8(pb);
7490 if (tmp == 0)
7491 primary_eye = AV_PRIMARY_EYE_NONE;
7492 else if (tmp == 1)
7493 primary_eye = AV_PRIMARY_EYE_LEFT;
7494 else if (tmp == 2)
7495 primary_eye = AV_PRIMARY_EYE_RIGHT;
7496 else
7497 av_log(c->fc, AV_LOG_WARNING, "Unknown hero eye type: %d\n", tmp);
7498
7499 break;
7500 }
7501 case MKTAG('c','a','m','s'): {
7502 uint32_t subtag;
7503 int subsize;
7504 if (size != 24) {
7505 av_log(c->fc, AV_LOG_ERROR, "Invalid size of cams box: %d\n", size);
7506 return AVERROR_INVALIDDATA;
7507 }
7508
7509 subsize = avio_rb32(pb);
7510 if (subsize != 16) {
7511 av_log(c->fc, AV_LOG_ERROR, "Invalid size of blin box: %d\n", size);
7512 return AVERROR_INVALIDDATA;
7513 }
7514
7515 subtag = avio_rl32(pb);
7516 if (subtag != MKTAG('b','l','i','n')) {
7517 av_log(c->fc, AV_LOG_ERROR, "Expected blin box, got %s\n",
7518 av_fourcc2str(subtag));
7519 return AVERROR_INVALIDDATA;
7520 }
7521
7522 avio_skip(pb, 1); // version
7523 avio_skip(pb, 3); // flags
7524
7525 baseline = avio_rb32(pb);
7526
7527 break;
7528 }
7529 case MKTAG('c','m','f','y'): {
7530 uint32_t subtag;
7531 int subsize;
7532 int32_t adjustment;
7533 if (size != 24) {
7534 av_log(c->fc, AV_LOG_ERROR, "Invalid size of cmfy box: %d\n", size);
7535 return AVERROR_INVALIDDATA;
7536 }
7537
7538 subsize = avio_rb32(pb);
7539 if (subsize != 16) {
7540 av_log(c->fc, AV_LOG_ERROR, "Invalid size of dadj box: %d\n", size);
7541 return AVERROR_INVALIDDATA;
7542 }
7543
7544 subtag = avio_rl32(pb);
7545 if (subtag != MKTAG('d','a','d','j')) {
7546 av_log(c->fc, AV_LOG_ERROR, "Expected dadj box, got %s\n",
7547 av_fourcc2str(subtag));
7548 return AVERROR_INVALIDDATA;
7549 }
7550
7551 avio_skip(pb, 1); // version
7552 avio_skip(pb, 3); // flags
7553
7554 adjustment = (int32_t) avio_rb32(pb);
7555
7556 horizontal_disparity_adjustment.num = (int) adjustment;
7557 horizontal_disparity_adjustment.den = 10000;
7558
7559 break;
7560 }
7561 default:
7562 av_log(c->fc, AV_LOG_WARNING, "Unknown tag in eyes: %s\n",
7564 avio_skip(pb, size - 8);
7565 break;
7566 }
7567 remaining -= size;
7568 }
7569
7570 if (remaining != 0) {
7571 av_log(c->fc, AV_LOG_ERROR, "Broken eyes box\n");
7572 return AVERROR_INVALIDDATA;
7573 }
7574
7575 if (type == AV_STEREO3D_2D)
7576 return 0;
7577
7578 if (!sc->stereo3d) {
7580 if (!sc->stereo3d)
7581 return AVERROR(ENOMEM);
7582 }
7583
7584 sc->stereo3d->flags = flags;
7585 /* eyes/stri only records packed vs single-eye, not SBS/TB. Keep a more
7586 * specific type already set by st3d. */
7587 if (type != AV_STEREO3D_UNSPEC)
7588 sc->stereo3d->type = type;
7589 else if (sc->stereo3d->type == AV_STEREO3D_2D)
7590 sc->stereo3d->type = type;
7591 sc->stereo3d->view = view;
7592 sc->stereo3d->primary_eye = primary_eye;
7593 sc->stereo3d->baseline = baseline;
7594 sc->stereo3d->horizontal_disparity_adjustment = horizontal_disparity_adjustment;
7595
7596 return 0;
7597}
7598
7600{
7601 int size;
7602 int64_t remaining;
7603 uint32_t tag;
7604
7605 if (c->fc->nb_streams < 1)
7606 return 0;
7607
7608 if (atom.size < 8) {
7609 av_log(c->fc, AV_LOG_ERROR, "Empty video extension usage box\n");
7610 return AVERROR_INVALIDDATA;
7611 }
7612
7613 remaining = atom.size;
7614 while (remaining > 0) {
7615 size = avio_rb32(pb);
7616 if (size < 8 || size > remaining ) {
7617 av_log(c->fc, AV_LOG_ERROR, "Invalid child size in vexu box\n");
7618 return AVERROR_INVALIDDATA;
7619 }
7620
7621 tag = avio_rl32(pb);
7622 switch (tag) {
7623 case MKTAG('p','r','o','j'): {
7624 MOVAtom proj = { tag, size - 8 };
7625 int ret = mov_read_vexu_proj(c, pb, proj);
7626 if (ret < 0)
7627 return ret;
7628 break;
7629 }
7630 case MKTAG('e','y','e','s'): {
7631 MOVAtom eyes = { tag, size - 8 };
7632 int ret = mov_read_eyes(c, pb, eyes);
7633 if (ret < 0)
7634 return ret;
7635 break;
7636 }
7637 case MKTAG('p','a','c','k'): {
7638 MOVAtom pack = { tag, size - 8 };
7639 int ret = mov_read_pack(c, pb, pack);
7640 if (ret < 0)
7641 return ret;
7642 break;
7643 }
7644 default:
7645 av_log(c->fc, AV_LOG_WARNING, "Unknown tag in vexu: %s\n",
7647 avio_skip(pb, size - 8);
7648 break;
7649 }
7650 remaining -= size;
7651 }
7652
7653 if (remaining != 0) {
7654 av_log(c->fc, AV_LOG_ERROR, "Broken vexu box\n");
7655 return AVERROR_INVALIDDATA;
7656 }
7657
7658 return 0;
7659}
7660
7662{
7663 AVStream *st;
7664 MOVStreamContext *sc;
7665
7666 if (c->fc->nb_streams < 1)
7667 return 0;
7668
7669 st = c->fc->streams[c->fc->nb_streams - 1];
7670 sc = st->priv_data;
7671
7672 if (atom.size != 4) {
7673 av_log(c->fc, AV_LOG_ERROR, "Invalid size of hfov box: %"PRIu64"\n", atom.size);
7674 return AVERROR_INVALIDDATA;
7675 }
7676
7677
7678 if (!sc->stereo3d) {
7680 if (!sc->stereo3d)
7681 return AVERROR(ENOMEM);
7682 }
7683
7685 sc->stereo3d->horizontal_field_of_view.den = 1000; // thousands of a degree
7686
7687 return 0;
7688}
7689
7691{
7692 int ret = 0;
7693 uint8_t *buffer = av_malloc(len + 1);
7694 const char *val;
7695
7696 if (!buffer)
7697 return AVERROR(ENOMEM);
7698 buffer[len] = '\0';
7699
7700 ret = ffio_read_size(pb, buffer, len);
7701 if (ret < 0)
7702 goto out;
7703
7704 /* Check for mandatory keys and values, try to support XML as best-effort */
7705 if (!sc->spherical &&
7706 av_stristr(buffer, "<GSpherical:StitchingSoftware>") &&
7707 (val = av_stristr(buffer, "<GSpherical:Spherical>")) &&
7708 av_stristr(val, "true") &&
7709 (val = av_stristr(buffer, "<GSpherical:Stitched>")) &&
7710 av_stristr(val, "true") &&
7711 (val = av_stristr(buffer, "<GSpherical:ProjectionType>")) &&
7712 av_stristr(val, "equirectangular")) {
7714 if (!sc->spherical)
7715 goto out;
7716
7718
7719 if (av_stristr(buffer, "<GSpherical:StereoMode>") && !sc->stereo3d) {
7720 enum AVStereo3DType mode;
7721
7722 if (av_stristr(buffer, "left-right"))
7724 else if (av_stristr(buffer, "top-bottom"))
7726 else
7728
7730 if (!sc->stereo3d)
7731 goto out;
7732
7733 sc->stereo3d->type = mode;
7734 }
7735
7736 /* orientation */
7737 val = av_stristr(buffer, "<GSpherical:InitialViewHeadingDegrees>");
7738 if (val)
7739 sc->spherical->yaw = strtol(val, NULL, 10) * (1 << 16);
7740 val = av_stristr(buffer, "<GSpherical:InitialViewPitchDegrees>");
7741 if (val)
7742 sc->spherical->pitch = strtol(val, NULL, 10) * (1 << 16);
7743 val = av_stristr(buffer, "<GSpherical:InitialViewRollDegrees>");
7744 if (val)
7745 sc->spherical->roll = strtol(val, NULL, 10) * (1 << 16);
7746 }
7747
7748out:
7749 av_free(buffer);
7750 return ret;
7751}
7752
7754{
7755 AVStream *st;
7756 MOVStreamContext *sc;
7757 int64_t ret;
7758 AVUUID uuid;
7759 static const AVUUID uuid_isml_manifest = {
7760 0xa5, 0xd4, 0x0b, 0x30, 0xe8, 0x14, 0x11, 0xdd,
7761 0xba, 0x2f, 0x08, 0x00, 0x20, 0x0c, 0x9a, 0x66
7762 };
7763 static const AVUUID uuid_xmp = {
7764 0xbe, 0x7a, 0xcf, 0xcb, 0x97, 0xa9, 0x42, 0xe8,
7765 0x9c, 0x71, 0x99, 0x94, 0x91, 0xe3, 0xaf, 0xac
7766 };
7767 static const AVUUID uuid_spherical = {
7768 0xff, 0xcc, 0x82, 0x63, 0xf8, 0x55, 0x4a, 0x93,
7769 0x88, 0x14, 0x58, 0x7a, 0x02, 0x52, 0x1f, 0xdd,
7770 };
7771
7772 if (atom.size < AV_UUID_LEN || atom.size >= FFMIN(INT_MAX, SIZE_MAX))
7773 return AVERROR_INVALIDDATA;
7774
7775 if (c->fc->nb_streams < 1)
7776 return 0;
7777 st = c->fc->streams[c->fc->nb_streams - 1];
7778 sc = st->priv_data;
7779
7780 ret = ffio_read_size(pb, uuid, AV_UUID_LEN);
7781 if (ret < 0)
7782 return ret;
7783 if (av_uuid_equal(uuid, uuid_isml_manifest)) {
7784 uint8_t *buffer, *ptr;
7785 char *endptr;
7786 size_t len = atom.size - AV_UUID_LEN;
7787
7788 if (len < 4) {
7789 return AVERROR_INVALIDDATA;
7790 }
7791 ret = avio_skip(pb, 4); // zeroes
7792 len -= 4;
7793
7794 buffer = av_mallocz(len + 1);
7795 if (!buffer) {
7796 return AVERROR(ENOMEM);
7797 }
7798 ret = ffio_read_size(pb, buffer, len);
7799 if (ret < 0) {
7800 av_free(buffer);
7801 return ret;
7802 }
7803
7804 ptr = buffer;
7805 while ((ptr = av_stristr(ptr, "systemBitrate=\""))) {
7806 ptr += sizeof("systemBitrate=\"") - 1;
7807 c->bitrates_count++;
7808 c->bitrates = av_realloc_f(c->bitrates, c->bitrates_count, sizeof(*c->bitrates));
7809 if (!c->bitrates) {
7810 c->bitrates_count = 0;
7811 av_free(buffer);
7812 return AVERROR(ENOMEM);
7813 }
7814 errno = 0;
7815 ret = strtol(ptr, &endptr, 10);
7816 if (ret < 0 || errno || *endptr != '"') {
7817 c->bitrates[c->bitrates_count - 1] = 0;
7818 } else {
7819 c->bitrates[c->bitrates_count - 1] = ret;
7820 }
7821 }
7822
7823 av_free(buffer);
7824 } else if (av_uuid_equal(uuid, uuid_xmp)) {
7825 uint8_t *buffer;
7826 size_t len = atom.size - AV_UUID_LEN;
7827 if (c->export_xmp) {
7828 buffer = av_mallocz(len + 1);
7829 if (!buffer) {
7830 return AVERROR(ENOMEM);
7831 }
7832 ret = ffio_read_size(pb, buffer, len);
7833 if (ret < 0) {
7834 av_free(buffer);
7835 return ret;
7836 }
7837 buffer[len] = '\0';
7838 av_dict_set(&c->fc->metadata, "xmp",
7840 } else {
7841 // skip all uuid atom, which makes it fast for long uuid-xmp file
7842 ret = avio_skip(pb, len);
7843 if (ret < 0)
7844 return ret;
7845 }
7846 } else if (av_uuid_equal(uuid, uuid_spherical)) {
7847 size_t len = atom.size - AV_UUID_LEN;
7848 ret = mov_parse_uuid_spherical(sc, pb, len);
7849 if (ret < 0)
7850 return ret;
7851 if (!sc->spherical)
7852 av_log(c->fc, AV_LOG_WARNING, "Invalid spherical metadata found\n");
7853 }
7854
7855 return 0;
7856}
7857
7859{
7860 int ret;
7861 uint8_t content[16];
7862
7863 if (atom.size < 8)
7864 return 0;
7865
7866 ret = ffio_read_size(pb, content, FFMIN(sizeof(content), atom.size));
7867 if (ret < 0)
7868 return ret;
7869
7870 if ( !c->found_moov
7871 && !c->found_mdat
7872 && !memcmp(content, "Anevia\x1A\x1A", 8)
7873 && c->use_mfra_for == FF_MOV_FLAG_MFRA_AUTO) {
7874 c->use_mfra_for = FF_MOV_FLAG_MFRA_PTS;
7875 }
7876
7877 return 0;
7878}
7879
7881{
7882 uint32_t format = avio_rl32(pb);
7883 MOVStreamContext *sc;
7884 enum AVCodecID id;
7885 AVStream *st;
7886
7887 if (c->fc->nb_streams < 1)
7888 return 0;
7889 st = c->fc->streams[c->fc->nb_streams - 1];
7890 sc = st->priv_data;
7891
7892 switch (sc->format)
7893 {
7894 case MKTAG('e','n','c','v'): // encrypted video
7895 case MKTAG('e','n','c','a'): // encrypted audio
7896 id = mov_codec_id(st, format);
7897 if (st->codecpar->codec_id != AV_CODEC_ID_NONE &&
7898 st->codecpar->codec_id != id) {
7899 av_log(c->fc, AV_LOG_WARNING,
7900 "ignoring 'frma' atom of '%.4s', stream has codec id %d\n",
7901 (char*)&format, st->codecpar->codec_id);
7902 break;
7903 }
7904
7905 st->codecpar->codec_id = id;
7906 sc->format = format;
7907 break;
7908
7909 default:
7910 if (format != sc->format) {
7911 av_log(c->fc, AV_LOG_WARNING,
7912 "ignoring 'frma' atom of '%.4s', stream format is '%.4s'\n",
7913 (char*)&format, (char*)&sc->format);
7914 }
7915 break;
7916 }
7917
7918 return 0;
7919}
7920
7921/**
7922 * Gets the current encryption info and associated current stream context. If
7923 * we are parsing a track fragment, this will return the specific encryption
7924 * info for this fragment; otherwise this will return the global encryption
7925 * info for the current stream.
7926 */
7928{
7929 MOVFragmentStreamInfo *frag_stream_info;
7930 AVStream *st;
7931 int i;
7932
7933 frag_stream_info = get_current_frag_stream_info(&c->frag_index);
7934 if (frag_stream_info) {
7935 for (i = 0; i < c->fc->nb_streams; i++) {
7936 *sc = c->fc->streams[i]->priv_data;
7937 if ((*sc)->id == frag_stream_info->id) {
7938 st = c->fc->streams[i];
7939 break;
7940 }
7941 }
7942 if (i == c->fc->nb_streams)
7943 return 0;
7944 *sc = st->priv_data;
7945
7946 if (!frag_stream_info->encryption_index) {
7947 // If this stream isn't encrypted, don't create the index.
7948 if (!(*sc)->cenc.default_encrypted_sample)
7949 return 0;
7950 frag_stream_info->encryption_index = av_mallocz(sizeof(*frag_stream_info->encryption_index));
7951 if (!frag_stream_info->encryption_index)
7952 return AVERROR(ENOMEM);
7953 }
7954 *encryption_index = frag_stream_info->encryption_index;
7955 return 1;
7956 } else {
7957 // No current track fragment, using stream level encryption info.
7958
7959 if (c->fc->nb_streams < 1)
7960 return 0;
7961 st = c->fc->streams[c->fc->nb_streams - 1];
7962 *sc = st->priv_data;
7963
7964 if (!(*sc)->cenc.encryption_index) {
7965 // If this stream isn't encrypted, don't create the index.
7966 if (!(*sc)->cenc.default_encrypted_sample)
7967 return 0;
7968 (*sc)->cenc.encryption_index = av_mallocz(sizeof(*frag_stream_info->encryption_index));
7969 if (!(*sc)->cenc.encryption_index)
7970 return AVERROR(ENOMEM);
7971 }
7972
7973 *encryption_index = (*sc)->cenc.encryption_index;
7974 return 1;
7975 }
7976}
7977
7979{
7980 int i, ret;
7981 unsigned int subsample_count;
7982 AVSubsampleEncryptionInfo *subsamples;
7983
7984 if (!sc->cenc.default_encrypted_sample) {
7985 av_log(c->fc, AV_LOG_ERROR, "Missing schm or tenc\n");
7986 return AVERROR_INVALIDDATA;
7987 }
7988
7989 if (sc->cenc.per_sample_iv_size || use_subsamples) {
7991 if (!*sample)
7992 return AVERROR(ENOMEM);
7993 } else
7994 *sample = NULL;
7995
7996 if (sc->cenc.per_sample_iv_size != 0) {
7997 if ((ret = ffio_read_size(pb, (*sample)->iv, sc->cenc.per_sample_iv_size)) < 0) {
7998 av_log(c->fc, AV_LOG_ERROR, "failed to read the initialization vector\n");
8000 *sample = NULL;
8001 return ret;
8002 }
8003 }
8004
8005 if (use_subsamples) {
8006 subsample_count = avio_rb16(pb);
8007 av_free((*sample)->subsamples);
8008 (*sample)->subsamples = av_calloc(subsample_count, sizeof(*subsamples));
8009 if (!(*sample)->subsamples) {
8011 *sample = NULL;
8012 return AVERROR(ENOMEM);
8013 }
8014
8015 for (i = 0; i < subsample_count && !pb->eof_reached; i++) {
8016 (*sample)->subsamples[i].bytes_of_clear_data = avio_rb16(pb);
8017 (*sample)->subsamples[i].bytes_of_protected_data = avio_rb32(pb);
8018 }
8019
8020 if (pb->eof_reached) {
8021 av_log(c->fc, AV_LOG_ERROR, "hit EOF while reading sub-sample encryption info\n");
8023 *sample = NULL;
8024 return AVERROR_INVALIDDATA;
8025 }
8026 (*sample)->subsample_count = subsample_count;
8027 }
8028
8029 return 0;
8030}
8031
8033{
8034 AVEncryptionInfo **encrypted_samples;
8035 MOVEncryptionIndex *encryption_index;
8036 MOVStreamContext *sc;
8037 int use_subsamples, ret;
8038 unsigned int sample_count, i, alloc_size = 0;
8039
8040 ret = get_current_encryption_info(c, &encryption_index, &sc);
8041 if (ret != 1)
8042 return ret;
8043
8044 if (encryption_index->nb_encrypted_samples) {
8045 // This can happen if we have both saio/saiz and senc atoms.
8046 av_log(c->fc, AV_LOG_DEBUG, "Ignoring duplicate encryption info in senc\n");
8047 return 0;
8048 }
8049
8050 avio_r8(pb); /* version */
8051 use_subsamples = avio_rb24(pb) & 0x02; /* flags */
8052
8053 sample_count = avio_rb32(pb);
8054 if (sample_count >= INT_MAX / sizeof(*encrypted_samples))
8055 return AVERROR(ENOMEM);
8056
8057 for (i = 0; i < sample_count; i++) {
8058 unsigned int min_samples = FFMIN(FFMAX(i + 1, 1024 * 1024), sample_count);
8059 encrypted_samples = av_fast_realloc(encryption_index->encrypted_samples, &alloc_size,
8060 min_samples * sizeof(*encrypted_samples));
8061 if (encrypted_samples) {
8062 encryption_index->encrypted_samples = encrypted_samples;
8063
8065 c, pb, sc, &encryption_index->encrypted_samples[i], use_subsamples);
8066 } else {
8067 ret = AVERROR(ENOMEM);
8068 }
8069 if (pb->eof_reached) {
8070 av_log(c->fc, AV_LOG_ERROR, "Hit EOF while reading senc\n");
8071 if (ret >= 0)
8072 av_encryption_info_free(encryption_index->encrypted_samples[i]);
8073 ret = AVERROR_INVALIDDATA;
8074 }
8075
8076 if (ret < 0) {
8077 for (; i > 0; i--)
8078 av_encryption_info_free(encryption_index->encrypted_samples[i - 1]);
8079 av_freep(&encryption_index->encrypted_samples);
8080 return ret;
8081 }
8082 }
8083 encryption_index->nb_encrypted_samples = sample_count;
8084
8085 return 0;
8086}
8087
8089{
8090 AVEncryptionInfo **sample, **encrypted_samples;
8091 int64_t prev_pos;
8092 size_t sample_count, sample_info_size, i;
8093 int ret = 0;
8094 unsigned int alloc_size = 0;
8095
8096 if (encryption_index->nb_encrypted_samples)
8097 return 0;
8098 sample_count = encryption_index->auxiliary_info_sample_count;
8099 if (encryption_index->auxiliary_offsets_count != 1) {
8100 av_log(c->fc, AV_LOG_ERROR, "Multiple auxiliary info chunks are not supported\n");
8101 return AVERROR_PATCHWELCOME;
8102 }
8103 if (sample_count >= INT_MAX / sizeof(*encrypted_samples))
8104 return AVERROR(ENOMEM);
8105
8106 prev_pos = avio_tell(pb);
8107 if (!(pb->seekable & AVIO_SEEKABLE_NORMAL) ||
8108 avio_seek(pb, encryption_index->auxiliary_offsets[0], SEEK_SET) != encryption_index->auxiliary_offsets[0]) {
8109 av_log(c->fc, AV_LOG_INFO, "Failed to seek for auxiliary info, will only parse senc atoms for encryption info\n");
8110 goto finish;
8111 }
8112
8113 for (i = 0; i < sample_count && !pb->eof_reached; i++) {
8114 unsigned int min_samples = FFMIN(FFMAX(i + 1, 1024 * 1024), sample_count);
8115 encrypted_samples = av_fast_realloc(encryption_index->encrypted_samples, &alloc_size,
8116 min_samples * sizeof(*encrypted_samples));
8117 if (!encrypted_samples) {
8118 ret = AVERROR(ENOMEM);
8119 goto finish;
8120 }
8121 encryption_index->encrypted_samples = encrypted_samples;
8122
8123 sample = &encryption_index->encrypted_samples[i];
8124 sample_info_size = encryption_index->auxiliary_info_default_size
8125 ? encryption_index->auxiliary_info_default_size
8126 : encryption_index->auxiliary_info_sizes[i];
8127
8128 ret = mov_read_sample_encryption_info(c, pb, sc, sample, sample_info_size > sc->cenc.per_sample_iv_size);
8129 if (ret < 0)
8130 goto finish;
8131 }
8132 if (pb->eof_reached) {
8133 av_log(c->fc, AV_LOG_ERROR, "Hit EOF while reading auxiliary info\n");
8134 ret = AVERROR_INVALIDDATA;
8135 } else {
8136 encryption_index->nb_encrypted_samples = sample_count;
8137 }
8138
8139finish:
8140 avio_seek(pb, prev_pos, SEEK_SET);
8141 if (ret < 0) {
8142 for (; i > 0; i--) {
8143 av_encryption_info_free(encryption_index->encrypted_samples[i - 1]);
8144 }
8145 av_freep(&encryption_index->encrypted_samples);
8146 }
8147 return ret;
8148}
8149
8151{
8152 MOVEncryptionIndex *encryption_index;
8153 MOVStreamContext *sc;
8154 int ret;
8155 unsigned int sample_count, aux_info_type, aux_info_param;
8156
8157 ret = get_current_encryption_info(c, &encryption_index, &sc);
8158 if (ret != 1)
8159 return ret;
8160
8161 if (encryption_index->nb_encrypted_samples) {
8162 // This can happen if we have both saio/saiz and senc atoms.
8163 av_log(c->fc, AV_LOG_DEBUG, "Ignoring duplicate encryption info in saiz\n");
8164 return 0;
8165 }
8166
8167 if (encryption_index->auxiliary_info_sample_count) {
8168 av_log(c->fc, AV_LOG_ERROR, "Duplicate saiz atom\n");
8169 return AVERROR_INVALIDDATA;
8170 }
8171
8172 avio_r8(pb); /* version */
8173 if (avio_rb24(pb) & 0x01) { /* flags */
8174 aux_info_type = avio_rb32(pb);
8175 aux_info_param = avio_rb32(pb);
8177 if (aux_info_type != sc->cenc.default_encrypted_sample->scheme) {
8178 av_log(c->fc, AV_LOG_DEBUG, "Ignoring saiz box with non-zero aux_info_type\n");
8179 return 0;
8180 }
8181 if (aux_info_param != 0) {
8182 av_log(c->fc, AV_LOG_DEBUG, "Ignoring saiz box with non-zero aux_info_type_parameter\n");
8183 return 0;
8184 }
8185 } else {
8186 // Didn't see 'schm' or 'tenc', so this isn't encrypted.
8187 if ((aux_info_type == MKBETAG('c','e','n','c') ||
8188 aux_info_type == MKBETAG('c','e','n','s') ||
8189 aux_info_type == MKBETAG('c','b','c','1') ||
8190 aux_info_type == MKBETAG('c','b','c','s')) &&
8191 aux_info_param == 0) {
8192 av_log(c->fc, AV_LOG_ERROR, "Saw encrypted saiz without schm/tenc\n");
8193 return AVERROR_INVALIDDATA;
8194 } else {
8195 return 0;
8196 }
8197 }
8198 } else if (!sc->cenc.default_encrypted_sample) {
8199 // Didn't see 'schm' or 'tenc', so this isn't encrypted.
8200 return 0;
8201 }
8202
8203 encryption_index->auxiliary_info_default_size = avio_r8(pb);
8204 sample_count = avio_rb32(pb);
8205
8206 if (encryption_index->auxiliary_info_default_size == 0) {
8207 if (sample_count == 0)
8208 return AVERROR_INVALIDDATA;
8209
8210 encryption_index->auxiliary_info_sizes = av_malloc(sample_count);
8211 if (!encryption_index->auxiliary_info_sizes)
8212 return AVERROR(ENOMEM);
8213
8214 ret = avio_read(pb, encryption_index->auxiliary_info_sizes, sample_count);
8215 if (ret != sample_count) {
8216 av_freep(&encryption_index->auxiliary_info_sizes);
8217
8218 if (ret >= 0)
8219 ret = AVERROR_INVALIDDATA;
8220 av_log(c->fc, AV_LOG_ERROR, "Failed to read the auxiliary info, %s\n",
8221 av_err2str(ret));
8222 return ret;
8223 }
8224 }
8225 encryption_index->auxiliary_info_sample_count = sample_count;
8226
8227 if (encryption_index->auxiliary_offsets_count) {
8228 return mov_parse_auxiliary_info(c, sc, pb, encryption_index);
8229 }
8230
8231 return 0;
8232}
8233
8235{
8236 uint64_t *auxiliary_offsets;
8237 MOVEncryptionIndex *encryption_index;
8238 MOVStreamContext *sc;
8239 int i, ret;
8240 unsigned int version, entry_count, aux_info_type, aux_info_param;
8241 unsigned int alloc_size = 0;
8242
8243 ret = get_current_encryption_info(c, &encryption_index, &sc);
8244 if (ret != 1)
8245 return ret;
8246
8247 if (encryption_index->nb_encrypted_samples) {
8248 // This can happen if we have both saio/saiz and senc atoms.
8249 av_log(c->fc, AV_LOG_DEBUG, "Ignoring duplicate encryption info in saio\n");
8250 return 0;
8251 }
8252
8253 if (encryption_index->auxiliary_offsets_count) {
8254 av_log(c->fc, AV_LOG_ERROR, "Duplicate saio atom\n");
8255 return AVERROR_INVALIDDATA;
8256 }
8257
8258 version = avio_r8(pb); /* version */
8259 if (avio_rb24(pb) & 0x01) { /* flags */
8260 aux_info_type = avio_rb32(pb);
8261 aux_info_param = avio_rb32(pb);
8263 if (aux_info_type != sc->cenc.default_encrypted_sample->scheme) {
8264 av_log(c->fc, AV_LOG_DEBUG, "Ignoring saio box with non-zero aux_info_type\n");
8265 return 0;
8266 }
8267 if (aux_info_param != 0) {
8268 av_log(c->fc, AV_LOG_DEBUG, "Ignoring saio box with non-zero aux_info_type_parameter\n");
8269 return 0;
8270 }
8271 } else {
8272 // Didn't see 'schm' or 'tenc', so this isn't encrypted.
8273 if ((aux_info_type == MKBETAG('c','e','n','c') ||
8274 aux_info_type == MKBETAG('c','e','n','s') ||
8275 aux_info_type == MKBETAG('c','b','c','1') ||
8276 aux_info_type == MKBETAG('c','b','c','s')) &&
8277 aux_info_param == 0) {
8278 av_log(c->fc, AV_LOG_ERROR, "Saw encrypted saio without schm/tenc\n");
8279 return AVERROR_INVALIDDATA;
8280 } else {
8281 return 0;
8282 }
8283 }
8284 } else if (!sc->cenc.default_encrypted_sample) {
8285 // Didn't see 'schm' or 'tenc', so this isn't encrypted.
8286 return 0;
8287 }
8288
8289 entry_count = avio_rb32(pb);
8290 if (entry_count >= INT_MAX / sizeof(*auxiliary_offsets))
8291 return AVERROR(ENOMEM);
8292
8293 for (i = 0; i < entry_count && !pb->eof_reached; i++) {
8294 unsigned int min_offsets = FFMIN(FFMAX(i + 1, 1024), entry_count);
8295 auxiliary_offsets = av_fast_realloc(
8296 encryption_index->auxiliary_offsets, &alloc_size,
8297 min_offsets * sizeof(*auxiliary_offsets));
8298 if (!auxiliary_offsets) {
8299 av_freep(&encryption_index->auxiliary_offsets);
8300 return AVERROR(ENOMEM);
8301 }
8302 encryption_index->auxiliary_offsets = auxiliary_offsets;
8303
8304 if (version == 0) {
8305 encryption_index->auxiliary_offsets[i] = avio_rb32(pb);
8306 } else {
8307 encryption_index->auxiliary_offsets[i] = avio_rb64(pb);
8308 }
8309 if (c->frag_index.current >= 0) {
8310 encryption_index->auxiliary_offsets[i] += c->fragment.base_data_offset;
8311 }
8312 }
8313
8314 if (pb->eof_reached) {
8315 av_log(c->fc, AV_LOG_ERROR, "Hit EOF while reading saio\n");
8316 av_freep(&encryption_index->auxiliary_offsets);
8317 return AVERROR_INVALIDDATA;
8318 }
8319
8320 encryption_index->auxiliary_offsets_count = entry_count;
8321
8322 if (encryption_index->auxiliary_info_sample_count) {
8323 return mov_parse_auxiliary_info(c, sc, pb, encryption_index);
8324 }
8325
8326 return 0;
8327}
8328
8330{
8331 AVEncryptionInitInfo *info, *old_init_info;
8332 uint8_t **key_ids;
8333 AVStream *st;
8334 const AVPacketSideData *old_side_data;
8335 uint8_t *side_data, *extra_data;
8336 size_t side_data_size;
8337 int ret = 0;
8338 unsigned int version, kid_count, extra_data_size, alloc_size = 0;
8339
8340 if (c->fc->nb_streams < 1)
8341 return 0;
8342 st = c->fc->streams[c->fc->nb_streams-1];
8343
8344 version = avio_r8(pb); /* version */
8345 avio_rb24(pb); /* flags */
8346
8347 info = av_encryption_init_info_alloc(/* system_id_size */ 16, /* num_key_ids */ 0,
8348 /* key_id_size */ 16, /* data_size */ 0);
8349 if (!info)
8350 return AVERROR(ENOMEM);
8351
8352 if ((ret = ffio_read_size(pb, info->system_id, 16)) < 0) {
8353 av_log(c->fc, AV_LOG_ERROR, "Failed to read the system id\n");
8354 goto finish;
8355 }
8356
8357 if (version > 0) {
8358 kid_count = avio_rb32(pb);
8359 if (kid_count >= INT_MAX / sizeof(*key_ids)) {
8360 ret = AVERROR(ENOMEM);
8361 goto finish;
8362 }
8363
8364 for (unsigned int i = 0; i < kid_count && !pb->eof_reached; i++) {
8365 unsigned int min_kid_count = FFMIN(FFMAX(i + 1, 1024), kid_count);
8366 key_ids = av_fast_realloc(info->key_ids, &alloc_size,
8367 min_kid_count * sizeof(*key_ids));
8368 if (!key_ids) {
8369 ret = AVERROR(ENOMEM);
8370 goto finish;
8371 }
8372 info->key_ids = key_ids;
8373
8374 info->key_ids[i] = av_mallocz(16);
8375 if (!info->key_ids[i]) {
8376 ret = AVERROR(ENOMEM);
8377 goto finish;
8378 }
8379 info->num_key_ids = i + 1;
8380
8381 if ((ret = ffio_read_size(pb, info->key_ids[i], 16)) < 0) {
8382 av_log(c->fc, AV_LOG_ERROR, "Failed to read the key id\n");
8383 goto finish;
8384 }
8385 }
8386
8387 if (pb->eof_reached) {
8388 av_log(c->fc, AV_LOG_ERROR, "Hit EOF while reading pssh\n");
8389 ret = AVERROR_INVALIDDATA;
8390 goto finish;
8391 }
8392 }
8393
8394 extra_data_size = avio_rb32(pb);
8395 extra_data = av_malloc(extra_data_size);
8396 if (!extra_data) {
8397 ret = AVERROR(ENOMEM);
8398 goto finish;
8399 }
8400 ret = avio_read(pb, extra_data, extra_data_size);
8401 if (ret != extra_data_size) {
8402 av_free(extra_data);
8403
8404 if (ret >= 0)
8405 ret = AVERROR_INVALIDDATA;
8406 goto finish;
8407 }
8408
8409 av_freep(&info->data); // malloc(0) may still allocate something.
8410 info->data = extra_data;
8411 info->data_size = extra_data_size;
8412
8413 // If there is existing initialization data, append to the list.
8416 if (old_side_data) {
8417 old_init_info = av_encryption_init_info_get_side_data(old_side_data->data, old_side_data->size);
8418 if (old_init_info) {
8419 // Append to the end of the list.
8420 for (AVEncryptionInitInfo *cur = old_init_info;; cur = cur->next) {
8421 if (!cur->next) {
8422 cur->next = info;
8423 break;
8424 }
8425 }
8426 info = old_init_info;
8427 } else {
8428 // Assume existing side-data will be valid, so the only error we could get is OOM.
8429 ret = AVERROR(ENOMEM);
8430 goto finish;
8431 }
8432 }
8433
8434 side_data = av_encryption_init_info_add_side_data(info, &side_data_size);
8435 if (!side_data) {
8436 ret = AVERROR(ENOMEM);
8437 goto finish;
8438 }
8442 side_data, side_data_size, 0))
8443 av_free(side_data);
8444
8445finish:
8447 return ret;
8448}
8449
8451{
8452 AVStream *st;
8453 MOVStreamContext *sc;
8454
8455 if (c->fc->nb_streams < 1)
8456 return 0;
8457 st = c->fc->streams[c->fc->nb_streams-1];
8458 sc = st->priv_data;
8459
8460 if (sc->pseudo_stream_id != 0) {
8461 av_log(c->fc, AV_LOG_ERROR, "schm boxes are only supported in first sample descriptor\n");
8462 return AVERROR_PATCHWELCOME;
8463 }
8464
8465 if (atom.size < 8)
8466 return AVERROR_INVALIDDATA;
8467
8468 avio_rb32(pb); /* version and flags */
8469
8470 if (!sc->cenc.default_encrypted_sample) {
8472 if (!sc->cenc.default_encrypted_sample) {
8473 return AVERROR(ENOMEM);
8474 }
8475 }
8476
8478 return 0;
8479}
8480
8482{
8483 AVStream *st;
8484 MOVStreamContext *sc;
8485 unsigned int version, pattern, is_protected, iv_size;
8486
8487 if (c->fc->nb_streams < 1)
8488 return 0;
8489 st = c->fc->streams[c->fc->nb_streams-1];
8490 sc = st->priv_data;
8491
8492 if (sc->pseudo_stream_id != 0) {
8493 av_log(c->fc, AV_LOG_ERROR, "tenc atom are only supported in first sample descriptor\n");
8494 return AVERROR_PATCHWELCOME;
8495 }
8496
8497 if (!sc->cenc.default_encrypted_sample) {
8499 if (!sc->cenc.default_encrypted_sample) {
8500 return AVERROR(ENOMEM);
8501 }
8502 }
8503
8504 if (atom.size < 20)
8505 return AVERROR_INVALIDDATA;
8506
8507 version = avio_r8(pb); /* version */
8508 avio_rb24(pb); /* flags */
8509
8510 avio_r8(pb); /* reserved */
8511 pattern = avio_r8(pb);
8512
8513 if (version > 0) {
8515 sc->cenc.default_encrypted_sample->skip_byte_block = pattern & 0xf;
8516 }
8517
8518 is_protected = avio_r8(pb);
8519 if (is_protected && !sc->cenc.encryption_index) {
8520 // The whole stream should be by-default encrypted.
8522 if (!sc->cenc.encryption_index)
8523 return AVERROR(ENOMEM);
8524 }
8525 iv_size = avio_r8(pb);
8526 if (iv_size != 0 && iv_size != 8 && iv_size != 16) {
8527 av_log(c->fc, AV_LOG_ERROR, "invalid per-sample IV size value\n");
8528 return AVERROR_INVALIDDATA;
8529 }
8530 sc->cenc.per_sample_iv_size = iv_size;
8531 if (avio_read(pb, sc->cenc.default_encrypted_sample->key_id, 16) != 16) {
8532 av_log(c->fc, AV_LOG_ERROR, "failed to read the default key ID\n");
8533 return AVERROR_INVALIDDATA;
8534 }
8535
8536 if (is_protected && !sc->cenc.per_sample_iv_size) {
8537 iv_size = avio_r8(pb);
8538 if (iv_size != 8 && iv_size != 16) {
8539 av_log(c->fc, AV_LOG_ERROR, "invalid default_constant_IV_size in tenc atom\n");
8540 return AVERROR_INVALIDDATA;
8541 }
8542
8543 if (avio_read(pb, sc->cenc.default_encrypted_sample->iv, iv_size) != iv_size) {
8544 av_log(c->fc, AV_LOG_ERROR, "failed to read the default IV\n");
8545 return AVERROR_INVALIDDATA;
8546 }
8547 }
8548
8549 return 0;
8550}
8551
8553{
8554 AVStream *st;
8555 int last, type, size, ret;
8556 uint8_t buf[4];
8557
8558 if (c->fc->nb_streams < 1)
8559 return 0;
8560 st = c->fc->streams[c->fc->nb_streams-1];
8561
8562 if ((uint64_t)atom.size > (1<<30) || atom.size < 42)
8563 return AVERROR_INVALIDDATA;
8564
8565 /* Check FlacSpecificBox version. */
8566 if (avio_r8(pb) != 0)
8567 return AVERROR_INVALIDDATA;
8568
8569 avio_rb24(pb); /* Flags */
8570
8571 if (avio_read(pb, buf, sizeof(buf)) != sizeof(buf)) {
8572 av_log(c->fc, AV_LOG_ERROR, "failed to read FLAC metadata block header\n");
8573 return pb->error < 0 ? pb->error : AVERROR_INVALIDDATA;
8574 }
8575 flac_parse_block_header(buf, &last, &type, &size);
8576
8578 av_log(c->fc, AV_LOG_ERROR, "STREAMINFO must be first FLACMetadataBlock\n");
8579 return AVERROR_INVALIDDATA;
8580 }
8581
8582 ret = ff_get_extradata(c->fc, st->codecpar, pb, size);
8583 if (ret < 0)
8584 return ret;
8585
8586 if (!last)
8587 av_log(c->fc, AV_LOG_WARNING, "non-STREAMINFO FLACMetadataBlock(s) ignored\n");
8588
8589 return 0;
8590}
8591
8593 AVDictionaryEntry *key_entry_hex;
8594 char kid_hex[16*2+1];
8595
8596 if (c->decryption_default_key && c->decryption_default_key_len != len) {
8597 av_log(c->fc, AV_LOG_ERROR, "invalid default decryption key length: got %d, expected %d\n", c->decryption_default_key_len, len);
8598 return -1;
8599 }
8600
8601 if (!c->decryption_keys) {
8602 av_assert0(c->decryption_default_key);
8603 memcpy(out, c->decryption_default_key, len);
8604 return 0;
8605 }
8606
8607 if (sample->key_id_size != 16) {
8608 av_log(c->fc, AV_LOG_ERROR, "invalid key ID size: got %u, expected 16\n", sample->key_id_size);
8609 return -1;
8610 }
8611
8612 ff_data_to_hex(kid_hex, sample->key_id, 16, 1);
8613 key_entry_hex = av_dict_get(c->decryption_keys, kid_hex, NULL, AV_DICT_DONT_STRDUP_KEY|AV_DICT_DONT_STRDUP_VAL);
8614 if (!key_entry_hex) {
8615 if (!c->decryption_default_key) {
8616 av_log(c->fc, AV_LOG_ERROR, "unable to find KID %s\n", kid_hex);
8617 return -1;
8618 }
8619 memcpy(out, c->decryption_default_key, len);
8620 return 0;
8621 }
8622 if (strlen(key_entry_hex->value) != len*2) {
8623 return -1;
8624 }
8625 ff_hex_to_data(out, key_entry_hex->value);
8626 return 0;
8627}
8628
8630{
8631 int i, ret;
8632 int bytes_of_protected_data;
8633 uint8_t decryption_key[AES_CTR_KEY_SIZE];
8634
8635 if (!sc->cenc.aes_ctr) {
8636 ret = get_key_from_kid(decryption_key, sizeof(decryption_key), c, sample);
8637 if (ret < 0) {
8638 return ret;
8639 }
8640
8641 /* initialize the cipher */
8643 if (!sc->cenc.aes_ctr) {
8644 return AVERROR(ENOMEM);
8645 }
8646
8647 ret = av_aes_ctr_init(sc->cenc.aes_ctr, decryption_key);
8648 if (ret < 0) {
8649 return ret;
8650 }
8651 }
8652
8654
8655 if (!sample->subsample_count) {
8656 /* decrypt the whole packet */
8657 av_aes_ctr_crypt(sc->cenc.aes_ctr, input, input, size);
8658 return 0;
8659 }
8660
8661 for (i = 0; i < sample->subsample_count; i++) {
8662 if (sample->subsamples[i].bytes_of_clear_data + (int64_t)sample->subsamples[i].bytes_of_protected_data > size) {
8663 av_log(c->fc, AV_LOG_ERROR, "subsample size exceeds the packet size left\n");
8664 return AVERROR_INVALIDDATA;
8665 }
8666
8667 /* skip the clear bytes */
8668 input += sample->subsamples[i].bytes_of_clear_data;
8669 size -= sample->subsamples[i].bytes_of_clear_data;
8670
8671 /* decrypt the encrypted bytes */
8672
8673 bytes_of_protected_data = sample->subsamples[i].bytes_of_protected_data;
8674 av_aes_ctr_crypt(sc->cenc.aes_ctr, input, input, bytes_of_protected_data);
8675
8676 input += bytes_of_protected_data;
8677 size -= bytes_of_protected_data;
8678 }
8679
8680 if (size > 0) {
8681 av_log(c->fc, AV_LOG_ERROR, "leftover packet bytes after subsample processing\n");
8682 return AVERROR_INVALIDDATA;
8683 }
8684
8685 return 0;
8686}
8687
8689{
8690 int i, ret;
8691 int num_of_encrypted_blocks;
8692 uint8_t iv[16];
8693 uint8_t decryption_key[16];
8694
8695 if (!sc->cenc.aes_ctx) {
8696 ret = get_key_from_kid(decryption_key, sizeof(decryption_key), c, sample);
8697 if (ret < 0) {
8698 return ret;
8699 }
8700
8701 /* initialize the cipher */
8702 sc->cenc.aes_ctx = av_aes_alloc();
8703 if (!sc->cenc.aes_ctx) {
8704 return AVERROR(ENOMEM);
8705 }
8706
8707 ret = av_aes_init(sc->cenc.aes_ctx, decryption_key, 16 * 8, 1);
8708 if (ret < 0) {
8709 return ret;
8710 }
8711 }
8712
8713 memcpy(iv, sample->iv, 16);
8714
8715 /* whole-block full sample encryption */
8716 if (!sample->subsample_count) {
8717 /* decrypt the whole packet */
8718 av_aes_crypt(sc->cenc.aes_ctx, input, input, size/16, iv, 1);
8719 return 0;
8720 }
8721
8722 for (i = 0; i < sample->subsample_count; i++) {
8723 if (sample->subsamples[i].bytes_of_clear_data + (int64_t)sample->subsamples[i].bytes_of_protected_data > size) {
8724 av_log(c->fc, AV_LOG_ERROR, "subsample size exceeds the packet size left\n");
8725 return AVERROR_INVALIDDATA;
8726 }
8727
8728 if (sample->subsamples[i].bytes_of_protected_data % 16) {
8729 av_log(c->fc, AV_LOG_ERROR, "subsample BytesOfProtectedData is not a multiple of 16\n");
8730 return AVERROR_INVALIDDATA;
8731 }
8732
8733 /* skip the clear bytes */
8734 input += sample->subsamples[i].bytes_of_clear_data;
8735 size -= sample->subsamples[i].bytes_of_clear_data;
8736
8737 /* decrypt the encrypted bytes */
8738 num_of_encrypted_blocks = sample->subsamples[i].bytes_of_protected_data/16;
8739 if (num_of_encrypted_blocks > 0) {
8740 av_aes_crypt(sc->cenc.aes_ctx, input, input, num_of_encrypted_blocks, iv, 1);
8741 }
8742 input += sample->subsamples[i].bytes_of_protected_data;
8743 size -= sample->subsamples[i].bytes_of_protected_data;
8744 }
8745
8746 if (size > 0) {
8747 av_log(c->fc, AV_LOG_ERROR, "leftover packet bytes after subsample processing\n");
8748 return AVERROR_INVALIDDATA;
8749 }
8750
8751 return 0;
8752}
8753
8755{
8756 int i, ret, rem_bytes;
8757 uint8_t *data;
8758 uint8_t decryption_key[AES_CTR_KEY_SIZE];
8759
8760 if (!sc->cenc.aes_ctr) {
8761 ret = get_key_from_kid(decryption_key, sizeof(decryption_key), c, sample);
8762 if (ret < 0) {
8763 return ret;
8764 }
8765
8766 /* initialize the cipher */
8768 if (!sc->cenc.aes_ctr) {
8769 return AVERROR(ENOMEM);
8770 }
8771
8772 ret = av_aes_ctr_init(sc->cenc.aes_ctr, decryption_key);
8773 if (ret < 0) {
8774 return ret;
8775 }
8776 }
8777
8779
8780 /* whole-block full sample encryption */
8781 if (!sample->subsample_count) {
8782 /* decrypt the whole packet */
8783 av_aes_ctr_crypt(sc->cenc.aes_ctr, input, input, size);
8784 return 0;
8785 } else if (!sample->crypt_byte_block && !sample->skip_byte_block) {
8786 av_log(c->fc, AV_LOG_ERROR, "pattern encryption is not present in 'cens' scheme\n");
8787 return AVERROR_INVALIDDATA;
8788 }
8789
8790 for (i = 0; i < sample->subsample_count; i++) {
8791 if (sample->subsamples[i].bytes_of_clear_data + (int64_t)sample->subsamples[i].bytes_of_protected_data > size) {
8792 av_log(c->fc, AV_LOG_ERROR, "subsample size exceeds the packet size left\n");
8793 return AVERROR_INVALIDDATA;
8794 }
8795
8796 /* skip the clear bytes */
8797 input += sample->subsamples[i].bytes_of_clear_data;
8798 size -= sample->subsamples[i].bytes_of_clear_data;
8799
8800 /* decrypt the encrypted bytes */
8801 data = input;
8802 rem_bytes = sample->subsamples[i].bytes_of_protected_data;
8803 while (rem_bytes > 0) {
8804 if (rem_bytes < 16*sample->crypt_byte_block) {
8805 break;
8806 }
8807 av_aes_ctr_crypt(sc->cenc.aes_ctr, data, data, 16*sample->crypt_byte_block);
8808 data += 16*sample->crypt_byte_block;
8809 rem_bytes -= 16*sample->crypt_byte_block;
8810 data += FFMIN(16*sample->skip_byte_block, rem_bytes);
8811 rem_bytes -= FFMIN(16*sample->skip_byte_block, rem_bytes);
8812 }
8813 input += sample->subsamples[i].bytes_of_protected_data;
8814 size -= sample->subsamples[i].bytes_of_protected_data;
8815 }
8816
8817 if (size > 0) {
8818 av_log(c->fc, AV_LOG_ERROR, "leftover packet bytes after subsample processing\n");
8819 return AVERROR_INVALIDDATA;
8820 }
8821
8822 return 0;
8823}
8824
8826{
8827 int i, ret, rem_bytes;
8828 uint8_t iv[16];
8829 uint8_t *data;
8830 uint8_t decryption_key[16];
8831
8832 if (!sc->cenc.aes_ctx) {
8833 ret = get_key_from_kid(decryption_key, sizeof(decryption_key), c, sample);
8834 if (ret < 0) {
8835 return ret;
8836 }
8837
8838 /* initialize the cipher */
8839 sc->cenc.aes_ctx = av_aes_alloc();
8840 if (!sc->cenc.aes_ctx) {
8841 return AVERROR(ENOMEM);
8842 }
8843
8844 ret = av_aes_init(sc->cenc.aes_ctx, decryption_key, 16 * 8, 1);
8845 if (ret < 0) {
8846 return ret;
8847 }
8848 }
8849
8850 /* whole-block full sample encryption */
8851 if (!sample->subsample_count) {
8852 /* decrypt the whole packet */
8853 memcpy(iv, sample->iv, 16);
8854 av_aes_crypt(sc->cenc.aes_ctx, input, input, size/16, iv, 1);
8855 return 0;
8856 } else if (!sample->crypt_byte_block && !sample->skip_byte_block) {
8857 av_log(c->fc, AV_LOG_ERROR, "pattern encryption is not present in 'cbcs' scheme\n");
8858 return AVERROR_INVALIDDATA;
8859 }
8860
8861 for (i = 0; i < sample->subsample_count; i++) {
8862 if (sample->subsamples[i].bytes_of_clear_data + (int64_t)sample->subsamples[i].bytes_of_protected_data > size) {
8863 av_log(c->fc, AV_LOG_ERROR, "subsample size exceeds the packet size left\n");
8864 return AVERROR_INVALIDDATA;
8865 }
8866
8867 /* skip the clear bytes */
8868 input += sample->subsamples[i].bytes_of_clear_data;
8869 size -= sample->subsamples[i].bytes_of_clear_data;
8870
8871 /* decrypt the encrypted bytes */
8872 memcpy(iv, sample->iv, 16);
8873 data = input;
8874 rem_bytes = sample->subsamples[i].bytes_of_protected_data;
8875 while (rem_bytes > 0) {
8876 if (rem_bytes < 16*sample->crypt_byte_block) {
8877 break;
8878 }
8879 av_aes_crypt(sc->cenc.aes_ctx, data, data, sample->crypt_byte_block, iv, 1);
8880 data += 16*sample->crypt_byte_block;
8881 rem_bytes -= 16*sample->crypt_byte_block;
8882 data += FFMIN(16*sample->skip_byte_block, rem_bytes);
8883 rem_bytes -= FFMIN(16*sample->skip_byte_block, rem_bytes);
8884 }
8885 input += sample->subsamples[i].bytes_of_protected_data;
8886 size -= sample->subsamples[i].bytes_of_protected_data;
8887 }
8888
8889 if (size > 0) {
8890 av_log(c->fc, AV_LOG_ERROR, "leftover packet bytes after subsample processing\n");
8891 return AVERROR_INVALIDDATA;
8892 }
8893
8894 return 0;
8895}
8896
8897static int cenc_decrypt(MOVContext *c, MOVStreamContext *sc, AVEncryptionInfo *sample, uint8_t *input, int size)
8898{
8899 if (sample->scheme == MKBETAG('c','e','n','c') && !sample->crypt_byte_block && !sample->skip_byte_block) {
8900 return cenc_scheme_decrypt(c, sc, sample, input, size);
8901 } else if (sample->scheme == MKBETAG('c','b','c','1') && !sample->crypt_byte_block && !sample->skip_byte_block) {
8902 return cbc1_scheme_decrypt(c, sc, sample, input, size);
8903 } else if (sample->scheme == MKBETAG('c','e','n','s')) {
8904 return cens_scheme_decrypt(c, sc, sample, input, size);
8905 } else if (sample->scheme == MKBETAG('c','b','c','s')) {
8906 return cbcs_scheme_decrypt(c, sc, sample, input, size);
8907 } else {
8908 av_log(c->fc, AV_LOG_ERROR, "invalid encryption scheme\n");
8909 return AVERROR_INVALIDDATA;
8910 }
8911}
8912
8914{
8915 int current = frag_index->current;
8916
8917 if (!frag_index->nb_items)
8918 return NULL;
8919
8920 // Check frag_index->current is the right one for pkt. It can out of sync.
8921 if (current >= 0 && current < frag_index->nb_items) {
8922 if (frag_index->item[current].moof_offset < pkt->pos &&
8923 (current + 1 == frag_index->nb_items ||
8924 frag_index->item[current + 1].moof_offset > pkt->pos))
8925 return get_frag_stream_info(frag_index, current, id);
8926 }
8927
8928
8929 for (int i = 0; i < frag_index->nb_items; i++) {
8930 if (frag_index->item[i].moof_offset > pkt->pos)
8931 break;
8932 current = i;
8933 }
8934 frag_index->current = current;
8935 return get_frag_stream_info(frag_index, current, id);
8936}
8937
8938static int cenc_filter(MOVContext *mov, AVStream* st, MOVStreamContext *sc, AVPacket *pkt, int current_index)
8939{
8940 MOVFragmentStreamInfo *frag_stream_info;
8941 MOVEncryptionIndex *encryption_index;
8942 AVEncryptionInfo *encrypted_sample;
8943 int encrypted_index, ret;
8944
8945 frag_stream_info = get_frag_stream_info_from_pkt(&mov->frag_index, pkt, sc->id);
8946 encrypted_index = current_index;
8947 encryption_index = NULL;
8948 if (frag_stream_info) {
8949 // Note this only supports encryption info in the first sample descriptor.
8950 if (frag_stream_info->stsd_id == 1) {
8951 if (frag_stream_info->encryption_index) {
8952 encrypted_index = current_index - frag_stream_info->index_base;
8953 encryption_index = frag_stream_info->encryption_index;
8954 } else {
8955 encryption_index = sc->cenc.encryption_index;
8956 }
8957 }
8958 } else {
8959 encryption_index = sc->cenc.encryption_index;
8960 }
8961
8962 if (encryption_index) {
8963 if (encryption_index->auxiliary_info_sample_count &&
8964 !encryption_index->nb_encrypted_samples) {
8965 av_log(mov->fc, AV_LOG_ERROR, "saiz atom found without saio\n");
8966 return AVERROR_INVALIDDATA;
8967 }
8968 if (encryption_index->auxiliary_offsets_count &&
8969 !encryption_index->nb_encrypted_samples) {
8970 av_log(mov->fc, AV_LOG_ERROR, "saio atom found without saiz\n");
8971 return AVERROR_INVALIDDATA;
8972 }
8973
8974 encrypted_sample = NULL;
8975 if (!encryption_index->nb_encrypted_samples) {
8976 // Full-sample encryption with default settings.
8977 encrypted_sample = sc->cenc.default_encrypted_sample;
8978 } else if (encrypted_index >= 0 && encrypted_index < encryption_index->nb_encrypted_samples) {
8979 // Per-sample setting override.
8980 encrypted_sample = encryption_index->encrypted_samples[encrypted_index];
8981 if (!encrypted_sample) {
8982 encrypted_sample = sc->cenc.default_encrypted_sample;
8983 }
8984 }
8985
8986 if (!encrypted_sample) {
8987 av_log(mov->fc, AV_LOG_ERROR, "Incorrect number of samples in encryption info\n");
8988 return AVERROR_INVALIDDATA;
8989 }
8990
8991 if (mov->decryption_keys || mov->decryption_default_key) {
8992 return cenc_decrypt(mov, sc, encrypted_sample, pkt->data, pkt->size);
8993 } else {
8994 size_t size;
8995 uint8_t *side_data = av_encryption_info_add_side_data(encrypted_sample, &size);
8996 if (!side_data)
8997 return AVERROR(ENOMEM);
8999 if (ret < 0)
9000 av_free(side_data);
9001 return ret;
9002 }
9003 }
9004
9005 return 0;
9006}
9007
9009{
9010 const int OPUS_SEEK_PREROLL_MS = 80;
9011 int ret;
9012 AVStream *st;
9013 size_t size;
9014 uint16_t pre_skip;
9015
9016 if (c->fc->nb_streams < 1)
9017 return 0;
9018 st = c->fc->streams[c->fc->nb_streams-1];
9019
9020 if ((uint64_t)atom.size > (1<<30) || atom.size < 11 || st->codecpar->extradata)
9021 return AVERROR_INVALIDDATA;
9022
9023 /* Check OpusSpecificBox version. */
9024 if (avio_r8(pb) != 0) {
9025 av_log(c->fc, AV_LOG_ERROR, "unsupported OpusSpecificBox version\n");
9026 return AVERROR_INVALIDDATA;
9027 }
9028
9029 /* OpusSpecificBox size plus magic for Ogg OpusHead header. */
9030 size = atom.size + 8;
9031
9032 if ((ret = ff_alloc_extradata(st->codecpar, size)) < 0)
9033 return ret;
9034
9035 AV_WL32A(st->codecpar->extradata, MKTAG('O','p','u','s'));
9036 AV_WL32A(st->codecpar->extradata + 4, MKTAG('H','e','a','d'));
9037 AV_WB8(st->codecpar->extradata + 8, 1); /* OpusHead version */
9038 if ((ret = ffio_read_size(pb, st->codecpar->extradata + 9, size - 9)) < 0) {
9040 st->codecpar->extradata_size = 0;
9041 return ret;
9042 }
9043
9044 /* OpusSpecificBox is stored in big-endian, but OpusHead is
9045 little-endian; aside from the preceding magic and version they're
9046 otherwise currently identical. Data after output gain at offset 16
9047 doesn't need to be bytewapped. */
9048 pre_skip = AV_RB16A(st->codecpar->extradata + 10);
9049 AV_WL16A(st->codecpar->extradata + 10, pre_skip);
9050 AV_WL32A(st->codecpar->extradata + 12, AV_RB32A(st->codecpar->extradata + 12));
9051 AV_WL16A(st->codecpar->extradata + 16, AV_RB16A(st->codecpar->extradata + 16));
9052
9053 st->codecpar->initial_padding = pre_skip;
9055 (AVRational){1, 1000},
9056 (AVRational){1, 48000});
9057
9058 return 0;
9059}
9060
9062{
9063 AVStream *st;
9064 unsigned format_info;
9065 int channel_assignment, channel_assignment1, channel_assignment2;
9066 int ratebits;
9067 uint64_t chmask;
9068
9069 if (c->fc->nb_streams < 1)
9070 return 0;
9071 st = c->fc->streams[c->fc->nb_streams-1];
9072
9073 if (atom.size < 10)
9074 return AVERROR_INVALIDDATA;
9075
9076 format_info = avio_rb32(pb);
9077
9078 ratebits = (format_info >> 28) & 0xF;
9079 channel_assignment1 = (format_info >> 15) & 0x1F;
9080 channel_assignment2 = format_info & 0x1FFF;
9081 if (channel_assignment2)
9082 channel_assignment = channel_assignment2;
9083 else
9084 channel_assignment = channel_assignment1;
9085
9086 st->codecpar->frame_size = 40 << (ratebits & 0x7);
9087 st->codecpar->sample_rate = mlp_samplerate(ratebits);
9088
9090 chmask = truehd_layout(channel_assignment);
9092
9093 return 0;
9094}
9095
9097{
9098 AVStream *st;
9099 uint8_t buf[ISOM_DVCC_DVVC_SIZE];
9100 int ret;
9101 int64_t read_size = atom.size;
9102
9103 if (c->fc->nb_streams < 1)
9104 return 0;
9105 st = c->fc->streams[c->fc->nb_streams-1];
9106
9107 // At most 24 bytes
9108 read_size = FFMIN(read_size, ISOM_DVCC_DVVC_SIZE);
9109
9110 if ((ret = ffio_read_size(pb, buf, read_size)) < 0)
9111 return ret;
9112
9113 return ff_isom_parse_dvcc_dvvc(c->fc, st, buf, read_size);
9114}
9115
9117{
9118 AVStream *st;
9119 AVPacketSideData *sd;
9120 int ret;
9121
9122 if (c->fc->nb_streams < 1)
9123 return 0;
9124 st = c->fc->streams[c->fc->nb_streams - 1];
9125
9126 if (atom.size < 23 || atom.size > INT_MAX - AV_INPUT_BUFFER_PADDING_SIZE)
9127 return AVERROR_INVALIDDATA;
9128
9132 atom.size, 0);
9133 if (!sd)
9134 return AVERROR(ENOMEM);
9135
9136 ret = ffio_read_size(pb, sd->data, atom.size);
9137 if (ret < 0)
9138 return ret;
9139
9140 return 0;
9141}
9142
9144{
9145 AVStream *st;
9146 uint8_t *buf;
9147 int ret, old_size, num_arrays;
9148
9149 if (c->fc->nb_streams < 1)
9150 return 0;
9151 st = c->fc->streams[c->fc->nb_streams-1];
9152
9153 if (!st->codecpar->extradata_size)
9154 // TODO: handle lhvC when present before hvcC
9155 return 0;
9156
9157 if (atom.size < 6 || st->codecpar->extradata_size < 23 ||
9158 atom.size > INT_MAX - AV_INPUT_BUFFER_PADDING_SIZE) {
9159 return AVERROR_INVALIDDATA;
9160 }
9161
9163 if (!buf)
9164 return AVERROR(ENOMEM);
9165 memset(buf + atom.size, 0, AV_INPUT_BUFFER_PADDING_SIZE);
9166
9167 ret = ffio_read_size(pb, buf, atom.size);
9168 if (ret < 0) {
9169 av_free(buf);
9170 av_log(c->fc, AV_LOG_WARNING, "lhvC atom truncated\n");
9171 return 0;
9172 }
9173
9174 num_arrays = buf[5];
9175 old_size = st->codecpar->extradata_size;
9176 atom.size -= 8 /* account for mov_realloc_extradata offsetting */
9177 + 6 /* lhvC bytes before the arrays*/;
9178
9179 ret = mov_realloc_extradata(st->codecpar, atom);
9180 if (ret < 0) {
9181 av_free(buf);
9182 return ret;
9183 }
9184
9185 st->codecpar->extradata[22] += num_arrays;
9186 memcpy(st->codecpar->extradata + old_size, buf + 6, atom.size + 8);
9187
9189
9190 av_free(buf);
9191 return 0;
9192}
9193
9195{
9196 AVFormatContext *ctx = c->fc;
9197 AVStream *st = NULL;
9198 AVBPrint scheme_buf, value_buf;
9199 int64_t scheme_str_len = 0, value_str_len = 0;
9200 int version, flags, ret = AVERROR_BUG;
9201 int64_t size = atom.size;
9202
9203 if (atom.size < 6)
9204 // 4 bytes for version + flags, 2x 1 byte for null
9205 return AVERROR_INVALIDDATA;
9206
9207 if (c->fc->nb_streams < 1)
9208 return 0;
9209 st = c->fc->streams[c->fc->nb_streams-1];
9210
9211 version = avio_r8(pb);
9212 flags = avio_rb24(pb);
9213 size -= 4;
9214
9215 if (version != 0 || flags != 0) {
9217 "Unsupported 'kind' box with version %d, flags: %x",
9218 version, flags);
9219 return AVERROR_INVALIDDATA;
9220 }
9221
9224
9225 if ((scheme_str_len = ff_read_string_to_bprint_overwrite(pb, &scheme_buf,
9226 size)) < 0) {
9227 ret = scheme_str_len;
9228 goto cleanup;
9229 }
9230
9231 if (scheme_str_len + 1 >= size) {
9232 // we need to have another string, even if nullptr.
9233 // we check with + 1 since we expect that if size was not hit,
9234 // an additional null was read.
9235 ret = AVERROR_INVALIDDATA;
9236 goto cleanup;
9237 }
9238
9239 size -= scheme_str_len + 1;
9240
9241 if ((value_str_len = ff_read_string_to_bprint_overwrite(pb, &value_buf,
9242 size)) < 0) {
9243 ret = value_str_len;
9244 goto cleanup;
9245 }
9246
9247 if (value_str_len == size) {
9248 // in case of no trailing null, box is not valid.
9249 ret = AVERROR_INVALIDDATA;
9250 goto cleanup;
9251 }
9252
9254 "%s stream %d KindBox(scheme: %s, value: %s)\n",
9256 st->index,
9257 scheme_buf.str, value_buf.str);
9258
9259 for (int i = 0; ff_mov_track_kind_table[i].scheme_uri; i++) {
9261 if (!av_strstart(scheme_buf.str, map.scheme_uri, NULL))
9262 continue;
9263
9264 for (int j = 0; map.value_maps[j].disposition; j++) {
9265 const struct MP4TrackKindValueMapping value_map = map.value_maps[j];
9266 if (!av_strstart(value_buf.str, value_map.value, NULL))
9267 continue;
9268
9269 st->disposition |= value_map.disposition;
9270 }
9271 }
9272
9273 ret = 0;
9274
9275cleanup:
9276
9277 av_bprint_finalize(&scheme_buf, NULL);
9278 av_bprint_finalize(&value_buf, NULL);
9279
9280 return ret;
9281}
9282
9284{
9285 AVStream *st;
9286 AVChannelLayout ch_layout = { 0 };
9287 int ret, i, version, type;
9288 int ambisonic_order, channel_order, normalization, channel_count;
9289 int ambi_channels, non_diegetic_channels;
9290
9291 if (c->fc->nb_streams < 1)
9292 return 0;
9293
9294 st = c->fc->streams[c->fc->nb_streams - 1];
9295
9296 if (atom.size < 16) {
9297 av_log(c->fc, AV_LOG_ERROR, "SA3D audio box too small\n");
9298 return AVERROR_INVALIDDATA;
9299 }
9300
9301 version = avio_r8(pb);
9302 if (version) {
9303 av_log(c->fc, AV_LOG_WARNING, "Unsupported SA3D box version %d\n", version);
9304 return 0;
9305 }
9306
9307 type = avio_r8(pb);
9308 if (type & 0x7f) {
9309 av_log(c->fc, AV_LOG_WARNING,
9310 "Unsupported ambisonic type %d\n", type & 0x7f);
9311 return 0;
9312 }
9313 non_diegetic_channels = (type >> 7) * 2; // head_locked_stereo
9314
9315 ambisonic_order = avio_rb32(pb);
9316
9317 channel_order = avio_r8(pb);
9318 if (channel_order) {
9319 av_log(c->fc, AV_LOG_WARNING,
9320 "Unsupported channel_order %d\n", channel_order);
9321 return 0;
9322 }
9323
9324 normalization = avio_r8(pb);
9325 if (normalization) {
9326 av_log(c->fc, AV_LOG_WARNING,
9327 "Unsupported normalization %d\n", normalization);
9328 return 0;
9329 }
9330
9331 channel_count = avio_rb32(pb);
9332 if (ambisonic_order < 0 || ambisonic_order > 31 ||
9333 channel_count != ((ambisonic_order + 1LL) * (ambisonic_order + 1LL) +
9334 non_diegetic_channels)) {
9335 av_log(c->fc, AV_LOG_ERROR,
9336 "Invalid number of channels (%d / %d)\n",
9337 channel_count, ambisonic_order);
9338 return 0;
9339 }
9340 ambi_channels = channel_count - non_diegetic_channels;
9341
9342 ret = av_channel_layout_custom_init(&ch_layout, channel_count);
9343 if (ret < 0)
9344 return 0;
9345
9346 for (i = 0; i < channel_count; i++) {
9347 unsigned channel = avio_rb32(pb);
9348
9349 if (channel >= channel_count) {
9350 av_log(c->fc, AV_LOG_ERROR, "Invalid channel index (%d / %d)\n",
9351 channel, ambisonic_order);
9352 av_channel_layout_uninit(&ch_layout);
9353 return 0;
9354 }
9355 if (channel >= ambi_channels)
9356 ch_layout.u.map[i].id = channel - ambi_channels;
9357 else
9358 ch_layout.u.map[i].id = AV_CHAN_AMBISONIC_BASE + channel;
9359 }
9360
9362 if (ret < 0) {
9363 av_channel_layout_uninit(&ch_layout);
9364 return 0;
9365 }
9366
9368 st->codecpar->ch_layout = ch_layout;
9369
9370 return 0;
9371}
9372
9374{
9375 AVStream *st;
9376 int version;
9377
9378 if (c->fc->nb_streams < 1)
9379 return 0;
9380
9381 st = c->fc->streams[c->fc->nb_streams - 1];
9382
9383 if (atom.size < 5) {
9384 av_log(c->fc, AV_LOG_ERROR, "Empty SAND audio box\n");
9385 return AVERROR_INVALIDDATA;
9386 }
9387
9388 version = avio_r8(pb);
9389 if (version) {
9390 av_log(c->fc, AV_LOG_WARNING, "Unsupported SAND box version %d\n", version);
9391 return 0;
9392 }
9393
9395
9396 return 0;
9397}
9398
9399static int rb_size(AVIOContext *pb, int64_t *value, int size)
9400{
9401 if (size == 0)
9402 *value = 0;
9403 else if (size == 1)
9404 *value = avio_r8(pb);
9405 else if (size == 2)
9406 *value = avio_rb16(pb);
9407 else if (size == 4)
9408 *value = avio_rb32(pb);
9409 else if (size == 8) {
9410 *value = avio_rb64(pb);
9411 if (*value < 0)
9412 return -1;
9413 } else
9414 return -1;
9415 return size;
9416}
9417
9419{
9420 avio_rb32(pb); // version & flags.
9421 c->primary_item_id = avio_rb16(pb);
9422 av_log(c->fc, AV_LOG_TRACE, "pitm: primary_item_id %d\n", c->primary_item_id);
9423 return atom.size;
9424}
9425
9427{
9428 c->idat_offset = avio_tell(pb);
9429 return 0;
9430}
9431
9433{
9434 HEIFItem **heif_item;
9435 int version, offset_size, length_size, base_offset_size, index_size;
9436 int item_count, extent_count;
9437 int64_t base_offset, extent_offset, extent_length;
9438 uint8_t value;
9439
9440 if (c->found_iloc) {
9441 av_log(c->fc, AV_LOG_INFO, "Duplicate iloc box found\n");
9442 return 0;
9443 }
9444
9445 version = avio_r8(pb);
9446 avio_rb24(pb); // flags.
9447
9448 value = avio_r8(pb);
9449 offset_size = (value >> 4) & 0xF;
9450 length_size = value & 0xF;
9451 value = avio_r8(pb);
9452 base_offset_size = (value >> 4) & 0xF;
9453 index_size = !version ? 0 : (value & 0xF);
9454 if (index_size) {
9455 avpriv_report_missing_feature(c->fc, "iloc: index_size != 0");
9456 return AVERROR_PATCHWELCOME;
9457 }
9458 item_count = (version < 2) ? avio_rb16(pb) : avio_rb32(pb);
9459
9460 if (item_count > atom.size)
9461 return AVERROR_INVALIDDATA;
9462
9463 heif_item = av_realloc_array(c->heif_item, FFMAX(item_count, c->nb_heif_item), sizeof(*c->heif_item));
9464 if (!heif_item)
9465 return AVERROR(ENOMEM);
9466 c->heif_item = heif_item;
9467 if (item_count > c->nb_heif_item)
9468 memset(&c->heif_item[c->nb_heif_item], 0,
9469 sizeof(*c->heif_item) * (item_count - c->nb_heif_item));
9470 c->nb_heif_item = FFMAX(c->nb_heif_item, item_count);
9471
9472 av_log(c->fc, AV_LOG_TRACE, "iloc: item_count %d\n", item_count);
9473 for (int i = 0; i < item_count; i++) {
9474 HEIFItem *item = NULL;
9475 int item_id = (version < 2) ? avio_rb16(pb) : avio_rb32(pb);
9476 int offset_type = (version > 0) ? avio_rb16(pb) & 0xf : 0;
9477 int j;
9478
9479 if (avio_feof(pb))
9480 return AVERROR_INVALIDDATA;
9481 if (offset_type > 1) {
9482 avpriv_report_missing_feature(c->fc, "iloc offset type %d", offset_type);
9483 return AVERROR_PATCHWELCOME;
9484 }
9485
9486 avio_rb16(pb); // data_reference_index.
9487 if (rb_size(pb, &base_offset, base_offset_size) < 0)
9488 return AVERROR_INVALIDDATA;
9489 extent_count = avio_rb16(pb);
9490 if (extent_count > 1) {
9491 // For still AVIF images, we only support one extent item.
9492 avpriv_report_missing_feature(c->fc, "iloc: extent_count > 1");
9493 return AVERROR_PATCHWELCOME;
9494 }
9495
9496 if (rb_size(pb, &extent_offset, offset_size) < 0 ||
9497 rb_size(pb, &extent_length, length_size) < 0 ||
9498 base_offset > INT64_MAX - extent_offset)
9499 return AVERROR_INVALIDDATA;
9500
9501 for (j = 0; j < c->nb_heif_item; j++) {
9502 item = c->heif_item[j];
9503 if (!item)
9504 item = c->heif_item[j] = av_mallocz(sizeof(*item));
9505 else if (item->item_id != item_id)
9506 continue;
9507 break;
9508 }
9509 if (!item)
9510 return AVERROR(ENOMEM);
9511 if (j == c->nb_heif_item)
9512 return AVERROR_INVALIDDATA;
9513
9514 item->item_id = item_id;
9515
9516 if (offset_type == 1)
9517 item->is_idat_relative = 1;
9518 item->extent_length = extent_length;
9519 item->extent_offset = base_offset + extent_offset;
9520 av_log(c->fc, AV_LOG_TRACE, "iloc: item_idx %d, item->item_id %d, offset_type %d, "
9521 "extent_offset %"PRId64", extent_length %"PRId64"\n",
9522 i, item->item_id, offset_type, item->extent_offset, item->extent_length);
9523 }
9524
9525 c->found_iloc = 1;
9526 return atom.size;
9527}
9528
9530{
9531 HEIFItem *item = NULL;
9532 AVBPrint item_name;
9533 int64_t size = atom.size;
9534 uint32_t item_type;
9535 int item_id;
9536 int i, version, ret;
9537
9538 version = avio_r8(pb);
9539 avio_rb24(pb); // flags.
9540 size -= 4;
9541 if (size < 0)
9542 return AVERROR_INVALIDDATA;
9543
9544 if (version < 2) {
9545 avpriv_report_missing_feature(c->fc, "infe version < 2");
9546 avio_skip(pb, size);
9547 return 1;
9548 }
9549
9550 item_id = version > 2 ? avio_rb32(pb) : avio_rb16(pb);
9551 avio_rb16(pb); // item_protection_index
9552 item_type = avio_rl32(pb);
9553 size -= 8;
9554 if (size < 1)
9555 return AVERROR_INVALIDDATA;
9556
9559 if (ret < 0) {
9561 return ret;
9562 }
9563
9564 av_log(c->fc, AV_LOG_TRACE, "infe: item_id %d, item_type %s, item_name %s\n",
9565 item_id, av_fourcc2str(item_type), item_name.str);
9566
9567 size -= ret + 1;
9568 if (size > 0)
9569 avio_skip(pb, size);
9570
9571 for (i = 0; i < c->nb_heif_item; i++) {
9572 item = c->heif_item[i];
9573 if (!item)
9574 item = c->heif_item[i] = av_mallocz(sizeof(*item));
9575 else if (item->item_id != item_id)
9576 continue;
9577 break;
9578 }
9579 if (!item) {
9581 return AVERROR(ENOMEM);
9582 }
9583 if (i == c->nb_heif_item) {
9585 return AVERROR_INVALIDDATA;
9586 }
9587
9588 av_freep(&item->name);
9589 av_bprint_finalize(&item_name, ret ? &item->name : NULL);
9590 item->item_id = item_id;
9591 item->type = item_type;
9592
9593 switch (item_type) {
9594 case MKTAG('a','v','0','1'):
9595 case MKTAG('j','p','e','g'):
9596 case MKTAG('h','v','c','1'):
9597 ret = heif_add_stream(c, item);
9598 if (ret < 0)
9599 return ret;
9600 break;
9601 }
9602
9603 return 0;
9604}
9605
9607{
9608 HEIFItem **heif_item;
9609 int entry_count;
9610 int version, got_stream = 0, ret, i;
9611
9612 if (c->found_iinf) {
9613 av_log(c->fc, AV_LOG_WARNING, "Duplicate iinf box found\n");
9614 return 0;
9615 }
9616
9617 version = avio_r8(pb);
9618 avio_rb24(pb); // flags.
9619 entry_count = version ? avio_rb32(pb) : avio_rb16(pb);
9620
9621 if (entry_count > atom.size)
9622 return AVERROR_INVALIDDATA;
9623
9624 heif_item = av_realloc_array(c->heif_item, FFMAX(entry_count, c->nb_heif_item), sizeof(*c->heif_item));
9625 if (!heif_item)
9626 return AVERROR(ENOMEM);
9627 c->heif_item = heif_item;
9628 if (entry_count > c->nb_heif_item)
9629 memset(&c->heif_item[c->nb_heif_item], 0,
9630 sizeof(*c->heif_item) * (entry_count - c->nb_heif_item));
9631 c->nb_heif_item = FFMAX(c->nb_heif_item, entry_count);
9632
9633 for (i = 0; i < entry_count; i++) {
9634 MOVAtom infe;
9635
9636 infe.size = avio_rb32(pb) - 8;
9637 infe.type = avio_rl32(pb);
9638 if (avio_feof(pb)) {
9639 ret = AVERROR_INVALIDDATA;
9640 goto fail;
9641 }
9642 ret = mov_read_infe(c, pb, infe);
9643 if (ret < 0)
9644 goto fail;
9645 if (!ret)
9646 got_stream = 1;
9647 }
9648
9649 c->found_iinf = got_stream;
9650 return 0;
9651fail:
9652 for (; i >= 0; i--) {
9653 HEIFItem *item = c->heif_item[i];
9654
9655 if (!item)
9656 continue;
9657
9658 av_freep(&item->name);
9659 }
9660 return ret;
9661}
9662
9664{
9665 HEIFItem *item = NULL;
9666 HEIFGrid *grid;
9667 int entries, i;
9668 int from_item_id = version ? avio_rb32(pb) : avio_rb16(pb);
9669 int ret = 0;
9670
9671 for (int i = 0; i < c->nb_heif_grid; i++) {
9672 if (c->heif_grid[i].item->item_id == from_item_id) {
9673 av_log(c->fc, AV_LOG_ERROR, "More than one 'dimg' box "
9674 "referencing the same Derived Image item\n");
9675 return AVERROR_INVALIDDATA;
9676 }
9677 }
9678 for (int i = 0; i < c->nb_heif_item; i++) {
9679 if (!c->heif_item[i] || c->heif_item[i]->item_id != from_item_id)
9680 continue;
9681 item = c->heif_item[i];
9682
9683 switch (item->type) {
9684 case MKTAG('g','r','i','d'):
9685 case MKTAG('i','o','v','l'):
9686 break;
9687 default:
9688 avpriv_report_missing_feature(c->fc, "Derived Image item of type %s",
9689 av_fourcc2str(item->type));
9690 return 0;
9691 }
9692 break;
9693 }
9694 if (!item) {
9695 av_log(c->fc, AV_LOG_ERROR, "Missing grid information\n");
9696 return AVERROR_INVALIDDATA;
9697 }
9698
9699 entries = avio_rb16(pb);
9700 if (!entries) {
9701 av_log(c->fc, AV_LOG_ERROR,
9702 "Derived image item references no input images\n");
9703 return AVERROR_INVALIDDATA;
9704 }
9705
9706 grid = av_realloc_array(c->heif_grid, c->nb_heif_grid + 1U,
9707 sizeof(*c->heif_grid));
9708 if (!grid)
9709 return AVERROR(ENOMEM);
9710 c->heif_grid = grid;
9711 grid = &grid[c->nb_heif_grid];
9712
9713 grid->tile_id_list = av_malloc_array(entries, sizeof(*grid->tile_id_list));
9714 grid->tile_idx_list = av_calloc(entries, sizeof(*grid->tile_idx_list));
9715 grid->tile_item_list = av_calloc(entries, sizeof(*grid->tile_item_list));
9716 if (!grid->tile_id_list || !grid->tile_item_list || !grid->tile_idx_list) {
9717 ret = AVERROR(ENOMEM);
9718 goto fail;
9719 }
9720 /* 'to' item ids */
9721 for (i = 0; i < entries; i++) {
9722 grid->tile_id_list[i] = version ? avio_rb32(pb) : avio_rb16(pb);
9723
9724 if (avio_feof(pb)) {
9725 ret = AVERROR_INVALIDDATA;
9726 goto fail;
9727 }
9728 }
9729
9730 grid->nb_tiles = entries;
9731 grid->item = item;
9732 ++c->nb_heif_grid;
9733
9734 av_log(c->fc, AV_LOG_TRACE, "dimg: from_item_id %d, entries %d\n",
9735 from_item_id, entries);
9736
9737 return 0;
9738fail:
9739 av_freep(&grid->tile_id_list);
9740 av_freep(&grid->tile_idx_list);
9741 av_freep(&grid->tile_item_list);
9742
9743 return ret;
9744}
9745
9746static int mov_read_iref_cdsc(MOVContext *c, AVIOContext *pb, uint32_t type, int version, uint32_t size)
9747{
9748 HEIFItem *from_item = NULL;
9749 int entries;
9750 int item_id_size = version ? 4 : 2;
9751 int from_item_id = version ? avio_rb32(pb) : avio_rb16(pb);
9752 const HEIFItemRef ref = { type, from_item_id };
9753
9754 from_item = get_heif_item(c, from_item_id);
9755 if (!from_item) {
9756 av_log(c->fc, AV_LOG_ERROR, "Missing stream referenced by thmb item\n");
9757 return AVERROR_INVALIDDATA;
9758 }
9759
9760 entries = avio_rb16(pb);
9761 if ((int64_t)entries * item_id_size > (int64_t)size - item_id_size - 2) {
9762 av_log(c->fc, AV_LOG_ERROR, "iref %s entry count %d exceeds the sub-box size\n",
9763 av_fourcc2str(type), entries);
9764 return AVERROR_INVALIDDATA;
9765 }
9766 /* 'to' item ids */
9767 for (int i = 0; i < entries; i++) {
9768 HEIFItem *item = get_heif_item(c, version ? avio_rb32(pb) : avio_rb16(pb));
9769
9770 if (avio_feof(pb))
9771 return AVERROR_INVALIDDATA;
9772
9773 if (!item) {
9774 av_log(c->fc, AV_LOG_WARNING, "Missing stream referenced by %s item\n",
9776 continue;
9777 }
9778
9779 if (!av_dynarray2_add((void **)&item->iref_list, &item->nb_iref_list,
9780 sizeof(*item->iref_list), (const uint8_t *)&ref))
9781 return AVERROR(ENOMEM);
9782 }
9783
9784 av_log(c->fc, AV_LOG_TRACE, "%s: from_item_id %d, entries %d\n",
9785 av_fourcc2str(type), from_item_id, entries);
9786
9787 return 0;
9788}
9789
9791{
9792 int version = avio_r8(pb);
9793 int ret;
9794
9795 avio_rb24(pb); // flags
9796 atom.size -= 4;
9797
9798 if (version > 1) {
9799 av_log(c->fc, AV_LOG_WARNING, "Unknown iref box version %d\n", version);
9800 return 0;
9801 }
9802
9803 while (atom.size) {
9804 int64_t next = avio_tell(pb);
9805 uint32_t type, size = avio_rb32(pb);
9806
9807 if (size < 14 || size > atom.size || next > INT64_MAX - size)
9808 return AVERROR_INVALIDDATA;
9809
9810 next += size;
9811 type = avio_rl32(pb);
9812 switch (type) {
9813 case MKTAG('d','i','m','g'):
9814 ret = mov_read_iref_dimg(c, pb, version);
9815 if (ret < 0)
9816 return ret;
9817 break;
9818 case MKTAG('c','d','s','c'):
9819 case MKTAG('t','h','m','b'):
9820 ret = mov_read_iref_cdsc(c, pb, type, version, size - 8);
9821 if (ret < 0)
9822 return ret;
9823 break;
9824 default:
9825 av_log(c->fc, AV_LOG_DEBUG, "Unknown iref type %s size %"PRIu32"\n",
9827 }
9828
9829 atom.size -= size;
9830 avio_seek(pb, next, SEEK_SET);
9831 }
9832 return 0;
9833}
9834
9836{
9837 HEIFItem *item;
9838 uint32_t width, height;
9839
9840 avio_r8(pb); /* version */
9841 avio_rb24(pb); /* flags */
9842 width = avio_rb32(pb);
9843 height = avio_rb32(pb);
9844
9845 av_log(c->fc, AV_LOG_TRACE, "ispe: item_id %d, width %"PRIu32", height %"PRIu32"\n",
9846 c->cur_item_id, width, height);
9847
9848 if (!width || !height || width > INT_MAX || height > INT_MAX) {
9849 av_log(c->fc, AV_LOG_ERROR, "Invalid ispe dimensions %"PRIu32"x%"PRIu32"\n",
9850 width, height);
9851 return AVERROR_INVALIDDATA;
9852 }
9853
9854 item = get_heif_item(c, c->cur_item_id);
9855 if (item) {
9856 item->width = width;
9857 item->height = height;
9858 }
9859
9860 return 0;
9861}
9862
9864{
9865 HEIFItem *item;
9866 int angle;
9867
9868 angle = avio_r8(pb) & 0x3;
9869
9870 av_log(c->fc, AV_LOG_TRACE, "irot: item_id %d, angle %u\n",
9871 c->cur_item_id, angle);
9872
9873 item = get_heif_item(c, c->cur_item_id);
9874 if (item) {
9875 // angle * 90 specifies the angle (in anti-clockwise direction)
9876 // in units of degrees.
9877 item->rotation = angle * 90;
9878 }
9879
9880 return 0;
9881}
9882
9884{
9885 HEIFItem *item;
9886 int axis;
9887
9888 axis = avio_r8(pb) & 0x1;
9889
9890 av_log(c->fc, AV_LOG_TRACE, "imir: item_id %d, axis %u\n",
9891 c->cur_item_id, axis);
9892
9893 item = get_heif_item(c, c->cur_item_id);
9894 if (item) {
9895 item->hflip = axis;
9896 item->vflip = !axis;
9897 }
9898
9899 return 0;
9900}
9901
9903{
9904 typedef struct MOVAtoms {
9905 FFIOContext b;
9906 uint32_t type;
9907 int64_t size;
9908 uint8_t *data;
9909 } MOVAtoms;
9910 MOVAtoms *atoms = NULL;
9911 MOVAtom a;
9912 unsigned count;
9913 int nb_atoms = 0;
9914 int version, flags;
9915 int ret;
9916
9917 a.size = avio_rb32(pb);
9918 a.type = avio_rl32(pb);
9919
9920 if (a.size < 8 || a.type != MKTAG('i','p','c','o'))
9921 return AVERROR_INVALIDDATA;
9922
9923 a.size -= 8;
9924 while (a.size >= 8) {
9925 MOVAtoms *ref = av_dynarray2_add((void**)&atoms, &nb_atoms, sizeof(MOVAtoms), NULL);
9926 if (!ref) {
9927 ret = AVERROR(ENOMEM);
9928 goto fail;
9929 }
9930 ref->data = NULL;
9931 ref->size = avio_rb32(pb);
9932 ref->type = avio_rl32(pb);
9933 if (ref->size > a.size || ref->size < 8)
9934 break;
9935 ref->data = av_malloc(ref->size);
9936 if (!ref->data) {
9937 ret = AVERROR_INVALIDDATA;
9938 goto fail;
9939 }
9940 av_log(c->fc, AV_LOG_TRACE, "ipco: index %d, box type %s\n", nb_atoms, av_fourcc2str(ref->type));
9941 avio_seek(pb, -8, SEEK_CUR);
9942 if (avio_read(pb, ref->data, ref->size) != ref->size) {
9943 ret = AVERROR_INVALIDDATA;
9944 goto fail;
9945 }
9946 ffio_init_read_context(&ref->b, ref->data, ref->size);
9947 a.size -= ref->size;
9948 }
9949
9950 if (a.size) {
9951 ret = AVERROR_INVALIDDATA;
9952 goto fail;
9953 }
9954
9955 a.size = avio_rb32(pb);
9956 a.type = avio_rl32(pb);
9957
9958 if (a.size < 8 || a.type != MKTAG('i','p','m','a')) {
9959 ret = AVERROR_INVALIDDATA;
9960 goto fail;
9961 }
9962
9963 version = avio_r8(pb);
9964 flags = avio_rb24(pb);
9965 count = avio_rb32(pb);
9966
9967 for (int i = 0; i < count; i++) {
9968 int item_id = version ? avio_rb32(pb) : avio_rb16(pb);
9969 int assoc_count = avio_r8(pb);
9970
9971 if (avio_feof(pb)) {
9972 ret = AVERROR_INVALIDDATA;
9973 goto fail;
9974 }
9975
9976 for (int j = 0; j < assoc_count; j++) {
9977 MOVAtoms *ref;
9978 int index = avio_r8(pb) & 0x7f;
9979 if (flags & 1) {
9980 index <<= 8;
9981 index |= avio_r8(pb);
9982 }
9983 if (index > nb_atoms || index <= 0) {
9984 ret = AVERROR_INVALIDDATA;
9985 goto fail;
9986 }
9987 ref = &atoms[--index];
9988
9989 av_log(c->fc, AV_LOG_TRACE, "ipma: property_index %d, item_id %d, item_type %s\n",
9990 index + 1, item_id, av_fourcc2str(ref->type));
9991
9992 c->cur_item_id = item_id;
9993
9994 ret = mov_read_default(c, &ref->b.pub,
9995 (MOVAtom) { .size = ref->size,
9996 .type = MKTAG('i','p','c','o') });
9997 if (ret < 0)
9998 goto fail;
9999 ffio_init_read_context(&ref->b, ref->data, ref->size);
10000 }
10001 }
10002
10003 ret = 0;
10004fail:
10005 c->cur_item_id = -1;
10006 for (int i = 0; i < nb_atoms; i++)
10007 av_free(atoms[i].data);
10008 av_free(atoms);
10009
10010 return ret;
10011}
10012
10014{
10015 avio_rb32(pb); // version & flags
10016 uint16_t graphics_mode = avio_rb16(pb);
10017 // ignored: opcolor[3]
10018
10019 if (c->fc->nb_streams < 1)
10020 return 0;
10021 AVStream *st = c->fc->streams[c->fc->nb_streams - 1];
10023 return 0;
10024
10025 switch (graphics_mode) {
10029 break;
10032 break;
10035 break;
10036 default:
10038 av_log(c->fc, AV_LOG_WARNING, "Unhandled graphics mode: 0x%x\n",
10039 graphics_mode);
10040 break;
10041 }
10042
10043 return 0;
10044}
10045
10047{
10048 AVFormatContext *ctx = c->fc;
10049 AVStream *st;
10050 int profile_level_indication, reference_ch_layout, config_length;
10051 int ret = 0;
10052
10053 if (ctx->nb_streams < 1)
10054 return 0;
10055
10056 st = ctx->streams[ctx->nb_streams - 1];
10058 return 0;
10059
10060 if (avio_r8(pb) != 1) // ConfigurationVersion
10061 return 0;
10062
10063 profile_level_indication = avio_r8(pb);
10064 st->codecpar->profile = (profile_level_indication - 1) / 5;
10065 st->codecpar->level = ((profile_level_indication - 1) % 5) + 1;
10066
10067 reference_ch_layout = avio_r8(pb);
10068 config_length = avio_rb16(pb);
10069 if (config_length)
10070 ret = ff_get_extradata(ctx, st->codecpar, pb, config_length);
10071
10072 if (!reference_ch_layout ||
10073 reference_ch_layout >= FF_ARRAY_ELEMS(ff_mpa_cicp_channel_layout_masks)) {
10074 av_log(ctx, AV_LOG_WARNING, "Unknown referenceChannelLayout value: %d\n", reference_ch_layout);
10075 return ret;
10076 }
10077
10079 ff_mpa_cicp_channel_layout_masks[reference_ch_layout]);
10080
10081 return ret;
10082}
10083
10085{ MKTAG('A','C','L','R'), mov_read_aclr },
10086{ MKTAG('A','P','R','G'), mov_read_avid },
10087{ MKTAG('A','A','L','P'), mov_read_avid },
10088{ MKTAG('A','R','E','S'), mov_read_ares },
10089{ MKTAG('a','v','s','s'), mov_read_avss },
10090{ MKTAG('a','v','1','C'), mov_read_glbl },
10091{ MKTAG('c','h','p','l'), mov_read_chpl },
10092{ MKTAG('c','o','6','4'), mov_read_stco },
10093{ MKTAG('c','o','l','r'), mov_read_colr },
10094{ MKTAG('c','t','t','s'), mov_read_ctts }, /* composition time to sample */
10095{ MKTAG('d','i','n','f'), mov_read_default },
10096{ MKTAG('D','p','x','E'), mov_read_dpxe },
10097{ MKTAG('d','r','e','f'), mov_read_dref },
10098{ MKTAG('e','d','t','s'), mov_read_default },
10099{ MKTAG('e','l','s','t'), mov_read_elst },
10100{ MKTAG('e','n','d','a'), mov_read_enda },
10101{ MKTAG('f','i','e','l'), mov_read_fiel },
10102{ MKTAG('a','d','r','m'), mov_read_adrm },
10103{ MKTAG('f','t','y','p'), mov_read_ftyp },
10104{ MKTAG('g','l','b','l'), mov_read_glbl },
10105{ MKTAG('h','d','l','r'), mov_read_hdlr },
10106{ MKTAG('i','l','s','t'), mov_read_ilst },
10107{ MKTAG('j','p','2','h'), mov_read_jp2h },
10108{ MKTAG('m','d','a','t'), mov_read_mdat },
10109{ MKTAG('m','d','h','d'), mov_read_mdhd },
10110{ MKTAG('m','d','i','a'), mov_read_default },
10111{ MKTAG('m','e','t','a'), mov_read_meta },
10112{ MKTAG('m','i','n','f'), mov_read_default },
10113{ MKTAG('m','o','o','f'), mov_read_moof },
10114{ MKTAG('m','o','o','v'), mov_read_moov },
10115{ MKTAG('m','v','e','x'), mov_read_default },
10116{ MKTAG('m','v','h','d'), mov_read_mvhd },
10117{ MKTAG('S','M','I',' '), mov_read_svq3 },
10118{ MKTAG('a','l','a','c'), mov_read_alac }, /* alac specific atom */
10119{ MKTAG('a','v','c','C'), mov_read_glbl },
10120{ MKTAG('p','a','s','p'), mov_read_pasp },
10121{ MKTAG('c','l','a','p'), mov_read_clap },
10122{ MKTAG('c','d','s','c'), mov_read_cdsc_rndr },
10123{ MKTAG('r','n','d','r'), mov_read_cdsc_rndr },
10124{ MKTAG('s','b','a','s'), mov_read_sbas },
10125{ MKTAG('v','d','e','p'), mov_read_vdep },
10126{ MKTAG('s','i','d','x'), mov_read_sidx },
10127{ MKTAG('s','t','b','l'), mov_read_default },
10128{ MKTAG('s','t','c','o'), mov_read_stco },
10129{ MKTAG('s','t','p','s'), mov_read_stps },
10130{ MKTAG('s','t','r','f'), mov_read_strf },
10131{ MKTAG('s','t','s','c'), mov_read_stsc },
10132{ MKTAG('s','t','s','d'), mov_read_stsd }, /* sample description */
10133{ MKTAG('s','t','s','s'), mov_read_stss }, /* sync sample */
10134{ MKTAG('s','t','s','z'), mov_read_stsz }, /* sample size */
10135{ MKTAG('s','t','t','s'), mov_read_stts },
10136{ MKTAG('s','t','z','2'), mov_read_stsz }, /* compact sample size */
10137{ MKTAG('s','d','t','p'), mov_read_sdtp }, /* independent and disposable samples */
10138{ MKTAG('t','k','h','d'), mov_read_tkhd }, /* track header */
10139{ MKTAG('t','f','d','t'), mov_read_tfdt },
10140{ MKTAG('t','f','h','d'), mov_read_tfhd }, /* track fragment header */
10141{ MKTAG('t','r','a','k'), mov_read_trak },
10142{ MKTAG('t','r','a','f'), mov_read_default },
10143{ MKTAG('t','r','e','f'), mov_read_default },
10144{ MKTAG('t','m','c','d'), mov_read_tmcd },
10145{ MKTAG('c','h','a','p'), mov_read_chap },
10146{ MKTAG('t','r','e','x'), mov_read_trex },
10147{ MKTAG('t','r','u','n'), mov_read_trun },
10148{ MKTAG('u','d','t','a'), mov_read_default },
10149{ MKTAG('w','a','v','e'), mov_read_wave },
10150{ MKTAG('e','s','d','s'), mov_read_esds },
10151{ MKTAG('d','a','c','3'), mov_read_dac3 }, /* AC-3 info */
10152{ MKTAG('d','e','c','3'), mov_read_dec3 }, /* EAC-3 info */
10153{ MKTAG('d','d','t','s'), mov_read_ddts }, /* DTS audio descriptor */
10154{ MKTAG('w','i','d','e'), mov_read_wide }, /* place holder */
10155{ MKTAG('w','f','e','x'), mov_read_wfex },
10156{ MKTAG('c','m','o','v'), mov_read_cmov },
10157{ MKTAG('c','h','a','n'), mov_read_chan }, /* channel layout from quicktime */
10158{ MKTAG('c','h','n','l'), mov_read_chnl }, /* channel layout from ISO-14496-12 */
10159{ MKTAG('d','v','c','1'), mov_read_dvc1 },
10160{ MKTAG('s','g','p','d'), mov_read_sgpd },
10161{ MKTAG('s','b','g','p'), mov_read_sbgp },
10162{ MKTAG('h','v','c','C'), mov_read_glbl },
10163{ MKTAG('v','v','c','C'), mov_read_glbl },
10164{ MKTAG('u','u','i','d'), mov_read_uuid },
10165{ MKTAG('C','i','n', 0x8e), mov_read_targa_y216 },
10166{ MKTAG('f','r','e','e'), mov_read_free },
10167{ MKTAG('-','-','-','-'), mov_read_custom },
10168{ MKTAG('s','i','n','f'), mov_read_default },
10169{ MKTAG('f','r','m','a'), mov_read_frma },
10170{ MKTAG('s','e','n','c'), mov_read_senc },
10171{ MKTAG('s','a','i','z'), mov_read_saiz },
10172{ MKTAG('s','a','i','o'), mov_read_saio },
10173{ MKTAG('p','s','s','h'), mov_read_pssh },
10174{ MKTAG('s','c','h','m'), mov_read_schm },
10175{ MKTAG('s','c','h','i'), mov_read_default },
10176{ MKTAG('t','e','n','c'), mov_read_tenc },
10177{ MKTAG('d','f','L','a'), mov_read_dfla },
10178{ MKTAG('s','t','3','d'), mov_read_st3d }, /* stereoscopic 3D video box */
10179{ MKTAG('s','v','3','d'), mov_read_sv3d }, /* spherical video box */
10180{ MKTAG('v','e','x','u'), mov_read_vexu }, /* video extension usage */
10181{ MKTAG('h','f','o','v'), mov_read_hfov },
10182{ MKTAG('d','O','p','s'), mov_read_dops },
10183{ MKTAG('d','m','l','p'), mov_read_dmlp },
10184{ MKTAG('S','m','D','m'), mov_read_smdm },
10185{ MKTAG('C','o','L','L'), mov_read_coll },
10186{ MKTAG('v','p','c','C'), mov_read_vpcc },
10187{ MKTAG('m','d','c','v'), mov_read_mdcv },
10188{ MKTAG('c','l','l','i'), mov_read_clli },
10189{ MKTAG('d','v','c','C'), mov_read_dvcc_dvvc },
10190{ MKTAG('d','v','v','C'), mov_read_dvcc_dvvc },
10191{ MKTAG('d','v','w','C'), mov_read_dvcc_dvvc },
10192{ MKTAG('h','v','c','E'), mov_read_hvce },
10193{ MKTAG('k','i','n','d'), mov_read_kind },
10194{ MKTAG('S','A','3','D'), mov_read_SA3D }, /* ambisonic audio box */
10195{ MKTAG('S','A','N','D'), mov_read_SAND }, /* non diegetic audio box */
10196{ MKTAG('i','l','o','c'), mov_read_iloc },
10197{ MKTAG('p','c','m','C'), mov_read_pcmc }, /* PCM configuration box */
10198{ MKTAG('p','i','t','m'), mov_read_pitm },
10199{ MKTAG('e','v','c','C'), mov_read_glbl },
10200{ MKTAG('i','d','a','t'), mov_read_idat },
10201{ MKTAG('i','m','i','r'), mov_read_imir },
10202{ MKTAG('i','r','e','f'), mov_read_iref },
10203{ MKTAG('i','s','p','e'), mov_read_ispe },
10204{ MKTAG('i','r','o','t'), mov_read_irot },
10205{ MKTAG('i','p','r','p'), mov_read_iprp },
10206{ MKTAG('i','i','n','f'), mov_read_iinf },
10207{ MKTAG('a','m','v','e'), mov_read_amve }, /* ambient viewing environment box */
10208{ MKTAG('l','h','v','C'), mov_read_lhvc },
10209{ MKTAG('l','v','c','C'), mov_read_glbl },
10210{ MKTAG('a','p','v','C'), mov_read_glbl },
10211#if CONFIG_IAMFDEC
10212{ MKTAG('i','a','c','b'), mov_read_iacb },
10213#endif
10214{ MKTAG('s','r','a','t'), mov_read_srat },
10215{ MKTAG('v','m','h','d'), mov_read_vmhd },
10216{ MKTAG('m','h','a','C'), mov_read_mhac },
10217{ 0, NULL }
10218};
10219
10221{
10222 int64_t total_size = 0;
10223 MOVAtom a;
10224 int i;
10225
10226 if (c->atom_depth > 10) {
10227 av_log(c->fc, AV_LOG_ERROR, "Atoms too deeply nested\n");
10228 return AVERROR_INVALIDDATA;
10229 }
10230 c->atom_depth ++;
10231
10232 if (atom.size < 0)
10233 atom.size = INT64_MAX;
10234 while (total_size <= atom.size - 8) {
10235 int (*parse)(MOVContext*, AVIOContext*, MOVAtom) = NULL;
10236 a.size = avio_rb32(pb);
10237 a.type = avio_rl32(pb);
10238 if (avio_feof(pb))
10239 break;
10240 if (((a.type == MKTAG('f','r','e','e') && c->moov_retry) ||
10241 a.type == MKTAG('h','o','o','v')) &&
10242 a.size >= 8 &&
10243 c->fc->strict_std_compliance < FF_COMPLIANCE_STRICT) {
10244 uint32_t type;
10245 avio_skip(pb, 4);
10246 type = avio_rl32(pb);
10247 if (avio_feof(pb))
10248 break;
10249 avio_seek(pb, -8, SEEK_CUR);
10250 if (type == MKTAG('m','v','h','d') ||
10251 type == MKTAG('c','m','o','v')) {
10252 av_log(c->fc, AV_LOG_ERROR, "Detected moov in a free or hoov atom.\n");
10253 a.type = MKTAG('m','o','o','v');
10254 }
10255 }
10256 if (atom.type != MKTAG('r','o','o','t') &&
10257 atom.type != MKTAG('m','o','o','v')) {
10258 if (a.type == MKTAG('t','r','a','k') ||
10259 a.type == MKTAG('m','d','a','t')) {
10260 av_log(c->fc, AV_LOG_ERROR, "Broken file, trak/mdat not at top-level\n");
10261 avio_skip(pb, -8);
10262 c->atom_depth --;
10263 return 0;
10264 }
10265 }
10266 total_size += 8;
10267 if (a.size == 1 && total_size + 8 <= atom.size) { /* 64 bit extended size */
10268 a.size = avio_rb64(pb) - 8;
10269 total_size += 8;
10270 }
10271 av_log(c->fc, AV_LOG_TRACE, "type:'%s' parent:'%s' sz: %"PRId64" %"PRId64" %"PRId64"\n",
10272 av_fourcc2str(a.type), av_fourcc2str(atom.type), a.size, total_size, atom.size);
10273 if (a.size == 0) {
10274 a.size = atom.size - total_size + 8;
10275 }
10276 if (a.size < 0)
10277 break;
10278 a.size -= 8;
10279 if (a.size < 0)
10280 break;
10281 a.size = FFMIN(a.size, atom.size - total_size);
10282
10283 for (i = 0; mov_default_parse_table[i].type; i++)
10284 if (mov_default_parse_table[i].type == a.type) {
10286 break;
10287 }
10288
10289 // container is user data
10290 if (!parse && (atom.type == MKTAG('u','d','t','a') ||
10291 atom.type == MKTAG('i','l','s','t')))
10293
10294 // Supports parsing the QuickTime Metadata Keys.
10295 // https://developer.apple.com/library/mac/documentation/QuickTime/QTFF/Metadata/Metadata.html
10296 if (!parse && c->found_hdlr_mdta &&
10297 atom.type == MKTAG('m','e','t','a') &&
10298 a.type == MKTAG('k','e','y','s') &&
10299 c->meta_keys_count == 0) {
10301 }
10302
10303 if (!parse) { /* skip leaf atoms data */
10304 avio_skip(pb, a.size);
10305 } else {
10306 int64_t start_pos = avio_tell(pb);
10307 int64_t left;
10308 int err = parse(c, pb, a);
10309 if (err < 0) {
10310 c->atom_depth --;
10311 return err;
10312 }
10313 if (c->found_moov && c->found_mdat && a.size <= INT64_MAX - start_pos &&
10314 ((!(pb->seekable & AVIO_SEEKABLE_NORMAL) || c->fc->flags & AVFMT_FLAG_IGNIDX || c->frag_index.complete) ||
10315 start_pos + a.size == avio_size(pb))) {
10316 if (!(pb->seekable & AVIO_SEEKABLE_NORMAL) || c->fc->flags & AVFMT_FLAG_IGNIDX || c->frag_index.complete)
10317 c->next_root_atom = start_pos + a.size;
10318 c->atom_depth --;
10319 return 0;
10320 }
10321 left = a.size - avio_tell(pb) + start_pos;
10322 if (left > 0) /* skip garbage at atom end */
10323 avio_skip(pb, left);
10324 else if (left < 0) {
10325 av_log(c->fc, AV_LOG_WARNING,
10326 "overread end of atom '%s' by %"PRId64" bytes\n",
10327 av_fourcc2str(a.type), -left);
10328 avio_seek(pb, left, SEEK_CUR);
10329 }
10330 }
10331
10332 total_size += a.size;
10333 }
10334
10335 if (total_size < atom.size && atom.size < 0x7ffff)
10336 avio_skip(pb, atom.size - total_size);
10337
10338 c->atom_depth --;
10339 return 0;
10340}
10341
10342static int mov_probe(const AVProbeData *p)
10343{
10345 uint32_t tag;
10346 int score = 0;
10347 int moov_offset = -1;
10348
10349 /* check file header */
10350 offset = 0;
10351 for (;;) {
10352 int64_t size;
10353 int minsize = 8;
10354 /* ignore invalid offset */
10355 if ((offset + 8ULL) > (unsigned int)p->buf_size)
10356 break;
10357 size = AV_RB32(p->buf + offset);
10358 if (size == 1 && offset + 16 <= (unsigned int)p->buf_size) {
10359 size = AV_RB64(p->buf+offset + 8);
10360 minsize = 16;
10361 } else if (size == 0) {
10362 size = p->buf_size - offset;
10363 }
10364 if (size < minsize) {
10365 offset += 4;
10366 continue;
10367 }
10368 tag = AV_RL32(p->buf + offset + 4);
10369 switch(tag) {
10370 /* check for obvious tags */
10371 case MKTAG('m','o','o','v'):
10372 moov_offset = offset + 4;
10374 case MKTAG('m','d','a','t'):
10375 case MKTAG('p','n','o','t'): /* detect movs with preview pics like ew.mov and april.mov */
10376 case MKTAG('u','d','t','a'): /* Packet Video PVAuthor adds this and a lot of more junk */
10377 case MKTAG('f','t','y','p'):
10378 if (tag == MKTAG('f','t','y','p') &&
10379 ( AV_RL32(p->buf + offset + 8) == MKTAG('j','p','2',' ')
10380 || AV_RL32(p->buf + offset + 8) == MKTAG('j','p','x',' ')
10381 || AV_RL32(p->buf + offset + 8) == MKTAG('j','x','l',' ')
10382 )) {
10383 score = FFMAX(score, 5);
10384 } else {
10385 score = AVPROBE_SCORE_MAX;
10386 }
10387 break;
10388 /* those are more common words, so rate then a bit less */
10389 case MKTAG('e','d','i','w'): /* xdcam files have reverted first tags */
10390 case MKTAG('w','i','d','e'):
10391 case MKTAG('f','r','e','e'):
10392 case MKTAG('j','u','n','k'):
10393 case MKTAG('p','i','c','t'):
10394 score = FFMAX(score, AVPROBE_SCORE_MAX - 5);
10395 break;
10396 case MKTAG(0x82,0x82,0x7f,0x7d):
10397 score = FFMAX(score, AVPROBE_SCORE_EXTENSION - 5);
10398 break;
10399 case MKTAG('s','k','i','p'):
10400 case MKTAG('u','u','i','d'):
10401 case MKTAG('p','r','f','l'):
10402 /* if we only find those cause probedata is too small at least rate them */
10403 score = FFMAX(score, AVPROBE_SCORE_EXTENSION);
10404 break;
10405 }
10406 if (size > INT64_MAX - offset)
10407 break;
10408 offset += size;
10409 }
10410 if (score > AVPROBE_SCORE_MAX - 50 && moov_offset != -1) {
10411 /* moov atom in the header - we should make sure that this is not a
10412 * MOV-packed MPEG-PS */
10413 offset = moov_offset;
10414
10415 while (offset < (p->buf_size - 16)) { /* Sufficient space */
10416 /* We found an actual hdlr atom */
10417 if (AV_RL32(p->buf + offset ) == MKTAG('h','d','l','r') &&
10418 AV_RL32(p->buf + offset + 8) == MKTAG('m','h','l','r') &&
10419 AV_RL32(p->buf + offset + 12) == MKTAG('M','P','E','G')) {
10420 av_log(NULL, AV_LOG_WARNING, "Found media data tag MPEG indicating this is a MOV-packed MPEG-PS.\n");
10421 /* We found a media handler reference atom describing an
10422 * MPEG-PS-in-MOV, return a
10423 * low score to force expanding the probe window until
10424 * mpegps_probe finds what it needs */
10425 return 5;
10426 } else {
10427 /* Keep looking */
10428 offset += 2;
10429 }
10430 }
10431 }
10432
10433 return score;
10434}
10435
10436// must be done after parsing all trak because there's no order requirement
10438{
10439 MOVContext *mov = s->priv_data;
10440 MOVStreamContext *sc;
10441 int64_t cur_pos;
10442 int i, j;
10443 int chapter_track;
10444
10445 for (j = 0; j < mov->nb_chapter_tracks; j++) {
10446 AVStream *st = NULL;
10447 FFStream *sti = NULL;
10448 chapter_track = mov->chapter_tracks[j];
10449 for (i = 0; i < s->nb_streams; i++) {
10450 sc = mov->fc->streams[i]->priv_data;
10451 if (sc->id == chapter_track) {
10452 st = s->streams[i];
10453 break;
10454 }
10455 }
10456 if (!st) {
10457 av_log(s, AV_LOG_ERROR, "Referenced QT chapter track not found\n");
10458 continue;
10459 }
10460 sti = ffstream(st);
10461
10462 sc = st->priv_data;
10463 cur_pos = avio_tell(sc->pb);
10464
10467 if (!st->attached_pic.data && sti->nb_index_entries) {
10468 // Retrieve the first frame, if possible
10469 AVIndexEntry *sample = &sti->index_entries[0];
10470 if (avio_seek(sc->pb, sample->pos, SEEK_SET) != sample->pos) {
10471 av_log(s, AV_LOG_ERROR, "Failed to retrieve first frame\n");
10472 goto finish;
10473 }
10474
10475 if (ff_add_attached_pic(s, st, sc->pb, NULL, sample->size) < 0)
10476 goto finish;
10477 }
10478 } else {
10481 st->discard = AVDISCARD_ALL;
10482 for (int i = 0; i < sti->nb_index_entries; i++) {
10484 int64_t end = i+1 < sti->nb_index_entries ? sti->index_entries[i+1].timestamp : st->duration;
10485 uint8_t *title;
10486 uint16_t ch;
10487 int len, title_len;
10488
10489 if (end < sample->timestamp) {
10490 av_log(s, AV_LOG_WARNING, "ignoring stream duration which is shorter than chapters\n");
10491 end = AV_NOPTS_VALUE;
10492 }
10493
10494 if (avio_seek(sc->pb, sample->pos, SEEK_SET) != sample->pos) {
10495 av_log(s, AV_LOG_ERROR, "Chapter %d not found in file\n", i);
10496 goto finish;
10497 }
10498
10499 // the first two bytes are the length of the title
10500 len = avio_rb16(sc->pb);
10501 if (len > sample->size-2)
10502 continue;
10503 title_len = 2*len + 1;
10504 if (!(title = av_mallocz(title_len)))
10505 goto finish;
10506
10507 // The samples could theoretically be in any encoding if there's an encd
10508 // atom following, but in practice are only utf-8 or utf-16, distinguished
10509 // instead by the presence of a BOM
10510 if (!len) {
10511 title[0] = 0;
10512 } else {
10513 ch = avio_rb16(sc->pb);
10514 if (ch == 0xfeff)
10515 avio_get_str16be(sc->pb, len, title, title_len);
10516 else if (ch == 0xfffe)
10517 avio_get_str16le(sc->pb, len, title, title_len);
10518 else {
10519 AV_WB16(title, ch);
10520 if (len == 1 || len == 2)
10521 title[len] = 0;
10522 else
10523 avio_get_str(sc->pb, INT_MAX, title + 2, len - 1);
10524 }
10525 }
10526
10527 avpriv_new_chapter(s, i, st->time_base, sample->timestamp, end, title);
10528 av_freep(&title);
10529 }
10530 }
10531finish:
10532 avio_seek(sc->pb, cur_pos, SEEK_SET);
10533 }
10534}
10535
10537 int64_t value, int flags)
10538{
10539 AVTimecode tc;
10540 char buf[AV_TIMECODE_STR_SIZE];
10541 AVRational rate = st->avg_frame_rate;
10542 int ret = av_timecode_init(&tc, rate, flags, 0, s);
10543 if (ret < 0)
10544 return ret;
10545 av_dict_set(&st->metadata, "timecode",
10546 av_timecode_make_string(&tc, buf, value), 0);
10547 return 0;
10548}
10549
10551{
10552 MOVStreamContext *sc = st->priv_data;
10553 FFStream *const sti = ffstream(st);
10554 char buf[AV_TIMECODE_STR_SIZE];
10555 int64_t cur_pos = avio_tell(sc->pb);
10556 int hh, mm, ss, ff, drop;
10557
10558 if (!sti->nb_index_entries)
10559 return -1;
10560
10561 avio_seek(sc->pb, sti->index_entries->pos, SEEK_SET);
10562 avio_skip(s->pb, 13);
10563 hh = avio_r8(s->pb);
10564 mm = avio_r8(s->pb);
10565 ss = avio_r8(s->pb);
10566 drop = avio_r8(s->pb);
10567 ff = avio_r8(s->pb);
10568 snprintf(buf, AV_TIMECODE_STR_SIZE, "%02d:%02d:%02d%c%02d",
10569 hh, mm, ss, drop ? ';' : ':', ff);
10570 av_dict_set(&st->metadata, "timecode", buf, 0);
10571
10572 avio_seek(sc->pb, cur_pos, SEEK_SET);
10573 return 0;
10574}
10575
10577{
10578 MOVStreamContext *sc = st->priv_data;
10579 FFStream *const sti = ffstream(st);
10580 int flags = 0;
10581 int64_t cur_pos = avio_tell(sc->pb);
10582 int64_t value;
10583 AVRational tc_rate = st->avg_frame_rate;
10584 int tmcd_nb_frames = sc->tmcd_nb_frames;
10585 int rounded_tc_rate;
10586
10587 if (!sti->nb_index_entries)
10588 return -1;
10589
10590 if (!tc_rate.num || !tc_rate.den || !tmcd_nb_frames)
10591 return -1;
10592
10593 avio_seek(sc->pb, sti->index_entries->pos, SEEK_SET);
10594 value = avio_rb32(s->pb);
10595
10596 if (sc->tmcd_flags & 0x0001) flags |= AV_TIMECODE_FLAG_DROPFRAME;
10597 if (sc->tmcd_flags & 0x0002) flags |= AV_TIMECODE_FLAG_24HOURSMAX;
10598 if (sc->tmcd_flags & 0x0004) flags |= AV_TIMECODE_FLAG_ALLOWNEGATIVE;
10599
10600 /* Assume Counter flag is set to 1 in tmcd track (even though it is likely
10601 * not the case) and thus assume "frame number format" instead of QT one.
10602 * No sample with tmcd track can be found with a QT timecode at the moment,
10603 * despite what the tmcd track "suggests" (Counter flag set to 0 means QT
10604 * format). */
10605
10606 /* 60 fps content have tmcd_nb_frames set to 30 but tc_rate set to 60, so
10607 * we multiply the frame number with the quotient.
10608 * See tickets #9492, #9710. */
10609 rounded_tc_rate = (tc_rate.num + tc_rate.den / 2LL) / tc_rate.den;
10610 /* Work around files where tmcd_nb_frames is rounded down from frame rate
10611 * instead of up. See ticket #5978. */
10612 if (tmcd_nb_frames == tc_rate.num / tc_rate.den &&
10613 s->strict_std_compliance < FF_COMPLIANCE_STRICT)
10614 tmcd_nb_frames = rounded_tc_rate;
10615 value = av_rescale(value, rounded_tc_rate, tmcd_nb_frames);
10616
10618
10619 avio_seek(sc->pb, cur_pos, SEEK_SET);
10620 return 0;
10621}
10622
10624 int i;
10625 if (!index || !*index) return;
10626 for (i = 0; i < (*index)->nb_encrypted_samples; i++) {
10627 av_encryption_info_free((*index)->encrypted_samples[i]);
10628 }
10629 av_freep(&(*index)->encrypted_samples);
10630 av_freep(&(*index)->auxiliary_info_sizes);
10631 av_freep(&(*index)->auxiliary_offsets);
10632 av_freep(index);
10633}
10634
10636{
10637 MOVStreamContext *sc = st->priv_data;
10638
10639 if (!sc || --sc->refcount) {
10640 st->priv_data = NULL;
10641 return;
10642 }
10643
10644 av_freep(&sc->tts_data);
10645 for (int i = 0; i < sc->drefs_count; i++) {
10646 av_freep(&sc->drefs[i].path);
10647 av_freep(&sc->drefs[i].dir);
10648 }
10649 av_freep(&sc->drefs);
10650
10651 sc->drefs_count = 0;
10652
10653 if (!sc->pb_is_copied)
10654 ff_format_io_close(s, &sc->pb);
10655
10656 sc->pb = NULL;
10657 av_freep(&sc->chunk_offsets);
10658 av_freep(&sc->stsc_data);
10659 av_freep(&sc->sample_sizes);
10660 av_freep(&sc->keyframes);
10661 av_freep(&sc->ctts_data);
10662 av_freep(&sc->stts_data);
10663 av_freep(&sc->sdtp_data);
10664 av_freep(&sc->stps_data);
10665 av_freep(&sc->elst_data);
10666 av_freep(&sc->rap_group);
10667 av_freep(&sc->sync_group);
10668 av_freep(&sc->sgpd_sync);
10672 av_freep(&sc->index_ranges);
10673 for (int i = 0; i < sc->nb_tref_tags; i++)
10674 av_freep(&sc->tref_tags[i].id);
10675 av_freep(&sc->tref_tags);
10676
10677 if (sc->extradata)
10678 for (int i = 0; i < sc->stsd_count; i++)
10679 av_free(sc->extradata[i]);
10680 av_freep(&sc->extradata);
10682
10686
10687 av_freep(&sc->stereo3d);
10688 av_freep(&sc->spherical);
10689 av_freep(&sc->mastering);
10690 av_freep(&sc->coll);
10691 av_freep(&sc->ambient);
10692
10693#if CONFIG_IAMFDEC
10694 if (sc->iamf)
10696#endif
10697 av_freep(&sc->iamf);
10698}
10699
10701{
10702 MOVContext *mov = s->priv_data;
10703 int i, j;
10704
10705 for (i = 0; i < s->nb_streams; i++) {
10706 AVStream *st = s->streams[i];
10707
10709 }
10710
10711 av_freep(&mov->dv_demux);
10713 mov->dv_fctx = NULL;
10714
10715 if (mov->meta_keys) {
10716 for (i = 1; i < mov->meta_keys_count; i++) {
10717 av_freep(&mov->meta_keys[i]);
10718 }
10719 av_freep(&mov->meta_keys);
10720 }
10721
10722 av_freep(&mov->trex_data);
10723 av_freep(&mov->bitrates);
10724
10725 for (i = 0; i < mov->frag_index.nb_items; i++) {
10727 for (j = 0; j < mov->frag_index.item[i].nb_stream_info; j++) {
10728 mov_free_encryption_index(&frag[j].encryption_index);
10729 }
10731 }
10732 av_freep(&mov->frag_index.item);
10733
10734 av_freep(&mov->aes_decrypt);
10735 av_freep(&mov->chapter_tracks);
10736 for (i = 0; i < mov->nb_heif_item; i++) {
10737 if (!mov->heif_item[i])
10738 continue;
10739 av_freep(&mov->heif_item[i]->name);
10740 av_freep(&mov->heif_item[i]->iref_list);
10742 av_freep(&mov->heif_item[i]);
10743 }
10744 av_freep(&mov->heif_item);
10745 for (i = 0; i < mov->nb_heif_grid; i++) {
10749 }
10750 av_freep(&mov->heif_grid);
10751
10752 return 0;
10753}
10754
10755static int tmcd_is_referenced(AVFormatContext *s, int tmcd_id)
10756{
10757 int i;
10758
10759 for (i = 0; i < s->nb_streams; i++) {
10760 AVStream *st = s->streams[i];
10761 MOVStreamContext *sc = st->priv_data;
10762 MovTref *tag = mov_find_tref_tag(sc, MKTAG('t','m','c','d'));
10763
10764 if (!tag)
10765 continue;
10766 if (mov_find_tref_id(tag, tmcd_id))
10767 return 1;
10768 }
10769 return 0;
10770}
10771
10772/* look for a tmcd track not referenced by any video track, and export it globally */
10774{
10775 int i;
10776
10777 for (i = 0; i < s->nb_streams; i++) {
10778 AVStream *st = s->streams[i];
10779
10780 if (st->codecpar->codec_tag == MKTAG('t','m','c','d') &&
10781 !tmcd_is_referenced(s, st->id)) {
10782 AVDictionaryEntry *tcr = av_dict_get(st->metadata, "timecode", NULL, 0);
10783 if (tcr) {
10784 av_dict_set(&s->metadata, "timecode", tcr->value, 0);
10785 break;
10786 }
10787 }
10788 }
10789}
10790
10792{
10793 int version, fieldlength, i, j;
10795 uint32_t size = avio_rb32(f);
10796 unsigned track_id, item_count;
10797
10798 if (avio_rb32(f) != MKBETAG('t', 'f', 'r', 'a')) {
10799 return 1;
10800 }
10801 av_log(mov->fc, AV_LOG_VERBOSE, "found tfra\n");
10802
10803 version = avio_r8(f);
10804 avio_rb24(f);
10805 track_id = avio_rb32(f);
10806 fieldlength = avio_rb32(f);
10807 item_count = avio_rb32(f);
10808 for (i = 0; i < item_count; i++) {
10809 int64_t time, offset;
10810 int index;
10811 MOVFragmentStreamInfo * frag_stream_info;
10812
10813 if (avio_feof(f)) {
10814 return AVERROR_INVALIDDATA;
10815 }
10816
10817 if (version == 1) {
10818 time = avio_rb64(f);
10819 offset = avio_rb64(f);
10820 } else {
10821 time = avio_rb32(f);
10822 offset = avio_rb32(f);
10823 }
10824
10825 // The first sample of each stream in a fragment is always a random
10826 // access sample. So it's entry in the tfra can be used as the
10827 // initial PTS of the fragment.
10829 frag_stream_info = get_frag_stream_info(&mov->frag_index, index, track_id);
10830 if (frag_stream_info &&
10831 frag_stream_info->first_tfra_pts == AV_NOPTS_VALUE)
10832 frag_stream_info->first_tfra_pts = time;
10833
10834 for (j = 0; j < ((fieldlength >> 4) & 3) + 1; j++)
10835 avio_r8(f);
10836 for (j = 0; j < ((fieldlength >> 2) & 3) + 1; j++)
10837 avio_r8(f);
10838 for (j = 0; j < ((fieldlength >> 0) & 3) + 1; j++)
10839 avio_r8(f);
10840 }
10841
10842 avio_seek(f, pos + size, SEEK_SET);
10843 return 0;
10844}
10845
10847{
10848 int64_t stream_size = avio_size(f);
10849 int64_t original_pos = avio_tell(f);
10850 int64_t seek_ret;
10851 int ret = -1;
10852 if ((seek_ret = avio_seek(f, stream_size - 4, SEEK_SET)) < 0) {
10853 ret = seek_ret;
10854 goto fail;
10855 }
10856 c->mfra_size = avio_rb32(f);
10857 c->have_read_mfra_size = 1;
10858 if (!c->mfra_size || c->mfra_size > stream_size) {
10859 av_log(c->fc, AV_LOG_DEBUG, "doesn't look like mfra (unreasonable size)\n");
10860 goto fail;
10861 }
10862 if ((seek_ret = avio_seek(f, -((int64_t) c->mfra_size), SEEK_CUR)) < 0) {
10863 ret = seek_ret;
10864 goto fail;
10865 }
10866 if (avio_rb32(f) != c->mfra_size) {
10867 av_log(c->fc, AV_LOG_DEBUG, "doesn't look like mfra (size mismatch)\n");
10868 goto fail;
10869 }
10870 if (avio_rb32(f) != MKBETAG('m', 'f', 'r', 'a')) {
10871 av_log(c->fc, AV_LOG_DEBUG, "doesn't look like mfra (tag mismatch)\n");
10872 goto fail;
10873 }
10874 av_log(c->fc, AV_LOG_VERBOSE, "stream has mfra\n");
10875 do {
10876 ret = read_tfra(c, f);
10877 if (ret < 0)
10878 goto fail;
10879 } while (!ret);
10880 ret = 0;
10881 c->frag_index.complete = 1;
10882fail:
10883 seek_ret = avio_seek(f, original_pos, SEEK_SET);
10884 if (seek_ret < 0) {
10885 av_log(c->fc, AV_LOG_ERROR,
10886 "failed to seek back after looking for mfra\n");
10887 ret = seek_ret;
10888 }
10889 return ret;
10890}
10891
10892static int set_icc_profile_from_item(AVPacketSideData **coded_side_data, int *nb_coded_side_data,
10893 const HEIFItem *item)
10894{
10895 AVPacketSideData *sd = av_packet_side_data_new(coded_side_data, nb_coded_side_data,
10897 item->icc_profile_size, 0);
10898 if (!sd)
10899 return AVERROR(ENOMEM);
10900
10901 memcpy(sd->data, item->icc_profile, item->icc_profile_size);
10902
10903 return 0;
10904}
10905
10906static int set_display_matrix_from_item(AVPacketSideData **coded_side_data, int *nb_coded_side_data,
10907 const HEIFItem *item)
10908{
10909 int32_t *matrix;
10910 AVPacketSideData *sd = av_packet_side_data_new(coded_side_data,
10911 nb_coded_side_data,
10913 9 * sizeof(*matrix), 0);
10914 if (!sd)
10915 return AVERROR(ENOMEM);
10916
10917 matrix = (int32_t*)sd->data;
10918 /* rotation is in the counter-clockwise direction whereas
10919 * av_display_rotation_set() expects its argument to be
10920 * oriented clockwise, so we need to negate it. */
10923
10924 return 0;
10925}
10926
10928 AVStreamGroupTileGrid *tile_grid)
10929{
10930 MOVContext *c = s->priv_data;
10931 const HEIFItem *item = grid->item;
10932 int64_t coded_width = 0, coded_height = 0;
10933 int64_t offset = 0, pos = avio_tell(s->pb);
10934 int64_t x = 0, y = 0;
10935 int i = 0;
10936 int tile_rows, tile_cols;
10937 int flags, size;
10938
10939 if (!(s->pb->seekable & AVIO_SEEKABLE_NORMAL)) {
10940 av_log(c->fc, AV_LOG_INFO, "grid box with non seekable input\n");
10941 return AVERROR_PATCHWELCOME;
10942 }
10943 if (item->is_idat_relative) {
10944 if (!c->idat_offset) {
10945 av_log(c->fc, AV_LOG_ERROR, "missing idat box required by the image grid\n");
10946 return AVERROR_INVALIDDATA;
10947 }
10948 offset = c->idat_offset;
10949 }
10950
10951 if (offset > INT64_MAX - item->extent_offset)
10952 return AVERROR_INVALIDDATA;
10953
10954 avio_seek(s->pb, item->extent_offset + offset, SEEK_SET);
10955
10956 avio_r8(s->pb); /* version */
10957 flags = avio_r8(s->pb);
10958
10959 tile_rows = avio_r8(s->pb) + 1;
10960 tile_cols = avio_r8(s->pb) + 1;
10961 /* actual width and height of output image */
10962 tile_grid->width = (flags & 1) ? avio_rb32(s->pb) : avio_rb16(s->pb);
10963 tile_grid->height = (flags & 1) ? avio_rb32(s->pb) : avio_rb16(s->pb);
10964
10965 av_log(c->fc, AV_LOG_TRACE, "grid: grid_rows %d grid_cols %d output_width %d output_height %d\n",
10966 tile_rows, tile_cols, tile_grid->width, tile_grid->height);
10967
10968 avio_seek(s->pb, pos, SEEK_SET);
10969
10971 tile_grid->nb_tiles = grid->nb_tiles;
10972
10973 if (tile_grid->nb_tiles != size)
10974 return AVERROR_INVALIDDATA;
10975
10976 for (int i = 0; i < tile_cols; i++)
10977 coded_width += grid->tile_item_list[i]->width;
10978 for (int i = 0; i < size; i += tile_cols)
10979 coded_height += grid->tile_item_list[i]->height;
10980
10981 if (coded_width > INT_MAX || coded_height > INT_MAX)
10982 return AVERROR_INVALIDDATA;
10983
10984 tile_grid->coded_width = coded_width;
10985 tile_grid->coded_height = coded_height;
10986
10987 tile_grid->offsets = av_calloc(tile_grid->nb_tiles, sizeof(*tile_grid->offsets));
10988 if (!tile_grid->offsets)
10989 return AVERROR(ENOMEM);
10990
10991 while (y < tile_grid->coded_height) {
10992 int left_col = i;
10993
10994 while (x < tile_grid->coded_width) {
10995 if (i == tile_grid->nb_tiles)
10996 return AVERROR_INVALIDDATA;
10997
10998 tile_grid->offsets[i].idx = grid->tile_idx_list[i];
10999 tile_grid->offsets[i].horizontal = x;
11000 tile_grid->offsets[i].vertical = y;
11001
11002 x += grid->tile_item_list[i++]->width;
11003 }
11004
11005 if (x > tile_grid->coded_width) {
11006 av_log(c->fc, AV_LOG_ERROR, "Non uniform HEIF tiles\n");
11007 return AVERROR_INVALIDDATA;
11008 }
11009
11010 x = 0;
11011 y += grid->tile_item_list[left_col]->height;
11012 }
11013
11014 if (y > tile_grid->coded_height || i != tile_grid->nb_tiles) {
11015 av_log(c->fc, AV_LOG_ERROR, "Non uniform HEIF tiles\n");
11016 return AVERROR_INVALIDDATA;
11017 }
11018
11019 return 0;
11020}
11021
11023 AVStreamGroupTileGrid *tile_grid)
11024{
11025 MOVContext *c = s->priv_data;
11026 const HEIFItem *item = grid->item;
11027 uint16_t canvas_fill_value[4];
11028 int64_t offset = 0, pos = avio_tell(s->pb);
11029 int ret = 0, flags;
11030
11031 if (!(s->pb->seekable & AVIO_SEEKABLE_NORMAL)) {
11032 av_log(c->fc, AV_LOG_INFO, "iovl box with non seekable input\n");
11033 return AVERROR_PATCHWELCOME;
11034 }
11035 if (item->is_idat_relative) {
11036 if (!c->idat_offset) {
11037 av_log(c->fc, AV_LOG_ERROR, "missing idat box required by the image overlay\n");
11038 return AVERROR_INVALIDDATA;
11039 }
11040 offset = c->idat_offset;
11041 }
11042
11043 if (offset > INT64_MAX - item->extent_offset)
11044 return AVERROR_INVALIDDATA;
11045
11046 avio_seek(s->pb, item->extent_offset + offset, SEEK_SET);
11047
11048 avio_r8(s->pb); /* version */
11049 flags = avio_r8(s->pb);
11050
11051 for (int i = 0; i < 4; i++)
11052 canvas_fill_value[i] = avio_rb16(s->pb);
11053 av_log(c->fc, AV_LOG_TRACE, "iovl: canvas_fill_value { %u, %u, %u, %u }\n",
11054 canvas_fill_value[0], canvas_fill_value[1],
11055 canvas_fill_value[2], canvas_fill_value[3]);
11056 for (int i = 0; i < 4; i++)
11057 tile_grid->background[i] = canvas_fill_value[i];
11058
11059 /* actual width and height of output image */
11060 tile_grid->width =
11061 tile_grid->coded_width = (flags & 1) ? avio_rb32(s->pb) : avio_rb16(s->pb);
11062 tile_grid->height =
11063 tile_grid->coded_height = (flags & 1) ? avio_rb32(s->pb) : avio_rb16(s->pb);
11064
11065 av_log(c->fc, AV_LOG_TRACE, "iovl: output_width %d, output_height %d\n",
11066 tile_grid->width, tile_grid->height);
11067
11068 tile_grid->nb_tiles = grid->nb_tiles;
11069 tile_grid->offsets = av_malloc_array(tile_grid->nb_tiles, sizeof(*tile_grid->offsets));
11070 if (!tile_grid->offsets) {
11071 ret = AVERROR(ENOMEM);
11072 goto fail;
11073 }
11074
11075 for (int i = 0; i < tile_grid->nb_tiles; i++) {
11076 tile_grid->offsets[i].idx = grid->tile_idx_list[i];
11077 tile_grid->offsets[i].horizontal = (flags & 1) ? avio_rb32(s->pb) : avio_rb16(s->pb);
11078 tile_grid->offsets[i].vertical = (flags & 1) ? avio_rb32(s->pb) : avio_rb16(s->pb);
11079 av_log(c->fc, AV_LOG_TRACE, "iovl: stream_idx[%d] %u, "
11080 "horizontal_offset[%d] %d, vertical_offset[%d] %d\n",
11081 i, tile_grid->offsets[i].idx,
11082 i, tile_grid->offsets[i].horizontal, i, tile_grid->offsets[i].vertical);
11083 }
11084
11085fail:
11086 avio_seek(s->pb, pos, SEEK_SET);
11087
11088 return ret;
11089}
11090
11092 AVPacketSideData **coded_side_data, int *nb_coded_side_data,
11093 const HEIFItem *ref)
11094{
11095 MOVContext *c = s->priv_data;
11096 AVPacketSideData *sd;
11097 AVExifMetadata ifd = { 0 };
11098 AVBufferRef *buf;
11099 int64_t offset = 0, pos = avio_tell(s->pb);
11100 unsigned orientation_id = av_exif_get_tag_id("Orientation");
11101 int err;
11102
11103 if (!(s->pb->seekable & AVIO_SEEKABLE_NORMAL)) {
11104 av_log(c->fc, AV_LOG_WARNING, "Exif metadata with non seekable input\n");
11105 return AVERROR_PATCHWELCOME;
11106 }
11107 if (ref->is_idat_relative) {
11108 if (!c->idat_offset) {
11109 av_log(c->fc, AV_LOG_ERROR, "missing idat box required by the Exif metadata\n");
11110 return AVERROR_INVALIDDATA;
11111 }
11112 offset = c->idat_offset;
11113 }
11114
11115 buf = av_buffer_alloc(ref->extent_length);
11116 if (!buf)
11117 return AVERROR(ENOMEM);
11118
11119 if (offset > INT64_MAX - ref->extent_offset) {
11120 err = AVERROR(ENOMEM);
11121 goto fail;
11122 }
11123
11124 avio_seek(s->pb, ref->extent_offset + offset, SEEK_SET);
11125 err = avio_read(s->pb, buf->data, ref->extent_length);
11126 if (err != ref->extent_length) {
11127 if (err > 0)
11128 err = AVERROR_INVALIDDATA;
11129 goto fail;
11130 }
11131
11132 // HEIF spec states that Exif metadata is informative. The irot item property is
11133 // the normative source of rotation information. So we remove any Orientation tag
11134 // present in the Exif buffer.
11135 err = av_exif_parse_buffer(s, buf->data, ref->extent_length, &ifd, AV_EXIF_T_OFF);
11136 if (err < 0) {
11137 av_log(s, AV_LOG_ERROR, "Unable to parse Exif metadata\n");
11138 goto fail;
11139 }
11140
11141 err = av_exif_remove_entry(s, &ifd, orientation_id, 0);
11142 if (err < 0)
11143 goto fail;
11144 else if (!err)
11145 goto finish;
11146
11147 av_buffer_unref(&buf);
11148 err = av_exif_write(s, &ifd, &buf, AV_EXIF_T_OFF);
11149 if (err < 0)
11150 goto fail;
11151
11152finish:
11153 offset = AV_RB32(buf->data) + 4;
11154 if (offset >= buf->size) {
11155 err = AVERROR_INVALIDDATA;
11156 goto fail;
11157 }
11158 sd = av_packet_side_data_new(coded_side_data, nb_coded_side_data,
11159 AV_PKT_DATA_EXIF, buf->size - offset, 0);
11160 if (!sd) {
11161 err = AVERROR(ENOMEM);
11162 goto fail;
11163 }
11164 memcpy(sd->data, buf->data + offset, buf->size - offset);
11165
11166 err = 0;
11167fail:
11168 av_buffer_unref(&buf);
11169 av_exif_free(&ifd);
11170 avio_seek(s->pb, pos, SEEK_SET);
11171
11172 return err;
11173}
11174
11176{
11177 MOVContext *mov = s->priv_data;
11178
11179 for (int i = 0; i < mov->nb_heif_grid; i++) {
11181 AVStreamGroupTileGrid *tile_grid;
11182 const HEIFGrid *grid = &mov->heif_grid[i];
11183 int err, loop = 1;
11184
11185 if (!stg)
11186 return AVERROR(ENOMEM);
11187
11188 stg->id = grid->item->item_id;
11189 tile_grid = stg->params.tile_grid;
11190
11191 for (int j = 0; j < grid->nb_tiles; j++) {
11192 int tile_id = grid->tile_id_list[j];
11193 int k;
11194
11195 for (k = 0; k < mov->nb_heif_item; k++) {
11196 HEIFItem *item = mov->heif_item[k];
11197 AVStream *st;
11198
11199 if (!item || item->item_id != tile_id)
11200 continue;
11201 st = item->st;
11202 if (!st) {
11203 av_log(s, AV_LOG_WARNING, "HEIF item id %d from grid id %d doesn't "
11204 "reference a stream\n",
11205 tile_id, grid->item->item_id);
11207 loop = 0;
11208 break;
11209 }
11210
11211 grid->tile_item_list[j] = item;
11212 grid->tile_idx_list[j] = stg->nb_streams;
11213
11214 err = avformat_stream_group_add_stream(stg, st);
11215 if (err < 0) {
11216 int l;
11217 if (err != AVERROR(EEXIST))
11218 return err;
11219
11220 for (l = 0; l < stg->nb_streams; l++)
11221 if (stg->streams[l]->index == st->index)
11222 break;
11223 av_assert0(l < stg->nb_streams);
11224 grid->tile_idx_list[j] = l;
11225 }
11226
11227 if (item->item_id != mov->primary_item_id)
11229 break;
11230 }
11231
11232 if (k == mov->nb_heif_item) {
11234 av_log(s, AV_LOG_WARNING, "HEIF item id %d referenced by grid id %d doesn't "
11235 "exist\n",
11236 tile_id, grid->item->item_id);
11238 loop = 0;
11239 }
11240 if (!loop)
11241 break;
11242 }
11243
11244 if (!loop)
11245 continue;
11246
11247 switch (grid->item->type) {
11248 case MKTAG('g','r','i','d'):
11249 err = read_image_grid(s, grid, tile_grid);
11250 break;
11251 case MKTAG('i','o','v','l'):
11252 err = read_image_iovl(s, grid, tile_grid);
11253 break;
11254 default:
11255 av_assert0(0);
11256 }
11257 if (err < 0)
11258 return err;
11259
11260 for (int j = 0; j < grid->item->nb_iref_list; j++) {
11261 HEIFItem *ref = get_heif_item(mov, grid->item->iref_list[j].item_id);
11262
11263 av_assert0(ref);
11264 switch(ref->type) {
11265 case MKTAG('E','x','i','f'):
11266 err = mov_parse_exif_item(s, &tile_grid->coded_side_data,
11267 &tile_grid->nb_coded_side_data, ref);
11268 if (err < 0 && (s->error_recognition & AV_EF_EXPLODE))
11269 return err;
11270 break;
11271 default:
11272 break;
11273 }
11274 }
11275
11276 /* rotation */
11277 if (grid->item->rotation || grid->item->hflip || grid->item->vflip) {
11279 &tile_grid->nb_coded_side_data, grid->item);
11280 if (err < 0)
11281 return err;
11282 }
11283
11284 /* ICC profile */
11285 if (grid->item->icc_profile_size) {
11287 &tile_grid->nb_coded_side_data, grid->item);
11288 if (err < 0)
11289 return err;
11290 }
11291
11292 if (grid->item->name)
11293 av_dict_set(&stg->metadata, "title", grid->item->name, 0);
11294 if (grid->item->item_id == mov->primary_item_id)
11296 }
11297
11298 return 0;
11299}
11300
11302{
11303 MOVContext *mov = s->priv_data;
11304 int err;
11305
11306 for (int i = 0; i < mov->nb_heif_item; i++) {
11307 HEIFItem *item = mov->heif_item[i];
11308 MOVStreamContext *sc;
11309 AVStream *st;
11310 int64_t offset = 0;
11311
11312 if (!item)
11313 continue;
11314 if (!item->st) {
11315 continue;
11316 }
11317 if (item->is_idat_relative) {
11318 if (!mov->idat_offset) {
11319 av_log(s, AV_LOG_ERROR, "Missing idat box for item %d\n", item->item_id);
11320 return AVERROR_INVALIDDATA;
11321 }
11322 offset = mov->idat_offset;
11323 }
11324
11325 st = item->st;
11326 sc = st->priv_data;
11327 st->codecpar->width = item->width;
11328 st->codecpar->height = item->height;
11329
11330 sc->sample_size = sc->stsz_sample_size = item->extent_length;
11331 sc->sample_count = 1;
11332
11333 err = sanity_checks(s, sc, st->index);
11334 if (err)
11335 return AVERROR_INVALIDDATA;
11336
11337 if (offset > INT64_MAX - item->extent_offset)
11338 return AVERROR_INVALIDDATA;
11339
11340 sc->chunk_offsets[0] = item->extent_offset + offset;
11341
11342 if (item->item_id == mov->primary_item_id)
11344
11345 for (int j = 0; j < item->nb_iref_list; j++) {
11346 HEIFItem *ref = get_heif_item(mov, item->iref_list[j].item_id);
11347
11348 av_assert0(ref);
11349 switch(ref->type) {
11350 case MKTAG('E','x','i','f'):
11353 if (err < 0 && (s->error_recognition & AV_EF_EXPLODE))
11354 return err;
11355 break;
11356 default:
11357 break;
11358 }
11359 }
11360
11361 if (item->rotation || item->hflip || item->vflip) {
11363 &st->codecpar->nb_coded_side_data, item);
11364 if (err < 0)
11365 return err;
11366 }
11367
11368 mov_build_index(mov, st);
11369 }
11370
11371 if (mov->nb_heif_grid) {
11372 err = mov_parse_tiles(s);
11373 if (err < 0)
11374 return err;
11375 }
11376
11377 return 0;
11378}
11379
11381{
11382 int err;
11383
11384 for (int i = 0; i < s->nb_streams; i++) {
11385 AVStreamGroup *stg;
11386 const AVDictionaryEntry *tcr;
11387 AVStream *st = s->streams[i];
11388
11389 if (st->codecpar->codec_tag != MKTAG('t','m','c','d'))
11390 continue;
11391
11393 if (!stg)
11394 return AVERROR(ENOMEM);
11395
11396 stg->id = st->id;
11397 tcr = av_dict_get(st->metadata, "timecode", NULL, 0);
11398
11399 for (int j = 0; j < s->nb_streams; j++) {
11400 AVStream *st2 = s->streams[j];
11401 MOVStreamContext *sc2 = st2->priv_data;
11402 MovTref *tag = mov_find_tref_tag(sc2, MKTAG('t','m','c','d'));
11403
11404 if (!tag)
11405 continue;
11406
11407 for (int k = 0; k < tag->nb_id; k++) {
11408 if (tag->id[k] != st->id)
11409 continue;
11410
11411 err = avformat_stream_group_add_stream(stg, st2);
11412 if (err < 0)
11413 return err;
11414
11415 if (tcr)
11416 av_dict_set(&st2->metadata, "timecode", tcr->value, AV_DICT_DONT_OVERWRITE);
11417 }
11418 }
11419
11420 if (!stg->nb_streams) {
11422 continue;
11423 }
11424
11425 err = avformat_stream_group_add_stream(stg, st);
11426 if (err < 0)
11427 return err;
11428
11429 stg->params.tref->metadata_index = stg->nb_streams - 1;
11430 }
11432
11433 return 0;
11434}
11435
11437 uint32_t *tref_id, int nb_tref_id, int first_index)
11438{
11439 if (!nb_tref_id)
11440 return NULL;
11441
11442 for (int i = first_index; i < s->nb_streams; i++)
11443 for (int j = 0; j < nb_tref_id; j++)
11444 if (s->streams[i]->index != st->index &&
11445 s->streams[i]->id == tref_id[j])
11446 return s->streams[i];
11447
11448 return NULL;
11449}
11450
11452{
11453 static const uint32_t tref_tags[] = {
11454 MKTAG('c','d','s','c'),
11455 MKTAG('r','n','d','r'),
11456 };
11457
11458 int err;
11459
11460 // Don't try to add a group if there's only one track
11461 if (s->nb_streams <= 1)
11462 return 0;
11463
11464 for (int i = 0; i < s->nb_streams; i++) {
11465 AVStream *st = s->streams[i];
11466 MOVStreamContext *sc = st->priv_data;
11467
11468 for (int c = 0; c < FF_ARRAY_ELEMS(tref_tags); c++) {
11469 AVStreamGroup *stg;
11470 AVStream *st_ref;
11471 MovTref *tag = mov_find_tref_tag(sc, tref_tags[c]);
11472
11473 if (!tag)
11474 continue;
11475
11476 st_ref = mov_find_reference_track(s, st, tag->id, tag->nb_id, 0);
11477 if (!st_ref) {
11478 av_log(s, AV_LOG_WARNING, "Failed to find referenced stream\n");
11479 continue;
11480 }
11481
11483 if (!stg)
11484 return AVERROR(ENOMEM);
11485
11486 stg->id = st_ref->id;
11487
11488 err = avformat_stream_group_add_stream(stg, st_ref);
11489 if (err < 0)
11490 return err;
11491
11492 err = avformat_stream_group_add_stream(stg, st);
11493 if (err < 0)
11494 return err;
11495
11496 stg->params.tref->metadata_index = stg->nb_streams - 1;
11497 }
11498 }
11499
11500 return 0;
11501}
11502
11504{
11505 int err;
11506
11507 // Don't try to add a group if there's only one track
11508 if (s->nb_streams <= 1)
11509 return 0;
11510
11511 for (int i = 0; i < s->nb_streams; i++) {
11512 AVStreamGroup *stg;
11513 AVStream *st = s->streams[i];
11514 AVStream *st_base;
11515 MOVStreamContext *sc = st->priv_data;
11516 MovTref *tag = mov_find_tref_tag(sc, MKTAG('s','b','a','s'));
11517 int j = 0;
11518
11519 /* Find an enhancement stream. */
11520 if (st->codecpar->codec_id != AV_CODEC_ID_LCEVC || !tag)
11521 continue;
11522
11524 if (!stg)
11525 return AVERROR(ENOMEM);
11526
11527 stg->id = st->id;
11530
11531 while (st_base = mov_find_reference_track(s, st, tag->id, tag->nb_id, j)) {
11532 err = avformat_stream_group_add_stream(stg, st_base);
11533 if (err < 0)
11534 return err;
11535
11536 j = st_base->index + 1;
11537 }
11538 if (!j) {
11539 int loglevel = (s->error_recognition & AV_EF_EXPLODE) ? AV_LOG_ERROR : AV_LOG_WARNING;
11540 av_log(s, loglevel, "Failed to find base stream for LCEVC stream\n");
11542 if (s->error_recognition & AV_EF_EXPLODE)
11543 return AVERROR_INVALIDDATA;
11544 continue;
11545 }
11546
11547 err = avformat_stream_group_add_stream(stg, st);
11548 if (err < 0)
11549 return err;
11550
11551 stg->params.layered_video->el_index = stg->nb_streams - 1;
11552 }
11553
11554 return 0;
11555}
11556
11558{
11559 int err;
11560
11561 if (s->nb_streams <= 1)
11562 return 0;
11563
11564 /* Identify legacy dual-track Dolby Vision profile 7 carriage per Annex
11565 * C of "Dolby Vision Streams Within the ISO Base Media File Format",
11566 * v2.7.1. The 'vdep' track reference type is shared with depth video
11567 * and multi-view dependencies. The spec-mandated DV-specific sample
11568 * entry combined with the dvcC configuration record disambiguates
11569 * those uses. */
11570 for (int i = 0; i < s->nb_streams; i++) {
11571 AVStreamGroup *stg;
11572 AVStream *st = s->streams[i];
11573 AVStream *st_base;
11574 MOVStreamContext *sc = st->priv_data;
11575 MovTref *tag = mov_find_tref_tag(sc, MKTAG('v','d','e','p'));
11576 const AVPacketSideData *sd;
11578
11579 if (st->codecpar->codec_id != AV_CODEC_ID_HEVC || !tag)
11580 continue;
11581
11582 if (st->codecpar->codec_tag != MKTAG('d','v','h','e') &&
11583 st->codecpar->codec_tag != MKTAG('d','v','h','1'))
11584 continue;
11585
11589 if (!sd)
11590 continue;
11591 dovi = (const AVDOVIDecoderConfigurationRecord *)sd->data;
11592
11593 /* EL track of a dual-track stream: rpu_present_flag = 1,
11594 * el_present_flag = 1, bl_present_flag = 0, dv_profile = 7. */
11595 if (dovi->dv_profile != 7 || !dovi->rpu_present_flag ||
11596 !dovi->el_present_flag || dovi->bl_present_flag)
11597 continue;
11598
11599 st_base = mov_find_reference_track(s, st, tag->id, tag->nb_id, 0);
11600 if (!st_base) {
11601 int loglevel = (s->error_recognition & AV_EF_EXPLODE) ? AV_LOG_ERROR : AV_LOG_WARNING;
11602 av_log(s, loglevel, "Failed to find base layer for Dolby Vision EL stream\n");
11603 if (s->error_recognition & AV_EF_EXPLODE)
11604 return AVERROR_INVALIDDATA;
11605 continue;
11606 }
11607
11609 if (!stg)
11610 return AVERROR(ENOMEM);
11611
11612 stg->id = st->id;
11613
11614 err = avformat_stream_group_add_stream(stg, st_base);
11615 if (err < 0)
11616 return err;
11617
11618 err = avformat_stream_group_add_stream(stg, st);
11619 if (err < 0)
11620 return err;
11621
11622 stg->params.layered_video->el_index = stg->nb_streams - 1;
11623 stg->params.layered_video->width = st_base->codecpar->width;
11624 stg->params.layered_video->height = st_base->codecpar->height;
11625 }
11626
11627 return 0;
11628}
11629
11631{
11632 int highest_id = 0, lowest_iamf_id = INT_MAX;
11633
11634 for (int i = 0; i < s->nb_streams; i++) {
11635 const AVStream *st = s->streams[i];
11636 const MOVStreamContext *sc = st->priv_data;
11637 if (!sc->iamf)
11638 highest_id = FFMAX(highest_id, st->id);
11639 }
11640
11641 for (int i = 0; i < s->nb_stream_groups; i++) {
11642 AVStreamGroup *stg = s->stream_groups[i];
11644 continue;
11645 for (int j = 0; j < stg->nb_streams; j++) {
11646 AVStream *st = stg->streams[j];
11647 lowest_iamf_id = FFMIN(lowest_iamf_id, st->id);
11648 }
11649 }
11650
11651 if (highest_id < lowest_iamf_id)
11652 return;
11653
11654 highest_id += !lowest_iamf_id;
11655 for (int i = 0; highest_id > 1 && i < s->nb_stream_groups; i++) {
11656 AVStreamGroup *stg = s->stream_groups[i];
11658 continue;
11659 for (int j = 0; j < stg->nb_streams; j++) {
11660 AVStream *st = stg->streams[j];
11661 MOVStreamContext *sc = st->priv_data;
11662 st->id += highest_id;
11663 sc->iamf_stream_offset = highest_id;
11664 }
11665 }
11666}
11667
11669{
11670 MOVContext *mov = s->priv_data;
11671 AVIOContext *pb = s->pb;
11672 int j, err;
11673 MOVAtom atom = { AV_RL32("root") };
11674 int i;
11675
11676 mov->fc = s;
11677 mov->trak_index = -1;
11678 mov->primary_item_id = -1;
11679 mov->cur_item_id = -1;
11680 /* .mov and .mp4 aren't streamable anyway (only progressive download if moov is before mdat) */
11682 atom.size = avio_size(pb);
11683 else
11684 atom.size = INT64_MAX;
11685
11686 /* check MOV header */
11687 do {
11688 if (mov->moov_retry)
11689 avio_seek(pb, 0, SEEK_SET);
11690 if ((err = mov_read_default(mov, pb, atom)) < 0) {
11691 av_log(s, AV_LOG_ERROR, "error reading header\n");
11692 return err;
11693 }
11694 } while ((pb->seekable & AVIO_SEEKABLE_NORMAL) &&
11695 !mov->found_moov && (!mov->found_iloc || !mov->found_iinf) && !mov->moov_retry++);
11696 if (!mov->found_moov && !mov->found_iloc && !mov->found_iinf) {
11697 av_log(s, AV_LOG_ERROR, "moov atom not found\n");
11698 return AVERROR_INVALIDDATA;
11699 }
11700 av_log(mov->fc, AV_LOG_TRACE, "on_parse_exit_offset=%"PRId64"\n", avio_tell(pb));
11701
11702 if (mov->found_iloc && mov->found_iinf) {
11703 err = mov_parse_heif_items(s);
11704 if (err < 0)
11705 return err;
11706 }
11707 // prevent iloc and iinf boxes from being parsed while reading packets.
11708 // this is needed because an iinf box may have been parsed but ignored
11709 // for having old infe boxes which create no streams.
11710 mov->found_iloc = mov->found_iinf = 1;
11711
11712 if (pb->seekable & AVIO_SEEKABLE_NORMAL) {
11713 if (mov->nb_chapter_tracks > 0 && !mov->ignore_chapters)
11715 for (i = 0; i < s->nb_streams; i++)
11716 if (s->streams[i]->codecpar->codec_tag == AV_RL32("tmcd")) {
11717 mov_read_timecode_track(s, s->streams[i]);
11718 } else if (s->streams[i]->codecpar->codec_tag == AV_RL32("rtmd")) {
11719 mov_read_rtmd_track(s, s->streams[i]);
11720 }
11721 }
11722
11723 /* Create metadata stream groups. */
11725 if (err < 0)
11726 return err;
11727
11728 /* copy timecode metadata from tmcd tracks to the related video streams */
11730 if (err < 0)
11731 return err;
11732
11733 /* Create LCEVC stream groups. */
11735 if (err < 0)
11736 return err;
11737
11738 /* Create Dolby Vision Profile 7 stream groups. */
11740 if (err < 0)
11741 return err;
11742
11743 for (i = 0; i < s->nb_streams; i++) {
11744 AVStream *st = s->streams[i];
11745 FFStream *const sti = ffstream(st);
11746 MOVStreamContext *sc = st->priv_data;
11747 uint32_t dvdsub_clut[FF_DVDCLUT_CLUT_LEN] = {0};
11748 fix_timescale(mov, sc);
11749
11750 /* Set the primary extradata based on the first Sample if it doesn't reference the first stsd entry. */
11751 if (sc->stsc_count && sc->extradata_size && !sc->iamf &&
11752 sc->stsc_data[0].id > 1 && sc->stsc_data[0].id <= sc->stsd_count) {
11753 sc->last_stsd_index = sc->stsc_data[0].id - 1;
11756 if (sc->extradata_size[sc->last_stsd_index]) {
11758 if (!st->codecpar->extradata)
11759 return AVERROR(ENOMEM);
11761 }
11762 }
11763
11767 }
11770 sc->time_scale*(int64_t)sc->nb_frames_for_fps, sc->duration_for_fps, INT_MAX);
11772 if (st->codecpar->width <= 0 || st->codecpar->height <= 0) {
11773 st->codecpar->width = sc->width;
11774 st->codecpar->height = sc->height;
11775 }
11778
11779 for (j = 0; j < FF_DVDCLUT_CLUT_LEN; j++)
11780 dvdsub_clut[j] = AV_RB32(st->codecpar->extradata + j * 4);
11781
11782 err = ff_dvdclut_yuv_to_rgb(dvdsub_clut, FF_DVDCLUT_CLUT_SIZE);
11783 if (err < 0)
11784 return err;
11785
11787 st->codecpar->extradata_size = 0;
11788
11790 st->codecpar);
11791 if (err < 0)
11792 return err;
11793 }
11794 }
11795 if (mov->handbrake_version &&
11796 mov->handbrake_version <= 1000000*0 + 1000*10 + 2 && // 0.10.2
11798 av_log(s, AV_LOG_VERBOSE, "Forcing full parsing for mp3 stream\n");
11800 }
11801 }
11802
11803 if (mov->trex_data || mov->use_mfra_for > 0) {
11804 for (i = 0; i < s->nb_streams; i++) {
11805 AVStream *st = s->streams[i];
11806 MOVStreamContext *sc = st->priv_data;
11807 if (sc->duration_for_fps > 0) {
11808 /* Akin to sc->data_size * 8 * sc->time_scale / sc->duration_for_fps but accounting for overflows. */
11810 if (st->codecpar->bit_rate == INT64_MIN) {
11811 av_log(s, AV_LOG_WARNING, "Overflow during bit rate calculation %"PRId64" * 8 * %d\n",
11812 sc->data_size, sc->time_scale);
11813 st->codecpar->bit_rate = 0;
11814 if (s->error_recognition & AV_EF_EXPLODE)
11815 return AVERROR_INVALIDDATA;
11816 }
11817 }
11818 }
11819 }
11820
11821 for (i = 0; i < mov->bitrates_count && i < s->nb_streams; i++) {
11822 if (mov->bitrates[i]) {
11823 s->streams[i]->codecpar->bit_rate = mov->bitrates[i];
11824 }
11825 }
11826
11828
11829 for (i = 0; i < s->nb_streams; i++) {
11830 AVStream *st = s->streams[i];
11831 MOVStreamContext *sc = st->priv_data;
11832
11833 switch (st->codecpar->codec_type) {
11834 case AVMEDIA_TYPE_AUDIO:
11835 err = ff_replaygain_export(st, s->metadata);
11836 if (err < 0)
11837 return err;
11838 break;
11839 case AVMEDIA_TYPE_VIDEO:
11840 if (sc->display_matrix) {
11843 (uint8_t*)sc->display_matrix, sizeof(int32_t) * 9, 0))
11844 return AVERROR(ENOMEM);
11845
11846 sc->display_matrix = NULL;
11847 }
11848 if (sc->stereo3d) {
11851 (uint8_t *)sc->stereo3d, sc->stereo3d_size, 0))
11852 return AVERROR(ENOMEM);
11853
11854 sc->stereo3d = NULL;
11855 }
11856 if (sc->spherical) {
11859 (uint8_t *)sc->spherical, sc->spherical_size, 0))
11860 return AVERROR(ENOMEM);
11861
11862 sc->spherical = NULL;
11863 }
11864 if (sc->mastering) {
11867 (uint8_t *)sc->mastering, sc->mastering_size, 0))
11868 return AVERROR(ENOMEM);
11869
11870 sc->mastering = NULL;
11871 }
11872 if (sc->coll) {
11875 (uint8_t *)sc->coll, sc->coll_size, 0))
11876 return AVERROR(ENOMEM);
11877
11878 sc->coll = NULL;
11879 }
11880 if (sc->ambient) {
11883 (uint8_t *) sc->ambient, sc->ambient_size, 0))
11884 return AVERROR(ENOMEM);
11885
11886 sc->ambient = NULL;
11887 }
11888 break;
11889 }
11890 }
11891
11893
11895
11896 for (i = 0; i < mov->frag_index.nb_items; i++)
11897 if (mov->frag_index.item[i].moof_offset <= mov->fragment.moof_offset)
11898 mov->frag_index.item[i].headers_read = 1;
11899
11900 return 0;
11901}
11902
11904{
11906 int64_t best_dts = INT64_MAX;
11907 int i;
11908 MOVContext *mov = s->priv_data;
11909 int no_interleave = !mov->interleaved_read || !(s->pb->seekable & AVIO_SEEKABLE_NORMAL);
11910 for (i = 0; i < s->nb_streams; i++) {
11911 AVStream *avst = s->streams[i];
11912 FFStream *const avsti = ffstream(avst);
11913 MOVStreamContext *msc = avst->priv_data;
11914 if (msc->pb && msc->current_sample < avsti->nb_index_entries) {
11915 AVIndexEntry *current_sample = &avsti->index_entries[msc->current_sample];
11916 int64_t dts = av_rescale(current_sample->timestamp, AV_TIME_BASE, msc->time_scale);
11917 uint64_t dtsdiff = best_dts > dts ? best_dts - (uint64_t)dts : ((uint64_t)dts - best_dts);
11918 av_log(s, AV_LOG_TRACE, "stream %d, sample %d, dts %"PRId64"\n", i, msc->current_sample, dts);
11919 if (!sample || (no_interleave && current_sample->pos < sample->pos) ||
11920 ((s->pb->seekable & AVIO_SEEKABLE_NORMAL) &&
11921 ((msc->pb != s->pb && dts < best_dts) || (msc->pb == s->pb && dts != AV_NOPTS_VALUE &&
11922 ((dtsdiff <= AV_TIME_BASE && current_sample->pos < sample->pos) ||
11923 (dtsdiff > AV_TIME_BASE && dts < best_dts && mov->interleaved_read)))))) {
11924 sample = current_sample;
11925 best_dts = dts;
11926 *st = avst;
11927 }
11928 }
11929 }
11930 return sample;
11931}
11932
11933static int should_retry(AVIOContext *pb, int error_code) {
11934 if (error_code == AVERROR_EOF || avio_feof(pb))
11935 return 0;
11936
11937 return 1;
11938}
11939
11941{
11942 int ret;
11943 MOVContext *mov = s->priv_data;
11944
11945 if (index >= 0 && index < mov->frag_index.nb_items)
11946 target = mov->frag_index.item[index].moof_offset;
11947 if (target >= 0 && avio_seek(s->pb, target, SEEK_SET) != target) {
11948 av_log(mov->fc, AV_LOG_ERROR, "root atom offset 0x%"PRIx64": partial file\n", target);
11949 return AVERROR_INVALIDDATA;
11950 }
11951
11952 mov->next_root_atom = 0;
11953 if ((index < 0 && target >= 0) || index >= mov->frag_index.nb_items)
11954 index = search_frag_moof_offset(&mov->frag_index, target);
11955 if (index >= 0 && index < mov->frag_index.nb_items &&
11956 mov->frag_index.item[index].moof_offset == target) {
11957 if (index + 1 < mov->frag_index.nb_items)
11960 return 0;
11962 }
11963
11964 mov->found_mdat = 0;
11965
11966 ret = mov_read_default(mov, s->pb, (MOVAtom){ AV_RL32("root"), INT64_MAX });
11967 if (ret < 0)
11968 return ret;
11969 if (avio_feof(s->pb))
11970 return AVERROR_EOF;
11971 av_log(s, AV_LOG_TRACE, "read fragments, offset 0x%"PRIx64"\n", avio_tell(s->pb));
11972
11973 return 1;
11974}
11975
11977{
11978 MOVStreamContext *sc = st->priv_data;
11979 uint8_t *side, *extradata;
11980 int extradata_size;
11981
11982 /* Save the current index. */
11983 sc->last_stsd_index = sc->stsc_data[sc->stsc_index].id - 1;
11984
11985 /* Notify the decoder that extradata changed. */
11986 extradata_size = sc->extradata_size[sc->last_stsd_index];
11987 extradata = sc->extradata[sc->last_stsd_index];
11988 if (st->discard != AVDISCARD_ALL && extradata_size > 0 && extradata) {
11991 extradata_size);
11992 if (!side)
11993 return AVERROR(ENOMEM);
11994 memcpy(side, extradata, extradata_size);
11995 }
11996
11997 return 0;
11998}
11999
12000static int get_eia608_packet(AVIOContext *pb, AVPacket *pkt, int src_size)
12001{
12002 /* We can't make assumptions about the structure of the payload,
12003 because it may include multiple cdat and cdt2 samples. */
12004 const uint32_t cdat = AV_RB32("cdat");
12005 const uint32_t cdt2 = AV_RB32("cdt2");
12006 int ret, out_size = 0;
12007
12008 /* a valid payload must have size, 4cc, and at least 1 byte pair: */
12009 if (src_size < 10)
12010 return AVERROR_INVALIDDATA;
12011
12012 /* avoid an int overflow: */
12013 if ((src_size - 8) / 2 >= INT_MAX / 3)
12014 return AVERROR_INVALIDDATA;
12015
12016 ret = av_new_packet(pkt, ((src_size - 8) / 2) * 3);
12017 if (ret < 0)
12018 return ret;
12019
12020 /* parse and re-format the c608 payload in one pass. */
12021 while (src_size >= 10) {
12022 const uint32_t atom_size = avio_rb32(pb);
12023 const uint32_t atom_type = avio_rb32(pb);
12024 const uint32_t data_size = atom_size - 8;
12025 const uint8_t cc_field =
12026 atom_type == cdat ? 1 :
12027 atom_type == cdt2 ? 2 :
12028 0;
12029
12030 /* account for bytes consumed for atom size and type. */
12031 src_size -= 8;
12032
12033 /* make sure the data size stays within the buffer boundaries. */
12034 if (data_size < 2 || data_size > src_size) {
12035 ret = AVERROR_INVALIDDATA;
12036 break;
12037 }
12038
12039 /* make sure the data size is consistent with N byte pairs. */
12040 if (data_size % 2 != 0) {
12041 ret = AVERROR_INVALIDDATA;
12042 break;
12043 }
12044
12045 if (!cc_field) {
12046 /* neither cdat or cdt2 ... skip it */
12047 avio_skip(pb, data_size);
12048 src_size -= data_size;
12049 continue;
12050 }
12051
12052 for (uint32_t i = 0; i < data_size; i += 2) {
12053 pkt->data[out_size] = (0x1F << 3) | (1 << 2) | (cc_field - 1);
12054 pkt->data[out_size + 1] = avio_r8(pb);
12055 pkt->data[out_size + 2] = avio_r8(pb);
12056 out_size += 3;
12057 src_size -= 2;
12058 }
12059 }
12060
12061 if (src_size > 0)
12062 /* skip any remaining unread portion of the input payload */
12063 avio_skip(pb, src_size);
12064
12066 return ret;
12067}
12068
12070 int64_t current_index, AVPacket *pkt)
12071{
12072 MOVContext *mov = s->priv_data;
12073 MOVStreamContext *sc = st->priv_data;
12074
12075 pkt->stream_index = sc->ffindex;
12076 pkt->dts = sample->timestamp;
12077 if (sample->flags & AVINDEX_DISCARD_FRAME) {
12078 pkt->flags |= AV_PKT_FLAG_DISCARD;
12079 }
12080 if (sc->stts_count && sc->tts_index < sc->tts_count)
12081 pkt->duration = sc->tts_data[sc->tts_index].duration;
12082 if (sc->ctts_count && sc->tts_index < sc->tts_count) {
12083 pkt->pts = av_sat_add64(pkt->dts, av_sat_add64(sc->dts_shift, sc->tts_data[sc->tts_index].offset));
12084 } else {
12085 if (pkt->duration == 0) {
12086 int64_t next_dts = (sc->current_sample < ffstream(st)->nb_index_entries) ?
12088 if (next_dts >= pkt->dts)
12089 pkt->duration = next_dts - pkt->dts;
12090 }
12091 pkt->pts = pkt->dts;
12092 }
12093
12095 sc->current_sample >= ffstream(st)->nb_index_entries) {
12096 int64_t pts = av_rescale_q(pkt->pts, st->time_base, (AVRational){ 1, st->codecpar->sample_rate });
12097 int64_t total = av_rescale_q(st->duration, st->time_base, (AVRational){ 1, st->codecpar->sample_rate });
12098 int64_t duration = pkt->duration;
12099
12100 if (st->duration < pkt->pts) {
12101 duration = 0;
12102 } else
12103 duration = FFMIN(duration, (uint64_t)st->duration - pkt->pts);
12104
12105 duration = av_rescale_q(duration, st->time_base, (AVRational){ 1, st->codecpar->sample_rate });
12106
12107 if (!ffstream(st)->first_discard_sample)
12109 if (!ffstream(st)->last_discard_sample)
12110 ffstream(st)->last_discard_sample = total;
12111 }
12112
12113 if (sc->tts_data && sc->tts_index < sc->tts_count) {
12114 /* update tts context */
12115 sc->tts_sample++;
12116 if (sc->tts_index < sc->tts_count &&
12117 sc->tts_data[sc->tts_index].count == sc->tts_sample) {
12118 sc->tts_index++;
12119 sc->tts_sample = 0;
12120 }
12121 }
12122
12123 if (sc->sdtp_data && sc->current_sample <= sc->sdtp_count) {
12124 uint8_t sample_flags = sc->sdtp_data[sc->current_sample - 1];
12125 uint8_t sample_is_depended_on = (sample_flags >> 2) & 0x3;
12126 pkt->flags |= sample_is_depended_on == MOV_SAMPLE_DEPENDENCY_NO ? AV_PKT_FLAG_DISPOSABLE : 0;
12127 }
12128 pkt->flags |= sample->flags & AVINDEX_KEYFRAME ? AV_PKT_FLAG_KEY : 0;
12129 pkt->pos = sample->pos;
12130
12131 /* Multiple stsd handling. */
12132 if (sc->stsc_data) {
12133 if (sc->stsc_data[sc->stsc_index].id > 0 &&
12134 sc->stsc_data[sc->stsc_index].id - 1 < sc->stsd_count &&
12135 sc->stsc_data[sc->stsc_index].id - 1 != sc->last_stsd_index) {
12136 int ret = mov_change_extradata(st, pkt);
12137 if (ret < 0)
12138 return ret;
12139 }
12140
12141 /* Update the stsc index for the next sample */
12142 sc->stsc_sample++;
12145 sc->stsc_index++;
12146 sc->stsc_sample = 0;
12147 }
12148 }
12149
12150 return 0;
12151}
12152
12154{
12155 MOVContext *mov = s->priv_data;
12156 MOVStreamContext *sc;
12158 AVStream *st = NULL;
12159 FFStream *avsti = NULL;
12160 int64_t current_index;
12161 int ret;
12162 int i;
12163 mov->fc = s;
12164 retry:
12165 if (s->pb->pos == 0) {
12166
12167 // Discard current fragment index
12168 if (mov->frag_index.allocated_size > 0) {
12169 for(int i = 0; i < mov->frag_index.nb_items; i++) {
12171 }
12172 av_freep(&mov->frag_index.item);
12173 mov->frag_index.nb_items = 0;
12174 mov->frag_index.allocated_size = 0;
12175 mov->frag_index.current = -1;
12176 mov->frag_index.complete = 0;
12177 }
12178
12179 for (i = 0; i < s->nb_streams; i++) {
12180 AVStream *avst = s->streams[i];
12181 MOVStreamContext *msc = avst->priv_data;
12182
12183 // Clear current sample
12184 mov_current_sample_set(msc, 0);
12185 msc->tts_index = 0;
12186
12187 // Discard current index entries
12188 avsti = ffstream(avst);
12189 if (avsti->index_entries_allocated_size > 0) {
12190 av_freep(&avsti->index_entries);
12192 avsti->nb_index_entries = 0;
12193 }
12194 }
12195
12196 if ((ret = mov_switch_root(s, -1, -1)) < 0)
12197 return ret;
12198 }
12200 if (!sample || (mov->next_root_atom && sample->pos > mov->next_root_atom)) {
12201 if (!mov->next_root_atom)
12202 return AVERROR_EOF;
12203 if ((ret = mov_switch_root(s, mov->next_root_atom, -1)) < 0)
12204 return ret;
12205 goto retry;
12206 }
12207 sc = st->priv_data;
12208 /* must be done just before reading, to avoid infinite loop on sample */
12209 current_index = sc->current_index;
12211
12212 if (mov->next_root_atom) {
12213 sample->pos = FFMIN(sample->pos, mov->next_root_atom);
12214 sample->size = FFMIN(sample->size, (mov->next_root_atom - sample->pos));
12215 }
12216
12217 if (st->discard != AVDISCARD_ALL || sc->iamf) {
12218 int64_t ret64 = avio_seek(sc->pb, sample->pos, SEEK_SET);
12219 if (ret64 != sample->pos) {
12220 av_log(mov->fc, AV_LOG_ERROR, "stream %d, offset 0x%"PRIx64": partial file\n",
12221 sc->ffindex, sample->pos);
12222 if (should_retry(sc->pb, ret64)) {
12224 } else if (ret64 < 0) {
12225 return (int)ret64;
12226 }
12227 return AVERROR_INVALIDDATA;
12228 }
12229
12230 if (st->discard == AVDISCARD_NONKEY && !(sample->flags & AVINDEX_KEYFRAME)) {
12231 av_log(mov->fc, AV_LOG_DEBUG, "Nonkey frame from stream %d discarded due to AVDISCARD_NONKEY\n", sc->ffindex);
12232 goto retry;
12233 }
12234
12235 if (st->codecpar->codec_id == AV_CODEC_ID_EIA_608 && sample->size > 8)
12236 ret = get_eia608_packet(sc->pb, pkt, sample->size);
12237#if CONFIG_IAMFDEC
12238 else if (sc->iamf) {
12239 int64_t pts, dts, pos, duration;
12240 int flags, size = sample->size;
12241 ret = mov_finalize_packet(s, st, sample, current_index, pkt);
12242 pts = pkt->pts; dts = pkt->dts;
12243 pos = pkt->pos; flags = pkt->flags;
12244 duration = pkt->duration;
12245 while (!ret && size > 0) {
12246 ret = ff_iamf_read_packet(s, sc->iamf, sc->pb, size, sc->iamf_stream_offset, pkt);
12247 if (ret < 0) {
12248 if (should_retry(sc->pb, ret))
12250 return ret;
12251 }
12252 size -= ret;
12253
12254 if (pkt->flags & AV_PKT_FLAG_DISCARD) {
12256 ret = 0;
12257 continue;
12258 }
12259 pkt->pts = pts; pkt->dts = dts;
12260 pkt->pos = pos; pkt->flags |= flags;
12261 pkt->duration = duration;
12262 ret = ff_buffer_packet(s, pkt);
12263 }
12264 if (!ret)
12265 return FFERROR_REDO;
12266 }
12267#endif
12268 else if (st->codecpar->codec_id == AV_CODEC_ID_APV && sample->size > 4) {
12269 uint32_t au_size = avio_rb32(sc->pb);
12270 int explode = !!(mov->fc->error_recognition & AV_EF_EXPLODE);
12271 if (au_size > sample->size - 4) {
12272 av_log(s, explode ? AV_LOG_ERROR : AV_LOG_WARNING,
12273 "APV au_size %u exceeds sample body %d\n",
12274 au_size, sample->size - 4);
12275 if (explode)
12276 return AVERROR_INVALIDDATA;
12277 au_size = sample->size - 4;
12278 }
12279 ret = av_get_packet(sc->pb, pkt, au_size);
12280 } else
12281 ret = av_get_packet(sc->pb, pkt, sample->size);
12282 if (ret < 0) {
12283 if (should_retry(sc->pb, ret)) {
12285 }
12286 return ret;
12287 }
12288#if CONFIG_DV_DEMUXER
12289 if (mov->dv_demux && sc->dv_audio_container) {
12290 ret = avpriv_dv_produce_packet(mov->dv_demux, NULL, pkt->data, pkt->size, pkt->pos);
12292 if (ret < 0)
12293 return ret;
12294 ret = avpriv_dv_get_packet(mov->dv_demux, pkt);
12295 if (ret < 0)
12296 return ret;
12297 }
12298#endif
12299 if (sc->has_palette) {
12300 uint8_t *pal;
12301
12303 if (!pal) {
12304 av_log(mov->fc, AV_LOG_ERROR, "Cannot append palette to packet\n");
12305 } else {
12306 memcpy(pal, sc->palette, AVPALETTE_SIZE);
12307 sc->has_palette = 0;
12308 }
12309 }
12310 if (st->codecpar->codec_id == AV_CODEC_ID_MP3 && !ffstream(st)->need_parsing && pkt->size > 4) {
12311 if (ff_mpa_check_header(AV_RB32(pkt->data)) < 0)
12313 }
12314 }
12315
12316 ret = mov_finalize_packet(s, st, sample, current_index, pkt);
12317 if (ret < 0)
12318 return ret;
12319
12320 if (st->discard == AVDISCARD_ALL)
12321 goto retry;
12322
12323 if (mov->aax_mode)
12324 aax_filter(pkt->data, pkt->size, mov);
12325
12326 ret = cenc_filter(mov, st, sc, pkt, current_index);
12327 if (ret < 0) {
12328 return ret;
12329 }
12330
12331 return 0;
12332}
12333
12335{
12336 MOVContext *mov = s->priv_data;
12337 int index;
12338
12339 if (!mov->frag_index.complete)
12340 return 0;
12341
12342 index = search_frag_timestamp(s, &mov->frag_index, st, timestamp);
12343 if (index < 0)
12344 index = 0;
12345 if (!mov->frag_index.item[index].headers_read)
12346 return mov_switch_root(s, -1, index);
12347 if (index + 1 < mov->frag_index.nb_items)
12349
12350 return 0;
12351}
12352
12354{
12355 // TODO: a bisect search would scale much better
12356 for (int i = 0; i < sc->open_key_samples_count; i++) {
12357 const int oks = sc->open_key_samples[i];
12358 if (oks == sample)
12359 return 1;
12360 if (oks > sample) /* list is monotically increasing so we can stop early */
12361 break;
12362 }
12363 return 0;
12364}
12365
12366/*
12367 * Some key sample may be key frames but not IDR frames, so a random access to
12368 * them may not be allowed.
12369 */
12370static int can_seek_to_key_sample(AVStream *st, int sample, int64_t requested_pts)
12371{
12372 MOVStreamContext *sc = st->priv_data;
12373 FFStream *const sti = ffstream(st);
12374 int64_t key_sample_dts, key_sample_pts;
12375
12377 return 1;
12378
12379 if (sample >= sc->sample_offsets_count)
12380 return 1;
12381
12382 av_assert0(sample >= 0);
12383 key_sample_dts = sti->index_entries[sample].timestamp;
12384 key_sample_pts = key_sample_dts + sc->sample_offsets[sample] + sc->dts_shift;
12385
12386 /*
12387 * If the sample needs to be presented before an open key sample, they may
12388 * not be decodable properly, even though they come after in decoding
12389 * order.
12390 */
12391 if (is_open_key_sample(sc, sample) && key_sample_pts > requested_pts)
12392 return 0;
12393
12394 return 1;
12395}
12396
12397static int mov_seek_stream(AVFormatContext *s, AVStream *st, int64_t timestamp, int flags)
12398{
12399 MOVStreamContext *sc = st->priv_data;
12400 FFStream *const sti = ffstream(st);
12401 int sample, time_sample, ret, requested_sample;
12402 int64_t next_ts;
12403 unsigned int i;
12404
12405 // Here we consider timestamp to be PTS, hence try to offset it so that we
12406 // can search over the DTS timeline.
12407 timestamp -= (sc->min_corrected_pts + sc->dts_shift);
12408
12409 ret = mov_seek_fragment(s, st, timestamp);
12410 if (ret < 0)
12411 return ret;
12412
12413 for (;;) {
12414 sample = av_index_search_timestamp(st, timestamp, flags);
12415 av_log(s, AV_LOG_TRACE, "stream %d, timestamp %"PRId64", sample %d\n", st->index, timestamp, sample);
12416 if (sample < 0 && sti->nb_index_entries && timestamp < sti->index_entries[0].timestamp)
12417 sample = 0;
12418 if (sample < 0) /* not sure what to do */
12419 return AVERROR_INVALIDDATA;
12420
12421 if (!sample || can_seek_to_key_sample(st, sample, timestamp))
12422 break;
12423
12424 next_ts = timestamp - FFMAX(sc->min_sample_duration, 1);
12425 requested_sample = av_index_search_timestamp(st, next_ts, flags);
12426 if (requested_sample < 0)
12427 return AVERROR_INVALIDDATA;
12428
12429 // If we've reached a different sample trying to find a good pts to
12430 // seek to, give up searching because we'll end up seeking back to
12431 // sample 0 on every seek.
12432 if (sample != requested_sample && !can_seek_to_key_sample(st, requested_sample, next_ts))
12433 break;
12434
12435 timestamp = next_ts;
12436 }
12437
12439 av_log(s, AV_LOG_TRACE, "stream %d, found sample %d\n", st->index, sc->current_sample);
12440 /* adjust time to sample index */
12441 if (sc->tts_data) {
12442 time_sample = 0;
12443 for (i = 0; i < sc->tts_count; i++) {
12444 int next = time_sample + sc->tts_data[i].count;
12445 if (next > sc->current_sample) {
12446 sc->tts_index = i;
12447 sc->tts_sample = sc->current_sample - time_sample;
12448 break;
12449 }
12450 time_sample = next;
12451 }
12452 }
12453
12454 /* adjust stsd index */
12455 if (sc->chunk_count) {
12456 time_sample = 0;
12457 for (i = 0; i < sc->stsc_count; i++) {
12458 int64_t next = time_sample + mov_get_stsc_samples(sc, i);
12459 if (next > sc->current_sample) {
12460 sc->stsc_index = i;
12461 sc->stsc_sample = sc->current_sample - time_sample;
12462 break;
12463 }
12464 av_assert0(next == (int)next);
12465 time_sample = next;
12466 }
12467 }
12468
12469 return sample;
12470}
12471
12473{
12474 FFStream *const sti = ffstream(st);
12475 int64_t first_ts = sti->index_entries[0].timestamp;
12477 int64_t off;
12478
12480 return 0;
12481
12482 /* compute skip samples according to stream initial_padding, seek ts and first ts */
12483 off = av_rescale_q(ts - first_ts, st->time_base,
12484 (AVRational){1, st->codecpar->sample_rate});
12485 return FFMAX(st->codecpar->initial_padding - off, 0);
12486}
12487
12488static int mov_read_seek(AVFormatContext *s, int stream_index, int64_t sample_time, int flags)
12489{
12490 MOVContext *mc = s->priv_data;
12491 AVStream *st;
12492 FFStream *sti;
12493 int sample;
12494 int i;
12495
12496 if (stream_index >= s->nb_streams)
12497 return AVERROR_INVALIDDATA;
12498
12499 st = s->streams[stream_index];
12500 sti = ffstream(st);
12501 sample = mov_seek_stream(s, st, sample_time, flags);
12502 if (sample < 0)
12503 return sample;
12504
12505 if (mc->seek_individually) {
12506 /* adjust seek timestamp to found sample timestamp */
12507 int64_t seek_timestamp = sti->index_entries[sample].timestamp;
12509
12510 for (i = 0; i < s->nb_streams; i++) {
12511 AVStream *const st = s->streams[i];
12512 FFStream *const sti = ffstream(st);
12513 int64_t timestamp;
12514
12515 if (stream_index == i)
12516 continue;
12517
12518 timestamp = av_rescale_q(seek_timestamp, s->streams[stream_index]->time_base, st->time_base);
12519 sample = mov_seek_stream(s, st, timestamp, flags);
12520 if (sample >= 0)
12522 }
12523 } else {
12524 for (i = 0; i < s->nb_streams; i++) {
12525 MOVStreamContext *sc;
12526 st = s->streams[i];
12527 sc = st->priv_data;
12529 }
12530 while (1) {
12531 MOVStreamContext *sc;
12533 if (!entry)
12534 return AVERROR_INVALIDDATA;
12535 sc = st->priv_data;
12536 if (sc->ffindex == stream_index && sc->current_sample == sample)
12537 break;
12539 }
12540 }
12541 return 0;
12542}
12543
12544#define OFFSET(x) offsetof(MOVContext, x)
12545#define FLAGS AV_OPT_FLAG_VIDEO_PARAM | AV_OPT_FLAG_DECODING_PARAM
12546static const AVOption mov_options[] = {
12547 {"use_absolute_path",
12548 "allow using absolute path when opening alias, this is a possible security issue",
12549 OFFSET(use_absolute_path), AV_OPT_TYPE_BOOL, {.i64 = 0},
12550 0, 1, FLAGS},
12551 {"seek_streams_individually",
12552 "Seek each stream individually to the closest point",
12553 OFFSET(seek_individually), AV_OPT_TYPE_BOOL, { .i64 = 1 },
12554 0, 1, FLAGS},
12555 {"ignore_editlist", "Ignore the edit list atom.", OFFSET(ignore_editlist), AV_OPT_TYPE_BOOL, {.i64 = 0},
12556 0, 1, FLAGS},
12557 {"advanced_editlist",
12558 "Modify the AVIndex according to the editlists. Use this option to decode in the order specified by the edits.",
12559 OFFSET(advanced_editlist), AV_OPT_TYPE_BOOL, {.i64 = 1},
12560 0, 1, FLAGS},
12561 {"ignore_chapters", "", OFFSET(ignore_chapters), AV_OPT_TYPE_BOOL, {.i64 = 0},
12562 0, 1, FLAGS},
12563 {"use_mfra_for",
12564 "use mfra for fragment timestamps",
12565 OFFSET(use_mfra_for), AV_OPT_TYPE_INT, {.i64 = FF_MOV_FLAG_MFRA_AUTO},
12567 .unit = "use_mfra_for"},
12568 {"auto", "auto", 0, AV_OPT_TYPE_CONST, {.i64 = FF_MOV_FLAG_MFRA_AUTO}, 0, 0,
12569 FLAGS, .unit = "use_mfra_for" },
12570 {"dts", "dts", 0, AV_OPT_TYPE_CONST, {.i64 = FF_MOV_FLAG_MFRA_DTS}, 0, 0,
12571 FLAGS, .unit = "use_mfra_for" },
12572 {"pts", "pts", 0, AV_OPT_TYPE_CONST, {.i64 = FF_MOV_FLAG_MFRA_PTS}, 0, 0,
12573 FLAGS, .unit = "use_mfra_for" },
12574 {"use_tfdt", "use tfdt for fragment timestamps", OFFSET(use_tfdt), AV_OPT_TYPE_BOOL, {.i64 = 1},
12575 0, 1, FLAGS},
12576 { "export_all", "Export unrecognized metadata entries", OFFSET(export_all),
12577 AV_OPT_TYPE_BOOL, { .i64 = 0 }, 0, 1, .flags = FLAGS },
12578 { "export_xmp", "Export full XMP metadata", OFFSET(export_xmp),
12579 AV_OPT_TYPE_BOOL, { .i64 = 0 }, 0, 1, .flags = FLAGS },
12580 { "activation_bytes", "Secret bytes for Audible AAX files", OFFSET(activation_bytes),
12582 { "audible_key", "AES-128 Key for Audible AAXC files", OFFSET(audible_key),
12584 { "audible_iv", "AES-128 IV for Audible AAXC files", OFFSET(audible_iv),
12586 { "audible_fixed_key", // extracted from libAAX_SDK.so and AAXSDKWin.dll files!
12587 "Fixed key used for handling Audible AAX files", OFFSET(audible_fixed_key),
12588 AV_OPT_TYPE_BINARY, {.str="77214d4b196a87cd520045fd20a51d67"},
12589 .flags = AV_OPT_FLAG_DECODING_PARAM },
12590 { "decryption_key", "The default media decryption key (hex)", OFFSET(decryption_default_key), AV_OPT_TYPE_BINARY, .flags = AV_OPT_FLAG_DECODING_PARAM },
12591 { "decryption_keys", "The media decryption keys by KID (hex)", OFFSET(decryption_keys), AV_OPT_TYPE_DICT, .flags = AV_OPT_FLAG_DECODING_PARAM },
12592 { "enable_drefs", "Enable external track support.", OFFSET(enable_drefs), AV_OPT_TYPE_BOOL,
12593 {.i64 = 0}, 0, 1, FLAGS },
12594 { "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 },
12595 { "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 },
12596
12597 { NULL },
12598};
12599
12600static const AVClass mov_class = {
12601 .class_name = "mov,mp4,m4a,3gp,3g2,mj2",
12602 .item_name = av_default_item_name,
12603 .option = mov_options,
12604 .version = LIBAVUTIL_VERSION_INT,
12605};
12606
12608 .p.name = "mov,mp4,m4a,3gp,3g2,mj2",
12609 .p.long_name = NULL_IF_CONFIG_SMALL("QuickTime / MOV"),
12610 .p.priv_class = &mov_class,
12611 .p.extensions = "mov,mp4,m4a,3gp,3g2,mj2,psp,m4v,m4b,ism,ismv,isma,f4v,avif,heic,heif",
12613 .priv_data_size = sizeof(MOVContext),
12614 .flags_internal = FF_INFMT_FLAG_INIT_CLEANUP,
12620};
uint8_t ptrdiff_t const uint8_t ptrdiff_t int intptr_t intptr_t int int16_t * dst
Definition dsp.h:87
const uint16_t ff_ac3_channel_layout_tab[8]
Map audio coding mode (acmod) to channel layout mask.
static double val(void *priv, double ch)
Definition aeval.c:77
static const char *const format[]
Definition af_aiir.c:445
#define ctype
#define ALAC_EXTRADATA_SIZE
Definition alac.c:63
const FFInputFormat ff_mov_demuxer
Definition mov.c:12607
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:352
@ AV_CODEC_ID_PCM_S24BE
Definition codec_id.h:344
@ AV_CODEC_ID_VORBIS
Definition codec_id.h:460
@ 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:495
@ AV_CODEC_ID_PCM_U8
Definition codec_id.h:336
@ AV_CODEC_ID_APV
Definition codec_id.h:323
@ AV_CODEC_ID_LCEVC
Definition codec_id.h:611
@ AV_CODEC_ID_PCM_S16LE
Definition codec_id.h:331
@ AV_CODEC_ID_GSM
as in Berlin toast format
Definition codec_id.h:473
@ AV_CODEC_ID_DVD_SUBTITLE
Definition codec_id.h:568
@ AV_CODEC_ID_TTML
Definition codec_id.h:592
@ AV_CODEC_ID_PCM_F32BE
Definition codec_id.h:351
@ 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:332
@ AV_CODEC_ID_PCM_S24LE
Definition codec_id.h:343
@ AV_CODEC_ID_PCM_S32LE
Definition codec_id.h:339
@ AV_CODEC_ID_PCM_S8
Definition codec_id.h:335
@ AV_CODEC_ID_AV1
Definition codec_id.h:275
@ AV_CODEC_ID_ADPCM_MS
Definition codec_id.h:377
@ 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:354
@ AV_CODEC_ID_ALAC
Definition codec_id.h:471
@ AV_CODEC_ID_EIA_608
Definition codec_id.h:578
@ AV_CODEC_ID_AMR_NB
Definition codec_id.h:436
@ 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:455
@ AV_CODEC_ID_DVAUDIO
Definition codec_id.h:461
@ AV_CODEC_ID_ADPCM_IMA_QT
Definition codec_id.h:371
@ AV_CODEC_ID_HEVC
Definition codec_id.h:223
@ AV_CODEC_ID_BIN_DATA
Definition codec_id.h:609
@ AV_CODEC_ID_AAC
Definition codec_id.h:457
@ 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:353
@ AV_CODEC_ID_H263
Definition codec_id.h:54
@ AV_CODEC_ID_QCELP
Definition codec_id.h:479
@ AV_CODEC_ID_AMR_WB
Definition codec_id.h:437
@ AV_CODEC_ID_AC3
Definition codec_id.h:458
@ AV_CODEC_ID_MACE3
Definition codec_id.h:464
@ AV_CODEC_ID_MACE6
Definition codec_id.h:465
@ AV_CODEC_ID_QDM2
Definition codec_id.h:474
@ AV_CODEC_ID_PCM_S32BE
Definition codec_id.h:340
@ 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:372
@ 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:490
@ AV_CODEC_ID_AVUI
Definition codec_id.h:252
@ AV_CODEC_ID_ILBC
Definition codec_id.h:514
@ AV_CODEC_ID_MP3
preferred ID for decoding MPEG audio layer 1, 2 or 3
Definition codec_id.h:456
@ 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:505
@ AV_CODEC_ID_ITUT_T35
Definition codec_id.h:613
@ 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:5711
static int64_t mov_get_skip_samples(AVStream *st, int sample)
Definition mov.c:12472
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:2735
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:12000
static int mov_read_iloc(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition mov.c:9432
static int mov_read_pack(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition mov.c:7126
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:4224
static int mov_read_seek(AVFormatContext *s, int stream_index, int64_t sample_time, int flags)
Definition mov.c:12488
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:10635
static int mov_read_stsd(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition mov.c:3452
static void mov_parse_stsd_video(MOVContext *c, AVIOContext *pb, AVStream *st, MOVStreamContext *sc)
Definition mov.c:2926
static int heif_add_stream(MOVContext *c, HEIFItem *item)
Definition mov.c:5873
static int mov_read_dops(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition mov.c:9008
static int set_display_matrix_from_item(AVPacketSideData **coded_side_data, int *nb_coded_side_data, const HEIFItem *item)
Definition mov.c:10906
static int mov_compare_presentation_samples(const void *a, const void *b)
Definition mov.c:5281
static int mov_switch_root(AVFormatContext *s, int64_t target, int index)
Definition mov.c:11940
static int mov_read_vexu_proj(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition mov.c:7344
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:8592
static int mov_read_aclr(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition mov.c:2476
static int mov_read_idat(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition mov.c:9426
static int mov_parse_tmcd_streams(AVFormatContext *s)
Definition mov.c:11380
static int mov_read_lhvc(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition mov.c:9143
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:4470
static int mov_finalize_stsd_entry(MOVContext *c, AVStream *st)
Definition mov.c:3330
static int mov_read_pitm(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition mov.c:9418
static int mov_seek_stream(AVFormatContext *s, AVStream *st, int64_t timestamp, int flags)
Definition mov.c:12397
static int mov_read_packet(AVFormatContext *s, AVPacket *pkt)
Definition mov.c:12153
static int mov_parse_lcevc_streams(AVFormatContext *s)
Definition mov.c:11503
static int mov_read_hvce(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition mov.c:9116
static int cbcs_scheme_decrypt(MOVContext *c, MOVStreamContext *sc, AVEncryptionInfo *sample, uint8_t *input, int size)
Definition mov.c:8825
static int mov_read_default(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition mov.c:10220
static int mov_finalize_packet(AVFormatContext *s, AVStream *st, AVIndexEntry *sample, int64_t current_index, AVPacket *pkt)
Definition mov.c:12069
static int mov_read_stss(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition mov.c:3660
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:8234
static int mov_skip_multiple_stsd(MOVContext *c, AVIOContext *pb, int codec_tag, int format, int64_t size)
Definition mov.c:3304
#define DRM_BLOB_SIZE
Definition mov.c:1507
static int mov_add_tref_id(MovTref *tag, uint32_t id)
Definition mov.c:2661
static int mov_read_mdhd(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition mov.c:2003
static int mov_read_tmcd(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition mov.c:6825
int ff_mov_read_stsd_entries(MOVContext *c, AVIOContext *pb, int entries)
Definition mov.c:3351
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:2404
static MovTref * mov_find_tref_tag(const MOVStreamContext *sc, uint32_t name)
Definition mov.c:2676
static int mov_read_eyes(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition mov.c:7417
static int cenc_scheme_decrypt(MOVContext *c, MOVStreamContext *sc, AVEncryptionInfo *sample, uint8_t *input, int size)
Definition mov.c:8629
static int mov_read_wave(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition mov.c:2524
static int read_image_iovl(AVFormatContext *s, const HEIFGrid *grid, AVStreamGroupTileGrid *tile_grid)
Definition mov.c:11022
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:9663
static int mov_read_stsz(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition mov.c:3715
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:9399
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:11668
static int mov_read_dfla(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition mov.c:8552
static int mov_read_stco(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition mov.c:2821
static int mov_read_st3d(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition mov.c:7079
static int mov_read_elst(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition mov.c:6751
static int test_same_origin(const char *src, const char *ref)
Definition mov.c:5379
static int sanity_checks(void *log_obj, MOVStreamContext *sc, int index)
Definition mov.c:5536
static void mov_current_sample_set(MOVStreamContext *sc, int current_sample)
Definition mov.c:4482
static int mov_merge_tts_data(MOVContext *mov, AVStream *st, int flags)
Definition mov.c:4897
static int mov_aaxc_crypto(MOVContext *c)
Definition mov.c:1610
static int mov_read_sv3d(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition mov.c:7207
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:3928
static int mov_read_stts(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition mov.c:3808
static int cenc_filter(MOVContext *mov, AVStream *st, MOVStreamContext *sc, AVPacket *pkt, int current_index)
Definition mov.c:8938
static const AVClass mov_class
Definition mov.c:12600
static int mov_read_sample_encryption_info(MOVContext *c, AVIOContext *pb, MOVStreamContext *sc, AVEncryptionInfo **sample, int use_subsamples)
Definition mov.c:7978
static int mov_read_meta(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition mov.c:5932
static int mov_read_smdm(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition mov.c:6897
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:6539
static int mov_read_strf(MOVContext *c, AVIOContext *pb, MOVAtom atom)
An strf atom is a BITMAPINFOHEADER struct.
Definition mov.c:2799
static uint32_t get_sgpd_sync_index(const MOVStreamContext *sc, int nal_unit_type)
Definition mov.c:4819
static void fix_frag_index_entries(MOVFragmentIndex *frag_index, int index, int id, int entries)
Definition mov.c:1932
static int mov_read_rtmd_track(AVFormatContext *s, AVStream *st)
Definition mov.c:10550
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:9061
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:8450
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:10791
static int mov_seek_fragment(AVFormatContext *s, AVStream *st, int64_t timestamp)
Definition mov.c:12334
static int mov_read_extradata(MOVContext *c, AVIOContext *pb, MOVAtom atom, enum AVCodecID codec_id)
Definition mov.c:2363
static int mov_read_enda(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition mov.c:2117
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:11557
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:1973
static int mov_parse_exif_item(AVFormatContext *s, AVPacketSideData **coded_side_data, int *nb_coded_side_data, const HEIFItem *ref)
Definition mov.c:11091
static int mov_stsc_index_valid(unsigned int index, unsigned int count)
Definition mov.c:3598
static int mov_read_hdlr(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition mov.c:799
#define MOV_MERGE_STTS
Definition mov.c:4891
static int mov_read_dvcc_dvvc(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition mov.c:9096
static int should_retry(AVIOContext *pb, int error_code)
Definition mov.c:11933
static int mov_read_mvhd(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition mov.c:2049
static int mov_read_tfdt(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition mov.c:6157
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:7025
static int mov_read_trun(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition mov.c:6196
static void mov_update_dts_shift(MOVStreamContext *sc, int duration, void *logctx)
Definition mov.c:3966
static int mov_read_kind(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition mov.c:9194
static int mov_read_sbgp(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition mov.c:4117
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:2431
static int mov_read_pssh(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition mov.c:8329
static int mov_finalize_stsd_codec(MOVContext *c, AVIOContext *pb, AVStream *st, MOVStreamContext *sc)
Definition mov.c:3200
static int mov_read_tkhd(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition mov.c:5958
static int mov_read_iprp(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition mov.c:9902
static int mov_read_cdsc_rndr(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition mov.c:2704
static int cens_scheme_decrypt(MOVContext *c, MOVStreamContext *sc, AVEncryptionInfo *sample, uint8_t *input, int size)
Definition mov.c:8754
static int mov_read_alac(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition mov.c:2389
static int mov_read_mfra(MOVContext *c, AVIOContext *f)
Definition mov.c:10846
#define MIN_DATA_ENTRY_BOX_SIZE
Definition mov.c:654
static int mov_change_extradata(AVStream *st, AVPacket *pkt)
Definition mov.c:11976
static int mov_read_mdcv(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition mov.c:6944
static int mov_read_timecode_track(AVFormatContext *s, AVStream *st)
Definition mov.c:10576
static int mov_read_imir(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition mov.c:9883
static int mov_read_stps(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition mov.c:3619
static int mov_read_svq3(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition mov.c:2519
static int mov_read_pcmc(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition mov.c:2126
static int mov_parse_cdsc_and_rndr_streams(AVFormatContext *s)
Definition mov.c:11451
static const MOVParseTableEntry mov_default_parse_table[]
Definition mov.c:10084
static int mov_read_jp2h(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition mov.c:2399
static int mov_read_iref(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition mov.c:9790
static int mov_read_trex(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition mov.c:6131
static int mov_read_saiz(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition mov.c:8150
static int mov_read_hfov(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition mov.c:7661
static int mov_read_free(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition mov.c:7858
static int set_icc_profile_from_item(AVPacketSideData **coded_side_data, int *nb_coded_side_data, const HEIFItem *item)
Definition mov.c:10892
static int mov_read_infe(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition mov.c:9529
static int mov_read_stsc(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition mov.c:3518
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:3127
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:8688
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:2409
static void fix_timescale(MOVContext *c, MOVStreamContext *sc)
Definition mov.c:5480
static int mov_read_custom(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition mov.c:5772
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:7927
static int mov_read_close(AVFormatContext *s)
Definition mov.c:10700
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:5408
static MOVFragmentStreamInfo * get_frag_stream_info_from_pkt(MOVFragmentIndex *frag_index, AVPacket *pkt, int id)
Definition mov.c:8913
static int mov_read_avss(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition mov.c:2394
static int mov_read_tenc(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition mov.c:8481
static int mov_read_uuid(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition mov.c:7753
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:4827
static void set_last_stream_little_endian(AVFormatContext *fc)
Definition mov.c:2088
static void mov_build_index(MOVContext *mov, AVStream *st)
Definition mov.c:4960
static void mov_update_sample_durations(MOVContext *mov, AVStream *st)
Definition mov.c:5294
static int mov_read_ctts(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition mov.c:3977
static int mov_find_tref_id(const MovTref *tag, uint32_t id)
Definition mov.c:2652
static int mov_read_amve(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition mov.c:7054
static int mov_read_keys(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition mov.c:5720
static int mov_read_wfex(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition mov.c: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:2581
static int mov_read_ftyp(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition mov.c:1649
#define IS_MATRIX_IDENT(matrix)
Definition mov.c:5950
static int can_seek_to_key_sample(AVStream *st, int sample, int64_t requested_pts)
Definition mov.c:12370
static int mov_parse_auxiliary_info(MOVContext *c, MOVStreamContext *sc, AVIOContext *pb, MOVEncryptionIndex *encryption_index)
Definition mov.c:8088
static int64_t mov_get_stsc_samples(MOVStreamContext *sc, unsigned int index)
Definition mov.c:3604
static int mov_read_vpcc(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition mov.c:6853
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:4320
static int mov_parse_tiles(AVFormatContext *s)
Definition mov.c:11175
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:4510
#define DDTS_SIZE
static int mov_read_iref_cdsc(MOVContext *c, AVIOContext *pb, uint32_t type, int version, uint32_t size)
Definition mov.c:9746
static int cenc_decrypt(MOVContext *c, MOVStreamContext *sc, AVEncryptionInfo *sample, uint8_t *input, int size)
Definition mov.c:8897
static int mov_read_senc(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition mov.c:8032
static int mov_read_sgpd(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition mov.c:4058
static AVStream * mov_find_reference_track(AVFormatContext *s, AVStream *st, uint32_t *tref_id, int nb_tref_id, int first_index)
Definition mov.c:11436
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:4361
static int mov_read_trak(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition mov.c:5555
static int mov_read_colr(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition mov.c:2203
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:4373
static void mov_parse_stsd_subtitle(MOVContext *c, AVIOContext *pb, AVStream *st, MOVStreamContext *sc, int64_t size)
Definition mov.c:3111
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:2627
static int mov_read_vdep(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition mov.c:2767
static int mov_read_SAND(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition mov.c:9373
static int64_t mov_read_atom_into_extradata(MOVContext *c, AVIOContext *pb, MOVAtom atom, AVCodecParameters *par, uint8_t *buf)
Definition mov.c:2341
static void mov_free_encryption_index(MOVEncryptionIndex **index)
Definition mov.c:10623
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:11630
#define OFFSET(x)
Definition mov.c:12544
static AVIndexEntry * mov_find_next_sample(AVFormatContext *s, AVStream **st)
Definition mov.c:11903
static int mov_read_chap(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition mov.c:6110
#define MOV_MERGE_CTTS
Definition mov.c:4890
static int is_open_key_sample(const MOVStreamContext *sc, int sample)
Definition mov.c:12353
static int mov_read_moof(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition mov.c:1947
static int mov_read_SA3D(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition mov.c:9283
static int mov_realloc_extradata(AVCodecParameters *par, MOVAtom atom)
Definition mov.c:2326
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:6988
static int mov_read_frma(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition mov.c:7880
static int mov_read_ispe(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition mov.c:9835
static int mov_codec_id(AVStream *st, uint32_t format)
Definition mov.c:2886
static void export_orphan_timecode(AVFormatContext *s)
Definition mov.c:10773
static int mov_parse_heif_items(AVFormatContext *s)
Definition mov.c:11301
static void mov_estimate_video_delay(MOVContext *c, AVStream *st)
Definition mov.c:4402
static int mov_read_vmhd(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition mov.c:10013
static int mov_read_tfhd(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition mov.c:6063
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:9863
static int read_image_grid(AVFormatContext *s, const HEIFGrid *grid, AVStreamGroupTileGrid *tile_grid)
Definition mov.c:10927
static int mov_probe(const AVProbeData *p)
Definition mov.c:10342
static int parse_timecode_in_framenum_format(AVFormatContext *s, AVStream *st, int64_t value, int flags)
Definition mov.c:10536
static int mov_parse_uuid_spherical(MOVStreamContext *sc, AVIOContext *pb, size_t len)
Definition mov.c:7690
static void mov_current_sample_inc(MOVStreamContext *sc)
Definition mov.c:4458
static int mov_read_fiel(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition mov.c:2292
static int mov_read_targa_y216(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition mov.c:2417
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:4178
static void mov_parse_stsd_audio(MOVContext *c, AVIOContext *pb, AVStream *st, MOVStreamContext *sc)
Definition mov.c:2990
static int mov_read_wide(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition mov.c:6678
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:9606
static int tmcd_is_referenced(AVFormatContext *s, int tmcd_id)
Definition mov.c:10755
static void mov_read_chapters(AVFormatContext *s)
Definition mov.c:10437
static int mov_read_mhac(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition mov.c:10046
static int mov_read_cmov(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition mov.c:6698
static void set_frag_stream(MOVFragmentIndex *frag_index, int id)
Definition mov.c:1734
static const AVOption mov_options[]
Definition mov.c:12546
static MovTref * mov_add_tref_tag(MOVStreamContext *sc, uint32_t name)
Definition mov.c:2687
static int mov_read_vexu(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition mov.c:7599
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:2127
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:3860
const char * av_color_transfer_name(enum AVColorTransferCharacteristic transfer)
Definition pixdesc.c:3827
const char * av_color_primaries_name(enum AVColorPrimaries primaries)
Definition pixdesc.c:3794
@ AVCOL_RANGE_MPEG
Narrow or limited range content.
Definition pixfmt.h:766
@ AVCOL_RANGE_JPEG
Full range content.
Definition pixfmt.h:783
@ AVALPHA_MODE_STRAIGHT
Alpha channel is independent of color values.
Definition pixfmt.h:819
@ AVALPHA_MODE_UNSPECIFIED
Unknown alpha handling, or no alpha channel.
Definition pixfmt.h:817
@ AVALPHA_MODE_PREMULTIPLIED
Alpha channel is multiplied into color values.
Definition pixfmt.h:818
#define AVPALETTE_SIZE
Definition pixfmt.h:32
@ AVCOL_PRI_UNSPECIFIED
Definition pixfmt.h:645
@ AVCOL_TRC_UNSPECIFIED
Definition pixfmt.h:675
@ AVCOL_SPC_UNSPECIFIED
Definition pixfmt.h:709
static const uint16_t table[]
Definition prosumer.c:203
const char * name
Definition qsvenc.c:142
int ff_get_qtpalette(int codec_id, AVIOContext *pb, uint32_t *palette)
Retrieve the palette (or "color table" in QuickTime terms), either from the video sample description,...
Definition qtpalette.c:323
int ff_replaygain_export(AVStream *st, AVDictionary *metadata)
Parse replaygain tags and export them as per-stream side data.
Definition replaygain.c:94
const AVCodecTag ff_codec_bmp_tags[]
Definition riff.c:36
const AVCodecTag ff_codec_wav_tags[]
Definition riff.c:525
internal header for RIFF based (de)muxers do NOT include this in end user applications
int ff_get_wav_header(AVFormatContext *s, AVIOContext *pb, AVCodecParameters *par, int size, int big_endian)
Definition riffdec.c:141
#define av_bswap32
Definition bswap.h:47
Public header for SHA-1 & SHA-256 hash function implementations.
#define FF_ARRAY_ELEMS(a)
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:89
#define width
Definition dsp.h:89
int av_timecode_init(AVTimecode *tc, AVRational rate, int flags, int frame_start, void *log_ctx)
Init a timecode struct with the passed parameters.
Definition timecode.c:201
char * av_timecode_make_string(const AVTimecode *tc, char *buf, int framenum_arg)
Load timecode string in buf.
Definition timecode.c:104
Timecode helpers header.
#define AV_TIMECODE_STR_SIZE
Definition timecode.h:33
@ AV_TIMECODE_FLAG_ALLOWNEGATIVE
negative time values are allowed
Definition timecode.h:38
@ AV_TIMECODE_FLAG_DROPFRAME
timecode is drop frame
Definition timecode.h:36
@ AV_TIMECODE_FLAG_24HOURSMAX
timecode wraps after 24 hours
Definition timecode.h:37
static int64_t pts
static const int16_t cdt2[8]
int size
UUID parsing and serialization utilities.
static int av_uuid_equal(const AVUUID uu1, const AVUUID uu2)
Compares two UUIDs for equality.
Definition uuid.h:119
#define AV_UUID_LEN
Definition uuid.h:57
uint8_t AVUUID[AV_UUID_LEN]
Definition uuid.h:60
enum AVCodecID codec_id
#define mc
static float mean(const float *input, int size)
Definition vf_nnedi.c:861
color_range
int len
static double c[64]