FFmpeg
Loading...
Searching...
No Matches
mov.c
Go to the documentation of this file.
1/*
2 * MOV demuxer
3 * Copyright (c) 2001 Fabrice Bellard
4 * Copyright (c) 2009 Baptiste Coudurier <baptiste dot coudurier at gmail dot com>
5 *
6 * first version by Francois Revol <revol@free.fr>
7 * seek function by Gael Chardon <gael.dev@4now.net>
8 *
9 * This file is part of FFmpeg.
10 *
11 * FFmpeg is free software; you can redistribute it and/or
12 * modify it under the terms of the GNU Lesser General Public
13 * License as published by the Free Software Foundation; either
14 * version 2.1 of the License, or (at your option) any later version.
15 *
16 * FFmpeg is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
19 * Lesser General Public License for more details.
20 *
21 * You should have received a copy of the GNU Lesser General Public
22 * License along with FFmpeg; if not, write to the Free Software
23 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
24 */
25
26#include "config_components.h"
27
28#include <inttypes.h>
29#include <limits.h>
30#include <stdint.h>
31#include <stdlib.h>
32
34#include "libavutil/bprint.h"
36#include "libavutil/dovi_meta.h"
37#include "libavutil/internal.h"
39#include "libavutil/intfloat.h"
41#include "libavutil/avassert.h"
42#include "libavutil/avstring.h"
43#include "libavutil/dict.h"
44#include "libavutil/display.h"
45#include "libavutil/mem.h"
46#include "libavutil/opt.h"
47#include "libavutil/aes.h"
48#include "libavutil/aes_ctr.h"
49#include "libavutil/pixdesc.h"
50#include "libavutil/sha.h"
51#include "libavutil/spherical.h"
52#include "libavutil/stereo3d.h"
53#include "libavutil/timecode.h"
54#include "libavutil/uuid.h"
55#include "libavcodec/ac3tab.h"
56#include "libavcodec/exif.h"
57#include "libavcodec/flac.h"
61#include "avformat.h"
62#include "internal.h"
63#include "avio_internal.h"
64#include "demux.h"
65#include "dvdclut.h"
66#include "iamf_parse.h"
67#include "iamf_reader.h"
68#include "dovi_isom.h"
69#include "riff.h"
70#include "isom.h"
71#include "libavcodec/get_bits.h"
72#include "id3v1.h"
73#include "mov_chan.h"
74#include "replaygain.h"
75
76#if CONFIG_ZLIB
77#include <zlib.h>
78#endif
79
80#include "qtpalette.h"
81
82/* those functions parse an atom */
83/* links atom IDs to parse functions */
84typedef struct MOVParseTableEntry {
85 uint32_t type;
86 int (*parse)(MOVContext *ctx, AVIOContext *pb, MOVAtom atom);
88
89static int mov_read_default(MOVContext *c, AVIOContext *pb, MOVAtom atom);
92
94 unsigned len, const char *key)
95{
96 char buf[16];
97
98 short current, total = 0;
99 avio_rb16(pb); // unknown
100 current = avio_rb16(pb);
101 if (len >= 6)
102 total = avio_rb16(pb);
103 if (!total)
104 snprintf(buf, sizeof(buf), "%d", current);
105 else
106 snprintf(buf, sizeof(buf), "%d/%d", current, total);
107 c->fc->event_flags |= AVFMT_EVENT_FLAG_METADATA_UPDATED;
108 av_dict_set(&c->fc->metadata, key, buf, 0);
109
110 return 0;
111}
112
114 unsigned len, const char *key)
115{
116 /* bypass padding bytes */
117 avio_r8(pb);
118 avio_r8(pb);
119 avio_r8(pb);
120
121 c->fc->event_flags |= AVFMT_EVENT_FLAG_METADATA_UPDATED;
122 av_dict_set_int(&c->fc->metadata, key, avio_r8(pb), 0);
123
124 return 0;
125}
126
128 unsigned len, const char *key)
129{
130 c->fc->event_flags |= AVFMT_EVENT_FLAG_METADATA_UPDATED;
131 av_dict_set_int(&c->fc->metadata, key, avio_r8(pb), 0);
132
133 return 0;
134}
135
137 unsigned len, const char *key)
138{
139 short genre;
140
141 avio_r8(pb); // unknown
142
143 genre = avio_r8(pb);
144 if (genre < 1 || genre > ID3v1_GENRE_MAX)
145 return 0;
146 c->fc->event_flags |= AVFMT_EVENT_FLAG_METADATA_UPDATED;
147 av_dict_set(&c->fc->metadata, key, ff_id3v1_genre_str[genre-1], 0);
148
149 return 0;
150}
151
152static const uint32_t mac_to_unicode[128] = {
153 0x00C4,0x00C5,0x00C7,0x00C9,0x00D1,0x00D6,0x00DC,0x00E1,
154 0x00E0,0x00E2,0x00E4,0x00E3,0x00E5,0x00E7,0x00E9,0x00E8,
155 0x00EA,0x00EB,0x00ED,0x00EC,0x00EE,0x00EF,0x00F1,0x00F3,
156 0x00F2,0x00F4,0x00F6,0x00F5,0x00FA,0x00F9,0x00FB,0x00FC,
157 0x2020,0x00B0,0x00A2,0x00A3,0x00A7,0x2022,0x00B6,0x00DF,
158 0x00AE,0x00A9,0x2122,0x00B4,0x00A8,0x2260,0x00C6,0x00D8,
159 0x221E,0x00B1,0x2264,0x2265,0x00A5,0x00B5,0x2202,0x2211,
160 0x220F,0x03C0,0x222B,0x00AA,0x00BA,0x03A9,0x00E6,0x00F8,
161 0x00BF,0x00A1,0x00AC,0x221A,0x0192,0x2248,0x2206,0x00AB,
162 0x00BB,0x2026,0x00A0,0x00C0,0x00C3,0x00D5,0x0152,0x0153,
163 0x2013,0x2014,0x201C,0x201D,0x2018,0x2019,0x00F7,0x25CA,
164 0x00FF,0x0178,0x2044,0x20AC,0x2039,0x203A,0xFB01,0xFB02,
165 0x2021,0x00B7,0x201A,0x201E,0x2030,0x00C2,0x00CA,0x00C1,
166 0x00CB,0x00C8,0x00CD,0x00CE,0x00CF,0x00CC,0x00D3,0x00D4,
167 0xF8FF,0x00D2,0x00DA,0x00DB,0x00D9,0x0131,0x02C6,0x02DC,
168 0x00AF,0x02D8,0x02D9,0x02DA,0x00B8,0x02DD,0x02DB,0x02C7,
169};
170
172 char *dst, int dstlen)
173{
174 char *p = dst;
175 char *end = dst+dstlen-1;
176 int i;
177
178 for (i = 0; i < len; i++) {
179 uint8_t t, c = avio_r8(pb);
180
181 if (p >= end)
182 continue;
183
184 if (c < 0x80)
185 *p++ = c;
186 else if (p < end)
187 PUT_UTF8(mac_to_unicode[c-0x80], t, if (p < end) *p++ = t;);
188 }
189 *p = 0;
190 return p - dst;
191}
192
193/**
194 * Get the requested item.
195 */
196static HEIFItem *get_heif_item(MOVContext *c, unsigned id)
197{
198 HEIFItem *item = NULL;
199
200 for (int i = 0; i < c->nb_heif_item; i++) {
201 if (!c->heif_item[i] || c->heif_item[i]->item_id != id)
202 continue;
203
204 item = c->heif_item[i];
205 break;
206 }
207
208 return item;
209}
210
211/**
212 * Get the current stream in the parsing process. This can either be the
213 * latest stream added to the context, or the stream referenced by an item.
214 */
216{
217 AVStream *st = NULL;
218 HEIFItem *item;
219
220 if (c->fc->nb_streams < 1)
221 return NULL;
222
223 if (c->cur_item_id == -1)
224 return c->fc->streams[c->fc->nb_streams-1];
225
226 item = get_heif_item(c, c->cur_item_id);
227 if (item)
228 st = item->st;
229
230 return st;
231}
232
233static int mov_read_covr(MOVContext *c, AVIOContext *pb, int type, int len)
234{
235 AVStream *st;
237 enum AVCodecID id;
238 int ret;
239
240 switch (type) {
241 case 0xd: id = AV_CODEC_ID_MJPEG; break;
242 case 0xe: id = AV_CODEC_ID_PNG; break;
243 case 0x1b: id = AV_CODEC_ID_BMP; break;
244 default:
245 av_log(c->fc, AV_LOG_WARNING, "Unknown cover type: 0x%x.\n", type);
246 avio_skip(pb, len);
247 return 0;
248 }
249
250 sc = av_mallocz(sizeof(*sc));
251 if (!sc)
252 return AVERROR(ENOMEM);
253 ret = ff_add_attached_pic(c->fc, NULL, pb, NULL, len);
254 if (ret < 0) {
255 av_free(sc);
256 return ret;
257 }
258 st = c->fc->streams[c->fc->nb_streams - 1];
259 st->priv_data = sc;
260 sc->id = st->id;
261 sc->refcount = 1;
262
263 if (st->attached_pic.size >= 8 && id != AV_CODEC_ID_BMP) {
264 if (AV_RB64(st->attached_pic.data) == 0x89504e470d0a1a0a) {
265 id = AV_CODEC_ID_PNG;
266 } else {
268 }
269 }
270 st->codecpar->codec_id = id;
271
272 return 0;
273}
274
275// 3GPP TS 26.244
276static int mov_metadata_loci(MOVContext *c, AVIOContext *pb, unsigned len)
277{
278 char language[4] = { 0 };
279 char buf[200], place[100];
280 uint16_t langcode = 0;
281 double longitude, latitude, altitude;
282 const char *key = "location";
283
284 if (len < 4 + 2 + 1 + 1 + 4 + 4 + 4) {
285 av_log(c->fc, AV_LOG_ERROR, "loci too short\n");
286 return AVERROR_INVALIDDATA;
287 }
288
289 avio_skip(pb, 4); // version+flags
290 langcode = avio_rb16(pb);
291 ff_mov_lang_to_iso639(langcode, language);
292 len -= 6;
293
294 len -= avio_get_str(pb, len, place, sizeof(place));
295 if (len < 1) {
296 av_log(c->fc, AV_LOG_ERROR, "place name too long\n");
297 return AVERROR_INVALIDDATA;
298 }
299 avio_skip(pb, 1); // role
300 len -= 1;
301
302 if (len < 12) {
303 av_log(c->fc, AV_LOG_ERROR,
304 "loci too short (%u bytes left, need at least %d)\n", len, 12);
305 return AVERROR_INVALIDDATA;
306 }
307 longitude = ((int32_t) avio_rb32(pb)) / (float) (1 << 16);
308 latitude = ((int32_t) avio_rb32(pb)) / (float) (1 << 16);
309 altitude = ((int32_t) avio_rb32(pb)) / (float) (1 << 16);
310
311 // Try to output in the same format as the ?xyz field
312 snprintf(buf, sizeof(buf), "%+08.4f%+09.4f", latitude, longitude);
313 if (altitude)
314 av_strlcatf(buf, sizeof(buf), "%+f", altitude);
315 av_strlcatf(buf, sizeof(buf), "/%s", place);
316
317 if (*language && strcmp(language, "und")) {
318 char key2[16];
319 snprintf(key2, sizeof(key2), "%s-%s", key, language);
320 av_dict_set(&c->fc->metadata, key2, buf, 0);
321 }
322 c->fc->event_flags |= AVFMT_EVENT_FLAG_METADATA_UPDATED;
323 return av_dict_set(&c->fc->metadata, key, buf, 0);
324}
325
326static int mov_metadata_hmmt(MOVContext *c, AVIOContext *pb, unsigned len)
327{
328 int i, n_hmmt;
329
330 if (len < 2)
331 return 0;
332 if (c->ignore_chapters)
333 return 0;
334
335 n_hmmt = avio_rb32(pb);
336 if (n_hmmt > len / 4)
337 return AVERROR_INVALIDDATA;
338 for (i = 0; i < n_hmmt && !pb->eof_reached; i++) {
339 int moment_time = avio_rb32(pb);
340 avpriv_new_chapter(c->fc, i, av_make_q(1, 1000), moment_time, AV_NOPTS_VALUE, NULL);
341 }
342 if (avio_feof(pb))
343 return AVERROR_INVALIDDATA;
344 return 0;
345}
346
348{
349 char tmp_key[AV_FOURCC_MAX_STRING_SIZE] = {0};
350 char key2[32], language[4] = {0};
351 char *str = NULL;
352 const char *key = NULL;
353 uint16_t langcode = 0;
354 uint32_t data_type = 0, str_size_alloc;
355 uint64_t str_size;
356 int (*parse)(MOVContext*, AVIOContext*, unsigned, const char*) = NULL;
357 int raw = 0;
358 int num = 0;
360
361 if (c->trak_index >= 0 && c->trak_index < c->fc->nb_streams)
362 metadata = &c->fc->streams[c->trak_index]->metadata;
363 else
364 metadata = &c->fc->metadata;
365
366 switch (atom.type) {
367 case MKTAG( '@','P','R','M'): key = "premiere_version"; raw = 1; break;
368 case MKTAG( '@','P','R','Q'): key = "quicktime_version"; raw = 1; break;
369 case MKTAG( 'X','M','P','_'):
370 if (c->export_xmp) { key = "xmp"; raw = 1; } break;
371 case MKTAG( 'a','A','R','T'): key = "album_artist"; break;
372 case MKTAG( 'a','k','I','D'): key = "account_type";
374 case MKTAG( 'a','p','I','D'): key = "account_id"; break;
375 case MKTAG( 'c','a','t','g'): key = "category"; break;
376 case MKTAG( 'c','p','i','l'): key = "compilation";
378 case MKTAG( 'c','p','r','t'): key = "copyright"; break;
379 case MKTAG( 'd','e','s','c'): key = "description"; break;
380 case MKTAG( 'd','i','s','k'): key = "disc";
382 case MKTAG( 'e','g','i','d'): key = "episode_uid";
384 case MKTAG( 'F','I','R','M'): key = "firmware"; raw = 1; break;
385 case MKTAG( 'g','n','r','e'): key = "genre";
386 parse = mov_metadata_gnre; break;
387 case MKTAG( 'h','d','v','d'): key = "hd_video";
389 case MKTAG( 'H','M','M','T'):
390 return mov_metadata_hmmt(c, pb, atom.size);
391 case MKTAG( 'k','e','y','w'): key = "keywords"; break;
392 case MKTAG( 'l','d','e','s'): key = "synopsis"; break;
393 case MKTAG( 'l','o','c','i'):
394 return mov_metadata_loci(c, pb, atom.size);
395 case MKTAG( 'm','a','n','u'): key = "make"; break;
396 case MKTAG( 'm','o','d','l'): key = "model"; break;
397 case MKTAG( 'n','a','m','e'): key = "name"; break;
398 case MKTAG( 'p','c','s','t'): key = "podcast";
400 case MKTAG( 'p','g','a','p'): key = "gapless_playback";
402 case MKTAG( 'p','u','r','d'): key = "purchase_date"; break;
403 case MKTAG( 'r','t','n','g'): key = "rating";
405 case MKTAG( 's','o','a','a'): key = "sort_album_artist"; break;
406 case MKTAG( 's','o','a','l'): key = "sort_album"; break;
407 case MKTAG( 's','o','a','r'): key = "sort_artist"; break;
408 case MKTAG( 's','o','c','o'): key = "sort_composer"; break;
409 case MKTAG( 's','o','n','m'): key = "sort_name"; break;
410 case MKTAG( 's','o','s','n'): key = "sort_show"; break;
411 case MKTAG( 's','t','i','k'): key = "media_type";
413 case MKTAG( 't','r','k','n'): key = "track";
415 case MKTAG( 't','v','e','n'): key = "episode_id"; break;
416 case MKTAG( 't','v','e','s'): key = "episode_sort";
418 case MKTAG( 't','v','n','n'): key = "network"; break;
419 case MKTAG( 't','v','s','h'): key = "show"; break;
420 case MKTAG( 't','v','s','n'): key = "season_number";
422 case MKTAG(0xa9,'A','R','T'): key = "artist"; break;
423 case MKTAG(0xa9,'P','R','D'): key = "producer"; break;
424 case MKTAG(0xa9,'a','l','b'): key = "album"; break;
425 case MKTAG(0xa9,'a','u','t'): key = "artist"; break;
426 case MKTAG(0xa9,'c','h','p'): key = "chapter"; break;
427 case MKTAG(0xa9,'c','m','t'): key = "comment"; break;
428 case MKTAG(0xa9,'c','o','m'): key = "composer"; break;
429 case MKTAG(0xa9,'c','p','y'): key = "copyright"; break;
430 case MKTAG(0xa9,'d','a','y'): key = "date"; break;
431 case MKTAG(0xa9,'d','i','r'): key = "director"; break;
432 case MKTAG(0xa9,'d','i','s'): key = "disclaimer"; break;
433 case MKTAG(0xa9,'e','d','1'): key = "edit_date"; break;
434 case MKTAG(0xa9,'e','n','c'): key = "encoder"; break;
435 case MKTAG(0xa9,'f','m','t'): key = "original_format"; break;
436 case MKTAG(0xa9,'g','e','n'): key = "genre"; break;
437 case MKTAG(0xa9,'g','r','p'): key = "grouping"; break;
438 case MKTAG(0xa9,'h','s','t'): key = "host_computer"; break;
439 case MKTAG(0xa9,'i','n','f'): key = "comment"; break;
440 case MKTAG(0xa9,'l','y','r'): key = "lyrics"; break;
441 case MKTAG(0xa9,'m','a','k'): key = "make"; break;
442 case MKTAG(0xa9,'m','o','d'): key = "model"; break;
443 case MKTAG(0xa9,'n','a','m'): key = "title"; break;
444 case MKTAG(0xa9,'o','p','e'): key = "original_artist"; break;
445 case MKTAG(0xa9,'p','r','d'): key = "producer"; break;
446 case MKTAG(0xa9,'p','r','f'): key = "performers"; break;
447 case MKTAG(0xa9,'r','e','q'): key = "playback_requirements"; break;
448 case MKTAG(0xa9,'s','r','c'): key = "original_source"; break;
449 case MKTAG(0xa9,'s','t','3'): key = "subtitle"; break;
450 case MKTAG(0xa9,'s','w','r'): key = "encoder"; break;
451 case MKTAG(0xa9,'t','o','o'): key = "encoder"; break;
452 case MKTAG(0xa9,'t','r','k'): key = "track"; break;
453 case MKTAG(0xa9,'u','r','l'): key = "URL"; break;
454 case MKTAG(0xa9,'w','r','n'): key = "warning"; break;
455 case MKTAG(0xa9,'w','r','t'): key = "composer"; break;
456 case MKTAG(0xa9,'x','y','z'): key = "location"; break;
457 }
458retry:
459 if (c->itunes_metadata && atom.size > 8) {
460 int data_size = avio_rb32(pb);
461 int tag = avio_rl32(pb);
462 if (tag == MKTAG('d','a','t','a') && data_size <= atom.size && data_size >= 16) {
463 data_type = avio_rb32(pb); // type
464 avio_rb32(pb); // unknown
465 str_size = data_size - 16;
466 atom.size -= 16;
467
468 if (!key && c->found_hdlr_mdta && c->meta_keys) {
469 uint32_t index = av_bswap32(atom.type); // BE number has been read as LE
470 if (index < c->meta_keys_count && index > 0) {
471 key = c->meta_keys[index];
472 } else if (atom.type != MKTAG('c', 'o', 'v', 'r')) {
474 "The index of 'data' is out of range: %"PRId32" < 1 or >= %d.\n",
475 index, c->meta_keys_count);
476 }
477 }
478 if (atom.type == MKTAG('c', 'o', 'v', 'r') ||
479 (key && !strcmp(key, "com.apple.quicktime.artwork"))) {
480 int ret = mov_read_covr(c, pb, data_type, str_size);
481 if (ret < 0) {
482 av_log(c->fc, AV_LOG_ERROR, "Error parsing cover art.\n");
483 return ret;
484 }
485 atom.size -= str_size;
486 if (atom.size > 8)
487 goto retry;
488 return ret;
489 }
490 } else return 0;
491 } else if (atom.size > 4 && (key || c->export_all) && !c->itunes_metadata && !raw) {
492 str_size = avio_rb16(pb); // string length
493 if (str_size > atom.size) {
494 raw = 1;
495 avio_seek(pb, -2, SEEK_CUR);
496 av_log(c->fc, AV_LOG_WARNING, "UDTA parsing failed retrying raw\n");
497 goto retry;
498 }
499 langcode = avio_rb16(pb);
500 ff_mov_lang_to_iso639(langcode, language);
501 atom.size -= 4;
502 } else
503 str_size = atom.size;
504
505 if (c->export_all && !key) {
506 key = av_fourcc_make_string(tmp_key, atom.type);
507 }
508
509 if (!key)
510 return 0;
511 if (atom.size < 0 || str_size >= INT_MAX/2)
512 return AVERROR_INVALIDDATA;
513
514 // Allocates enough space if data_type is a int32 or float32 number, otherwise
515 // worst-case requirement for output string in case of utf8 coded input
516 num = (data_type >= 21 && data_type <= 23);
517 str_size_alloc = (num ? 512 : (raw ? str_size : str_size * 2)) + 1;
518 str = av_mallocz(str_size_alloc);
519 if (!str)
520 return AVERROR(ENOMEM);
521
522 if (parse)
523 parse(c, pb, str_size, key);
524 else {
525 if (!raw && (data_type == 3 || (data_type == 0 && (langcode < 0x400 || langcode == 0x7fff)))) { // MAC Encoded
526 mov_read_mac_string(c, pb, str_size, str, str_size_alloc);
527 } else if (data_type == 21) { // BE signed integer, variable size
528 int val = 0;
529 if (str_size == 1)
530 val = (int8_t)avio_r8(pb);
531 else if (str_size == 2)
532 val = (int16_t)avio_rb16(pb);
533 else if (str_size == 3)
534 val = ((int32_t)(avio_rb24(pb)<<8))>>8;
535 else if (str_size == 4)
536 val = (int32_t)avio_rb32(pb);
537 if (snprintf(str, str_size_alloc, "%d", val) >= str_size_alloc) {
538 av_log(c->fc, AV_LOG_ERROR,
539 "Failed to store the number (%d) in string.\n", val);
540 av_free(str);
541 return AVERROR_INVALIDDATA;
542 }
543 } else if (data_type == 22) { // BE unsigned integer, variable size
544 unsigned int val = 0;
545 if (str_size == 1)
546 val = avio_r8(pb);
547 else if (str_size == 2)
548 val = avio_rb16(pb);
549 else if (str_size == 3)
550 val = avio_rb24(pb);
551 else if (str_size == 4)
552 val = avio_rb32(pb);
553 if (snprintf(str, str_size_alloc, "%u", val) >= str_size_alloc) {
554 av_log(c->fc, AV_LOG_ERROR,
555 "Failed to store the number (%u) in string.\n", val);
556 av_free(str);
557 return AVERROR_INVALIDDATA;
558 }
559 } else if (data_type == 23 && str_size >= 4) { // BE float32
560 float val = av_int2float(avio_rb32(pb));
561 if (snprintf(str, str_size_alloc, "%f", val) >= str_size_alloc) {
562 av_log(c->fc, AV_LOG_ERROR,
563 "Failed to store the float32 number (%f) in string.\n", val);
564 av_free(str);
565 return AVERROR_INVALIDDATA;
566 }
567 } else if (data_type > 1 && data_type != 4) {
568 // data_type can be 0 if not set at all above. data_type 1 means
569 // UTF8 and 4 means "UTF8 sort". For any other type (UTF16 or e.g.
570 // a picture), don't return it blindly in a string that is supposed
571 // to be UTF8 text.
572 av_log(c->fc, AV_LOG_WARNING, "Skipping unhandled metadata %s of type %"PRIu32"\n", key, data_type);
573 av_free(str);
574 return 0;
575 } else {
576 int ret = ffio_read_size(pb, str, str_size);
577 if (ret < 0) {
578 av_free(str);
579 return ret;
580 }
581 str[str_size] = 0;
582 }
583 c->fc->event_flags |= AVFMT_EVENT_FLAG_METADATA_UPDATED;
584 if (c->itunes_metadata && av_dict_get(*metadata, key, NULL, 0))
586 av_dict_set(metadata, key, str, c->itunes_metadata ? AV_DICT_APPEND : 0);
587 if (*language && strcmp(language, "und")) {
588 snprintf(key2, sizeof(key2), "%s-%s", key, language);
589 av_dict_set(metadata, key2, str, 0);
590 }
591 if (!strcmp(key, "encoder")) {
592 int major, minor, micro;
593 if (sscanf(str, "HandBrake %d.%d.%d", &major, &minor, &micro) == 3) {
594 c->handbrake_version = 1000000*major + 1000*minor + micro;
595 }
596 }
597
598 atom.size -= str_size;
599 av_freep(&str);
600
601 // Read remaining data atoms for multi-valued iTunes tags (e.g. multiple
602 // artists stored as multiple data atoms within one tag atom), consistent
603 // with the existing covr path.
604 // Note: multiple sibling tag atoms with the same key (e.g. three separate
605 // ©ART atoms under ilst) are handled by the AV_DICT_APPEND logic above,
606 // since mov_read_udta_string() is called once per tag atom.
607 if (c->itunes_metadata && atom.size > 8)
608 goto retry;
609 }
610
611 av_freep(&str);
612 return 0;
613}
614
616{
617 int64_t start;
618 int i, nb_chapters, str_len, version;
619 char str[256+1];
620 int ret;
621
622 if (c->ignore_chapters)
623 return 0;
624
625 if ((atom.size -= 5) < 0)
626 return 0;
627
628 version = avio_r8(pb);
629 avio_rb24(pb);
630 if (version)
631 avio_rb32(pb); // ???
632 nb_chapters = avio_r8(pb);
633
634 for (i = 0; i < nb_chapters; i++) {
635 if (atom.size < 9)
636 return 0;
637
638 start = avio_rb64(pb);
639 str_len = avio_r8(pb);
640
641 if ((atom.size -= 9+str_len) < 0)
642 return 0;
643
644 ret = ffio_read_size(pb, str, str_len);
645 if (ret < 0)
646 return ret;
647 str[str_len] = 0;
648 avpriv_new_chapter(c->fc, i, (AVRational){1,10000000}, start, AV_NOPTS_VALUE, str);
649 }
650 return 0;
651}
652
653#define MIN_DATA_ENTRY_BOX_SIZE 12
655{
656 AVStream *st;
658 int entries, i, j;
659
660 if (c->fc->nb_streams < 1)
661 return 0;
662 st = c->fc->streams[c->fc->nb_streams-1];
663 sc = st->priv_data;
664
665 avio_rb32(pb); // version + flags
666 entries = avio_rb32(pb);
667 if (!entries ||
668 entries > (atom.size - 1) / MIN_DATA_ENTRY_BOX_SIZE + 1 ||
669 entries >= UINT_MAX / sizeof(*sc->drefs))
670 return AVERROR_INVALIDDATA;
671
672 for (i = 0; i < sc->drefs_count; i++) {
673 MOVDref *dref = &sc->drefs[i];
674 av_freep(&dref->path);
675 av_freep(&dref->dir);
676 }
677 av_free(sc->drefs);
678 sc->drefs_count = 0;
679 sc->drefs = av_mallocz(entries * sizeof(*sc->drefs));
680 if (!sc->drefs)
681 return AVERROR(ENOMEM);
682 sc->drefs_count = entries;
683
684 for (i = 0; i < entries; i++) {
685 MOVDref *dref = &sc->drefs[i];
686 uint32_t size = avio_rb32(pb);
687 int64_t next = avio_tell(pb);
688
689 if (size < 12 || next < 0 || next > INT64_MAX - size)
690 return AVERROR_INVALIDDATA;
691
692 next += size - 4;
693
694 dref->type = avio_rl32(pb);
695 avio_rb32(pb); // version + flags
696
697 if (dref->type == MKTAG('a','l','i','s') && size > 150) {
698 /* macintosh alias record */
699 uint16_t volume_len, len;
700 int16_t type;
701 int ret;
702
703 avio_skip(pb, 10);
704
705 volume_len = avio_r8(pb);
706 volume_len = FFMIN(volume_len, 27);
707 ret = ffio_read_size(pb, dref->volume, 27);
708 if (ret < 0)
709 return ret;
710 dref->volume[volume_len] = 0;
711 av_log(c->fc, AV_LOG_DEBUG, "volume %s, len %d\n", dref->volume, volume_len);
712
713 avio_skip(pb, 12);
714
715 len = avio_r8(pb);
716 len = FFMIN(len, 63);
717 ret = ffio_read_size(pb, dref->filename, 63);
718 if (ret < 0)
719 return ret;
720 dref->filename[len] = 0;
721 av_log(c->fc, AV_LOG_DEBUG, "filename %s, len %d\n", dref->filename, len);
722
723 avio_skip(pb, 16);
724
725 /* read next level up_from_alias/down_to_target */
726 dref->nlvl_from = avio_rb16(pb);
727 dref->nlvl_to = avio_rb16(pb);
728 av_log(c->fc, AV_LOG_DEBUG, "nlvl from %d, nlvl to %d\n",
729 dref->nlvl_from, dref->nlvl_to);
730
731 avio_skip(pb, 16);
732
733 for (type = 0; type != -1 && avio_tell(pb) < next; ) {
734 if (avio_feof(pb))
735 return AVERROR_EOF;
736 type = avio_rb16(pb);
737 len = avio_rb16(pb);
738 av_log(c->fc, AV_LOG_DEBUG, "type %d, len %d\n", type, len);
739 if (len&1)
740 len += 1;
741 if (type == 2) { // absolute path
742 av_free(dref->path);
743 dref->path = av_mallocz(len+1);
744 if (!dref->path)
745 return AVERROR(ENOMEM);
746
747 ret = ffio_read_size(pb, dref->path, len);
748 if (ret < 0) {
749 av_freep(&dref->path);
750 return ret;
751 }
752 if (len > volume_len && !strncmp(dref->path, dref->volume, volume_len)) {
753 len -= volume_len;
754 memmove(dref->path, dref->path+volume_len, len);
755 dref->path[len] = 0;
756 }
757 // trim string of any ending zeros
758 for (j = len - 1; j >= 0; j--) {
759 if (dref->path[j] == 0)
760 len--;
761 else
762 break;
763 }
764 for (j = 0; j < len; j++)
765 if (dref->path[j] == ':' || dref->path[j] == 0)
766 dref->path[j] = '/';
767 av_log(c->fc, AV_LOG_DEBUG, "path %s\n", dref->path);
768 } else if (type == 0) { // directory name
769 av_free(dref->dir);
770 dref->dir = av_malloc(len+1);
771 if (!dref->dir)
772 return AVERROR(ENOMEM);
773
774 ret = ffio_read_size(pb, dref->dir, len);
775 if (ret < 0) {
776 av_freep(&dref->dir);
777 return ret;
778 }
779 dref->dir[len] = 0;
780 for (j = 0; j < len; j++)
781 if (dref->dir[j] == ':')
782 dref->dir[j] = '/';
783 av_log(c->fc, AV_LOG_DEBUG, "dir %s\n", dref->dir);
784 } else
785 avio_skip(pb, len);
786 }
787 } else {
788 av_log(c->fc, AV_LOG_DEBUG, "Unknown dref type 0x%08"PRIx32" size %"PRIu32"\n",
789 dref->type, size);
790 entries--;
791 i--;
792 }
793 avio_seek(pb, next, SEEK_SET);
794 }
795 return 0;
796}
797
799{
800 AVStream *st;
801 uint32_t type;
802 uint32_t ctype;
803 int64_t title_size;
804 char *title_str;
805 int ret;
806
807 avio_r8(pb); /* version */
808 avio_rb24(pb); /* flags */
809
810 /* component type */
811 ctype = avio_rl32(pb);
812 type = avio_rl32(pb); /* component subtype */
813
814 av_log(c->fc, AV_LOG_TRACE, "ctype=%s\n", av_fourcc2str(ctype));
815 av_log(c->fc, AV_LOG_TRACE, "stype=%s\n", av_fourcc2str(type));
816
817 if (c->trak_index < 0) { // meta not inside a trak
818 if (type == MKTAG('m','d','t','a')) {
819 c->found_hdlr_mdta = 1;
820 }
821 return 0;
822 }
823
824 st = c->fc->streams[c->fc->nb_streams-1];
825
826 if (type == MKTAG('v','i','d','e'))
828 else if (type == MKTAG('s','o','u','n'))
830 else if (type == MKTAG('m','1','a',' '))
832 else if ((type == MKTAG('s','u','b','p')) || (type == MKTAG('c','l','c','p')))
834
835 avio_rb32(pb); /* component manufacture */
836 avio_rb32(pb); /* component flags */
837 avio_rb32(pb); /* component flags mask */
838
839 title_size = atom.size - 24;
840 if (title_size > 0) {
841 if (title_size > FFMIN(INT_MAX, SIZE_MAX-1))
842 return AVERROR_INVALIDDATA;
843 title_str = av_malloc(title_size + 1); /* Add null terminator */
844 if (!title_str)
845 return AVERROR(ENOMEM);
846
847 ret = ffio_read_size(pb, title_str, title_size);
848 if (ret < 0) {
849 av_freep(&title_str);
850 return ret;
851 }
852 title_str[title_size] = 0;
853 if (title_str[0]) {
854 int off = (!c->isom && title_str[0] == title_size - 1);
855 // flag added so as to not set stream handler name if already set from mdia->hdlr
856 av_dict_set(&st->metadata, "handler_name", title_str + off, AV_DICT_DONT_OVERWRITE);
857 }
858 av_freep(&title_str);
859 }
860
861 return 0;
862}
863
865{
866 return ff_mov_read_esds(c->fc, pb);
867}
868
870{
871 AVStream *st;
873 enum AVAudioServiceType *ast;
874 int ac3info, acmod, lfeon, bsmod;
875 uint64_t mask;
876
877 if (c->fc->nb_streams < 1)
878 return 0;
879 st = c->fc->streams[c->fc->nb_streams-1];
880
884 sizeof(*ast), 0);
885 if (!sd)
886 return AVERROR(ENOMEM);
887
888 ast = (enum AVAudioServiceType*)sd->data;
889 ac3info = avio_rb24(pb);
890 bsmod = (ac3info >> 14) & 0x7;
891 acmod = (ac3info >> 11) & 0x7;
892 lfeon = (ac3info >> 10) & 0x1;
893
895 if (lfeon)
899
900 *ast = bsmod;
901 if (st->codecpar->ch_layout.nb_channels > 1 && bsmod == 0x7)
903
904 return 0;
905}
906
907#if CONFIG_IAMFDEC
908static int mov_read_iacb(MOVContext *c, AVIOContext *pb, MOVAtom atom)
909{
910 AVStream *st;
913 AVIOContext *descriptor_pb;
915 IAMFContext *iamf;
917 unsigned descriptors_size;
918 int nb_frames, disposition;
919 int version, ret;
920
921 if (atom.size < 5)
922 return AVERROR_INVALIDDATA;
923
924 if (c->fc->nb_streams < 1)
925 return 0;
926
927 version = avio_r8(pb);
928 if (version != 1) {
929 av_log(c->fc, AV_LOG_ERROR, "%s configurationVersion %d",
930 version < 1 ? "invalid" : "unsupported", version);
931 return AVERROR_INVALIDDATA;
932 }
933
934 descriptors_size = ffio_read_leb(pb);
935 if (!descriptors_size || descriptors_size > INT_MAX)
936 return AVERROR_INVALIDDATA;
937
938 st = c->fc->streams[c->fc->nb_streams - 1];
939 sc = st->priv_data;
940
941 if (st->codecpar->extradata) {
942 av_log(c->fc, AV_LOG_WARNING, "ignoring iacb\n");
943 return 0;
944 }
945
946 sc->iamf = av_mallocz(sizeof(*sc->iamf));
947 if (!sc->iamf)
948 return AVERROR(ENOMEM);
949 iamf = &sc->iamf->iamf;
950
951 ret = ff_alloc_extradata(st->codecpar, descriptors_size);
952 if (ret < 0)
953 return ret;
954
955 ret = avio_read(pb, st->codecpar->extradata, descriptors_size);
956 if (ret != descriptors_size)
957 return ret < 0 ? ret : AVERROR_INVALIDDATA;
958
959 ffio_init_read_context(&b, st->codecpar->extradata, descriptors_size);
960 descriptor_pb = &b.pub;
961
962 ret = ff_iamfdec_read_descriptors(iamf, descriptor_pb, descriptors_size, c->fc);
963 if (ret < 0)
964 return ret;
965
966 metadata = st->metadata;
967 st->metadata = NULL;
969 nb_frames = st->nb_frames;
970 duration = st->duration;
971 disposition = st->disposition;
972
973 for (int i = 0; i < iamf->nb_audio_elements; i++) {
974 IAMFAudioElement *audio_element = iamf->audio_elements[i];
975 const AVIAMFAudioElement *element;
976 AVStreamGroup *stg =
978
979 if (!stg) {
980 ret = AVERROR(ENOMEM);
981 goto fail;
982 }
983
985 stg->id = audio_element->audio_element_id;
986 /* Transfer ownership */
987 element = stg->params.iamf_audio_element = audio_element->element;
988 audio_element->element = NULL;
989
990 for (int j = 0; j < audio_element->nb_substreams; j++) {
991 IAMFSubStream *substream = &audio_element->substreams[j];
992 AVStream *stream;
993
994 if (!i && !j) {
995 if (audio_element->layers[0].substream_count != 1)
996 disposition &= ~AV_DISPOSITION_DEFAULT;
997 stream = st;
998 } else
999 stream = avformat_new_stream(c->fc, NULL);
1000 if (!stream) {
1001 ret = AVERROR(ENOMEM);
1002 goto fail;
1003 }
1004
1005 stream->start_time = start_time;
1006 stream->nb_frames = nb_frames;
1007 stream->duration = duration;
1008 stream->disposition = disposition;
1009 if (stream != st) {
1010 stream->priv_data = sc;
1011 sc->refcount++;
1012 }
1013
1016 if (i || j) {
1018 if (audio_element->layers[0].substream_count == 1)
1020 }
1021
1022 ret = avcodec_parameters_copy(stream->codecpar, substream->codecpar);
1023 if (ret < 0)
1024 goto fail;
1025
1026 stream->id = substream->audio_substream_id;
1027
1028 avpriv_set_pts_info(st, 64, 1, sc->time_scale);
1029
1030 ret = avformat_stream_group_add_stream(stg, stream);
1031 if (ret < 0)
1032 goto fail;
1033 }
1034
1035 ret = av_dict_copy(&stg->metadata, metadata, 0);
1036 if (ret < 0)
1037 goto fail;
1038 }
1039
1040 for (int i = 0; i < iamf->nb_mix_presentations; i++) {
1041 IAMFMixPresentation *mix_presentation = iamf->mix_presentations[i];
1042 const AVIAMFMixPresentation *mix = mix_presentation->cmix;
1043 AVStreamGroup *stg =
1045
1046 if (!stg) {
1047 ret = AVERROR(ENOMEM);
1048 goto fail;
1049 }
1050
1052 stg->id = mix_presentation->mix_presentation_id;
1053 /* Transfer ownership */
1054 stg->params.iamf_mix_presentation = mix_presentation->mix;
1055 mix_presentation->mix = NULL;
1056
1057 for (int j = 0; j < mix->nb_submixes; j++) {
1058 const AVIAMFSubmix *submix = mix->submixes[j];
1059
1060 for (int k = 0; k < submix->nb_elements; k++) {
1061 const AVIAMFSubmixElement *submix_element = submix->elements[k];
1062 const AVStreamGroup *audio_element = NULL;
1063
1064 for (int l = 0; l < c->fc->nb_stream_groups; l++)
1065 if (c->fc->stream_groups[l]->type == AV_STREAM_GROUP_PARAMS_IAMF_AUDIO_ELEMENT &&
1066 c->fc->stream_groups[l]->id == submix_element->audio_element_id) {
1067 audio_element = c->fc->stream_groups[l];
1068 break;
1069 }
1070 av_assert0(audio_element);
1071
1072 for (int l = 0; l < audio_element->nb_streams; l++) {
1073 ret = avformat_stream_group_add_stream(stg, audio_element->streams[l]);
1074 if (ret < 0 && ret != AVERROR(EEXIST))
1075 goto fail;
1076 }
1077 }
1078 }
1079
1080 ret = av_dict_copy(&stg->metadata, metadata, 0);
1081 if (ret < 0)
1082 goto fail;
1083 }
1084
1085 ret = 0;
1086fail:
1088
1089 return ret;
1090}
1091#endif
1092
1094{
1095 AVStream *st;
1096 int32_t sample_rate;
1097
1098 if (atom.size < 8 || c->fc->nb_streams < 1)
1099 return 0;
1100
1101 st = c->fc->streams[c->fc->nb_streams-1];
1103 av_log(c->fc, AV_LOG_WARNING, "'srat' within non-audio sample entry, skip\n");
1104 return 0;
1105 }
1106
1107 if (!c->isom) {
1108 av_log(c->fc, AV_LOG_WARNING, "'srat' within non-isom, skip\n");
1109 return 0;
1110 }
1111
1112 avio_skip(pb, 4); // version+flags
1113 sample_rate = avio_rb32(pb);
1114 if (sample_rate > 0) {
1115 av_log(c->fc, AV_LOG_DEBUG,
1116 "overwrite sample rate from %d to %d by 'srat'\n",
1117 st->codecpar->sample_rate, sample_rate);
1118 st->codecpar->sample_rate = sample_rate;
1119 } else {
1120 av_log(c->fc, AV_LOG_WARNING,
1121 "ignore invalid sample rate %d in 'srat'\n", sample_rate);
1122 }
1123
1124 return 0;
1125}
1126
1128{
1129 AVStream *st;
1130 AVPacketSideData *sd;
1131 enum AVAudioServiceType *ast;
1132 int eac3info, acmod, lfeon, bsmod;
1133 uint64_t mask;
1134
1135 if (c->fc->nb_streams < 1)
1136 return 0;
1137 st = c->fc->streams[c->fc->nb_streams-1];
1138
1142 sizeof(*ast), 0);
1143 if (!sd)
1144 return AVERROR(ENOMEM);
1145
1146 ast = (enum AVAudioServiceType*)sd->data;
1147
1148 /* No need to parse fields for additional independent substreams and its
1149 * associated dependent substreams since libavcodec's E-AC-3 decoder
1150 * does not support them yet. */
1151 avio_rb16(pb); /* data_rate and num_ind_sub */
1152 eac3info = avio_rb24(pb);
1153 bsmod = (eac3info >> 12) & 0x1f;
1154 acmod = (eac3info >> 9) & 0x7;
1155 lfeon = (eac3info >> 8) & 0x1;
1156
1158 if (lfeon)
1162
1163 *ast = bsmod;
1164 if (st->codecpar->ch_layout.nb_channels > 1 && bsmod == 0x7)
1166
1167 return 0;
1168}
1169
1170/* Maps the DTS `StreamConstruction` field (ETSI TS 102 114 Table E-2) to the
1171 * coarse FFmpeg DTS profile enum. Extension-substream XLL maps to HD_MA;
1172 * extension-substream XXCH, X96, or XBR maps to HD_HRA; core-substream XCH or
1173 * XXCH maps to ES; core-substream X96 maps to 96/24; a core component alone
1174 * maps to DTS; and extension-substream LBR maps to Express. Value 0 (undefined)
1175 * and values outside 1..21 map to AV_PROFILE_UNKNOWN. */
1177{
1178 static const int profile[22] = {
1179 [ 1] = AV_PROFILE_DTS, /* core Core */
1180 [ 2] = AV_PROFILE_DTS_ES, /* core Core + core XCH */
1181 [ 3] = AV_PROFILE_DTS_ES, /* core Core + core XXCH */
1182 [ 4] = AV_PROFILE_DTS_96_24, /* core Core + core X96 */
1183 [ 5] = AV_PROFILE_DTS_HD_HRA, /* core Core + ext XXCH */
1184 [ 6] = AV_PROFILE_DTS_HD_HRA, /* core Core + ext XBR */
1185 [ 7] = AV_PROFILE_DTS_HD_HRA, /* core Core + core XCH + ext XBR */
1186 [ 8] = AV_PROFILE_DTS_HD_HRA, /* core Core + core XXCH + ext XBR */
1187 [ 9] = AV_PROFILE_DTS_HD_HRA, /* core Core + ext XXCH + ext XBR */
1188 [10] = AV_PROFILE_DTS_HD_HRA, /* core Core + ext X96 */
1189 [11] = AV_PROFILE_DTS_HD_HRA, /* core Core + core XCH + ext X96 */
1190 [12] = AV_PROFILE_DTS_HD_HRA, /* core Core + core XXCH + ext X96 */
1191 [13] = AV_PROFILE_DTS_HD_HRA, /* core Core + ext XXCH + ext X96 */
1192 [14] = AV_PROFILE_DTS_HD_MA, /* core Core + ext XLL */
1193 [15] = AV_PROFILE_DTS_HD_MA, /* core Core + core XCH + ext XLL */
1194 [16] = AV_PROFILE_DTS_HD_MA, /* core Core + core X96 + ext XLL */
1195 [17] = AV_PROFILE_DTS_HD_MA, /* ext XLL */
1196 [18] = AV_PROFILE_DTS_EXPRESS, /* ext LBR */
1197 [19] = AV_PROFILE_DTS, /* ext Core */
1198 [20] = AV_PROFILE_DTS_HD_HRA, /* ext Core + ext XXCH */
1199 [21] = AV_PROFILE_DTS_HD_MA, /* ext Core + ext XLL */
1200 };
1201 if (!sc || sc > 21)
1202 return AV_PROFILE_UNKNOWN;
1203 return profile[sc];
1204}
1205
1206/* Maps the 16-bit DTS `ChannelLayout` bitmask (ETSI TS 102 114 Table E-5) to an
1207 * ffmpeg channel mask. Pair bits follow Table 7-10 / DCA_SPEAKER_PAIR_*;
1208 * LwRw (0x0400) and LssRss (0x0800) must not collapse onto SIDE like LsRs. */
1209static uint64_t mov_dts_channel_layout_to_mask(unsigned int code)
1210{
1211 static const struct { unsigned int dts; uint64_t av; } map[] = {
1212 { 0x0001, AV_CH_FRONT_CENTER },
1213 { 0x0002, AV_CH_FRONT_LEFT | AV_CH_FRONT_RIGHT },
1214 { 0x0004, AV_CH_SIDE_LEFT | AV_CH_SIDE_RIGHT },
1215 { 0x0008, AV_CH_LOW_FREQUENCY },
1216 { 0x0010, AV_CH_BACK_CENTER },
1218 { 0x0040, AV_CH_BACK_LEFT | AV_CH_BACK_RIGHT },
1219 { 0x0080, AV_CH_TOP_FRONT_CENTER },
1220 { 0x0100, AV_CH_TOP_CENTER },
1222 { 0x0400, AV_CH_WIDE_LEFT | AV_CH_WIDE_RIGHT },
1224 { 0x1000, AV_CH_LOW_FREQUENCY_2 },
1226 { 0x4000, AV_CH_TOP_BACK_CENTER },
1228 };
1229 uint64_t mask = 0;
1230 int i;
1231 for (i = 0; i < FF_ARRAY_ELEMS(map); i++)
1232 if (code & map[i].dts)
1233 mask |= map[i].av;
1234 return mask;
1235}
1236
1238{
1239#define DDTS_SIZE 20
1241 AVStream *st = NULL;
1242 uint32_t frame_duration_code = 0;
1243 uint32_t channel_layout_code = 0;
1244 uint64_t channel_layout_mask;
1245 unsigned int stream_construction;
1246 unsigned int representation_type;
1247 GetBitContext gb;
1248 int ret;
1249
1250 if ((ret = ffio_read_size(pb, buf, DDTS_SIZE)) < 0)
1251 return ret;
1252
1253 init_get_bits(&gb, buf, 8 * DDTS_SIZE);
1254
1255 if (c->fc->nb_streams < 1) {
1256 return 0;
1257 }
1258 st = c->fc->streams[c->fc->nb_streams-1];
1259
1260 st->codecpar->sample_rate = get_bits_long(&gb, 32);
1261 if (st->codecpar->sample_rate <= 0) {
1262 av_log(c->fc, AV_LOG_ERROR, "Invalid sample rate %d\n", st->codecpar->sample_rate);
1263 return AVERROR_INVALIDDATA;
1264 }
1265 skip_bits_long(&gb, 32); /* max bitrate */
1266 st->codecpar->bit_rate = get_bits_long(&gb, 32);
1268 frame_duration_code = get_bits(&gb, 2);
1269 stream_construction = get_bits(&gb, 5); /* Table E-2 - profile source */
1270 skip_bits(&gb, 1); /* CoreLFEPresent */
1271 skip_bits(&gb, 6); /* CoreLayout */
1272 skip_bits(&gb, 14); /* CoreSize */
1273 skip_bits(&gb, 1); /* StereoDownmix */
1274 representation_type = get_bits(&gb, 3);
1275 channel_layout_code = get_bits(&gb, 16);
1276
1277 st->codecpar->frame_size =
1278 (frame_duration_code == 0) ? 512 :
1279 (frame_duration_code == 1) ? 1024 :
1280 (frame_duration_code == 2) ? 2048 :
1281 (frame_duration_code == 3) ? 4096 : 0;
1282
1283 /* Publish StreamConstruction as codecpar->profile, including for encrypted
1284 * tracks where frame headers cannot be inspected. */
1285 st->codecpar->profile = mov_dts_stream_construction_to_profile(stream_construction);
1286
1287 channel_layout_mask = mov_dts_channel_layout_to_mask(channel_layout_code);
1288 if (channel_layout_mask) {
1290 av_channel_layout_from_mask(&st->codecpar->ch_layout, channel_layout_mask);
1291 } else if (representation_type == 2 || representation_type == 3) {
1294 }
1295
1296 return 0;
1297}
1298
1300{
1301 AVStream *st;
1302
1303 if (c->fc->nb_streams < 1)
1304 return 0;
1305 st = c->fc->streams[c->fc->nb_streams-1];
1306
1307 if (atom.size < 16)
1308 return 0;
1309
1310 /* skip version and flags */
1311 avio_skip(pb, 4);
1312
1313 ff_mov_read_chan(c->fc, pb, st, atom.size - 4);
1314
1315 return 0;
1316}
1317
1319{
1320 int64_t end = av_sat_add64(avio_tell(pb), atom.size);
1321 int version, flags;
1322 int ret;
1323 AVStream *st;
1324
1325 if (c->fc->nb_streams < 1)
1326 return 0;
1327 st = c->fc->streams[c->fc->nb_streams-1];
1328
1329 version = avio_r8(pb);
1330 flags = avio_rb24(pb);
1331 if (version > 1 || flags != 0) {
1332 av_log(c->fc, AV_LOG_WARNING,
1333 "Unsupported 'chnl' box with version %d, flags: %#x\n",
1334 version, flags);
1335 return 0;
1336 }
1337
1338 ret = ff_mov_read_chnl(c->fc, pb, st, version);
1339 if (ret < 0) {
1340 avio_seek(pb, end, SEEK_SET);
1341 return 0;
1342 }
1343
1344 if (avio_tell(pb) != end) {
1345 av_log(c->fc, AV_LOG_WARNING, "skip %" PRId64 " bytes of unknown data inside chnl\n",
1346 end - avio_tell(pb));
1347 avio_seek(pb, end, SEEK_SET);
1348 }
1349 return ret;
1350}
1351
1353{
1354 AVStream *st;
1355 int ret;
1356
1357 if (c->fc->nb_streams < 1)
1358 return 0;
1359 st = c->fc->streams[c->fc->nb_streams-1];
1360
1361 if ((ret = ff_get_wav_header(c->fc, pb, st->codecpar, atom.size, 0)) < 0)
1362 av_log(c->fc, AV_LOG_WARNING, "get_wav_header failed\n");
1363
1364 return ret;
1365}
1366
1368{
1369 AVStream *st;
1370 HEIFItem *item;
1371 AVPacketSideData *sd;
1372 int width, height, err = 0;
1373 AVRational aperture_width, aperture_height, horiz_off, vert_off;
1374 AVRational pc_x, pc_y;
1375 uint64_t top, bottom, left, right;
1376
1377 item = get_heif_item(c, c->cur_item_id);
1378 st = get_curr_st(c);
1379 if (!st)
1380 return 0;
1381
1382 width = st->codecpar->width;
1383 height = st->codecpar->height;
1384 if ((!width || !height) && item) {
1385 width = item->width;
1386 height = item->height;
1387 }
1388 if (!width || !height) {
1389 err = AVERROR_INVALIDDATA;
1390 goto fail;
1391 }
1392
1393 aperture_width.num = avio_rb32(pb);
1394 aperture_width.den = avio_rb32(pb);
1395 aperture_height.num = avio_rb32(pb);
1396 aperture_height.den = avio_rb32(pb);
1397
1398 horiz_off.num = avio_rb32(pb);
1399 horiz_off.den = avio_rb32(pb);
1400 vert_off.num = avio_rb32(pb);
1401 vert_off.den = avio_rb32(pb);
1402
1403 if (aperture_width.num < 0 || aperture_width.den < 0 ||
1404 aperture_height.num < 0 || aperture_height.den < 0 ||
1405 horiz_off.den < 0 || vert_off.den < 0) {
1406 err = AVERROR_INVALIDDATA;
1407 goto fail;
1408 }
1409 if ((av_cmp_q((AVRational) { width, 1 }, aperture_width) < 0) ||
1410 (av_cmp_q((AVRational) { height, 1 }, aperture_height) < 0)) {
1411 err = AVERROR_INVALIDDATA;
1412 goto fail;
1413 }
1414 av_log(c->fc, AV_LOG_TRACE, "clap: apertureWidth %d/%d, apertureHeight %d/%d "
1415 "horizOff %d/%d vertOff %d/%d\n",
1416 aperture_width.num, aperture_width.den, aperture_height.num, aperture_height.den,
1417 horiz_off.num, horiz_off.den, vert_off.num, vert_off.den);
1418
1419 pc_x = av_mul_q((AVRational) { width - 1, 1 }, (AVRational) { 1, 2 });
1420 pc_x = av_add_q(pc_x, horiz_off);
1421 pc_y = av_mul_q((AVRational) { height - 1, 1 }, (AVRational) { 1, 2 });
1422 pc_y = av_add_q(pc_y, vert_off);
1423
1424 aperture_width = av_sub_q(aperture_width, (AVRational) { 1, 1 });
1425 aperture_width = av_mul_q(aperture_width, (AVRational) { 1, 2 });
1426 aperture_height = av_sub_q(aperture_height, (AVRational) { 1, 1 });
1427 aperture_height = av_mul_q(aperture_height, (AVRational) { 1, 2 });
1428
1429 left = av_q2d(av_sub_q(pc_x, aperture_width));
1430 right = av_q2d(av_add_q(pc_x, aperture_width));
1431 top = av_q2d(av_sub_q(pc_y, aperture_height));
1432 bottom = av_q2d(av_add_q(pc_y, aperture_height));
1433
1434 if (bottom > (height - 1) ||
1435 right > (width - 1)) {
1436 err = AVERROR_INVALIDDATA;
1437 goto fail;
1438 }
1439
1440 bottom = height - 1 - bottom;
1441 right = width - 1 - right;
1442
1443 if (!(left | right | top | bottom))
1444 return 0;
1445
1446 if ((left + right) >= width ||
1447 (top + bottom) >= height) {
1448 err = AVERROR_INVALIDDATA;
1449 goto fail;
1450 }
1451
1455 sizeof(uint32_t) * 4, 0);
1456 if (!sd)
1457 return AVERROR(ENOMEM);
1458
1459 AV_WL32A(sd->data, top);
1460 AV_WL32A(sd->data + 4, bottom);
1461 AV_WL32A(sd->data + 8, left);
1462 AV_WL32A(sd->data + 12, right);
1463
1464fail:
1465 if (err < 0) {
1466 int explode = !!(c->fc->error_recognition & AV_EF_EXPLODE);
1467 av_log(c->fc, explode ? AV_LOG_ERROR : AV_LOG_WARNING, "Invalid clap box\n");
1468 if (!explode)
1469 err = 0;
1470 }
1471
1472 return err;
1473}
1474
1475/* This atom overrides any previously set aspect ratio */
1477{
1478 const int num = avio_rb32(pb);
1479 const int den = avio_rb32(pb);
1480 AVStream *st;
1481 MOVStreamContext *sc;
1482
1483 if (c->fc->nb_streams < 1)
1484 return 0;
1485 st = c->fc->streams[c->fc->nb_streams-1];
1486 sc = st->priv_data;
1487
1488 av_log(c->fc, AV_LOG_TRACE, "pasp: hSpacing %d, vSpacing %d\n", num, den);
1489
1490 if (den != 0) {
1491 sc->h_spacing = num;
1492 sc->v_spacing = den;
1493 }
1494 return 0;
1495}
1496
1497/* this atom contains actual media data */
1499{
1500 if (atom.size == 0) /* wrong one (MP4) */
1501 return 0;
1502 c->found_mdat=1;
1503 return 0; /* now go for moov */
1504}
1505
1506#define DRM_BLOB_SIZE 56
1507
1509{
1510 uint8_t intermediate_key[20];
1511 uint8_t intermediate_iv[20];
1512 uint8_t input[64];
1513 uint8_t output[64];
1514 uint8_t file_checksum[20];
1515 uint8_t calculated_checksum[20];
1516 char checksum_string[2 * sizeof(file_checksum) + 1];
1517 struct AVSHA *sha;
1518 int i;
1519 int ret = 0;
1520 uint8_t *activation_bytes = c->activation_bytes;
1521 uint8_t *fixed_key = c->audible_fixed_key;
1522
1523 c->aax_mode = 1;
1524
1525 sha = av_sha_alloc();
1526 if (!sha)
1527 return AVERROR(ENOMEM);
1528 av_free(c->aes_decrypt);
1529 c->aes_decrypt = av_aes_alloc();
1530 if (!c->aes_decrypt) {
1531 ret = AVERROR(ENOMEM);
1532 goto fail;
1533 }
1534
1535 /* drm blob processing */
1536 avio_read(pb, output, 8); // go to offset 8, absolute position 0x251
1537 avio_read(pb, input, DRM_BLOB_SIZE);
1538 avio_read(pb, output, 4); // go to offset 4, absolute position 0x28d
1539 ret = ffio_read_size(pb, file_checksum, 20);
1540 if (ret < 0)
1541 goto fail;
1542
1543 // required by external tools
1544 ff_data_to_hex(checksum_string, file_checksum, sizeof(file_checksum), 1);
1545 av_log(c->fc, AV_LOG_INFO, "[aax] file checksum == %s\n", checksum_string);
1546
1547 /* verify activation data */
1548 if (!activation_bytes) {
1549 av_log(c->fc, AV_LOG_WARNING, "[aax] activation_bytes option is missing!\n");
1550 ret = 0; /* allow ffprobe to continue working on .aax files */
1551 goto fail;
1552 }
1553 if (c->activation_bytes_size != 4) {
1554 av_log(c->fc, AV_LOG_FATAL, "[aax] activation_bytes value needs to be 4 bytes!\n");
1555 ret = AVERROR(EINVAL);
1556 goto fail;
1557 }
1558
1559 /* verify fixed key */
1560 if (c->audible_fixed_key_size != 16) {
1561 av_log(c->fc, AV_LOG_FATAL, "[aax] audible_fixed_key value needs to be 16 bytes!\n");
1562 ret = AVERROR(EINVAL);
1563 goto fail;
1564 }
1565
1566 /* AAX (and AAX+) key derivation */
1567 av_sha_init(sha, 160);
1568 av_sha_update(sha, fixed_key, 16);
1569 av_sha_update(sha, activation_bytes, 4);
1570 av_sha_final(sha, intermediate_key);
1571 av_sha_init(sha, 160);
1572 av_sha_update(sha, fixed_key, 16);
1573 av_sha_update(sha, intermediate_key, 20);
1574 av_sha_update(sha, activation_bytes, 4);
1575 av_sha_final(sha, intermediate_iv);
1576 av_sha_init(sha, 160);
1577 av_sha_update(sha, intermediate_key, 16);
1578 av_sha_update(sha, intermediate_iv, 16);
1579 av_sha_final(sha, calculated_checksum);
1580 if (memcmp(calculated_checksum, file_checksum, 20)) { // critical error
1581 av_log(c->fc, AV_LOG_ERROR, "[aax] mismatch in checksums!\n");
1582 ret = AVERROR_INVALIDDATA;
1583 goto fail;
1584 }
1585 av_aes_init(c->aes_decrypt, intermediate_key, 128, 1);
1586 av_aes_crypt(c->aes_decrypt, output, input, DRM_BLOB_SIZE >> 4, intermediate_iv, 1);
1587 for (i = 0; i < 4; i++) {
1588 // file data (in output) is stored in big-endian mode
1589 if (activation_bytes[i] != output[3 - i]) { // critical error
1590 av_log(c->fc, AV_LOG_ERROR, "[aax] error in drm blob decryption!\n");
1591 ret = AVERROR_INVALIDDATA;
1592 goto fail;
1593 }
1594 }
1595 memcpy(c->file_key, output + 8, 16);
1596 memcpy(input, output + 26, 16);
1597 av_sha_init(sha, 160);
1598 av_sha_update(sha, input, 16);
1599 av_sha_update(sha, c->file_key, 16);
1600 av_sha_update(sha, fixed_key, 16);
1601 av_sha_final(sha, c->file_iv);
1602
1603fail:
1604 av_free(sha);
1605
1606 return ret;
1607}
1608
1610{
1611 if (c->audible_key_size != 16) {
1612 av_log(c->fc, AV_LOG_FATAL, "[aaxc] audible_key value needs to be 16 bytes!\n");
1613 return AVERROR(EINVAL);
1614 }
1615
1616 if (c->audible_iv_size != 16) {
1617 av_log(c->fc, AV_LOG_FATAL, "[aaxc] audible_iv value needs to be 16 bytes!\n");
1618 return AVERROR(EINVAL);
1619 }
1620
1621 c->aes_decrypt = av_aes_alloc();
1622 if (!c->aes_decrypt) {
1623 return AVERROR(ENOMEM);
1624 }
1625
1626 memcpy(c->file_key, c->audible_key, 16);
1627 memcpy(c->file_iv, c->audible_iv, 16);
1628 c->aax_mode = 1;
1629
1630 return 0;
1631}
1632
1633// Audible AAX (and AAX+) bytestream decryption
1634static int aax_filter(uint8_t *input, int size, MOVContext *c)
1635{
1636 int blocks = 0;
1637 unsigned char iv[16];
1638
1639 memcpy(iv, c->file_iv, 16); // iv is overwritten
1640 blocks = size >> 4; // trailing bytes are not encrypted!
1641 av_aes_init(c->aes_decrypt, c->file_key, 128, 1);
1642 av_aes_crypt(c->aes_decrypt, input, input, blocks, iv, 1);
1643
1644 return 0;
1645}
1646
1647/* read major brand, minor version and compatible brands and store them as metadata */
1649{
1650 uint32_t minor_ver;
1651 int comp_brand_size;
1652 char* comp_brands_str;
1653 uint8_t type[5] = {0};
1654 int ret = ffio_read_size(pb, type, 4);
1655 if (ret < 0)
1656 return ret;
1657 if (c->fc->nb_streams) {
1658 if (c->fc->strict_std_compliance >= FF_COMPLIANCE_STRICT)
1659 return AVERROR_INVALIDDATA;
1660 av_log(c->fc, AV_LOG_DEBUG, "Ignoring duplicate FTYP\n");
1661 return 0;
1662 }
1663
1664 if (strcmp(type, "qt "))
1665 c->isom = 1;
1666 av_log(c->fc, AV_LOG_DEBUG, "ISO: File Type Major Brand: %.4s\n",(char *)&type);
1667 av_dict_set(&c->fc->metadata, "major_brand", type, 0);
1668 minor_ver = avio_rb32(pb); /* minor version */
1669 av_dict_set_int(&c->fc->metadata, "minor_version", minor_ver, 0);
1670
1671 comp_brand_size = atom.size - 8;
1672 if (comp_brand_size < 0 || comp_brand_size == INT_MAX)
1673 return AVERROR_INVALIDDATA;
1674 comp_brands_str = av_malloc(comp_brand_size + 1); /* Add null terminator */
1675 if (!comp_brands_str)
1676 return AVERROR(ENOMEM);
1677
1678 ret = ffio_read_size(pb, comp_brands_str, comp_brand_size);
1679 if (ret < 0) {
1680 av_freep(&comp_brands_str);
1681 return ret;
1682 }
1683 comp_brands_str[comp_brand_size] = 0;
1684 av_dict_set(&c->fc->metadata, "compatible_brands",
1685 comp_brands_str, AV_DICT_DONT_STRDUP_VAL);
1686
1687 // Logic for handling Audible's .aaxc files
1688 if (!strcmp(type, "aaxc")) {
1690 }
1691
1692 return 0;
1693}
1694
1695/* this atom should contain all header atoms */
1697{
1698 int ret;
1699
1700 if (c->found_moov) {
1701 av_log(c->fc, AV_LOG_WARNING, "Found duplicated MOOV Atom. Skipped it\n");
1702 avio_skip(pb, atom.size);
1703 return 0;
1704 }
1705
1706 if ((ret = mov_read_default(c, pb, atom)) < 0)
1707 return ret;
1708 /* we parsed the 'moov' atom, we can terminate the parsing as soon as we find the 'mdat' */
1709 /* so we don't parse the whole file if over a network */
1710 c->found_moov=1;
1711 return 0; /* now go for mdat */
1712}
1713
1715 MOVFragmentIndex *frag_index,
1716 int index,
1717 int id)
1718{
1719 int i;
1720 MOVFragmentIndexItem * item;
1721
1722 if (index < 0 || index >= frag_index->nb_items)
1723 return NULL;
1724 item = &frag_index->item[index];
1725 for (i = 0; i < item->nb_stream_info; i++)
1726 if (item->stream_info[i].id == id)
1727 return &item->stream_info[i];
1728
1729 // This shouldn't happen
1730 return NULL;
1731}
1732
1733static void set_frag_stream(MOVFragmentIndex *frag_index, int id)
1734{
1735 int i;
1736 MOVFragmentIndexItem * item;
1737
1738 if (frag_index->current < 0 ||
1739 frag_index->current >= frag_index->nb_items)
1740 return;
1741
1742 item = &frag_index->item[frag_index->current];
1743 for (i = 0; i < item->nb_stream_info; i++)
1744 if (item->stream_info[i].id == id) {
1745 item->current = i;
1746 return;
1747 }
1748
1749 // id not found. This shouldn't happen.
1750 item->current = -1;
1751}
1752
1754 MOVFragmentIndex *frag_index)
1755{
1757 if (frag_index->current < 0 ||
1758 frag_index->current >= frag_index->nb_items)
1759 return NULL;
1760
1761 item = &frag_index->item[frag_index->current];
1762 if (item->current >= 0 && item->current < item->nb_stream_info)
1763 return &item->stream_info[item->current];
1764
1765 // This shouldn't happen
1766 return NULL;
1767}
1768
1770{
1771 int a, b, m;
1772 int64_t moof_offset;
1773
1774 // Optimize for appending new entries
1775 if (!frag_index->nb_items ||
1776 frag_index->item[frag_index->nb_items - 1].moof_offset < offset)
1777 return frag_index->nb_items;
1778
1779 a = -1;
1780 b = frag_index->nb_items;
1781
1782 while (b - a > 1) {
1783 m = (a + b) >> 1;
1784 moof_offset = frag_index->item[m].moof_offset;
1785 if (moof_offset >= offset)
1786 b = m;
1787 if (moof_offset <= offset)
1788 a = m;
1789 }
1790 return b;
1791}
1792
1794{
1795 av_assert0(frag_stream_info);
1796 if (frag_stream_info->sidx_pts != AV_NOPTS_VALUE)
1797 return frag_stream_info->sidx_pts;
1798 if (frag_stream_info->first_tfra_pts != AV_NOPTS_VALUE)
1799 return frag_stream_info->first_tfra_pts;
1800 return frag_stream_info->tfdt_dts;
1801}
1802
1804 MOVFragmentIndex *frag_index, int index)
1805{
1806 MOVFragmentStreamInfo * frag_stream_info;
1807 MOVStreamContext *sc = dst_st->priv_data;
1808 int64_t timestamp;
1809 int i, j;
1810
1811 // If the stream is referenced by any sidx, limit the search
1812 // to fragments that referenced this stream in the sidx
1813 if (sc->has_sidx) {
1814 frag_stream_info = get_frag_stream_info(frag_index, index, sc->id);
1815 if (!frag_stream_info)
1816 return AV_NOPTS_VALUE;
1817 if (frag_stream_info->sidx_pts != AV_NOPTS_VALUE)
1818 return frag_stream_info->sidx_pts;
1819 if (frag_stream_info->first_tfra_pts != AV_NOPTS_VALUE)
1820 return frag_stream_info->first_tfra_pts;
1821 return frag_stream_info->sidx_pts;
1822 }
1823
1824 for (i = 0; i < frag_index->item[index].nb_stream_info; i++) {
1825 if (dst_st->id != frag_index->item[index].stream_info[i].id)
1826 continue;
1827 AVStream *frag_stream = NULL;
1828 frag_stream_info = &frag_index->item[index].stream_info[i];
1829 for (j = 0; j < s->nb_streams; j++) {
1830 MOVStreamContext *sc2 = s->streams[j]->priv_data;
1831 if (sc2->id == frag_stream_info->id)
1832 frag_stream = s->streams[j];
1833 }
1834 if (!frag_stream) {
1835 av_log(s, AV_LOG_WARNING, "No stream matching sidx ID found.\n");
1836 continue;
1837 }
1838 timestamp = get_stream_info_time(frag_stream_info);
1839 if (timestamp != AV_NOPTS_VALUE)
1840 return av_rescale_q(timestamp, frag_stream->time_base, dst_st->time_base);
1841 }
1842 return AV_NOPTS_VALUE;
1843}
1844
1846 AVStream *st, int64_t timestamp)
1847{
1848 int a, b, m, m0;
1849 int64_t frag_time;
1850
1851 a = -1;
1852 b = frag_index->nb_items;
1853
1854 while (b - a > 1) {
1855 m0 = m = (a + b) >> 1;
1856
1857 while (m < b &&
1858 (frag_time = get_frag_time(s, st, frag_index, m)) == AV_NOPTS_VALUE)
1859 m++;
1860
1861 if (m < b && frag_time <= timestamp)
1862 a = m;
1863 else
1864 b = m0;
1865 }
1866
1867 return a;
1868}
1869
1871{
1872 int index, i;
1873 MOVFragmentIndexItem * item;
1874 MOVFragmentStreamInfo * frag_stream_info;
1875
1876 // If moof_offset already exists in frag_index, return index to it
1877 index = search_frag_moof_offset(&c->frag_index, offset);
1878 if (index < c->frag_index.nb_items &&
1879 c->frag_index.item[index].moof_offset == offset)
1880 return index;
1881
1882 // offset is not yet in frag index.
1883 // Insert new item at index (sorted by moof offset)
1884 item = av_fast_realloc(c->frag_index.item,
1885 &c->frag_index.allocated_size,
1886 (c->frag_index.nb_items + 1) *
1887 sizeof(*c->frag_index.item));
1888 if (!item)
1889 return -1;
1890 c->frag_index.item = item;
1891
1892 frag_stream_info = av_realloc_array(NULL, c->fc->nb_streams,
1893 sizeof(*item->stream_info));
1894 if (!frag_stream_info)
1895 return -1;
1896
1897 for (i = 0; i < c->fc->nb_streams; i++) {
1898 // Avoid building frag index if streams lack track id.
1899 MOVStreamContext *sc = c->fc->streams[i]->priv_data;
1900 if (sc->id < 0) {
1901 av_free(frag_stream_info);
1902 return AVERROR_INVALIDDATA;
1903 }
1904
1905 frag_stream_info[i].id = sc->id;
1906 frag_stream_info[i].sidx_pts = AV_NOPTS_VALUE;
1907 frag_stream_info[i].tfdt_dts = AV_NOPTS_VALUE;
1908 frag_stream_info[i].next_trun_dts = AV_NOPTS_VALUE;
1909 frag_stream_info[i].first_tfra_pts = AV_NOPTS_VALUE;
1910 frag_stream_info[i].index_base = -1;
1911 frag_stream_info[i].index_entry = -1;
1912 frag_stream_info[i].encryption_index = NULL;
1913 frag_stream_info[i].stsd_id = -1;
1914 }
1915
1916 if (index < c->frag_index.nb_items)
1917 memmove(c->frag_index.item + index + 1, c->frag_index.item + index,
1918 (c->frag_index.nb_items - index) * sizeof(*c->frag_index.item));
1919
1920 item = &c->frag_index.item[index];
1921 item->headers_read = 0;
1922 item->current = 0;
1923 item->nb_stream_info = c->fc->nb_streams;
1924 item->moof_offset = offset;
1925 item->stream_info = frag_stream_info;
1926 c->frag_index.nb_items++;
1927
1928 return index;
1929}
1930
1931static void fix_frag_index_entries(MOVFragmentIndex *frag_index, int index,
1932 int id, int entries)
1933{
1934 int i;
1935 MOVFragmentStreamInfo * frag_stream_info;
1936
1937 if (index < 0)
1938 return;
1939 for (i = index; i < frag_index->nb_items; i++) {
1940 frag_stream_info = get_frag_stream_info(frag_index, i, id);
1941 if (frag_stream_info && frag_stream_info->index_entry >= 0)
1942 frag_stream_info->index_entry += entries;
1943 }
1944}
1945
1947{
1948 // Set by mov_read_tfhd(). mov_read_trun() will reject files missing tfhd.
1949 c->fragment.found_tfhd = 0;
1950
1951 if (!c->has_looked_for_mfra && c->use_mfra_for > 0) {
1952 c->has_looked_for_mfra = 1;
1953 if (pb->seekable & AVIO_SEEKABLE_NORMAL) {
1954 int ret;
1955 av_log(c->fc, AV_LOG_VERBOSE, "stream has moof boxes, will look "
1956 "for a mfra\n");
1957 if ((ret = mov_read_mfra(c, pb)) < 0) {
1958 av_log(c->fc, AV_LOG_VERBOSE, "found a moof box but failed to "
1959 "read the mfra (may be a live ismv)\n");
1960 }
1961 } else {
1962 av_log(c->fc, AV_LOG_VERBOSE, "found a moof box but stream is not "
1963 "seekable, can not look for mfra\n");
1964 }
1965 }
1966 c->fragment.moof_offset = c->fragment.implicit_offset = avio_tell(pb) - 8;
1967 av_log(c->fc, AV_LOG_TRACE, "moof offset %"PRIx64"\n", c->fragment.moof_offset);
1968 c->frag_index.current = update_frag_index(c, c->fragment.moof_offset);
1969 return mov_read_default(c, pb, atom);
1970}
1971
1973{
1974 int64_t time;
1975 if (version == 1) {
1976 time = avio_rb64(pb);
1977 avio_rb64(pb);
1978 if (time < 0) {
1979 av_log(c->fc, AV_LOG_DEBUG, "creation_time is negative\n");
1980 return;
1981 }
1982 } else {
1983 time = avio_rb32(pb);
1984 avio_rb32(pb); /* modification time */
1985 if (time > 0 && time < 2082844800) {
1986 av_log(c->fc, AV_LOG_WARNING, "Detected creation time before 1970, parsing as unix timestamp.\n");
1987 time += 2082844800;
1988 }
1989 }
1990 if (time) {
1991 time -= 2082844800; /* seconds between 1904-01-01 and Epoch */
1992
1993 if ((int64_t)(time * 1000000ULL) / 1000000 != time) {
1994 av_log(c->fc, AV_LOG_DEBUG, "creation_time is not representable\n");
1995 return;
1996 }
1997
1998 ff_dict_set_timestamp(metadata, "creation_time", time * 1000000);
1999 }
2000}
2001
2003{
2004 AVStream *st;
2005 MOVStreamContext *sc;
2006 int version;
2007 char language[4] = {0};
2008 unsigned lang;
2009
2010 if (c->fc->nb_streams < 1)
2011 return 0;
2012 st = c->fc->streams[c->fc->nb_streams-1];
2013 sc = st->priv_data;
2014
2015 if (sc->time_scale) {
2016 av_log(c->fc, AV_LOG_ERROR, "Multiple mdhd?\n");
2017 return AVERROR_INVALIDDATA;
2018 }
2019
2020 version = avio_r8(pb);
2021 if (version > 1) {
2022 avpriv_request_sample(c->fc, "Version %d", version);
2023 return AVERROR_PATCHWELCOME;
2024 }
2025 avio_rb24(pb); /* flags */
2027
2028 sc->time_scale = avio_rb32(pb);
2029 if (sc->time_scale <= 0) {
2030 av_log(c->fc, AV_LOG_ERROR, "Invalid mdhd time scale %d, defaulting to 1\n", sc->time_scale);
2031 sc->time_scale = 1;
2032 }
2033 st->duration = (version == 1) ? avio_rb64(pb) : avio_rb32(pb); /* duration */
2034
2035 if ((version == 1 && st->duration == UINT64_MAX) ||
2036 (version != 1 && st->duration == UINT32_MAX)) {
2037 st->duration = 0;
2038 }
2039
2040 lang = avio_rb16(pb); /* language */
2041 if (ff_mov_lang_to_iso639(lang, language))
2042 av_dict_set(&st->metadata, "language", language, 0);
2043 avio_rb16(pb); /* quality */
2044
2045 return 0;
2046}
2047
2049{
2050 int i;
2051 int version = avio_r8(pb); /* version */
2052 avio_rb24(pb); /* flags */
2053
2054 mov_metadata_creation_time(c, pb, &c->fc->metadata, version);
2055 c->time_scale = avio_rb32(pb); /* time scale */
2056 if (c->time_scale <= 0) {
2057 av_log(c->fc, AV_LOG_ERROR, "Invalid mvhd time scale %d, defaulting to 1\n", c->time_scale);
2058 c->time_scale = 1;
2059 }
2060 av_log(c->fc, AV_LOG_TRACE, "time scale = %i\n", c->time_scale);
2061
2062 c->duration = (version == 1) ? avio_rb64(pb) : avio_rb32(pb); /* duration */
2063 avio_rb32(pb); /* preferred scale */
2064
2065 avio_rb16(pb); /* preferred volume */
2066
2067 avio_skip(pb, 10); /* reserved */
2068
2069 /* movie display matrix, store it in main context and use it later on */
2070 for (i = 0; i < 3; i++) {
2071 c->movie_display_matrix[i][0] = avio_rb32(pb); // 16.16 fixed point
2072 c->movie_display_matrix[i][1] = avio_rb32(pb); // 16.16 fixed point
2073 c->movie_display_matrix[i][2] = avio_rb32(pb); // 2.30 fixed point
2074 }
2075
2076 avio_rb32(pb); /* preview time */
2077 avio_rb32(pb); /* preview duration */
2078 avio_rb32(pb); /* poster time */
2079 avio_rb32(pb); /* selection time */
2080 avio_rb32(pb); /* selection duration */
2081 avio_rb32(pb); /* current time */
2082 avio_rb32(pb); /* next track ID */
2083
2084 return 0;
2085}
2086
2088{
2089 AVStream *st;
2090
2091 if (fc->nb_streams < 1)
2092 return;
2093 st = fc->streams[fc->nb_streams-1];
2094
2095 switch (st->codecpar->codec_id) {
2098 break;
2101 break;
2104 break;
2107 break;
2110 break;
2111 default:
2112 break;
2113 }
2114}
2115
2117{
2118 int little_endian = avio_rb16(pb) & 0xFF;
2119 av_log(c->fc, AV_LOG_TRACE, "enda %d\n", little_endian);
2120 if (little_endian == 1)
2122 return 0;
2123}
2124
2126{
2127 int format_flags;
2128 int version, flags;
2129 int pcm_sample_size;
2130 AVFormatContext *fc = c->fc;
2131 AVStream *st;
2132 MOVStreamContext *sc;
2133
2134 if (atom.size < 6) {
2135 av_log(c->fc, AV_LOG_ERROR, "Empty pcmC box\n");
2136 return AVERROR_INVALIDDATA;
2137 }
2138
2139 version = avio_r8(pb);
2140 flags = avio_rb24(pb);
2141
2142 if (version != 0 || flags != 0) {
2143 av_log(c->fc, AV_LOG_ERROR,
2144 "Unsupported 'pcmC' box with version %d, flags: %x",
2145 version, flags);
2146 return AVERROR_INVALIDDATA;
2147 }
2148
2149 format_flags = avio_r8(pb);
2150 pcm_sample_size = avio_r8(pb);
2151
2152 if (fc->nb_streams < 1)
2153 return AVERROR_INVALIDDATA;
2154
2155 st = fc->streams[fc->nb_streams - 1];
2156 sc = st->priv_data;
2157
2158 if (sc->format == MOV_MP4_FPCM_TAG) {
2159 switch (pcm_sample_size) {
2160 case 32:
2162 break;
2163 case 64:
2165 break;
2166 default:
2167 av_log(fc, AV_LOG_ERROR, "invalid pcm_sample_size %d for %s\n",
2168 pcm_sample_size,
2169 av_fourcc2str(sc->format));
2170 return AVERROR_INVALIDDATA;
2171 }
2172 } else if (sc->format == MOV_MP4_IPCM_TAG) {
2173 switch (pcm_sample_size) {
2174 case 16:
2176 break;
2177 case 24:
2179 break;
2180 case 32:
2182 break;
2183 default:
2184 av_log(fc, AV_LOG_ERROR, "invalid pcm_sample_size %d for %s\n",
2185 pcm_sample_size,
2186 av_fourcc2str(sc->format));
2187 return AVERROR_INVALIDDATA;
2188 }
2189 } else {
2190 av_log(fc, AV_LOG_ERROR, "'pcmC' with invalid sample entry '%s'\n",
2191 av_fourcc2str(sc->format));
2192 return AVERROR_INVALIDDATA;
2193 }
2194
2195 if (format_flags & 1) // indicates little-endian format. If not present, big-endian format is used
2198
2199 return 0;
2200}
2201
2203{
2204 AVStream *st;
2205 HEIFItem *item = NULL;
2206 char color_parameter_type[5] = { 0 };
2207 uint16_t color_primaries, color_trc, color_matrix;
2208 int ret;
2209
2210 st = get_curr_st(c);
2211 if (!st) {
2212 item = get_heif_item(c, c->cur_item_id);
2213 if (!item)
2214 return 0;
2215 }
2216
2217 ret = ffio_read_size(pb, color_parameter_type, 4);
2218 if (ret < 0)
2219 return ret;
2220 if (strncmp(color_parameter_type, "nclx", 4) &&
2221 strncmp(color_parameter_type, "nclc", 4) &&
2222 strncmp(color_parameter_type, "prof", 4)) {
2223 av_log(c->fc, AV_LOG_WARNING, "unsupported color_parameter_type %s\n",
2224 color_parameter_type);
2225 return 0;
2226 }
2227
2228 if (!strncmp(color_parameter_type, "prof", 4)) {
2229 AVPacketSideData *sd;
2230 uint8_t *icc_profile;
2231 if (st) {
2235 atom.size - 4, 0);
2236 if (!sd)
2237 return AVERROR(ENOMEM);
2238 icc_profile = sd->data;
2239 } else {
2240 if (c->heif_icc_profile_items >= c->fc->max_streams) {
2241 av_log(c->fc, AV_LOG_WARNING,
2242 "HEIF ICC profile copies exceed cap %d; ignoring further items\n",
2243 c->fc->max_streams);
2244 return 0;
2245 }
2246 av_freep(&item->icc_profile);
2247 icc_profile = item->icc_profile = av_malloc(atom.size - 4);
2248 if (!icc_profile) {
2249 item->icc_profile_size = 0;
2250 return AVERROR(ENOMEM);
2251 }
2252 item->icc_profile_size = atom.size - 4;
2253 c->heif_icc_profile_items++;
2254 }
2255 ret = ffio_read_size(pb, icc_profile, atom.size - 4);
2256 if (ret < 0)
2257 return ret;
2258 } else if (st) {
2260 color_trc = avio_rb16(pb);
2261 color_matrix = avio_rb16(pb);
2262
2263 av_log(c->fc, AV_LOG_TRACE,
2264 "%s: pri %d trc %d matrix %d",
2265 color_parameter_type, color_primaries, color_trc, color_matrix);
2266
2267 if (!strncmp(color_parameter_type, "nclx", 4)) {
2268 uint8_t color_range = avio_r8(pb) >> 7;
2269 av_log(c->fc, AV_LOG_TRACE, " full %"PRIu8"", color_range);
2270 if (color_range)
2272 else
2274 }
2275
2278 if (!av_color_transfer_name(color_trc))
2279 color_trc = AVCOL_TRC_UNSPECIFIED;
2280 if (!av_color_space_name(color_matrix))
2281 color_matrix = AVCOL_SPC_UNSPECIFIED;
2282
2284 st->codecpar->color_trc = color_trc;
2285 st->codecpar->color_space = color_matrix;
2286 av_log(c->fc, AV_LOG_TRACE, "\n");
2287 }
2288 return 0;
2289}
2290
2292{
2293 AVStream *st;
2294 unsigned mov_field_order;
2295 enum AVFieldOrder decoded_field_order = AV_FIELD_UNKNOWN;
2296
2297 if (c->fc->nb_streams < 1) // will happen with jp2 files
2298 return 0;
2299 st = c->fc->streams[c->fc->nb_streams-1];
2300 if (atom.size < 2)
2301 return AVERROR_INVALIDDATA;
2302 mov_field_order = avio_rb16(pb);
2303 if ((mov_field_order & 0xFF00) == 0x0100)
2304 decoded_field_order = AV_FIELD_PROGRESSIVE;
2305 else if ((mov_field_order & 0xFF00) == 0x0200) {
2306 switch (mov_field_order & 0xFF) {
2307 case 0x01: decoded_field_order = AV_FIELD_TT;
2308 break;
2309 case 0x06: decoded_field_order = AV_FIELD_BB;
2310 break;
2311 case 0x09: decoded_field_order = AV_FIELD_TB;
2312 break;
2313 case 0x0E: decoded_field_order = AV_FIELD_BT;
2314 break;
2315 }
2316 }
2317 if (decoded_field_order == AV_FIELD_UNKNOWN && mov_field_order) {
2318 av_log(c->fc, AV_LOG_ERROR, "Unknown MOV field order 0x%04x\n", mov_field_order);
2319 }
2320 st->codecpar->field_order = decoded_field_order;
2321
2322 return 0;
2323}
2324
2326{
2327 int err = 0;
2328 uint64_t size = (uint64_t)par->extradata_size + atom.size + 8 + AV_INPUT_BUFFER_PADDING_SIZE;
2329 if (size > INT_MAX || (uint64_t)atom.size > INT_MAX)
2330 return AVERROR_INVALIDDATA;
2331 if ((err = av_reallocp(&par->extradata, size)) < 0) {
2332 par->extradata_size = 0;
2333 return err;
2334 }
2336 return 0;
2337}
2338
2339/* Read a whole atom into the extradata return the size of the atom read, possibly truncated if != atom.size */
2341 AVCodecParameters *par, uint8_t *buf)
2342{
2343 int64_t result = atom.size;
2344 int err;
2345
2346 AV_WB32(buf , atom.size + 8);
2347 AV_WL32(buf + 4, atom.type);
2348 err = ffio_read_size(pb, buf + 8, atom.size);
2349 if (err < 0) {
2350 par->extradata_size -= atom.size;
2351 return err;
2352 } else if (err < atom.size) {
2353 av_log(c->fc, AV_LOG_WARNING, "truncated extradata\n");
2354 par->extradata_size -= atom.size - err;
2355 result = err;
2356 }
2357 memset(buf + 8 + err, 0, AV_INPUT_BUFFER_PADDING_SIZE);
2358 return result;
2359}
2360
2361/* FIXME modify QDM2/SVQ3/H.264 decoders to take full atom as extradata */
2363 enum AVCodecID codec_id)
2364{
2365 AVStream *st;
2366 uint64_t original_size;
2367 int err;
2368
2369 if (c->fc->nb_streams < 1) // will happen with jp2 files
2370 return 0;
2371 st = c->fc->streams[c->fc->nb_streams-1];
2372
2373 if (st->codecpar->codec_id != codec_id)
2374 return 0; /* unexpected codec_id - don't mess with extradata */
2375
2376 original_size = st->codecpar->extradata_size;
2377 err = mov_realloc_extradata(st->codecpar, atom);
2378 if (err)
2379 return err;
2380
2381 err = mov_read_atom_into_extradata(c, pb, atom, st->codecpar, st->codecpar->extradata + original_size);
2382 if (err < 0)
2383 return err;
2384 return 0; // Note: this is the original behavior to ignore truncation.
2385}
2386
2387/* wrapper functions for reading ALAC/AVS/MJPEG/MJPEG2000 extradata atoms only for those codecs */
2389{
2390 return mov_read_extradata(c, pb, atom, AV_CODEC_ID_ALAC);
2391}
2392
2394{
2395 return mov_read_extradata(c, pb, atom, AV_CODEC_ID_CAVS);
2396}
2397
2399{
2400 return mov_read_extradata(c, pb, atom, AV_CODEC_ID_JPEG2000);
2401}
2402
2404{
2405 return mov_read_extradata(c, pb, atom, AV_CODEC_ID_R10K);
2406}
2407
2409{
2410 int ret = mov_read_extradata(c, pb, atom, AV_CODEC_ID_AVUI);
2411 if (!ret)
2412 ret = mov_read_extradata(c, pb, atom, AV_CODEC_ID_DNXHD);
2413 return ret;
2414}
2415
2417{
2418 int ret = mov_read_extradata(c, pb, atom, AV_CODEC_ID_TARGA_Y216);
2419
2420 if (!ret && c->fc->nb_streams >= 1) {
2421 AVCodecParameters *par = c->fc->streams[c->fc->nb_streams-1]->codecpar;
2422 if (par->extradata_size >= 40) {
2423 par->height = AV_RB16(&par->extradata[36]);
2424 par->width = AV_RB16(&par->extradata[38]);
2425 }
2426 }
2427 return ret;
2428}
2429
2431{
2432 if (c->fc->nb_streams >= 1) {
2433 AVStream *const st = c->fc->streams[c->fc->nb_streams - 1];
2434 FFStream *const sti = ffstream(st);
2435 AVCodecParameters *par = st->codecpar;
2436
2437 if (par->codec_tag == MKTAG('A', 'V', 'i', 'n') &&
2438 par->codec_id == AV_CODEC_ID_H264 &&
2439 atom.size > 11) {
2440 int cid;
2441 avio_skip(pb, 10);
2442 cid = avio_rb16(pb);
2443 /* For AVID AVCI50, force width of 1440 to be able to select the correct SPS and PPS */
2444 if (cid == 0xd4d || cid == 0xd4e)
2445 par->width = 1440;
2446 return 0;
2447 } else if ((par->codec_tag == MKTAG('A', 'V', 'd', '1') ||
2448 par->codec_tag == MKTAG('A', 'V', 'j', '2') ||
2449 par->codec_tag == MKTAG('A', 'V', 'd', 'n')) &&
2450 atom.size >= 24) {
2451 int num, den;
2452 avio_skip(pb, 12);
2453 num = avio_rb32(pb);
2454 den = avio_rb32(pb);
2455 if (num <= 0 || den <= 0)
2456 return 0;
2457 switch (avio_rb32(pb)) {
2458 case 2:
2459 if (den >= INT_MAX / 2)
2460 return 0;
2461 den *= 2;
2463 case 1:
2464 sti->display_aspect_ratio = (AVRational){ num, den };
2466 default:
2467 return 0;
2468 }
2469 }
2470 }
2471
2472 return mov_read_avid(c, pb, atom);
2473}
2474
2476{
2477 int ret = 0;
2478 int length = 0;
2479 uint64_t original_size;
2480 if (c->fc->nb_streams >= 1) {
2481 AVCodecParameters *par = c->fc->streams[c->fc->nb_streams-1]->codecpar;
2482 if (par->codec_id == AV_CODEC_ID_H264)
2483 return 0;
2484 if (atom.size == 16) {
2485 original_size = par->extradata_size;
2486 ret = mov_realloc_extradata(par, atom);
2487 if (!ret) {
2488 length = mov_read_atom_into_extradata(c, pb, atom, par, par->extradata + original_size);
2489 if (length == atom.size) {
2490 const uint8_t range_value = par->extradata[original_size + 19];
2491 switch (range_value) {
2492 case 1:
2494 break;
2495 case 2:
2497 break;
2498 default:
2499 av_log(c->fc, AV_LOG_WARNING, "ignored unknown aclr value (%d)\n", range_value);
2500 break;
2501 }
2502 ff_dlog(c->fc, "color_range: %d\n", par->color_range);
2503 } else {
2504 /* For some reason the whole atom was not added to the extradata */
2505 av_log(c->fc, AV_LOG_ERROR, "aclr not decoded - incomplete atom\n");
2506 }
2507 } else {
2508 av_log(c->fc, AV_LOG_ERROR, "aclr not decoded - unable to add atom to extradata\n");
2509 }
2510 } else {
2511 av_log(c->fc, AV_LOG_WARNING, "aclr not decoded - unexpected size %"PRId64"\n", atom.size);
2512 }
2513 }
2514
2515 return ret;
2516}
2517
2519{
2520 return mov_read_extradata(c, pb, atom, AV_CODEC_ID_SVQ3);
2521}
2522
2524{
2525 AVStream *st;
2526 int ret;
2527
2528 if (c->fc->nb_streams < 1)
2529 return 0;
2530 st = c->fc->streams[c->fc->nb_streams-1];
2531
2532 if ((uint64_t)atom.size > (1<<30))
2533 return AVERROR_INVALIDDATA;
2534
2535 if (st->codecpar->codec_id == AV_CODEC_ID_QDM2 ||
2538 // pass all frma atom to codec, needed at least for QDMC and QDM2
2539 ret = ff_get_extradata(c->fc, st->codecpar, pb, atom.size);
2540 if (ret < 0)
2541 return ret;
2542 } else if (atom.size > 8) { /* to read frma, esds atoms */
2543 if (st->codecpar->codec_id == AV_CODEC_ID_ALAC && atom.size >= 24) {
2544 uint64_t buffer;
2545 ret = ffio_ensure_seekback(pb, 8);
2546 if (ret < 0)
2547 return ret;
2548 buffer = avio_rb64(pb);
2549 atom.size -= 8;
2550 if ( (buffer & 0xFFFFFFFF) == MKBETAG('f','r','m','a')
2551 && buffer >> 32 <= atom.size
2552 && buffer >> 32 >= 8) {
2553 avio_skip(pb, -8);
2554 atom.size += 8;
2555 } else if (!st->codecpar->extradata_size) {
2556#define ALAC_EXTRADATA_SIZE 36
2558 if (!st->codecpar->extradata)
2559 return AVERROR(ENOMEM);
2562 AV_WB32(st->codecpar->extradata + 4, MKTAG('a','l','a','c'));
2563 AV_WB64(st->codecpar->extradata + 12, buffer);
2564 avio_read(pb, st->codecpar->extradata + 20, 16);
2565 avio_skip(pb, atom.size - 24);
2566 return 0;
2567 }
2568 }
2569 if ((ret = mov_read_default(c, pb, atom)) < 0)
2570 return ret;
2571 } else
2572 avio_skip(pb, atom.size);
2573 return 0;
2574}
2575
2576/**
2577 * This function reads atom content and puts data in extradata without tag
2578 * nor size unlike mov_read_extradata.
2579 */
2581{
2582 AVStream *st;
2583 int ret;
2584
2585 st = get_curr_st(c);
2586 if (!st)
2587 return 0;
2588
2589 if ((uint64_t)atom.size > (1<<30))
2590 return AVERROR_INVALIDDATA;
2591
2592 if (atom.type == MKTAG('v','v','c','C')) {
2593 avio_skip(pb, 4);
2594 atom.size -= 4;
2595 }
2596
2597 if (atom.size >= 10) {
2598 // Broken files created by legacy versions of libavformat will
2599 // wrap a whole fiel atom inside of a glbl atom.
2600 unsigned size = avio_rb32(pb);
2601 unsigned type = avio_rl32(pb);
2602 if (avio_feof(pb))
2603 return AVERROR_INVALIDDATA;
2604 avio_seek(pb, -8, SEEK_CUR);
2605 if (type == MKTAG('f','i','e','l') && size == atom.size)
2606 return mov_read_default(c, pb, atom);
2607 }
2608 if (st->codecpar->extradata_size > 1 && st->codecpar->extradata) {
2609 av_log(c->fc, AV_LOG_WARNING, "ignoring multiple glbl\n");
2610 return 0;
2611 }
2612 ret = ff_get_extradata(c->fc, st->codecpar, pb, atom.size);
2613 if (ret < 0)
2614 return ret;
2615 if (atom.type == MKTAG('h','v','c','C') && st->codecpar->codec_tag == MKTAG('d','v','h','1'))
2616 /* HEVC-based Dolby Vision derived from hvc1.
2617 Happens to match with an identifier
2618 previously utilized for DV. Thus, if we have
2619 the hvcC extradata box available as specified,
2620 set codec to HEVC */
2622
2623 return 0;
2624}
2625
2627{
2628 AVStream *st;
2629 uint8_t profile_level;
2630 int ret;
2631
2632 if (c->fc->nb_streams < 1)
2633 return 0;
2634 st = c->fc->streams[c->fc->nb_streams-1];
2635
2636 if (atom.size >= (1<<28) || atom.size < 7)
2637 return AVERROR_INVALIDDATA;
2638
2639 profile_level = avio_r8(pb);
2640 if ((profile_level & 0xf0) != 0xc0)
2641 return 0;
2642
2643 avio_seek(pb, 6, SEEK_CUR);
2644 ret = ff_get_extradata(c->fc, st->codecpar, pb, atom.size - 7);
2645 if (ret < 0)
2646 return ret;
2647
2648 return 0;
2649}
2650
2651static int mov_find_tref_id(const MovTref *tag, uint32_t id)
2652{
2653 for (int i = 0; i < tag->nb_id; i++) {
2654 if (tag->id[i] == id)
2655 return 1;
2656 }
2657 return 0;
2658}
2659
2660static int mov_add_tref_id(MovTref *tag, uint32_t id)
2661{
2662 int ret = mov_find_tref_id(tag, id);
2663
2664 if (!ret) {
2665 uint32_t *tmp = av_realloc_array(tag->id, tag->nb_id + 1, sizeof(*tag->id));
2666 if (!tmp)
2667 return AVERROR(ENOMEM);
2668 tag->id = tmp;
2669 tag->id[tag->nb_id++] = id;
2670 }
2671
2672 return 0;
2673}
2674
2676{
2677 for (int i = 0; i < sc->nb_tref_tags; i++) {
2678 MovTref *entry = &sc->tref_tags[i];
2679
2680 if (entry->name == name)
2681 return entry;
2682 }
2683 return NULL;
2684}
2685
2687{
2689
2690 if (!tag) {
2692 sizeof(*sc->tref_tags));
2693 if (!tmp)
2694 return NULL;
2695 sc->tref_tags = tmp;
2696 tag = &sc->tref_tags[sc->nb_tref_tags++];
2697 *tag = (MovTref){ .name = name };
2698 }
2699
2700 return tag;
2701}
2702
2704{
2705 AVStream* st;
2706 MOVStreamContext* sc;
2707
2708 if (c->fc->nb_streams < 1)
2709 return 0;
2710
2711 if (atom.size > 4) {
2712 av_log(c->fc, AV_LOG_ERROR, "Only a single tref of type cdsc/rndr is supported\n");
2713 return AVERROR_PATCHWELCOME;
2714 }
2715 if (atom.size < 4)
2716 return AVERROR_INVALIDDATA;
2717
2718 st = get_curr_st(c);
2719 if (!st)
2720 return AVERROR_INVALIDDATA;
2721 sc = st->priv_data;
2722
2723 MovTref *tag = mov_add_tref_tag(sc, atom.type);
2724 if (!tag)
2725 return AVERROR(ENOMEM);
2726
2727 int ret = mov_add_tref_id(tag, avio_rb32(pb));
2728 if (ret < 0)
2729 return ret;
2730
2731 return 0;
2732}
2733
2735{
2736 AVStream* st;
2737 MOVStreamContext* sc;
2738
2739 if (c->fc->nb_streams < 1)
2740 return 0;
2741
2742 /* For SBAS this should be fine - though beware if someone implements a
2743 * tref atom processor that doesn't drop down to default then this may
2744 * be lost. */
2745 if (atom.size > 4) {
2746 av_log(c->fc, AV_LOG_ERROR, "Only a single tref of type sbas is supported\n");
2747 return AVERROR_PATCHWELCOME;
2748 }
2749 if (atom.size < 4)
2750 return AVERROR_INVALIDDATA;
2751
2752 st = c->fc->streams[c->fc->nb_streams - 1];
2753 sc = st->priv_data;
2754
2755 MovTref *tag = mov_add_tref_tag(sc, atom.type);
2756 if (!tag)
2757 return AVERROR(ENOMEM);
2758
2759 int ret = mov_add_tref_id(tag, avio_rb32(pb));
2760 if (ret < 0)
2761 return ret;
2762
2763 return 0;
2764}
2765
2767{
2768 AVStream* st;
2769 MOVStreamContext* sc;
2770
2771 if (c->fc->nb_streams < 1)
2772 return 0;
2773
2774 if (atom.size > 4)
2775 av_log(c->fc, AV_LOG_WARNING, "More than one vdep reference is not supported.\n");
2776 if (atom.size < 4)
2777 return AVERROR_INVALIDDATA;
2778
2779 st = c->fc->streams[c->fc->nb_streams - 1];
2780 sc = st->priv_data;
2781
2782 MovTref *tag = mov_add_tref_tag(sc, atom.type);
2783 if (!tag)
2784 return AVERROR(ENOMEM);
2785
2786 int ret = mov_add_tref_id(tag, avio_rb32(pb));
2787 if (ret < 0)
2788 return ret;
2789
2790 return 0;
2791}
2792
2793/**
2794 * An strf atom is a BITMAPINFOHEADER struct. This struct is 40 bytes itself,
2795 * but can have extradata appended at the end after the 40 bytes belonging
2796 * to the struct.
2797 */
2799{
2800 AVStream *st;
2801 int ret;
2802
2803 if (c->fc->nb_streams < 1)
2804 return 0;
2805 if (atom.size <= 40)
2806 return 0;
2807 st = c->fc->streams[c->fc->nb_streams-1];
2808
2809 if ((uint64_t)atom.size > (1<<30))
2810 return AVERROR_INVALIDDATA;
2811
2812 avio_skip(pb, 40);
2813 ret = ff_get_extradata(c->fc, st->codecpar, pb, atom.size - 40);
2814 if (ret < 0)
2815 return ret;
2816
2817 return 0;
2818}
2819
2821{
2822 AVStream *st;
2823 MOVStreamContext *sc;
2824 unsigned int i, entries;
2825
2826 if (c->trak_index < 0) {
2827 av_log(c->fc, AV_LOG_WARNING, "STCO outside TRAK\n");
2828 return 0;
2829 }
2830 if (c->fc->nb_streams < 1)
2831 return 0;
2832 st = c->fc->streams[c->fc->nb_streams-1];
2833 sc = st->priv_data;
2834
2835 avio_r8(pb); /* version */
2836 avio_rb24(pb); /* flags */
2837
2838 // Clamp allocation size for `chunk_offsets` -- don't throw an error for an
2839 // invalid count since the EOF path doesn't throw either.
2840 entries = avio_rb32(pb);
2841 entries =
2842 FFMIN(entries,
2843 FFMAX(0, (atom.size - 8) /
2844 (atom.type == MKTAG('s', 't', 'c', 'o') ? 4 : 8)));
2845
2846 if (!entries)
2847 return 0;
2848
2849 if (sc->chunk_offsets) {
2850 av_log(c->fc, AV_LOG_WARNING, "Ignoring duplicated STCO atom\n");
2851 return 0;
2852 }
2853
2855 sc->chunk_count = 0;
2856 sc->chunk_offsets = av_malloc_array(entries, sizeof(*sc->chunk_offsets));
2857 if (!sc->chunk_offsets)
2858 return AVERROR(ENOMEM);
2859 sc->chunk_count = entries;
2860
2861 if (atom.type == MKTAG('s','t','c','o'))
2862 for (i = 0; i < entries && !pb->eof_reached; i++)
2863 sc->chunk_offsets[i] = avio_rb32(pb);
2864 else if (atom.type == MKTAG('c','o','6','4'))
2865 for (i = 0; i < entries && !pb->eof_reached; i++) {
2866 sc->chunk_offsets[i] = avio_rb64(pb);
2867 if (sc->chunk_offsets[i] < 0) {
2868 av_log(c->fc, AV_LOG_WARNING, "Impossible chunk_offset\n");
2869 sc->chunk_offsets[i] = 0;
2870 }
2871 }
2872 else
2873 return AVERROR_INVALIDDATA;
2874
2875 sc->chunk_count = i;
2876
2877 if (pb->eof_reached) {
2878 av_log(c->fc, AV_LOG_WARNING, "reached eof, corrupted STCO atom\n");
2879 return AVERROR_EOF;
2880 }
2881
2882 return 0;
2883}
2884
2885static int mov_codec_id(AVStream *st, uint32_t format)
2886{
2888
2889 if (id <= 0 &&
2890 ((format & 0xFFFF) == 'm' + ('s' << 8) ||
2891 (format & 0xFFFF) == 'T' + ('S' << 8)))
2893
2894 if (st->codecpar->codec_type != AVMEDIA_TYPE_VIDEO && id > 0) {
2896 } else if (st->codecpar->codec_type != AVMEDIA_TYPE_AUDIO &&
2897 /* skip old ASF MPEG-4 tag */
2898 format && format != MKTAG('m','p','4','s')) {
2900 if (id <= 0)
2902 if (id > 0)
2904 else if (st->codecpar->codec_type == AVMEDIA_TYPE_DATA ||
2908 if (id <= 0) {
2911 }
2912
2913 if (id > 0)
2915 else
2917 }
2918 }
2919
2920 st->codecpar->codec_tag = format;
2921
2922 return id;
2923}
2924
2926 AVStream *st, MOVStreamContext *sc)
2927{
2928 uint8_t codec_name[32] = { 0 };
2929 int64_t stsd_start;
2930 unsigned int len;
2931 uint32_t id = 0;
2932
2933 /* The first 16 bytes of the video sample description are already
2934 * read in ff_mov_read_stsd_entries() */
2935 stsd_start = avio_tell(pb) - 16;
2936
2937 if (c->isom) {
2938 avio_skip(pb, 2); /* pre_defined */
2939 avio_skip(pb, 2); /* reserved */
2940 avio_skip(pb, 12); /* pre_defined */
2941 } else {
2942 avio_rb16(pb); /* version */
2943 avio_rb16(pb); /* revision level */
2944 id = avio_rl32(pb); /* vendor */
2945 av_dict_set(&st->metadata, "vendor_id", av_fourcc2str(id), 0);
2946 avio_rb32(pb); /* temporal quality */
2947 avio_rb32(pb); /* spatial quality */
2948 }
2949
2950 st->codecpar->width = avio_rb16(pb); /* width */
2951 st->codecpar->height = avio_rb16(pb); /* height */
2952
2953 avio_rb32(pb); /* horiz resolution */
2954 avio_rb32(pb); /* vert resolution */
2955 avio_rb32(pb); /* data size, always 0 */
2956 avio_rb16(pb); /* frames per samples */
2957
2958 len = avio_r8(pb); /* codec name, pascal string */
2959 if (len > 31)
2960 len = 31;
2961 mov_read_mac_string(c, pb, len, codec_name, sizeof(codec_name));
2962 if (len < 31)
2963 avio_skip(pb, 31 - len);
2964
2965 if (codec_name[0])
2966 av_dict_set(&st->metadata, "encoder", codec_name, 0);
2967
2968 /* codec_tag YV12 triggers an UV swap in rawdec.c */
2969 if (!strncmp(codec_name, "Planar Y'CbCr 8-bit 4:2:0", 25)) {
2970 st->codecpar->codec_tag = MKTAG('I', '4', '2', '0');
2971 st->codecpar->width &= ~1;
2972 st->codecpar->height &= ~1;
2973 }
2974 /* Flash Media Server uses tag H.263 with Sorenson Spark */
2975 if (st->codecpar->codec_tag == MKTAG('H','2','6','3') &&
2976 !strncmp(codec_name, "Sorenson H263", 13))
2978
2979 st->codecpar->bits_per_coded_sample = avio_rb16(pb); /* depth */
2980
2981 avio_seek(pb, stsd_start, SEEK_SET);
2982
2983 if (ff_get_qtpalette(st->codecpar->codec_id, pb, sc->palette)) {
2984 st->codecpar->bits_per_coded_sample &= 0x1F;
2985 sc->has_palette = 1;
2986 }
2987}
2988
2990 AVStream *st, MOVStreamContext *sc)
2991{
2992 int bits_per_sample, flags;
2993 uint16_t version = avio_rb16(pb);
2994 uint32_t id = 0;
2995 AVDictionaryEntry *compatible_brands = av_dict_get(c->fc->metadata, "compatible_brands", NULL, AV_DICT_MATCH_CASE);
2996 int channel_count;
2997
2998 if (c->isom)
2999 avio_skip(pb, 6); /* reserved */
3000 else {
3001 avio_rb16(pb); /* revision level */
3002 id = avio_rl32(pb); /* vendor */
3003 av_dict_set(&st->metadata, "vendor_id", av_fourcc2str(id), 0);
3004 }
3005
3006 channel_count = avio_rb16(pb);
3007
3009 st->codecpar->ch_layout.nb_channels = channel_count;
3010 st->codecpar->bits_per_coded_sample = avio_rb16(pb); /* sample size */
3011 av_log(c->fc, AV_LOG_TRACE, "audio channels %d\n", channel_count);
3012
3013 sc->audio_cid = avio_rb16(pb);
3014 avio_rb16(pb); /* packet size = 0 */
3015
3016 st->codecpar->sample_rate = ((avio_rb32(pb) >> 16));
3017
3018 // Read QT version 1 fields. In version 0 these do not exist.
3019 av_log(c->fc, AV_LOG_TRACE, "version =%d, isom =%d\n", version, c->isom);
3020 if (!c->isom ||
3021 (compatible_brands && strstr(compatible_brands->value, "qt ")) ||
3022 (sc->stsd_version == 0 && version > 0)) {
3023 if (version == 1) {
3024 sc->samples_per_frame = avio_rb32(pb);
3025 avio_rb32(pb); /* bytes per packet */
3026 sc->bytes_per_frame = avio_rb32(pb);
3027 avio_rb32(pb); /* bytes per sample */
3028 } else if (version == 2) {
3029 avio_rb32(pb); /* sizeof struct only */
3031 channel_count = avio_rb32(pb);
3033 st->codecpar->ch_layout.nb_channels = channel_count;
3034 avio_rb32(pb); /* always 0x7F000000 */
3036
3037 flags = avio_rb32(pb); /* lpcm format specific flag */
3038 sc->bytes_per_frame = avio_rb32(pb);
3039 sc->samples_per_frame = avio_rb32(pb);
3040 if (st->codecpar->codec_tag == MKTAG('l','p','c','m'))
3041 st->codecpar->codec_id =
3043 flags);
3044 }
3045 if (version == 0 || (version == 1 && sc->audio_cid != -2)) {
3046 /* can't correctly handle variable sized packet as audio unit */
3047 switch (st->codecpar->codec_id) {
3048 case AV_CODEC_ID_MP2:
3049 case AV_CODEC_ID_MP3:
3051 break;
3052 }
3053 }
3054 }
3055
3056 if (sc->format == 0) {
3057 if (st->codecpar->bits_per_coded_sample == 8)
3058 st->codecpar->codec_id = mov_codec_id(st, MKTAG('r','a','w',' '));
3059 else if (st->codecpar->bits_per_coded_sample == 16)
3060 st->codecpar->codec_id = mov_codec_id(st, MKTAG('t','w','o','s'));
3061 }
3062
3063 switch (st->codecpar->codec_id) {
3064 case AV_CODEC_ID_PCM_S8:
3065 case AV_CODEC_ID_PCM_U8:
3066 if (st->codecpar->bits_per_coded_sample == 16)
3068 break;
3071 if (st->codecpar->bits_per_coded_sample == 8)
3073 else if (st->codecpar->bits_per_coded_sample == 24)
3074 st->codecpar->codec_id =
3077 else if (st->codecpar->bits_per_coded_sample == 32)
3078 st->codecpar->codec_id =
3081 break;
3082 /* set values for old format before stsd version 1 appeared */
3083 case AV_CODEC_ID_MACE3:
3084 sc->samples_per_frame = 6;
3086 break;
3087 case AV_CODEC_ID_MACE6:
3088 sc->samples_per_frame = 6;
3090 break;
3092 sc->samples_per_frame = 64;
3094 break;
3095 case AV_CODEC_ID_GSM:
3096 sc->samples_per_frame = 160;
3097 sc->bytes_per_frame = 33;
3098 break;
3099 default:
3100 break;
3101 }
3102
3103 bits_per_sample = av_get_bits_per_sample(st->codecpar->codec_id);
3104 if (bits_per_sample && (bits_per_sample >> 3) * (uint64_t)st->codecpar->ch_layout.nb_channels <= INT_MAX) {
3105 st->codecpar->bits_per_coded_sample = bits_per_sample;
3106 sc->sample_size = (bits_per_sample >> 3) * st->codecpar->ch_layout.nb_channels;
3107 }
3108}
3109
3111 AVStream *st, MOVStreamContext *sc,
3112 int64_t size)
3113{
3114 // ttxt stsd contains display flags, justification, background
3115 // color, fonts, and default styles, so fake an atom to read it
3116 MOVAtom fake_atom = { .size = size };
3117 // mp4s contains a regular esds atom, dfxp ISMV TTML has no content
3118 // in extradata unlike stpp MP4 TTML.
3119 if (st->codecpar->codec_tag != AV_RL32("mp4s") &&
3121 mov_read_glbl(c, pb, fake_atom);
3122 st->codecpar->width = sc->width;
3123 st->codecpar->height = sc->height;
3124}
3125
3127 AVStream *st, MOVStreamContext *sc,
3128 int64_t size)
3129{
3130 int ret;
3131
3132 if (st->codecpar->codec_tag == MKTAG('t','m','c','d')) {
3133 if ((int)size != size)
3134 return AVERROR(ENOMEM);
3135
3136 ret = ff_get_extradata(c->fc, st->codecpar, pb, size);
3137 if (ret < 0)
3138 return ret;
3139 if (size > 16) {
3140 MOVStreamContext *tmcd_ctx = st->priv_data;
3141 int val;
3142 val = AV_RB32(st->codecpar->extradata + 4);
3143 tmcd_ctx->tmcd_flags = val;
3144 st->avg_frame_rate.num = AV_RB32(st->codecpar->extradata + 8); /* timescale */
3145 st->avg_frame_rate.den = AV_RB32(st->codecpar->extradata + 12); /* frameDuration */
3146 tmcd_ctx->tmcd_nb_frames = st->codecpar->extradata[16]; /* number of frames */
3147 if (size > 30) {
3148 uint32_t len = AV_RB32(st->codecpar->extradata + 18); /* name atom length */
3149 uint32_t format = AV_RB32(st->codecpar->extradata + 22);
3150 if (format == AV_RB32("name") && (int64_t)size >= (int64_t)len + 18) {
3151 uint16_t str_size = AV_RB16(st->codecpar->extradata + 26); /* string length */
3152 if (str_size > 0 && size >= (int)str_size + 30 &&
3153 st->codecpar->extradata[30] /* Don't add empty string */) {
3154 char *reel_name = av_malloc(str_size + 1);
3155 if (!reel_name)
3156 return AVERROR(ENOMEM);
3157 memcpy(reel_name, st->codecpar->extradata + 30, str_size);
3158 reel_name[str_size] = 0; /* Add null terminator */
3159 av_dict_set(&st->metadata, "reel_name", reel_name,
3161 }
3162 }
3163 }
3164 }
3165 } else if (st->codecpar->codec_id == AV_CODEC_ID_ITUT_T35) {
3166 int t35_identifier_length = avio_r8(pb);
3167
3168 if (t35_identifier_length <= 0 || t35_identifier_length >= size)
3169 return AVERROR_INVALIDDATA;
3170
3171 ret = ff_get_extradata(c->fc, st->codecpar, pb, t35_identifier_length);
3172 if (ret < 0)
3173 return ret;
3174
3175 int hrsd_len = size - t35_identifier_length - 1;
3176 if (hrsd_len > 0) {
3177 uint8_t *hrsd_str = av_malloc(hrsd_len + 1);
3178 if (!hrsd_str)
3179 return AVERROR(ENOMEM);
3180
3181 ret = ffio_read_size(pb, hrsd_str, hrsd_len);
3182 if (ret < 0) {
3183 av_free(hrsd_str);
3184 return ret;
3185 }
3186 if (hrsd_str[0]) {
3187 hrsd_str[hrsd_len] = 0;
3188 ret = av_dict_set(&st->metadata, "description", hrsd_str, AV_DICT_DONT_OVERWRITE);
3189 }
3190 av_free(hrsd_str);
3191 }
3192 } else {
3193 /* other codec type, just skip (rtp, mp4s ...) */
3194 avio_skip(pb, size);
3195 }
3196 return 0;
3197}
3198
3200 AVStream *st, MOVStreamContext *sc)
3201{
3202 FFStream *const sti = ffstream(st);
3203
3205 !st->codecpar->sample_rate && sc->time_scale > 1)
3206 st->codecpar->sample_rate = sc->time_scale;
3207
3208 /* special codec parameters handling */
3209 switch (st->codecpar->codec_id) {
3210#if CONFIG_DV_DEMUXER
3212 if (c->dv_fctx) {
3213 avpriv_request_sample(c->fc, "multiple DV audio streams");
3214 return AVERROR(ENOSYS);
3215 }
3216
3217 c->dv_fctx = avformat_alloc_context();
3218 if (!c->dv_fctx) {
3219 av_log(c->fc, AV_LOG_ERROR, "dv demux context alloc error\n");
3220 return AVERROR(ENOMEM);
3221 }
3222 c->dv_demux = avpriv_dv_init_demux(c->dv_fctx);
3223 if (!c->dv_demux) {
3224 av_log(c->fc, AV_LOG_ERROR, "dv demux context init error\n");
3225 return AVERROR(ENOMEM);
3226 }
3227 sc->dv_audio_container = 1;
3229 break;
3230#endif
3231 /* no ifdef since parameters are always those */
3232 case AV_CODEC_ID_QCELP:
3235 // force sample rate for qcelp when not stored in mov
3236 if (st->codecpar->codec_tag != MKTAG('Q','c','l','p'))
3237 st->codecpar->sample_rate = 8000;
3238 // FIXME: Why is the following needed for some files?
3239 sc->samples_per_frame = 160;
3240 if (!sc->bytes_per_frame)
3241 sc->bytes_per_frame = 35;
3242 break;
3243 case AV_CODEC_ID_AMR_NB:
3246 /* force sample rate for amr, stsd in 3gp does not store sample rate */
3247 st->codecpar->sample_rate = 8000;
3248 break;
3249 case AV_CODEC_ID_AMR_WB:
3252 st->codecpar->sample_rate = 16000;
3253 break;
3254 case AV_CODEC_ID_MP2:
3255 case AV_CODEC_ID_MP3:
3256 /* force type after stsd for m1a hdlr */
3258 break;
3259 case AV_CODEC_ID_GSM:
3262 case AV_CODEC_ID_ILBC:
3263 case AV_CODEC_ID_MACE3:
3264 case AV_CODEC_ID_MACE6:
3265 case AV_CODEC_ID_QDM2:
3267 break;
3268 case AV_CODEC_ID_ALAC:
3269 if (st->codecpar->extradata_size == 36) {
3270 int channel_count = AV_RB8(st->codecpar->extradata + 21);
3271 if (st->codecpar->ch_layout.nb_channels != channel_count) {
3274 st->codecpar->ch_layout.nb_channels = channel_count;
3275 }
3276 st->codecpar->sample_rate = AV_RB32(st->codecpar->extradata + 32);
3277 }
3278 break;
3279 case AV_CODEC_ID_AC3:
3280 case AV_CODEC_ID_EAC3:
3282 case AV_CODEC_ID_VC1:
3283 case AV_CODEC_ID_VP8:
3284 case AV_CODEC_ID_VP9:
3286 break;
3288 case AV_CODEC_ID_PRORES:
3289 case AV_CODEC_ID_APV:
3290 case AV_CODEC_ID_EVC:
3291 case AV_CODEC_ID_LCEVC:
3292 case AV_CODEC_ID_AV1:
3293 /* field_order detection of H264 requires parsing */
3294 case AV_CODEC_ID_H264:
3296 break;
3297 default:
3298 break;
3299 }
3300 return 0;
3301}
3302
3304 int codec_tag, int format,
3305 int64_t size)
3306{
3307 if (codec_tag &&
3308 (codec_tag != format &&
3309 // AVID 1:1 samples with differing data format and codec tag exist
3310 (codec_tag != AV_RL32("AV1x") || format != AV_RL32("AVup")) &&
3311 // prores is allowed to have differing data format and codec tag
3312 codec_tag != AV_RL32("apcn") && codec_tag != AV_RL32("apch") &&
3313 // so is dv (sigh)
3314 codec_tag != AV_RL32("dvpp") && codec_tag != AV_RL32("dvcp") &&
3315 (c->fc->video_codec_id ? ff_codec_get_id(ff_codec_movvideo_tags, format) != c->fc->video_codec_id
3316 : codec_tag != MKTAG('j','p','e','g')))) {
3317 /* Multiple fourcc, we skip JPEG. This is not correct, we should
3318 * export it as a separate AVStream but this needs a few changes
3319 * in the MOV demuxer, patch welcome. */
3320
3321 av_log(c->fc, AV_LOG_WARNING, "multiple fourcc not supported\n");
3322 avio_skip(pb, size);
3323 return 1;
3324 }
3325
3326 return 0;
3327}
3328
3330{
3331 int ret;
3332
3333 /* special codec parameters handling */
3334 switch (st->codecpar->codec_id) {
3335 case AV_CODEC_ID_H264:
3336 // done for ai5q, ai52, ai55, ai1q, ai12 and ai15.
3339 if (ret < 0)
3340 return ret;
3341 }
3342 break;
3343 default:
3344 break;
3345 }
3346
3347 return 0;
3348}
3349
3351{
3352 AVStream *st;
3353 MOVStreamContext *sc;
3354 int pseudo_stream_id;
3355
3356 av_assert0 (c->fc->nb_streams >= 1);
3357 st = c->fc->streams[c->fc->nb_streams-1];
3358 sc = st->priv_data;
3359
3360 for (pseudo_stream_id = 0;
3361 pseudo_stream_id < entries && !pb->eof_reached;
3362 pseudo_stream_id++) {
3363 //Parsing Sample description table
3364 enum AVCodecID id;
3365 int ret, dref_id = 1;
3366 MOVAtom a = { AV_RL32("stsd") };
3367 int64_t start_pos = avio_tell(pb);
3368 int64_t size = avio_rb32(pb); /* size */
3369 uint32_t format = avio_rl32(pb); /* data format */
3370
3371 if (size >= 16) {
3372 avio_rb32(pb); /* reserved */
3373 avio_rb16(pb); /* reserved */
3374 dref_id = avio_rb16(pb);
3375 } else if (size <= 7) {
3376 av_log(c->fc, AV_LOG_ERROR,
3377 "invalid size %"PRId64" in stsd\n", size);
3378 return AVERROR_INVALIDDATA;
3379 }
3380
3382 size - (avio_tell(pb) - start_pos))) {
3383 sc->stsd_count++;
3384 continue;
3385 }
3386
3387 sc->pseudo_stream_id = st->codecpar->codec_tag ? -1 : pseudo_stream_id;
3388 sc->dref_id= dref_id;
3389 sc->format = format;
3390
3391 id = mov_codec_id(st, format);
3392
3393 av_log(c->fc, AV_LOG_TRACE,
3394 "size=%"PRId64" 4CC=%s codec_type=%d\n", size,
3396
3397 st->codecpar->codec_id = id;
3399 mov_parse_stsd_video(c, pb, st, sc);
3400 } else if (st->codecpar->codec_type==AVMEDIA_TYPE_AUDIO) {
3401 mov_parse_stsd_audio(c, pb, st, sc);
3402 if (st->codecpar->sample_rate < 0) {
3403 av_log(c->fc, AV_LOG_ERROR, "Invalid sample rate %d\n", st->codecpar->sample_rate);
3404 return AVERROR_INVALIDDATA;
3405 }
3406 if (st->codecpar->ch_layout.nb_channels < 0) {
3407 av_log(c->fc, AV_LOG_ERROR, "Invalid channels %d\n", st->codecpar->ch_layout.nb_channels);
3408 return AVERROR_INVALIDDATA;
3409 }
3410 } else if (st->codecpar->codec_type==AVMEDIA_TYPE_SUBTITLE){
3411 mov_parse_stsd_subtitle(c, pb, st, sc,
3412 size - (avio_tell(pb) - start_pos));
3413 } else {
3414 ret = mov_parse_stsd_data(c, pb, st, sc,
3415 size - (avio_tell(pb) - start_pos));
3416 if (ret < 0)
3417 return ret;
3418 }
3419 /* this will read extra atoms at the end (wave, alac, damr, avcC, hvcC, SMI ...) */
3420 a.size = size - (avio_tell(pb) - start_pos);
3421 if (a.size > 8) {
3422 if ((ret = mov_read_default(c, pb, a)) < 0)
3423 return ret;
3424 } else if (a.size > 0)
3425 avio_skip(pb, a.size);
3426
3427 ret = mov_finalize_stsd_entry(c, st);
3428 if (ret < 0)
3429 return ret;
3430
3431 if (sc->extradata && st->codecpar->extradata) {
3432 int extra_size = st->codecpar->extradata_size;
3433
3434 /* Move the current stream extradata to the stream context one. */
3435 sc->extradata_size[pseudo_stream_id] = extra_size;
3436 sc->extradata[pseudo_stream_id] = st->codecpar->extradata;
3437 st->codecpar->extradata = NULL;
3438 st->codecpar->extradata_size = 0;
3439 }
3440 sc->stsd_count++;
3441 }
3442
3443 if (pb->eof_reached) {
3444 av_log(c->fc, AV_LOG_WARNING, "reached eof, corrupted STSD atom\n");
3445 return AVERROR_EOF;
3446 }
3447
3448 return 0;
3449}
3450
3452{
3453 AVStream *st;
3454 MOVStreamContext *sc;
3455 int ret, entries;
3456
3457 if (c->fc->nb_streams < 1)
3458 return 0;
3459 st = c->fc->streams[c->fc->nb_streams - 1];
3460 sc = st->priv_data;
3461
3462 if (sc->extradata) {
3463 av_log(c->fc, AV_LOG_ERROR,
3464 "Duplicate stsd found in this track.\n");
3465 return AVERROR_INVALIDDATA;
3466 }
3467
3468 sc->stsd_version = avio_r8(pb);
3469 avio_rb24(pb); /* flags */
3470 entries = avio_rb32(pb);
3471
3472 /* Each entry contains a size (4 bytes) and format (4 bytes). */
3473 if (entries <= 0 || entries > atom.size / 8 || entries > 1024) {
3474 av_log(c->fc, AV_LOG_ERROR, "invalid STSD entries %d\n", entries);
3475 return AVERROR_INVALIDDATA;
3476 }
3477
3478 /* Prepare space for hosting multiple extradata. */
3479 sc->extradata = av_calloc(entries, sizeof(*sc->extradata));
3480 if (!sc->extradata)
3481 return AVERROR(ENOMEM);
3482
3483 sc->extradata_size = av_calloc(entries, sizeof(*sc->extradata_size));
3484 if (!sc->extradata_size) {
3485 ret = AVERROR(ENOMEM);
3486 goto fail;
3487 }
3488
3489 ret = ff_mov_read_stsd_entries(c, pb, entries);
3490 if (ret < 0)
3491 goto fail;
3492
3493 /* Restore back the primary extradata. */
3496 if (sc->extradata_size[0]) {
3498 if (!st->codecpar->extradata)
3499 return AVERROR(ENOMEM);
3500 memcpy(st->codecpar->extradata, sc->extradata[0], sc->extradata_size[0]);
3501 }
3502
3503 return mov_finalize_stsd_codec(c, pb, st, sc);
3504fail:
3505 if (sc->extradata) {
3506 int j;
3507 for (j = 0; j < sc->stsd_count; j++)
3508 av_freep(&sc->extradata[j]);
3509 }
3510
3511 sc->stsd_count = 0;
3512 av_freep(&sc->extradata);
3514 return ret;
3515}
3516
3518{
3519 AVStream *st;
3520 MOVStreamContext *sc;
3521 unsigned int i, entries;
3522
3523 if (c->trak_index < 0) {
3524 av_log(c->fc, AV_LOG_WARNING, "STSC outside TRAK\n");
3525 return 0;
3526 }
3527
3528 if (c->fc->nb_streams < 1)
3529 return 0;
3530 st = c->fc->streams[c->fc->nb_streams-1];
3531 sc = st->priv_data;
3532
3533 avio_r8(pb); /* version */
3534 avio_rb24(pb); /* flags */
3535
3536 entries = avio_rb32(pb);
3537 if ((uint64_t)entries * 12 + 4 > atom.size)
3538 return AVERROR_INVALIDDATA;
3539
3540 av_log(c->fc, AV_LOG_TRACE, "track[%u].stsc.entries = %u\n", c->fc->nb_streams - 1, entries);
3541
3542 if (!entries)
3543 return 0;
3544 if (sc->stsc_data) {
3545 av_log(c->fc, AV_LOG_WARNING, "Ignoring duplicated STSC atom\n");
3546 return 0;
3547 }
3548 av_free(sc->stsc_data);
3549 sc->stsc_count = 0;
3550 sc->stsc_data = av_malloc_array(entries, sizeof(*sc->stsc_data));
3551 if (!sc->stsc_data)
3552 return AVERROR(ENOMEM);
3553
3554 for (i = 0; i < entries && !pb->eof_reached; i++) {
3555 sc->stsc_data[i].first = avio_rb32(pb);
3556 sc->stsc_data[i].count = avio_rb32(pb);
3557 sc->stsc_data[i].id = avio_rb32(pb);
3558 }
3559
3560 sc->stsc_count = i;
3561 for (i = sc->stsc_count - 1; i < UINT_MAX; i--) {
3562 int64_t first_min = i + 1;
3563 if ((i+1 < sc->stsc_count && sc->stsc_data[i].first >= sc->stsc_data[i+1].first) ||
3564 (i > 0 && sc->stsc_data[i].first <= sc->stsc_data[i-1].first) ||
3565 sc->stsc_data[i].first < first_min ||
3566 sc->stsc_data[i].count < 1 ||
3567 sc->stsc_data[i].id < 1) {
3568 av_log(c->fc, AV_LOG_WARNING, "STSC entry %d is invalid (first=%d count=%d id=%d)\n", i, sc->stsc_data[i].first, sc->stsc_data[i].count, sc->stsc_data[i].id);
3569 if (i+1 >= sc->stsc_count) {
3570 if (sc->stsc_data[i].count == 0 && i > 0) {
3571 sc->stsc_count --;
3572 continue;
3573 }
3574 sc->stsc_data[i].first = FFMAX(sc->stsc_data[i].first, first_min);
3575 if (i > 0 && sc->stsc_data[i].first <= sc->stsc_data[i-1].first)
3576 sc->stsc_data[i].first = FFMIN(sc->stsc_data[i-1].first + 1LL, INT_MAX);
3577 sc->stsc_data[i].count = FFMAX(sc->stsc_data[i].count, 1);
3578 sc->stsc_data[i].id = FFMAX(sc->stsc_data[i].id, 1);
3579 continue;
3580 }
3581 av_assert0(sc->stsc_data[i+1].first >= 2);
3582 // We replace this entry by the next valid
3583 sc->stsc_data[i].first = sc->stsc_data[i+1].first - 1;
3584 sc->stsc_data[i].count = sc->stsc_data[i+1].count;
3585 sc->stsc_data[i].id = sc->stsc_data[i+1].id;
3586 }
3587 }
3588
3589 if (pb->eof_reached) {
3590 av_log(c->fc, AV_LOG_WARNING, "reached eof, corrupted STSC atom\n");
3591 return AVERROR_EOF;
3592 }
3593
3594 return 0;
3595}
3596
3597static inline int mov_stsc_index_valid(unsigned int index, unsigned int count)
3598{
3599 return index < count - 1;
3600}
3601
3602/* Compute the samples value for the stsc entry at the given index. */
3603static inline int64_t mov_get_stsc_samples(MOVStreamContext *sc, unsigned int index)
3604{
3605 int chunk_count;
3606
3608 chunk_count = sc->stsc_data[index + 1].first - sc->stsc_data[index].first;
3609 else {
3610 // Validation for stsc / stco happens earlier in mov_read_stsc + mov_read_trak.
3612 chunk_count = sc->chunk_count - (sc->stsc_data[index].first - 1);
3613 }
3614
3615 return sc->stsc_data[index].count * (int64_t)chunk_count;
3616}
3617
3619{
3620 AVStream *st;
3621 MOVStreamContext *sc;
3622 unsigned i, entries;
3623
3624 if (c->trak_index < 0) {
3625 av_log(c->fc, AV_LOG_WARNING, "STPS outside TRAK\n");
3626 return 0;
3627 }
3628
3629 if (c->fc->nb_streams < 1)
3630 return 0;
3631 st = c->fc->streams[c->fc->nb_streams-1];
3632 sc = st->priv_data;
3633
3634 avio_rb32(pb); // version + flags
3635
3636 entries = avio_rb32(pb);
3637 if (sc->stps_data)
3638 av_log(c->fc, AV_LOG_WARNING, "Duplicated STPS atom\n");
3639 av_free(sc->stps_data);
3640 sc->stps_count = 0;
3641 sc->stps_data = av_malloc_array(entries, sizeof(*sc->stps_data));
3642 if (!sc->stps_data)
3643 return AVERROR(ENOMEM);
3644
3645 for (i = 0; i < entries && !pb->eof_reached; i++) {
3646 sc->stps_data[i] = avio_rb32(pb);
3647 }
3648
3649 sc->stps_count = i;
3650
3651 if (pb->eof_reached) {
3652 av_log(c->fc, AV_LOG_WARNING, "reached eof, corrupted STPS atom\n");
3653 return AVERROR_EOF;
3654 }
3655
3656 return 0;
3657}
3658
3660{
3661 AVStream *st;
3662 FFStream *sti;
3663 MOVStreamContext *sc;
3664 unsigned int i, entries;
3665
3666 if (c->trak_index < 0) {
3667 av_log(c->fc, AV_LOG_WARNING, "STSS outside TRAK\n");
3668 return 0;
3669 }
3670
3671 if (c->fc->nb_streams < 1)
3672 return 0;
3673 st = c->fc->streams[c->fc->nb_streams-1];
3674 sti = ffstream(st);
3675 sc = st->priv_data;
3676
3677 avio_r8(pb); /* version */
3678 avio_rb24(pb); /* flags */
3679
3680 entries = avio_rb32(pb);
3681
3682 av_log(c->fc, AV_LOG_TRACE, "keyframe_count = %u\n", entries);
3683
3684 if (!entries) {
3685 sc->keyframe_absent = 1;
3688 return 0;
3689 }
3690 if (sc->keyframes)
3691 av_log(c->fc, AV_LOG_WARNING, "Duplicated STSS atom\n");
3692 if (entries >= UINT_MAX / sizeof(int))
3693 return AVERROR_INVALIDDATA;
3694 av_freep(&sc->keyframes);
3695 sc->keyframe_count = 0;
3696 sc->keyframes = av_malloc_array(entries, sizeof(*sc->keyframes));
3697 if (!sc->keyframes)
3698 return AVERROR(ENOMEM);
3699
3700 for (i = 0; i < entries && !pb->eof_reached; i++) {
3701 sc->keyframes[i] = avio_rb32(pb);
3702 }
3703
3704 sc->keyframe_count = i;
3705
3706 if (pb->eof_reached) {
3707 av_log(c->fc, AV_LOG_WARNING, "reached eof, corrupted STSS atom\n");
3708 return AVERROR_EOF;
3709 }
3710
3711 return 0;
3712}
3713
3715{
3716 AVStream *st;
3717 MOVStreamContext *sc;
3718 unsigned int i, entries, sample_size, field_size, num_bytes;
3719 GetBitContext gb;
3720 unsigned char* buf;
3721 int ret;
3722
3723 if (c->trak_index < 0) {
3724 av_log(c->fc, AV_LOG_WARNING, "STSZ outside TRAK\n");
3725 return 0;
3726 }
3727
3728 if (c->fc->nb_streams < 1)
3729 return 0;
3730 st = c->fc->streams[c->fc->nb_streams-1];
3731 sc = st->priv_data;
3732
3733 avio_r8(pb); /* version */
3734 avio_rb24(pb); /* flags */
3735
3736 if (atom.type == MKTAG('s','t','s','z')) {
3737 sample_size = avio_rb32(pb);
3738 if (!sc->sample_size) /* do not overwrite value computed in stsd */
3739 sc->sample_size = sample_size;
3740 sc->stsz_sample_size = sample_size;
3741 field_size = 32;
3742 } else {
3743 sample_size = 0;
3744 avio_rb24(pb); /* reserved */
3745 field_size = avio_r8(pb);
3746 }
3747 entries = avio_rb32(pb);
3748
3749 av_log(c->fc, AV_LOG_TRACE, "sample_size = %u sample_count = %u\n", sc->sample_size, entries);
3750
3751 sc->sample_count = entries;
3752 if (sample_size)
3753 return 0;
3754
3755 if (field_size != 4 && field_size != 8 && field_size != 16 && field_size != 32) {
3756 av_log(c->fc, AV_LOG_ERROR, "Invalid sample field size %u\n", field_size);
3757 return AVERROR_INVALIDDATA;
3758 }
3759
3760 if (!entries)
3761 return 0;
3762 if (entries >= (INT_MAX - 4 - 8 * AV_INPUT_BUFFER_PADDING_SIZE) / field_size)
3763 return AVERROR_INVALIDDATA;
3764 if (sc->sample_sizes)
3765 av_log(c->fc, AV_LOG_WARNING, "Duplicated STSZ atom\n");
3766 av_free(sc->sample_sizes);
3767 sc->sample_count = 0;
3768 sc->sample_sizes = av_malloc_array(entries, sizeof(*sc->sample_sizes));
3769 if (!sc->sample_sizes)
3770 return AVERROR(ENOMEM);
3771
3772 num_bytes = (entries*field_size+4)>>3;
3773
3774 buf = av_malloc(num_bytes+AV_INPUT_BUFFER_PADDING_SIZE);
3775 if (!buf) {
3776 av_freep(&sc->sample_sizes);
3777 return AVERROR(ENOMEM);
3778 }
3779
3780 ret = ffio_read_size(pb, buf, num_bytes);
3781 if (ret < 0) {
3782 av_freep(&sc->sample_sizes);
3783 av_free(buf);
3784 av_log(c->fc, AV_LOG_WARNING, "STSZ atom truncated\n");
3785 return 0;
3786 }
3787
3788 init_get_bits(&gb, buf, 8*num_bytes);
3789
3790 for (i = 0; i < entries; i++) {
3791 sc->sample_sizes[i] = get_bits_long(&gb, field_size);
3792 if (sc->sample_sizes[i] > INT64_MAX - sc->data_size) {
3793 av_free(buf);
3794 av_log(c->fc, AV_LOG_ERROR, "Sample size overflow in STSZ\n");
3795 return AVERROR_INVALIDDATA;
3796 }
3797 sc->data_size += sc->sample_sizes[i];
3798 }
3799
3800 sc->sample_count = i;
3801
3802 av_free(buf);
3803
3804 return 0;
3805}
3806
3808{
3809 AVStream *st;
3810 MOVStreamContext *sc;
3811 unsigned int i, entries;
3812 int64_t duration = 0;
3813 int64_t total_sample_count = 0;
3814 int64_t current_dts = 0;
3815 int64_t corrected_dts = 0;
3816
3817 if (c->trak_index < 0) {
3818 av_log(c->fc, AV_LOG_WARNING, "STTS outside TRAK\n");
3819 return 0;
3820 }
3821
3822 if (c->fc->nb_streams < 1)
3823 return 0;
3824 st = c->fc->streams[c->fc->nb_streams-1];
3825 sc = st->priv_data;
3826
3827 avio_r8(pb); /* version */
3828 avio_rb24(pb); /* flags */
3829 entries = avio_rb32(pb);
3830
3831 av_log(c->fc, AV_LOG_TRACE, "track[%u].stts.entries = %u\n",
3832 c->fc->nb_streams-1, entries);
3833
3834 if (sc->stts_data)
3835 av_log(c->fc, AV_LOG_WARNING, "Duplicated STTS atom\n");
3836 av_freep(&sc->stts_data);
3837 sc->stts_count = 0;
3838 if (entries >= INT_MAX / sizeof(*sc->stts_data))
3839 return AVERROR(ENOMEM);
3840
3841 for (i = 0; i < entries && !pb->eof_reached; i++) {
3842 unsigned int sample_duration;
3843 unsigned int sample_count;
3844 unsigned int min_entries = FFMIN(FFMAX(i + 1, 1024 * 1024), entries);
3846 min_entries * sizeof(*sc->stts_data));
3847 if (!stts_data) {
3848 av_freep(&sc->stts_data);
3849 sc->stts_count = 0;
3850 return AVERROR(ENOMEM);
3851 }
3852 sc->stts_count = min_entries;
3853 sc->stts_data = stts_data;
3854
3855 sample_count = avio_rb32(pb);
3856 sample_duration = avio_rb32(pb);
3857
3858 sc->stts_data[i].count= sample_count;
3859 sc->stts_data[i].duration= sample_duration;
3860
3861 av_log(c->fc, AV_LOG_TRACE, "sample_count=%u, sample_duration=%u\n",
3862 sample_count, sample_duration);
3863
3864 /* STTS sample offsets are uint32 but some files store it as int32
3865 * with negative values used to correct DTS delays.
3866 There may be abnormally large values as well. */
3867 if (sample_duration > c->max_stts_delta) {
3868 // assume high delta is a correction if negative when cast as int32
3869 int32_t delta_magnitude = (int32_t)sample_duration;
3870 av_log(c->fc, AV_LOG_WARNING, "Too large sample offset %u in stts entry %u with count %u in st:%d. Clipping to 1.\n",
3871 sample_duration, i, sample_count, st->index);
3872 sc->stts_data[i].duration = 1;
3873 corrected_dts = av_sat_add64(corrected_dts, (delta_magnitude < 0 ? (int64_t)delta_magnitude : 1) * sample_count);
3874 } else {
3875 corrected_dts += sample_duration * (uint64_t)sample_count;
3876 }
3877
3878 current_dts += sc->stts_data[i].duration * (uint64_t)sample_count;
3879
3880 if (current_dts > corrected_dts) {
3881 int64_t drift = av_sat_sub64(current_dts, corrected_dts) / FFMAX(sample_count, 1);
3882 uint32_t correction = (sc->stts_data[i].duration > drift) ? drift : sc->stts_data[i].duration - 1;
3883 current_dts -= correction * (uint64_t)sample_count;
3884 sc->stts_data[i].duration -= correction;
3885 }
3886
3887 duration+=(int64_t)sc->stts_data[i].duration*(uint64_t)sc->stts_data[i].count;
3888 total_sample_count+=sc->stts_data[i].count;
3889 }
3890
3891 sc->stts_count = i;
3892
3893 if (duration > 0 &&
3894 duration <= INT64_MAX - sc->duration_for_fps &&
3895 total_sample_count <= INT_MAX - sc->nb_frames_for_fps) {
3897 sc->nb_frames_for_fps += total_sample_count;
3898 }
3899
3900 if (pb->eof_reached) {
3901 av_log(c->fc, AV_LOG_WARNING, "reached eof, corrupted STTS atom\n");
3902 return AVERROR_EOF;
3903 }
3904
3905 st->nb_frames= total_sample_count;
3906 if (duration)
3907 st->duration= FFMIN(st->duration, duration);
3908
3909 // All samples have zero duration. They have higher chance be chose by
3910 // mov_find_next_sample, which leads to seek again and again.
3911 //
3912 // It's AVERROR_INVALIDDATA actually, but such files exist in the wild.
3913 // So only mark data stream as discarded for safety.
3914 if (!duration && sc->stts_count &&
3916 av_log(c->fc, AV_LOG_WARNING,
3917 "All samples in data stream index:id [%d:%d] have zero "
3918 "duration, stream set to be discarded by default. Override "
3919 "using AVStream->discard or -discard for ffmpeg command.\n",
3920 st->index, sc->id);
3921 st->discard = AVDISCARD_ALL;
3922 }
3923 sc->track_end = duration;
3924 return 0;
3925}
3926
3928{
3929 AVStream *st;
3930 MOVStreamContext *sc;
3931 unsigned int i;
3932 int64_t entries;
3933
3934 if (c->fc->nb_streams < 1)
3935 return 0;
3936 st = c->fc->streams[c->fc->nb_streams - 1];
3937 sc = st->priv_data;
3938
3939 avio_r8(pb); /* version */
3940 avio_rb24(pb); /* flags */
3941 entries = atom.size - 4;
3942
3943 av_log(c->fc, AV_LOG_TRACE, "track[%u].sdtp.entries = %" PRId64 "\n",
3944 c->fc->nb_streams - 1, entries);
3945
3946 if (sc->sdtp_data)
3947 av_log(c->fc, AV_LOG_WARNING, "Duplicated SDTP atom\n");
3948 av_freep(&sc->sdtp_data);
3949 sc->sdtp_count = 0;
3950
3951 if (entries < 0 || entries > UINT_MAX)
3952 return AVERROR(ERANGE);
3953
3954 sc->sdtp_data = av_malloc(entries);
3955 if (!sc->sdtp_data)
3956 return AVERROR(ENOMEM);
3957
3958 for (i = 0; i < entries && !pb->eof_reached; i++)
3959 sc->sdtp_data[i] = avio_r8(pb);
3960 sc->sdtp_count = i;
3961
3962 return 0;
3963}
3964
3965static void mov_update_dts_shift(MOVStreamContext *sc, int duration, void *logctx)
3966{
3967 if (duration < 0) {
3968 if (duration == INT_MIN) {
3969 av_log(logctx, AV_LOG_WARNING, "mov_update_dts_shift(): dts_shift set to %d\n", INT_MAX);
3970 duration++;
3971 }
3972 sc->dts_shift = FFMAX(sc->dts_shift, -duration);
3973 }
3974}
3975
3977{
3978 AVStream *st;
3979 MOVStreamContext *sc;
3980 unsigned int i, entries, ctts_count = 0;
3981
3982 if (c->trak_index < 0) {
3983 av_log(c->fc, AV_LOG_WARNING, "CTTS outside TRAK\n");
3984 return 0;
3985 }
3986
3987 if (c->fc->nb_streams < 1)
3988 return 0;
3989 st = c->fc->streams[c->fc->nb_streams-1];
3990 sc = st->priv_data;
3991
3992 avio_r8(pb); /* version */
3993 avio_rb24(pb); /* flags */
3994 entries = avio_rb32(pb);
3995
3996 av_log(c->fc, AV_LOG_TRACE, "track[%u].ctts.entries = %u\n", c->fc->nb_streams - 1, entries);
3997
3998 if (!entries)
3999 return 0;
4000 if (entries >= UINT_MAX / sizeof(*sc->ctts_data))
4001 return AVERROR_INVALIDDATA;
4002 av_freep(&sc->ctts_data);
4003 sc->ctts_data = av_fast_realloc(NULL, &sc->ctts_allocated_size, entries * sizeof(*sc->ctts_data));
4004 if (!sc->ctts_data)
4005 return AVERROR(ENOMEM);
4006
4007 for (i = 0; i < entries && !pb->eof_reached; i++) {
4008 MOVCtts *ctts_data;
4009 const size_t min_size_needed = (ctts_count + 1) * sizeof(MOVCtts);
4010 const size_t requested_size =
4011 min_size_needed > sc->ctts_allocated_size ?
4012 FFMAX(min_size_needed, 2 * sc->ctts_allocated_size) :
4013 min_size_needed;
4014 int count = avio_rb32(pb);
4015 int duration = avio_rb32(pb);
4016
4017 if (count <= 0) {
4018 av_log(c->fc, AV_LOG_TRACE,
4019 "ignoring CTTS entry with count=%d duration=%d\n",
4020 count, duration);
4021 continue;
4022 }
4023
4024 if (ctts_count >= UINT_MAX / sizeof(MOVCtts) - 1)
4025 return AVERROR(ENOMEM);
4026
4027 ctts_data = av_fast_realloc(sc->ctts_data, &sc->ctts_allocated_size, requested_size);
4028
4029 if (!ctts_data)
4030 return AVERROR(ENOMEM);
4031
4032 sc->ctts_data = ctts_data;
4033
4034 ctts_data[ctts_count].count = count;
4035 ctts_data[ctts_count].offset = duration;
4036 ctts_count++;
4037
4038 av_log(c->fc, AV_LOG_TRACE, "count=%d, duration=%d\n",
4039 count, duration);
4040
4041 if (i+2<entries)
4043 }
4044
4045 sc->ctts_count = ctts_count;
4046
4047 if (pb->eof_reached) {
4048 av_log(c->fc, AV_LOG_WARNING, "reached eof, corrupted CTTS atom\n");
4049 return AVERROR_EOF;
4050 }
4051
4052 av_log(c->fc, AV_LOG_TRACE, "dts shift %d\n", sc->dts_shift);
4053
4054 return 0;
4055}
4056
4058{
4059 AVStream *st;
4060 MOVStreamContext *sc;
4061 uint8_t version;
4062 uint32_t grouping_type;
4063 uint32_t default_length;
4064 av_unused uint32_t default_group_description_index;
4065 uint32_t entry_count;
4066
4067 if (c->fc->nb_streams < 1)
4068 return 0;
4069 st = c->fc->streams[c->fc->nb_streams - 1];
4070 sc = st->priv_data;
4071
4072 version = avio_r8(pb); /* version */
4073 avio_rb24(pb); /* flags */
4074 grouping_type = avio_rl32(pb);
4075
4076 /*
4077 * This function only supports "sync" boxes, but the code is able to parse
4078 * other boxes (such as "tscl", "tsas" and "stsa")
4079 */
4080 if (grouping_type != MKTAG('s','y','n','c'))
4081 return 0;
4082
4083 default_length = version >= 1 ? avio_rb32(pb) : 0;
4084 default_group_description_index = version >= 2 ? avio_rb32(pb) : 0;
4085 entry_count = avio_rb32(pb);
4086
4087 if (entry_count > atom.size)
4088 return AVERROR_INVALIDDATA;
4089
4090 av_freep(&sc->sgpd_sync);
4091 sc->sgpd_sync_count = entry_count;
4092 sc->sgpd_sync = av_calloc(entry_count, sizeof(*sc->sgpd_sync));
4093 if (!sc->sgpd_sync)
4094 return AVERROR(ENOMEM);
4095
4096 for (uint32_t i = 0; i < entry_count && !pb->eof_reached; i++) {
4097 uint32_t description_length = default_length;
4098 if (version >= 1 && default_length == 0)
4099 description_length = avio_rb32(pb);
4100 if (grouping_type == MKTAG('s','y','n','c')) {
4101 const uint8_t nal_unit_type = avio_r8(pb) & 0x3f;
4102 sc->sgpd_sync[i] = nal_unit_type;
4103 description_length -= 1;
4104 }
4105 avio_skip(pb, description_length);
4106 }
4107
4108 if (pb->eof_reached) {
4109 av_log(c->fc, AV_LOG_WARNING, "reached eof, corrupted SGPD atom\n");
4110 return AVERROR_EOF;
4111 }
4112
4113 return 0;
4114}
4115
4117{
4118 AVStream *st;
4119 MOVStreamContext *sc;
4120 unsigned int i, entries;
4121 uint8_t version;
4122 uint32_t grouping_type;
4123 MOVSbgp *table, **tablep;
4124 int *table_count;
4125
4126 if (c->fc->nb_streams < 1)
4127 return 0;
4128 st = c->fc->streams[c->fc->nb_streams-1];
4129 sc = st->priv_data;
4130
4131 version = avio_r8(pb); /* version */
4132 avio_rb24(pb); /* flags */
4133 grouping_type = avio_rl32(pb);
4134
4135 if (grouping_type == MKTAG('r','a','p',' ')) {
4136 tablep = &sc->rap_group;
4137 table_count = &sc->rap_group_count;
4138 } else if (grouping_type == MKTAG('s','y','n','c')) {
4139 tablep = &sc->sync_group;
4140 table_count = &sc->sync_group_count;
4141 } else {
4142 return 0;
4143 }
4144
4145 if (version == 1)
4146 avio_rb32(pb); /* grouping_type_parameter */
4147
4148 entries = avio_rb32(pb);
4149 if (!entries)
4150 return 0;
4151 if (*tablep)
4152 av_log(c->fc, AV_LOG_WARNING, "Duplicated SBGP %s atom\n", av_fourcc2str(grouping_type));
4153 av_freep(tablep);
4154 table = av_malloc_array(entries, sizeof(*table));
4155 if (!table)
4156 return AVERROR(ENOMEM);
4157 *tablep = table;
4158
4159 for (i = 0; i < entries && !pb->eof_reached; i++) {
4160 table[i].count = avio_rb32(pb); /* sample_count */
4161 table[i].index = avio_rb32(pb); /* group_description_index */
4162 }
4163
4164 *table_count = i;
4165
4166 if (pb->eof_reached) {
4167 av_log(c->fc, AV_LOG_WARNING, "reached eof, corrupted SBGP atom\n");
4168 return AVERROR_EOF;
4169 }
4170
4171 return 0;
4172}
4173
4174/**
4175 * Get ith edit list entry (media time, duration).
4176 */
4178 const MOVStreamContext *msc,
4179 unsigned int edit_list_index,
4180 int64_t *edit_list_media_time,
4181 int64_t *edit_list_duration,
4182 int64_t global_timescale)
4183{
4184 if (edit_list_index == msc->elst_count) {
4185 return 0;
4186 }
4187 *edit_list_media_time = msc->elst_data[edit_list_index].time;
4188 *edit_list_duration = msc->elst_data[edit_list_index].duration;
4189
4190 /* duration is in global timescale units;convert to msc timescale */
4191 if (global_timescale == 0) {
4192 avpriv_request_sample(mov->fc, "Support for mvhd.timescale = 0 with editlists");
4193 return 0;
4194 }
4195 *edit_list_duration = av_rescale(*edit_list_duration, msc->time_scale,
4196 global_timescale);
4197
4198 if (*edit_list_duration + (uint64_t)*edit_list_media_time > INT64_MAX)
4199 *edit_list_duration = 0;
4200
4201 return 1;
4202}
4203
4204/**
4205 * Find the closest previous frame to the timestamp_pts, in e_old index
4206 * entries. Searching for just any frame / just key frames can be controlled by
4207 * last argument 'flag'.
4208 * Note that if ctts_data is not NULL, we will always search for a key frame
4209 * irrespective of the value of 'flag'. If we don't find any keyframe, we will
4210 * return the first frame of the video.
4211 *
4212 * Here the timestamp_pts is considered to be a presentation timestamp and
4213 * the timestamp of index entries are considered to be decoding timestamps.
4214 *
4215 * Returns 0 if successful in finding a frame, else returns -1.
4216 * Places the found index corresponding output arg.
4217 *
4218 * If ctts_old is not NULL, then refines the searched entry by searching
4219 * backwards from the found timestamp, to find the frame with correct PTS.
4220 *
4221 * Places the found ctts_index and ctts_sample in corresponding output args.
4222 */
4224 AVIndexEntry *e_old,
4225 int nb_old,
4226 MOVTimeToSample *tts_data,
4227 int64_t tts_count,
4228 int64_t timestamp_pts,
4229 int flag,
4230 int64_t* index,
4231 int64_t* tts_index,
4232 int64_t* tts_sample)
4233{
4234 MOVStreamContext *msc = st->priv_data;
4235 FFStream *const sti = ffstream(st);
4236 AVIndexEntry *e_keep = sti->index_entries;
4237 int nb_keep = sti->nb_index_entries;
4238 int64_t i = 0;
4239
4241
4242 // If dts_shift > 0, then all the index timestamps will have to be offset by
4243 // at least dts_shift amount to obtain PTS.
4244 // Hence we decrement the searched timestamp_pts by dts_shift to find the closest index element.
4245 if (msc->dts_shift > 0) {
4246 timestamp_pts -= msc->dts_shift;
4247 }
4248
4249 sti->index_entries = e_old;
4250 sti->nb_index_entries = nb_old;
4252
4253 // Keep going backwards in the index entries until the timestamp is the same.
4254 if (*index >= 0) {
4255 for (i = *index; i > 0 && e_old[i].timestamp == e_old[i - 1].timestamp;
4256 i--) {
4257 if ((flag & AVSEEK_FLAG_ANY) ||
4258 (e_old[i - 1].flags & AVINDEX_KEYFRAME)) {
4259 *index = i - 1;
4260 }
4261 }
4262 }
4263
4264 // If we have CTTS then refine the search, by searching backwards over PTS
4265 // computed by adding corresponding CTTS durations to index timestamps.
4266 if (msc->ctts_count && *index >= 0) {
4267 av_assert0(tts_index);
4268 av_assert0(tts_sample);
4269 // Find out the ctts_index for the found frame.
4270 *tts_index = 0;
4271 *tts_sample = 0;
4272 for (int64_t index_tts_count = 0; index_tts_count < *index; index_tts_count++) {
4273 if (*tts_index < tts_count) {
4274 (*tts_sample)++;
4275 if (tts_data[*tts_index].count == *tts_sample) {
4276 (*tts_index)++;
4277 *tts_sample = 0;
4278 }
4279 }
4280 }
4281
4282 while (*index >= 0 && (*tts_index) >= 0 && (*tts_index) < tts_count) {
4283 // Find a "key frame" with PTS <= timestamp_pts (So that we can decode B-frames correctly).
4284 // No need to add dts_shift to the timestamp here because timestamp_pts has already been
4285 // compensated by dts_shift above.
4286 if ((e_old[*index].timestamp + tts_data[*tts_index].offset) <= timestamp_pts &&
4287 (e_old[*index].flags & AVINDEX_KEYFRAME)) {
4288 break;
4289 }
4290
4291 (*index)--;
4292 if (*tts_sample == 0) {
4293 (*tts_index)--;
4294 if (*tts_index >= 0)
4295 *tts_sample = tts_data[*tts_index].count - 1;
4296 } else {
4297 (*tts_sample)--;
4298 }
4299 }
4300 }
4301
4302 /* restore AVStream state*/
4303 sti->index_entries = e_keep;
4304 sti->nb_index_entries = nb_keep;
4305 return *index >= 0 ? 0 : -1;
4306}
4307
4308/**
4309 * Add index entry with the given values, to the end of ffstream(st)->index_entries.
4310 * Returns the new size ffstream(st)->index_entries if successful, else returns -1.
4311 *
4312 * This function is similar to ff_add_index_entry in libavformat/utils.c
4313 * except that here we are always unconditionally adding an index entry to
4314 * the end, instead of searching the entries list and skipping the add if
4315 * there is an existing entry with the same timestamp.
4316 * This is needed because the mov_fix_index calls this func with the same
4317 * unincremented timestamp for successive discarded frames.
4318 */
4320 int size, int distance, int flags)
4321{
4322 FFStream *const sti = ffstream(st);
4323 AVIndexEntry *entries, *ie;
4324 int64_t index = -1;
4325 const size_t min_size_needed = (sti->nb_index_entries + 1) * sizeof(AVIndexEntry);
4326
4327 // Double the allocation each time, to lower memory fragmentation.
4328 // Another difference from ff_add_index_entry function.
4329 const size_t requested_size =
4330 min_size_needed > sti->index_entries_allocated_size ?
4331 FFMAX(min_size_needed, 2 * sti->index_entries_allocated_size) :
4332 min_size_needed;
4333
4334 if (sti->nb_index_entries + 1U >= UINT_MAX / sizeof(AVIndexEntry))
4335 return -1;
4336
4337 entries = av_fast_realloc(sti->index_entries,
4339 requested_size);
4340 if (!entries)
4341 return -1;
4342
4343 sti->index_entries = entries;
4344
4345 index = sti->nb_index_entries++;
4346 ie= &entries[index];
4347
4348 ie->pos = pos;
4349 ie->timestamp = timestamp;
4351 ie->size= size;
4352 ie->flags = flags;
4353 return index;
4354}
4355
4356/**
4357 * Rewrite timestamps of index entries in the range [end_index - frame_duration_buffer_size, end_index)
4358 * by subtracting end_ts successively by the amounts given in frame_duration_buffer.
4359 */
4360static void fix_index_entry_timestamps(AVStream* st, int end_index, int64_t end_ts,
4361 int64_t* frame_duration_buffer,
4362 int frame_duration_buffer_size) {
4363 FFStream *const sti = ffstream(st);
4364 int i = 0;
4365 av_assert0(end_index >= 0 && end_index <= sti->nb_index_entries);
4366 for (i = 0; i < frame_duration_buffer_size; i++) {
4367 end_ts -= frame_duration_buffer[frame_duration_buffer_size - 1 - i];
4368 sti->index_entries[end_index - 1 - i].timestamp = end_ts;
4369 }
4370}
4371
4372static int add_tts_entry(MOVTimeToSample **tts_data, unsigned int *tts_count, unsigned int *allocated_size,
4373 int count, int offset, unsigned int duration)
4374{
4375 MOVTimeToSample *tts_buf_new;
4376 const size_t min_size_needed = (*tts_count + 1) * sizeof(MOVTimeToSample);
4377 const size_t requested_size =
4378 min_size_needed > *allocated_size ?
4379 FFMAX(min_size_needed, 2 * (*allocated_size)) :
4380 min_size_needed;
4381
4382 if ((unsigned)(*tts_count) >= UINT_MAX / sizeof(MOVTimeToSample) - 1)
4383 return -1;
4384
4385 tts_buf_new = av_fast_realloc(*tts_data, allocated_size, requested_size);
4386
4387 if (!tts_buf_new)
4388 return -1;
4389
4390 *tts_data = tts_buf_new;
4391
4392 tts_buf_new[*tts_count].count = count;
4393 tts_buf_new[*tts_count].offset = offset;
4394 tts_buf_new[*tts_count].duration = duration;
4395
4396 *tts_count = (*tts_count) + 1;
4397 return 0;
4398}
4399
4400#define MAX_REORDER_DELAY 16
4402{
4403 MOVStreamContext *msc = st->priv_data;
4404 FFStream *const sti = ffstream(st);
4405 int ctts_ind = 0;
4406 int ctts_sample = 0;
4407 int64_t pts_buf[MAX_REORDER_DELAY + 1]; // Circular buffer to sort pts.
4408 int buf_start = 0;
4409 int j, r, num_swaps;
4410
4411 for (j = 0; j < MAX_REORDER_DELAY + 1; j++)
4412 pts_buf[j] = INT64_MIN;
4413
4414 if (st->codecpar->video_delay <= 0 && msc->ctts_count &&
4416 st->codecpar->video_delay = 0;
4417 for (int ind = 0; ind < sti->nb_index_entries && ctts_ind < msc->tts_count; ++ind) {
4418 // Point j to the last elem of the buffer and insert the current pts there.
4419 j = buf_start;
4420 buf_start = (buf_start + 1);
4421 if (buf_start == MAX_REORDER_DELAY + 1)
4422 buf_start = 0;
4423
4424 pts_buf[j] = sti->index_entries[ind].timestamp + msc->tts_data[ctts_ind].offset;
4425
4426 // The timestamps that are already in the sorted buffer, and are greater than the
4427 // current pts, are exactly the timestamps that need to be buffered to output PTS
4428 // in correct sorted order.
4429 // Hence the video delay (which is the buffer size used to sort DTS and output PTS),
4430 // can be computed as the maximum no. of swaps any particular timestamp needs to
4431 // go through, to keep this buffer in sorted order.
4432 num_swaps = 0;
4433 while (j != buf_start) {
4434 r = j - 1;
4435 if (r < 0) r = MAX_REORDER_DELAY;
4436 if (pts_buf[j] < pts_buf[r]) {
4437 FFSWAP(int64_t, pts_buf[j], pts_buf[r]);
4438 ++num_swaps;
4439 } else {
4440 break;
4441 }
4442 j = r;
4443 }
4444 st->codecpar->video_delay = FFMAX(st->codecpar->video_delay, num_swaps);
4445
4446 ctts_sample++;
4447 if (ctts_sample == msc->tts_data[ctts_ind].count) {
4448 ctts_ind++;
4449 ctts_sample = 0;
4450 }
4451 }
4452 av_log(c->fc, AV_LOG_DEBUG, "Setting codecpar->delay to %d for stream st: %d\n",
4453 st->codecpar->video_delay, st->index);
4454 }
4455}
4456
4458{
4459 sc->current_sample++;
4460 sc->current_index++;
4461 if (sc->index_ranges &&
4463 sc->current_index_range->end) {
4464 sc->current_index_range++;
4466 }
4467}
4468
4470{
4471 sc->current_sample--;
4472 sc->current_index--;
4473 if (sc->index_ranges &&
4476 sc->current_index_range--;
4477 sc->current_index = sc->current_index_range->end - 1;
4478 }
4479}
4480
4481static void mov_current_sample_set(MOVStreamContext *sc, int current_sample)
4482{
4483 int64_t range_size;
4484
4485 sc->current_sample = current_sample;
4486 sc->current_index = current_sample;
4487 if (!sc->index_ranges) {
4488 return;
4489 }
4490
4491 for (sc->current_index_range = sc->index_ranges;
4493 sc->current_index_range++) {
4494 range_size = sc->current_index_range->end - sc->current_index_range->start;
4495 if (range_size > current_sample) {
4496 sc->current_index = sc->current_index_range->start + current_sample;
4497 break;
4498 }
4499 current_sample -= range_size;
4500 }
4501}
4502
4503/**
4504 * Fix ffstream(st)->index_entries, so that it contains only the entries (and the entries
4505 * which are needed to decode them) that fall in the edit list time ranges.
4506 * Also fixes the timestamps of the index entries to match the timeline
4507 * specified the edit lists.
4508 */
4509static void mov_fix_index(MOVContext *mov, AVStream *st)
4510{
4511 MOVStreamContext *msc = st->priv_data;
4512 FFStream *const sti = ffstream(st);
4513 AVIndexEntry *e_old = sti->index_entries;
4514 int nb_old = sti->nb_index_entries;
4515 const AVIndexEntry *e_old_end = e_old + nb_old;
4516 const AVIndexEntry *current = NULL;
4517 MOVTimeToSample *tts_data_old = msc->tts_data;
4518 int64_t tts_index_old = 0;
4519 int64_t tts_sample_old = 0;
4520 int64_t tts_count_old = msc->tts_count;
4521 int64_t edit_list_media_time = 0;
4522 int64_t edit_list_duration = 0;
4523 int64_t frame_duration = 0;
4524 int64_t edit_list_dts_counter = 0;
4525 int64_t edit_list_dts_entry_end = 0;
4526 int64_t edit_list_start_tts_sample = 0;
4527 int64_t curr_cts;
4528 int64_t curr_ctts = 0;
4529 int64_t empty_edits_sum_duration = 0;
4530 int64_t edit_list_index = 0;
4531 int64_t index;
4532 int flags;
4533 int64_t start_dts = 0;
4534 int64_t edit_list_start_encountered = 0;
4535 int64_t search_timestamp = 0;
4536 int64_t* frame_duration_buffer = NULL;
4537 int num_discarded_begin = 0;
4538 int first_non_zero_audio_edit = -1;
4539 int packet_skip_samples = 0;
4540 MOVIndexRange *current_index_range = NULL;
4541 int found_keyframe_after_edit = 0;
4542 int found_non_empty_edit = 0;
4543
4544 if (!msc->elst_data || msc->elst_count <= 0 || nb_old <= 0) {
4545 return;
4546 }
4547
4548 // allocate the index ranges array
4549 msc->index_ranges = av_malloc_array(msc->elst_count + 1,
4550 sizeof(msc->index_ranges[0]));
4551 if (!msc->index_ranges) {
4552 av_log(mov->fc, AV_LOG_ERROR, "Cannot allocate index ranges buffer\n");
4553 return;
4554 }
4556
4557 // Clean AVStream from traces of old index
4558 sti->index_entries = NULL;
4560 sti->nb_index_entries = 0;
4561
4562 // Clean time to sample fields of MOVStreamContext
4563 msc->tts_data = NULL;
4564 msc->tts_count = 0;
4565 msc->tts_index = 0;
4566 msc->tts_sample = 0;
4567 msc->tts_allocated_size = 0;
4568
4569 // Reinitialize min_corrected_pts so that it can be computed again.
4570 msc->min_corrected_pts = -1;
4571
4572 // If the dts_shift is positive (in case of negative ctts values in mov),
4573 // then negate the DTS by dts_shift
4574 if (msc->dts_shift > 0) {
4575 edit_list_dts_entry_end -= msc->dts_shift;
4576 av_log(mov->fc, AV_LOG_DEBUG, "Shifting DTS by %d because of negative CTTS.\n", msc->dts_shift);
4577 }
4578
4579 start_dts = edit_list_dts_entry_end;
4580
4581 while (get_edit_list_entry(mov, msc, edit_list_index, &edit_list_media_time,
4582 &edit_list_duration, mov->time_scale)) {
4583 av_log(mov->fc, AV_LOG_DEBUG, "Processing st: %d, edit list %"PRId64" - media time: %"PRId64", duration: %"PRId64"\n",
4584 st->index, edit_list_index, edit_list_media_time, edit_list_duration);
4585 edit_list_index++;
4586 edit_list_dts_counter = edit_list_dts_entry_end;
4587 edit_list_dts_entry_end = av_sat_add64(edit_list_dts_entry_end, edit_list_duration);
4588 if (edit_list_dts_entry_end == INT64_MAX) {
4589 av_log(mov->fc, AV_LOG_ERROR, "Cannot calculate dts entry length with duration %"PRId64"\n",
4590 edit_list_duration);
4591 break;
4592 }
4593 num_discarded_begin = 0;
4594 if (!found_non_empty_edit && edit_list_media_time == -1) {
4595 empty_edits_sum_duration += edit_list_duration;
4596 continue;
4597 }
4598 found_non_empty_edit = 1;
4599
4600 // If we encounter a non-negative edit list reset the skip_samples/initial_padding fields and set them
4601 // according to the edit list below.
4603 if (first_non_zero_audio_edit < 0) {
4604 first_non_zero_audio_edit = 1;
4605 } else {
4606 first_non_zero_audio_edit = 0;
4607 }
4608
4609 if (first_non_zero_audio_edit > 0)
4610 sti->skip_samples = st->codecpar->initial_padding = 0;
4611 }
4612
4613 // While reordering frame index according to edit list we must handle properly
4614 // the scenario when edit list entry starts from none key frame.
4615 // We find closest previous key frame and preserve it and consequent frames in index.
4616 // All frames which are outside edit list entry time boundaries will be dropped after decoding.
4617 search_timestamp = edit_list_media_time;
4619 // Audio decoders like AAC need need a decoder delay samples previous to the current sample,
4620 // to correctly decode this frame. Hence for audio we seek to a frame 1 sec. before the
4621 // edit_list_media_time to cover the decoder delay.
4622 search_timestamp = FFMAX(search_timestamp - msc->time_scale, e_old[0].timestamp);
4623 }
4624
4625 if (find_prev_closest_index(st, e_old, nb_old, tts_data_old, tts_count_old, search_timestamp, 0,
4626 &index, &tts_index_old, &tts_sample_old) < 0) {
4627 av_log(mov->fc, AV_LOG_WARNING,
4628 "st: %d edit list: %"PRId64" Missing key frame while searching for timestamp: %"PRId64"\n",
4629 st->index, edit_list_index, search_timestamp);
4630 if (find_prev_closest_index(st, e_old, nb_old, tts_data_old, tts_count_old, search_timestamp, AVSEEK_FLAG_ANY,
4631 &index, &tts_index_old, &tts_sample_old) < 0) {
4632 av_log(mov->fc, AV_LOG_WARNING,
4633 "st: %d edit list %"PRId64" Cannot find an index entry before timestamp: %"PRId64".\n",
4634 st->index, edit_list_index, search_timestamp);
4635 index = 0;
4636 tts_index_old = 0;
4637 tts_sample_old = 0;
4638 }
4639 }
4640 current = e_old + index;
4641 edit_list_start_tts_sample = tts_sample_old;
4642
4643 // Iterate over index and arrange it according to edit list
4644 edit_list_start_encountered = 0;
4645 found_keyframe_after_edit = 0;
4646 for (; current < e_old_end; current++, index++) {
4647 // check if frame outside edit list mark it for discard
4648 frame_duration = (current + 1 < e_old_end) ?
4649 ((current + 1)->timestamp - current->timestamp) : edit_list_duration;
4650
4651 flags = current->flags;
4652
4653 // frames (pts) before or after edit list
4654 curr_cts = current->timestamp + msc->dts_shift;
4655 curr_ctts = 0;
4656
4657 if (tts_data_old && tts_index_old < tts_count_old) {
4658 curr_ctts = tts_data_old[tts_index_old].offset;
4659 av_log(mov->fc, AV_LOG_TRACE, "stts: %"PRId64" ctts: %"PRId64", tts_index: %"PRId64", tts_count: %"PRId64"\n",
4660 curr_cts, curr_ctts, tts_index_old, tts_count_old);
4661 curr_cts += curr_ctts;
4662 tts_sample_old++;
4663 if (tts_sample_old == tts_data_old[tts_index_old].count) {
4664 if (add_tts_entry(&msc->tts_data, &msc->tts_count,
4665 &msc->tts_allocated_size,
4666 tts_data_old[tts_index_old].count - edit_list_start_tts_sample,
4667 tts_data_old[tts_index_old].offset, tts_data_old[tts_index_old].duration) == -1) {
4668 av_log(mov->fc, AV_LOG_ERROR, "Cannot add Time To Sample entry %"PRId64" - {%"PRId64", %d}\n",
4669 tts_index_old,
4670 tts_data_old[tts_index_old].count - edit_list_start_tts_sample,
4671 tts_data_old[tts_index_old].offset);
4672 break;
4673 }
4674 tts_index_old++;
4675 tts_sample_old = 0;
4676 edit_list_start_tts_sample = 0;
4677 }
4678 }
4679
4680 if (curr_cts < edit_list_media_time || curr_cts >= (edit_list_duration + edit_list_media_time)) {
4682 curr_cts < edit_list_media_time && curr_cts + frame_duration > edit_list_media_time &&
4683 first_non_zero_audio_edit > 0) {
4684 packet_skip_samples = edit_list_media_time - curr_cts;
4685 sti->skip_samples += packet_skip_samples;
4686
4687 // Shift the index entry timestamp by packet_skip_samples to be correct.
4688 edit_list_dts_counter -= packet_skip_samples;
4689 if (edit_list_start_encountered == 0) {
4690 edit_list_start_encountered = 1;
4691 // Make timestamps strictly monotonically increasing for audio, by rewriting timestamps for
4692 // discarded packets.
4693 if (frame_duration_buffer) {
4694 fix_index_entry_timestamps(st, sti->nb_index_entries, edit_list_dts_counter,
4695 frame_duration_buffer, num_discarded_begin);
4696 av_freep(&frame_duration_buffer);
4697 }
4698 }
4699
4700 av_log(mov->fc, AV_LOG_DEBUG, "skip %d audio samples from curr_cts: %"PRId64"\n", packet_skip_samples, curr_cts);
4701 } else {
4703 av_log(mov->fc, AV_LOG_DEBUG, "drop a frame at curr_cts: %"PRId64" @ %"PRId64"\n", curr_cts, index);
4704
4705 if (edit_list_start_encountered == 0) {
4706 num_discarded_begin++;
4707 frame_duration_buffer = av_realloc(frame_duration_buffer,
4708 num_discarded_begin * sizeof(int64_t));
4709 if (!frame_duration_buffer) {
4710 av_log(mov->fc, AV_LOG_ERROR, "Cannot reallocate frame duration buffer\n");
4711 break;
4712 }
4713 frame_duration_buffer[num_discarded_begin - 1] = frame_duration;
4714
4715 // Increment skip_samples for the first non-zero audio edit list
4717 first_non_zero_audio_edit > 0 && st->codecpar->codec_id != AV_CODEC_ID_VORBIS) {
4718 sti->skip_samples += frame_duration;
4719 }
4720 }
4721 }
4722 } else {
4723 if (msc->min_corrected_pts < 0) {
4724 msc->min_corrected_pts = edit_list_dts_counter + curr_ctts + msc->dts_shift;
4725 } else {
4726 msc->min_corrected_pts = FFMIN(msc->min_corrected_pts, edit_list_dts_counter + curr_ctts + msc->dts_shift);
4727 }
4728 if (edit_list_start_encountered == 0) {
4729 edit_list_start_encountered = 1;
4730 // Make timestamps strictly monotonically increasing by rewriting timestamps for
4731 // discarded packets.
4732 if (frame_duration_buffer) {
4733 fix_index_entry_timestamps(st, sti->nb_index_entries, edit_list_dts_counter,
4734 frame_duration_buffer, num_discarded_begin);
4735 av_freep(&frame_duration_buffer);
4736 }
4737 }
4738 }
4739
4740 if (add_index_entry(st, current->pos, edit_list_dts_counter, current->size,
4741 current->min_distance, flags) == -1) {
4742 av_log(mov->fc, AV_LOG_ERROR, "Cannot add index entry\n");
4743 break;
4744 }
4745
4746 // Update the index ranges array
4747 if (!current_index_range || index != current_index_range->end) {
4748 current_index_range = current_index_range ? current_index_range + 1
4749 : msc->index_ranges;
4750 current_index_range->start = index;
4751 }
4752 current_index_range->end = index + 1;
4753
4754 // Only start incrementing DTS in frame_duration amounts, when we encounter a frame in edit list.
4755 if (edit_list_start_encountered > 0) {
4756 edit_list_dts_counter = edit_list_dts_counter + frame_duration;
4757 }
4758
4759 // Break when found first key frame after edit entry completion
4760 if ((curr_cts + frame_duration >= (edit_list_duration + edit_list_media_time)) &&
4762 if (msc->ctts_count) {
4763 // If we have CTTS and this is the first keyframe after edit elist,
4764 // wait for one more, because there might be trailing B-frames after this I-frame
4765 // that do belong to the edit.
4766 if (st->codecpar->codec_type != AVMEDIA_TYPE_AUDIO && found_keyframe_after_edit == 0) {
4767 found_keyframe_after_edit = 1;
4768 continue;
4769 }
4770 if (tts_sample_old != 0) {
4771 if (add_tts_entry(&msc->tts_data, &msc->tts_count,
4772 &msc->tts_allocated_size,
4773 tts_sample_old - edit_list_start_tts_sample,
4774 tts_data_old[tts_index_old].offset, tts_data_old[tts_index_old].duration) == -1) {
4775 av_log(mov->fc, AV_LOG_ERROR, "Cannot add Time To Sample entry %"PRId64" - {%"PRId64", %d}\n",
4776 tts_index_old, tts_sample_old - edit_list_start_tts_sample,
4777 tts_data_old[tts_index_old].offset);
4778 break;
4779 }
4780 }
4781 }
4782 break;
4783 }
4784 }
4785 }
4786 // If there are empty edits, then msc->min_corrected_pts might be positive
4787 // intentionally. So we subtract the sum duration of empty edits here.
4788 msc->min_corrected_pts -= empty_edits_sum_duration;
4789
4790 // If the minimum pts turns out to be greater than zero after fixing the index, then we subtract the
4791 // dts by that amount to make the first pts zero.
4793 if (msc->min_corrected_pts > 0) {
4794 av_log(mov->fc, AV_LOG_DEBUG, "Offset DTS by %"PRId64" to make first pts zero.\n", msc->min_corrected_pts);
4795 for (int i = 0; i < sti->nb_index_entries; ++i)
4797 }
4798 }
4799 // Start time should be equal to zero or the duration of any empty edits.
4800 st->start_time = empty_edits_sum_duration;
4801
4802 // Update av stream length, if it ends up shorter than the track's media duration
4803 st->duration = FFMIN(st->duration, edit_list_dts_entry_end - start_dts);
4805
4806 // Free the old index and the old CTTS structures
4807 av_free(e_old);
4808 av_free(tts_data_old);
4809 av_freep(&frame_duration_buffer);
4810
4811 // Null terminate the index ranges array
4812 current_index_range = current_index_range ? current_index_range + 1
4813 : msc->index_ranges;
4814 current_index_range->start = 0;
4815 current_index_range->end = 0;
4816 msc->current_index = msc->index_ranges[0].start;
4817}
4818
4819static uint32_t get_sgpd_sync_index(const MOVStreamContext *sc, int nal_unit_type)
4820{
4821 for (uint32_t i = 0; i < sc->sgpd_sync_count; i++)
4822 if (sc->sgpd_sync[i] == nal_unit_type)
4823 return i + 1;
4824 return 0;
4825}
4826
4828{
4829 int k;
4830 int sample_id = 0;
4831 uint32_t cra_index;
4832 MOVStreamContext *sc = st->priv_data;
4833
4835 return 0;
4836
4837 /* Build an unrolled index of the samples */
4838 sc->sample_offsets_count = 0;
4839 for (uint32_t i = 0; i < sc->ctts_count; i++) {
4840 if (sc->ctts_data[i].count > INT_MAX - sc->sample_offsets_count)
4841 return AVERROR(ENOMEM);
4843 }
4846 if (!sc->sample_offsets)
4847 return AVERROR(ENOMEM);
4848 k = 0;
4849 for (uint32_t i = 0; i < sc->ctts_count; i++)
4850 for (int j = 0; j < sc->ctts_data[i].count; j++)
4851 sc->sample_offsets[k++] = sc->ctts_data[i].offset;
4852
4853 /* The following HEVC NAL type reveal the use of open GOP sync points
4854 * (TODO: BLA types may also be concerned) */
4855 cra_index = get_sgpd_sync_index(sc, HEVC_NAL_CRA_NUT); /* Clean Random Access */
4856 if (!cra_index)
4857 return 0;
4858
4859 /* Build a list of open-GOP key samples */
4860 sc->open_key_samples_count = 0;
4861 for (uint32_t i = 0; i < sc->sync_group_count; i++)
4862 if (sc->sync_group[i].index == cra_index) {
4863 if (sc->sync_group[i].count > INT_MAX - sc->open_key_samples_count)
4864 return AVERROR(ENOMEM);
4866 }
4869 if (!sc->open_key_samples)
4870 return AVERROR(ENOMEM);
4871 k = 0;
4872 for (uint32_t i = 0; i < sc->sync_group_count; i++) {
4873 const MOVSbgp *sg = &sc->sync_group[i];
4874 if (sg->index == cra_index)
4875 for (uint32_t j = 0; j < sg->count; j++)
4876 sc->open_key_samples[k++] = sample_id;
4877 if (sg->count > INT_MAX - sample_id)
4878 return AVERROR_PATCHWELCOME;
4879 sample_id += sg->count;
4880 }
4881
4882 /* Identify the minimal time step between samples */
4883 sc->min_sample_duration = UINT_MAX;
4884 for (uint32_t i = 0; i < sc->stts_count; i++)
4886
4887 return 0;
4888}
4889
4890#define MOV_MERGE_CTTS 1
4891#define MOV_MERGE_STTS 2
4892/*
4893 * Merge stts and ctts arrays into a new combined array.
4894 * stts_count and ctts_count may be left untouched as they will be
4895 * used to check for the presence of either of them.
4896 */
4898{
4899 MOVStreamContext *sc = st->priv_data;
4900 int ctts = sc->ctts_data && (flags & MOV_MERGE_CTTS);
4901 int stts = sc->stts_data && (flags & MOV_MERGE_STTS);
4902 int idx = 0;
4903
4904 if (!sc->ctts_data && !sc->stts_data)
4905 return 0;
4906 // Expand time to sample entries such that we have a 1-1 mapping with samples
4907 if (!sc->sample_count || sc->sample_count >= UINT_MAX / sizeof(*sc->tts_data))
4908 return -1;
4909
4910 if (ctts) {
4912 sc->sample_count * sizeof(*sc->tts_data));
4913 if (!sc->tts_data)
4914 return -1;
4915
4916 memset(sc->tts_data, 0, sc->tts_allocated_size);
4917
4918 for (int i = 0; i < sc->ctts_count &&
4919 idx < sc->sample_count; i++)
4920 for (int j = 0; j < sc->ctts_data[i].count &&
4921 idx < sc->sample_count; j++) {
4922 sc->tts_data[idx].offset = sc->ctts_data[i].offset;
4923 sc->tts_data[idx++].count = 1;
4924 }
4925
4926 sc->tts_count = idx;
4927 } else
4928 sc->ctts_count = 0;
4929 av_freep(&sc->ctts_data);
4930 sc->ctts_allocated_size = 0;
4931
4932 idx = 0;
4933 if (stts) {
4935 sc->sample_count * sizeof(*sc->tts_data));
4936 if (!tts_data)
4937 return -1;
4938
4939 if (!sc->tts_data)
4940 memset(tts_data, 0, sc->tts_allocated_size);
4941 sc->tts_data = tts_data;
4942
4943 for (int i = 0; i < sc->stts_count &&
4944 idx < sc->sample_count; i++)
4945 for (int j = 0; j < sc->stts_data[i].count &&
4946 idx < sc->sample_count; j++) {
4947 sc->tts_data[idx].duration = sc->stts_data[i].duration;
4948 sc->tts_data[idx++].count = 1;
4949 }
4950
4951 sc->tts_count = FFMAX(sc->tts_count, idx);
4952 } else
4953 sc->stts_count = 0;
4954 av_freep(&sc->stts_data);
4955 sc->stts_allocated_size = 0;
4956
4957 return 0;
4958}
4959
4961{
4962 MOVStreamContext *sc = st->priv_data;
4963 FFStream *const sti = ffstream(st);
4964 int64_t current_offset;
4965 int64_t current_dts = 0;
4966 unsigned int stts_index = 0;
4967 unsigned int stsc_index = 0;
4968 unsigned int stss_index = 0;
4969 unsigned int stps_index = 0;
4970 unsigned int i, j;
4971 uint64_t stream_size = 0;
4972
4973 int ret = build_open_gop_key_points(st);
4974 if (ret < 0)
4975 return;
4976
4977 if (sc->elst_count) {
4978 int i, edit_start_index = 0, multiple_edits = 0;
4979 int64_t empty_duration = 0; // empty duration of the first edit list entry
4980 int64_t start_time = 0; // start time of the media
4981
4982 for (i = 0; i < sc->elst_count; i++) {
4983 const MOVElst *e = &sc->elst_data[i];
4984 if (i == 0 && e->time == -1) {
4985 /* if empty, the first entry is the start time of the stream
4986 * relative to the presentation itself */
4987 empty_duration = e->duration;
4988 edit_start_index = 1;
4989 } else if (i == edit_start_index && e->time >= 0) {
4990 start_time = e->time;
4991 } else {
4992 multiple_edits = 1;
4993 }
4994 }
4995
4996 if (multiple_edits && !mov->advanced_editlist) {
4998 av_log(mov->fc, AV_LOG_WARNING, "multiple edit list entries, "
4999 "not supported in fragmented MP4 files\n");
5000 else
5001 av_log(mov->fc, AV_LOG_WARNING, "multiple edit list entries, "
5002 "Use -advanced_editlist to correctly decode otherwise "
5003 "a/v desync might occur\n");
5004 }
5005
5006 /* adjust first dts according to edit list */
5007 if ((empty_duration || start_time) && mov->time_scale > 0) {
5008 if (empty_duration)
5009 empty_duration = av_rescale(empty_duration, sc->time_scale, mov->time_scale);
5010
5011 if (av_sat_sub64(start_time, empty_duration) != start_time - (uint64_t)empty_duration)
5012 av_log(mov->fc, AV_LOG_WARNING, "start_time - empty_duration is not representable\n");
5013
5014 sc->time_offset = start_time - (uint64_t)empty_duration;
5016 if (!mov->advanced_editlist)
5017 current_dts = -av_clip64(sc->time_offset, -INT64_MAX, INT64_MAX);
5018 }
5019
5020 if (!multiple_edits && !mov->advanced_editlist &&
5023 (AVRational){1, st->codecpar->sample_rate});
5024 }
5025
5026 /* only use old uncompressed audio chunk demuxing when stts specifies it */
5027 if (!(st->codecpar->codec_type == AVMEDIA_TYPE_AUDIO &&
5028 sc->stts_count == 1 && sc->stts_data && sc->stts_data[0].duration == 1)) {
5029 unsigned int current_sample = 0;
5030 unsigned int stts_sample = 0;
5031 unsigned int sample_size;
5032 unsigned int distance = 0;
5033 unsigned int rap_group_index = 0;
5034 unsigned int rap_group_sample = 0;
5035 int rap_group_present = sc->rap_group_count && sc->rap_group;
5036 int key_off = (sc->keyframe_count && sc->keyframes[0] > 0) || (sc->stps_count && sc->stps_data[0] > 0);
5037
5038 av_assert0(sc->dts_shift >= 0);
5039 if (current_dts < INT64_MIN + sc->dts_shift)
5040 return;
5041 current_dts -= sc->dts_shift;
5042 if (!sc->sample_count || sti->nb_index_entries || sc->tts_count)
5043 return;
5044 if (sc->sample_count >= UINT_MAX / sizeof(*sti->index_entries) - sti->nb_index_entries)
5045 return;
5047 sti->nb_index_entries + sc->sample_count,
5048 sizeof(*sti->index_entries)) < 0) {
5049 sti->nb_index_entries = 0;
5050 return;
5051 }
5052 sti->index_entries_allocated_size = (sti->nb_index_entries + sc->sample_count) * sizeof(*sti->index_entries);
5053
5055 if (ret < 0)
5056 return;
5057
5058 for (i = 0; i < sc->chunk_count; i++) {
5059 int64_t next_offset = i+1 < sc->chunk_count ? sc->chunk_offsets[i+1] : INT64_MAX;
5060 current_offset = sc->chunk_offsets[i];
5061 while (mov_stsc_index_valid(stsc_index, sc->stsc_count) &&
5062 i + 1 == sc->stsc_data[stsc_index + 1].first)
5063 stsc_index++;
5064
5065 if (next_offset > current_offset && sc->sample_size>0 && sc->sample_size < sc->stsz_sample_size &&
5066 sc->stsc_data[stsc_index].count * (int64_t)sc->stsz_sample_size > next_offset - current_offset) {
5067 av_log(mov->fc, AV_LOG_WARNING, "STSZ sample size %d invalid (too large), ignoring\n", sc->stsz_sample_size);
5068 sc->stsz_sample_size = sc->sample_size;
5069 }
5070 if (sc->stsz_sample_size>0 && sc->stsz_sample_size < sc->sample_size) {
5071 av_log(mov->fc, AV_LOG_WARNING, "STSZ sample size %d invalid (too small), ignoring\n", sc->stsz_sample_size);
5072 sc->stsz_sample_size = sc->sample_size;
5073 }
5074
5075 for (j = 0; j < sc->stsc_data[stsc_index].count; j++) {
5076 int keyframe = 0;
5077 if (current_sample >= sc->sample_count) {
5078 av_log(mov->fc, AV_LOG_ERROR, "wrong sample count\n");
5079 return;
5080 }
5081
5082 if (!sc->keyframe_absent && (!sc->keyframe_count || current_sample+key_off == sc->keyframes[stss_index])) {
5083 keyframe = 1;
5084 if (stss_index + 1 < sc->keyframe_count)
5085 stss_index++;
5086 } else if (sc->stps_count && current_sample+key_off == sc->stps_data[stps_index]) {
5087 keyframe = 1;
5088 if (stps_index + 1 < sc->stps_count)
5089 stps_index++;
5090 }
5091 if (rap_group_present && rap_group_index < sc->rap_group_count) {
5092 if (sc->rap_group[rap_group_index].index > 0)
5093 keyframe = 1;
5094 if (++rap_group_sample == sc->rap_group[rap_group_index].count) {
5095 rap_group_sample = 0;
5096 rap_group_index++;
5097 }
5098 }
5099 if (sc->keyframe_absent
5100 && !sc->stps_count
5101 && !rap_group_present
5102 && (st->codecpar->codec_type == AVMEDIA_TYPE_AUDIO || (i==0 && j==0)))
5103 keyframe = 1;
5104 if (keyframe)
5105 distance = 0;
5106 sample_size = sc->stsz_sample_size > 0 ? sc->stsz_sample_size : sc->sample_sizes[current_sample];
5107 if (current_offset > INT64_MAX - sample_size) {
5108 av_log(mov->fc, AV_LOG_ERROR, "Current offset %"PRId64" or sample size %u is too large\n",
5109 current_offset,
5110 sample_size);
5111 return;
5112 }
5113
5114 if (sc->pseudo_stream_id == -1 ||
5115 sc->stsc_data[stsc_index].id - 1 == sc->pseudo_stream_id) {
5116 AVIndexEntry *e;
5117 if (sample_size > 0x3FFFFFFF) {
5118 av_log(mov->fc, AV_LOG_ERROR, "Sample size %u is too large\n", sample_size);
5119 return;
5120 }
5121 e = &sti->index_entries[sti->nb_index_entries++];
5122 e->pos = current_offset;
5123 e->timestamp = current_dts;
5124 e->size = sample_size;
5126 e->flags = keyframe ? AVINDEX_KEYFRAME : 0;
5127 av_log(mov->fc, AV_LOG_TRACE, "AVIndex stream %d, sample %u, offset %"PRIx64", dts %"PRId64", "
5128 "size %u, distance %u, keyframe %d\n", st->index, current_sample,
5129 current_offset, current_dts, sample_size, distance, keyframe);
5130 if (st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO && sti->nb_index_entries < 100)
5131 ff_rfps_add_frame(mov->fc, st, current_dts);
5132 }
5133
5134 current_offset += sample_size;
5135 stream_size += sample_size;
5136
5137 if (current_dts > INT64_MAX - sc->tts_data[stts_index].duration)
5138 return;
5139 current_dts += sc->tts_data[stts_index].duration;
5140
5141 distance++;
5142 stts_sample++;
5143 current_sample++;
5144 if (stts_index + 1 < sc->tts_count && stts_sample == sc->tts_data[stts_index].count) {
5145 stts_sample = 0;
5146 stts_index++;
5147 }
5148 }
5149 }
5150 if (st->duration > 0)
5151 st->codecpar->bit_rate = stream_size*8*sc->time_scale/st->duration;
5152 } else {
5153 unsigned chunk_samples, total = 0;
5154
5155 if (!sc->chunk_count || sc->tts_count)
5156 return;
5157
5158 // compute total chunk count
5159 for (i = 0; i < sc->stsc_count; i++) {
5160 unsigned count, chunk_count;
5161
5162 chunk_samples = sc->stsc_data[i].count;
5163 if (i != sc->stsc_count - 1 &&
5164 sc->samples_per_frame && chunk_samples % sc->samples_per_frame) {
5165 av_log(mov->fc, AV_LOG_ERROR, "error unaligned chunk\n");
5166 return;
5167 }
5168
5169 if (sc->samples_per_frame >= 160) { // gsm
5170 count = chunk_samples / sc->samples_per_frame;
5171 } else if (sc->samples_per_frame > 1) {
5172 unsigned samples = (1024/sc->samples_per_frame)*sc->samples_per_frame;
5173 count = (chunk_samples+samples-1) / samples;
5174 } else {
5175 count = (chunk_samples+1023) / 1024;
5176 }
5177
5179 chunk_count = sc->stsc_data[i+1].first - sc->stsc_data[i].first;
5180 else
5181 chunk_count = sc->chunk_count - (sc->stsc_data[i].first - 1);
5182 total += chunk_count * count;
5183 }
5184
5185 av_log(mov->fc, AV_LOG_TRACE, "chunk count %u\n", total);
5186 if (total >= UINT_MAX / sizeof(*sti->index_entries) - sti->nb_index_entries)
5187 return;
5189 sti->nb_index_entries + total,
5190 sizeof(*sti->index_entries)) < 0) {
5191 sti->nb_index_entries = 0;
5192 return;
5193 }
5194 sti->index_entries_allocated_size = (sti->nb_index_entries + total) * sizeof(*sti->index_entries);
5195
5196 // populate index
5197 for (i = 0; i < sc->chunk_count; i++) {
5198 current_offset = sc->chunk_offsets[i];
5199 if (mov_stsc_index_valid(stsc_index, sc->stsc_count) &&
5200 i + 1 == sc->stsc_data[stsc_index + 1].first)
5201 stsc_index++;
5202 chunk_samples = sc->stsc_data[stsc_index].count;
5203
5204 while (chunk_samples > 0) {
5205 AVIndexEntry *e;
5206 unsigned size, samples;
5207
5208 if (sc->samples_per_frame > 1 && !sc->bytes_per_frame) {
5210 "Zero bytes per frame, but %d samples per frame",
5211 sc->samples_per_frame);
5212 return;
5213 }
5214
5215 if (sc->samples_per_frame >= 160) { // gsm
5216 samples = sc->samples_per_frame;
5217 size = sc->bytes_per_frame;
5218 } else {
5219 if (sc->samples_per_frame > 1) {
5220 samples = FFMIN((1024 / sc->samples_per_frame)*
5221 sc->samples_per_frame, chunk_samples);
5222 size = (samples / sc->samples_per_frame) * sc->bytes_per_frame;
5223 } else {
5224 samples = FFMIN(1024, chunk_samples);
5225 size = samples * sc->sample_size;
5226 }
5227 }
5228
5229 if (sti->nb_index_entries >= total) {
5230 av_log(mov->fc, AV_LOG_ERROR, "wrong chunk count %u\n", total);
5231 return;
5232 }
5233 if (size > 0x3FFFFFFF) {
5234 av_log(mov->fc, AV_LOG_ERROR, "Sample size %u is too large\n", size);
5235 return;
5236 }
5237 e = &sti->index_entries[sti->nb_index_entries++];
5238 e->pos = current_offset;
5239 e->timestamp = current_dts;
5240 e->size = size;
5241 e->min_distance = 0;
5243 av_log(mov->fc, AV_LOG_TRACE, "AVIndex stream %d, chunk %u, offset %"PRIx64", dts %"PRId64", "
5244 "size %u, duration %u\n", st->index, i, current_offset, current_dts,
5245 size, samples);
5246
5247 current_offset += size;
5248 if (current_dts > INT64_MAX - samples)
5249 return;
5250 current_dts += samples;
5251 chunk_samples -= samples;
5252 }
5253 }
5254
5255 ret = mov_merge_tts_data(mov, st, MOV_MERGE_CTTS);
5256 if (ret < 0)
5257 return;
5258 }
5259
5260 if (!mov->ignore_editlist && mov->advanced_editlist) {
5261 // Fix index according to edit lists.
5262 mov_fix_index(mov, st);
5263 }
5264
5265 // Update start time of the stream.
5268 if (sc->tts_data) {
5270 }
5271 }
5272
5273 mov_estimate_video_delay(mov, st);
5274}
5275
5280
5281static int mov_compare_presentation_samples(const void *a, const void *b)
5282{
5283 const MOVPresentationSample *sa = a;
5284 const MOVPresentationSample *sb = b;
5285
5286 if (sa->pts != sb->pts)
5287 return (sa->pts > sb->pts) - (sa->pts < sb->pts);
5288 return (sa->index > sb->index) - (sa->index < sb->index);
5289}
5290
5291/*
5292 * Set sample durations from adjacent presentation timestamps.
5293 */
5295{
5296 MOVStreamContext *sc = st->priv_data;
5297 FFStream *const sti = ffstream(st);
5298 MOVPresentationSample *samples = NULL;
5299 MOVTimeToSample *tts_data = NULL;
5300 unsigned int tts_index = 0, tts_sample = 0;
5301 int count = sti->nb_index_entries;
5302
5303 /* A single STTS entry describes a fixed sample delta. */
5305 !sc->ctts_count || sc->stts_count < 2 ||
5306 !sc->tts_data || count < 2 ||
5307 count >= UINT_MAX / sizeof(*tts_data))
5308 return;
5309
5310 samples = av_malloc_array(count, sizeof(*samples));
5311 tts_data = av_malloc_array(count, sizeof(*tts_data));
5312 if (!samples || !tts_data)
5313 goto fail;
5314
5315 for (int i = 0; i < count; i++) {
5316 int64_t dts, offset;
5317
5318 if (tts_index >= sc->tts_count || !sc->tts_data[tts_index].count)
5319 goto fail;
5320
5321 tts_data[i] = sc->tts_data[tts_index];
5322 tts_data[i].count = 1;
5323
5324 dts = sti->index_entries[i].timestamp;
5325 offset = (int64_t)sc->dts_shift + tts_data[i].offset;
5326 if (dts == AV_NOPTS_VALUE ||
5327 (offset > 0 && dts > INT64_MAX - offset) ||
5328 (offset < 0 && dts < INT64_MIN - offset))
5329 goto fail;
5330
5331 samples[i].index = i;
5332 samples[i].pts = dts + offset;
5333
5334 if (++tts_sample == sc->tts_data[tts_index].count) {
5335 tts_index++;
5336 tts_sample = 0;
5337 }
5338 }
5339 if (tts_index != sc->tts_count || tts_sample)
5340 goto fail;
5341
5342 qsort(samples, count, sizeof(*samples), mov_compare_presentation_samples);
5343
5344 for (int i = 0; i + 1 < count; i++) {
5345 uint64_t duration;
5346
5347 if (samples[i].pts >= samples[i + 1].pts)
5348 goto fail;
5349
5350 /*
5351 * In VFR streams with reordered frames, STTS deltas follow decode
5352 * order while AVPacket.duration follows presentation order. CTTS
5353 * may produce presentation intervals that cannot be obtained by
5354 * merely permuting the STTS deltas, so derive each known duration
5355 * from adjacent PTS.
5356 */
5357 duration = (uint64_t)samples[i + 1].pts - samples[i].pts;
5358 if (!duration || duration > UINT_MAX)
5359 goto fail;
5360
5361 tts_data[samples[i].index].duration = (unsigned int)duration;
5362 }
5363
5364 av_log(mov->fc, AV_LOG_DEBUG,
5365 "Updated sample durations in presentation order for stream %d\n",
5366 st->index);
5367
5368 av_freep(&sc->tts_data);
5369 sc->tts_data = tts_data;
5370 sc->tts_count = count;
5371 sc->tts_allocated_size = count * sizeof(*tts_data);
5372 tts_data = NULL;
5373
5374fail:
5375 av_free(samples);
5376 av_free(tts_data);
5377}
5378
5379static int test_same_origin(const char *src, const char *ref) {
5380 char src_proto[64];
5381 char ref_proto[64];
5382 char src_auth[256];
5383 char ref_auth[256];
5384 char src_host[256];
5385 char ref_host[256];
5386 int src_port=-1;
5387 int ref_port=-1;
5388
5389 av_url_split(src_proto, sizeof(src_proto), src_auth, sizeof(src_auth), src_host, sizeof(src_host), &src_port, NULL, 0, src);
5390 av_url_split(ref_proto, sizeof(ref_proto), ref_auth, sizeof(ref_auth), ref_host, sizeof(ref_host), &ref_port, NULL, 0, ref);
5391
5392 if (strlen(src) == 0) {
5393 return -1;
5394 } else if (strlen(src_auth) + 1 >= sizeof(src_auth) ||
5395 strlen(ref_auth) + 1 >= sizeof(ref_auth) ||
5396 strlen(src_host) + 1 >= sizeof(src_host) ||
5397 strlen(ref_host) + 1 >= sizeof(ref_host)) {
5398 return 0;
5399 } else if (strcmp(src_proto, ref_proto) ||
5400 strcmp(src_auth, ref_auth) ||
5401 strcmp(src_host, ref_host) ||
5402 src_port != ref_port) {
5403 return 0;
5404 } else
5405 return 1;
5406}
5407
5408static int mov_open_dref(MOVContext *c, AVIOContext **pb, const char *src, MOVDref *ref)
5409{
5410 /* try relative path, we do not try the absolute because it can leak information about our
5411 system to an attacker */
5412 if (ref->nlvl_to > 0 && ref->nlvl_from > 0) {
5413 char filename[1025];
5414 const char *src_path;
5415 int i, l;
5416
5417 /* find a source dir */
5418 src_path = strrchr(src, '/');
5419 if (src_path)
5420 src_path++;
5421 else
5422 src_path = src;
5423
5424 /* find a next level down to target */
5425 for (i = 0, l = strlen(ref->path) - 1; l >= 0; l--)
5426 if (ref->path[l] == '/') {
5427 if (i == ref->nlvl_to - 1)
5428 break;
5429 else
5430 i++;
5431 }
5432
5433 /* compose filename if next level down to target was found */
5434 if (i == ref->nlvl_to - 1 && src_path - src < sizeof(filename)) {
5435 memcpy(filename, src, src_path - src);
5436 filename[src_path - src] = 0;
5437
5438 for (i = 1; i < ref->nlvl_from; i++)
5439 av_strlcat(filename, "../", sizeof(filename));
5440
5441 av_strlcat(filename, ref->path + l + 1, sizeof(filename));
5442 if (!c->use_absolute_path) {
5443 int same_origin = test_same_origin(src, filename);
5444
5445 if (!same_origin) {
5446 av_log(c->fc, AV_LOG_ERROR,
5447 "Reference with mismatching origin, %s not tried for security reasons, "
5448 "set demuxer option use_absolute_path to allow it anyway\n",
5449 ref->path);
5450 return AVERROR(ENOENT);
5451 }
5452
5453 if (strstr(ref->path + l + 1, "..") ||
5454 strstr(ref->path + l + 1, ":") ||
5455 (ref->nlvl_from > 1 && same_origin < 0) ||
5456 (filename[0] == '/' && src_path == src))
5457 return AVERROR(ENOENT);
5458 }
5459
5460 if (strlen(filename) + 1 == sizeof(filename))
5461 return AVERROR(ENOENT);
5462 if (!c->fc->io_open(c->fc, pb, filename, AVIO_FLAG_READ, NULL))
5463 return 0;
5464 }
5465 } else if (c->use_absolute_path) {
5466 av_log(c->fc, AV_LOG_WARNING, "Using absolute path on user request, "
5467 "this is a possible security issue\n");
5468 if (!c->fc->io_open(c->fc, pb, ref->path, AVIO_FLAG_READ, NULL))
5469 return 0;
5470 } else {
5471 av_log(c->fc, AV_LOG_ERROR,
5472 "Absolute path %s not tried for security reasons, "
5473 "set demuxer option use_absolute_path to allow absolute paths\n",
5474 ref->path);
5475 }
5476
5477 return AVERROR(ENOENT);
5478}
5479
5481{
5482 if (sc->time_scale <= 0) {
5483 av_log(c->fc, AV_LOG_WARNING, "stream %d, timescale not set\n", sc->ffindex);
5484 sc->time_scale = c->time_scale;
5485 if (sc->time_scale <= 0)
5486 sc->time_scale = 1;
5487 }
5488}
5489
5490#if CONFIG_IAMFDEC
5491static int mov_update_iamf_streams(MOVContext *c, const AVStream *st)
5492{
5493 const MOVStreamContext *sc = st->priv_data;
5494 const IAMFContext *iamf = &sc->iamf->iamf;
5495
5496 for (int i = 0; i < iamf->nb_audio_elements; i++) {
5497 const AVStreamGroup *stg = NULL;
5498
5499 for (int j = 0; j < c->fc->nb_stream_groups; j++)
5500 if (c->fc->stream_groups[j]->id == iamf->audio_elements[i]->audio_element_id)
5501 stg = c->fc->stream_groups[j];
5502 av_assert0(stg);
5503
5504 for (int j = 0; j < stg->nb_streams; j++) {
5505 const FFStream *sti = cffstream(st);
5506 AVStream *out = stg->streams[j];
5507 FFStream *out_sti = ffstream(stg->streams[j]);
5508
5509 out->codecpar->bit_rate = 0;
5510
5511 if (out == st)
5512 continue;
5513
5514 out->time_base = st->time_base;
5515 out->start_time = st->start_time;
5516 out->duration = st->duration;
5517 out->nb_frames = st->nb_frames;
5518 out->discard = st->discard;
5519
5520 av_assert0(!out_sti->index_entries);
5522 if (!out_sti->index_entries)
5523 return AVERROR(ENOMEM);
5524
5526 out_sti->nb_index_entries = sti->nb_index_entries;
5527 out_sti->skip_samples = sti->skip_samples;
5528 memcpy(out_sti->index_entries, sti->index_entries, sti->index_entries_allocated_size);
5529 }
5530 }
5531
5532 return 0;
5533}
5534#endif
5535
5536static int sanity_checks(void *log_obj, MOVStreamContext *sc, int index)
5537{
5538 if ((sc->chunk_count && (!sc->stts_count || !sc->stsc_count ||
5539 (!sc->sample_size && !sc->sample_count))) ||
5540 (sc->sample_count && (!sc->chunk_count ||
5541 (!sc->sample_size && !sc->sample_sizes)))) {
5542 av_log(log_obj, AV_LOG_ERROR, "stream %d, missing mandatory atoms, broken header\n",
5543 index);
5544 return 1;
5545 }
5546
5547 if (sc->stsc_count && sc->stsc_data[ sc->stsc_count - 1 ].first > sc->chunk_count) {
5548 av_log(log_obj, AV_LOG_ERROR, "stream %d, contradictionary STSC and STCO\n",
5549 index);
5550 return 2;
5551 }
5552 return 0;
5553}
5554
5556{
5557 AVStream *st;
5558 MOVStreamContext *sc;
5559 int ret;
5560
5561 st = avformat_new_stream(c->fc, NULL);
5562 if (!st) return AVERROR(ENOMEM);
5563 st->id = -1;
5564 sc = av_mallocz(sizeof(MOVStreamContext));
5565 if (!sc) return AVERROR(ENOMEM);
5566
5567 st->priv_data = sc;
5569 sc->ffindex = st->index;
5570 c->trak_index = st->index;
5571 sc->refcount = 1;
5572
5573 if ((ret = mov_read_default(c, pb, atom)) < 0)
5574 return ret;
5575
5576 c->trak_index = -1;
5577
5578 // Here stsc refers to a chunk not described in stco. This is technically invalid,
5579 // but we can overlook it (clearing stsc) whenever stts_count == 0 (indicating no samples).
5580 if (!sc->chunk_count && !sc->stts_count && sc->stsc_count) {
5581 sc->stsc_count = 0;
5582 av_freep(&sc->stsc_data);
5583 }
5584
5585 ret = sanity_checks(c->fc, sc, st->index);
5586 if (ret)
5587 return ret > 1 ? AVERROR_INVALIDDATA : 0;
5588
5589 fix_timescale(c, sc);
5590
5591 avpriv_set_pts_info(st, 64, 1, sc->time_scale);
5592
5593 /*
5594 * Advanced edit list support does not work with fragemented MP4s, which
5595 * have stsc, stsz, stco, and stts with zero entries in the moov atom.
5596 * In these files, trun atoms may be streamed in.
5597 */
5598 if (!sc->stts_count && c->advanced_editlist) {
5599
5600 av_log(c->fc, AV_LOG_VERBOSE, "advanced_editlist does not work with fragmented "
5601 "MP4. disabling.\n");
5602 c->advanced_editlist = 0;
5603 c->advanced_editlist_autodisabled = 1;
5604 }
5605
5606 mov_build_index(c, st);
5607 /*
5608 * Fragment samples are appended later by mov_read_trun() and are not
5609 * covered by this non-fragmented track update.
5610 */
5612
5613#if CONFIG_IAMFDEC
5614 if (sc->iamf) {
5615 ret = mov_update_iamf_streams(c, st);
5616 if (ret < 0)
5617 return ret;
5618 }
5619#endif
5620
5621 if (sc->dref_id-1 < sc->drefs_count && sc->drefs[sc->dref_id-1].path) {
5622 MOVDref *dref = &sc->drefs[sc->dref_id - 1];
5623 if (c->enable_drefs) {
5624 if (mov_open_dref(c, &sc->pb, c->fc->url, dref) < 0)
5625 av_log(c->fc, AV_LOG_ERROR,
5626 "stream %d, error opening alias: path='%s', dir='%s', "
5627 "filename='%s', volume='%s', nlvl_from=%d, nlvl_to=%d\n",
5628 st->index, dref->path, dref->dir, dref->filename,
5629 dref->volume, dref->nlvl_from, dref->nlvl_to);
5630 } else {
5631 av_log(c->fc, AV_LOG_WARNING,
5632 "Skipped opening external track: "
5633 "stream %d, alias: path='%s', dir='%s', "
5634 "filename='%s', volume='%s', nlvl_from=%d, nlvl_to=%d."
5635 "Set enable_drefs to allow this.\n",
5636 st->index, dref->path, dref->dir, dref->filename,
5637 dref->volume, dref->nlvl_from, dref->nlvl_to);
5638 }
5639 } else {
5640 sc->pb = c->fc->pb;
5641 sc->pb_is_copied = 1;
5642 }
5643
5645 int stts_constant = sc->stts_count && sc->tts_count;
5646 if (sc->h_spacing && sc->v_spacing)
5648 sc->h_spacing, sc->v_spacing, INT_MAX);
5649 if (!st->sample_aspect_ratio.num && st->codecpar->width && st->codecpar->height &&
5650 sc->height && sc->width &&
5651 (st->codecpar->width != sc->width || st->codecpar->height != sc->height)) {
5653 (int64_t)st->codecpar->height * sc->width,
5654 (int64_t)st->codecpar->width * sc->height, INT_MAX);
5655 }
5656
5657#if FF_API_R_FRAME_RATE
5658 for (unsigned int i = 1; sc->stts_count && i + 1 < sc->tts_count; i++) {
5659 if (sc->tts_data[i].duration == sc->tts_data[0].duration)
5660 continue;
5661 stts_constant = 0;
5662 }
5663 if (stts_constant)
5665 sc->time_scale, sc->tts_data[0].duration, INT_MAX);
5666#endif
5667 }
5668
5669#if CONFIG_H261_DECODER || CONFIG_H263_DECODER || CONFIG_MPEG4_DECODER
5670 switch (st->codecpar->codec_id) {
5671#if CONFIG_H261_DECODER
5672 case AV_CODEC_ID_H261:
5673#endif
5674#if CONFIG_H263_DECODER
5675 case AV_CODEC_ID_H263:
5676#endif
5677#if CONFIG_MPEG4_DECODER
5678 case AV_CODEC_ID_MPEG4:
5679#endif
5680 st->codecpar->width = 0; /* let decoder init width/height */
5681 st->codecpar->height= 0;
5682 break;
5683 }
5684#endif
5685
5686 // If the duration of the mp3 packets is not constant, then they could need a parser
5688 && sc->time_scale == st->codecpar->sample_rate) {
5689 int stts_constant = 1;
5690 for (int i = 1; sc->stts_count && i < sc->tts_count; i++) {
5691 if (sc->tts_data[i].duration == sc->tts_data[0].duration)
5692 continue;
5693 stts_constant = 0;
5694 }
5695 if (!stts_constant)
5697 }
5698 /* Do not need those anymore. */
5699 av_freep(&sc->chunk_offsets);
5700 av_freep(&sc->sample_sizes);
5701 av_freep(&sc->keyframes);
5702 av_freep(&sc->stps_data);
5703 av_freep(&sc->elst_data);
5704 av_freep(&sc->rap_group);
5705 av_freep(&sc->sync_group);
5706 av_freep(&sc->sgpd_sync);
5707
5708 return 0;
5709}
5710
5712{
5713 int ret;
5714 c->itunes_metadata = 1;
5715 ret = mov_read_default(c, pb, atom);
5716 c->itunes_metadata = 0;
5717 return ret;
5718}
5719
5721{
5722 uint32_t count;
5723 uint32_t i;
5724
5725 if (atom.size < 8)
5726 return 0;
5727
5728 avio_skip(pb, 4);
5729 count = avio_rb32(pb);
5730 atom.size -= 8;
5731 if (count > 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 if ((uint64_t)entries+sc->tts_count >= UINT_MAX/sizeof(*sc->tts_data))
6259 return AVERROR_INVALIDDATA;
6260 if (flags & MOV_TRUN_DATA_OFFSET) data_offset = avio_rb32(pb);
6261 if (flags & MOV_TRUN_FIRST_SAMPLE_FLAGS) first_sample_flags = avio_rb32(pb);
6262
6263 int entry_size = !!(flags & MOV_TRUN_SAMPLE_DURATION) * 4
6264 + !!(flags & MOV_TRUN_SAMPLE_SIZE) * 4
6265 + !!(flags & MOV_TRUN_SAMPLE_FLAGS) * 4
6266 + !!(flags & MOV_TRUN_SAMPLE_CTS) * 4;
6267 int64_t sample_data_size = avio_size(sc->pb);
6268 int64_t max_entries = INT64_MAX;
6269
6270 if (sample_data_size > 0)
6271 max_entries = sample_data_size - sti->nb_index_entries;
6272 if (entry_size) {
6273 int64_t size = sc->pb == pb ? sample_data_size : avio_size(pb);
6274 int64_t pos = avio_tell(pb);
6275 int64_t left = atom.size - 8 - !!(flags & MOV_TRUN_DATA_OFFSET) * 4
6277
6278 if (pos >= 0 && size >= pos)
6279 left = FFMIN(left, size - pos);
6280 max_entries = FFMIN(max_entries, left / entry_size);
6281 }
6282 if (entries > max_entries) {
6283 av_log(c->fc, AV_LOG_ERROR, "trun sample count %u exceeds the %"PRId64" "
6284 "samples the input can hold\n", entries, max_entries);
6285 return AVERROR_INVALIDDATA;
6286 }
6287
6288 frag_stream_info = get_current_frag_stream_info(&c->frag_index);
6289 if (frag_stream_info) {
6290 if (frag_stream_info->next_trun_dts != AV_NOPTS_VALUE) {
6291 dts = frag_stream_info->next_trun_dts - sc->time_offset;
6292 } else if (frag_stream_info->first_tfra_pts != AV_NOPTS_VALUE &&
6293 c->use_mfra_for == FF_MOV_FLAG_MFRA_PTS) {
6294 pts = frag_stream_info->first_tfra_pts;
6295 av_log(c->fc, AV_LOG_DEBUG, "found mfra time %"PRId64
6296 ", using it for pts\n", pts);
6297 } else if (frag_stream_info->first_tfra_pts != AV_NOPTS_VALUE &&
6298 c->use_mfra_for == FF_MOV_FLAG_MFRA_DTS) {
6299 dts = frag_stream_info->first_tfra_pts;
6300 av_log(c->fc, AV_LOG_DEBUG, "found mfra time %"PRId64
6301 ", using it for dts\n", pts);
6302 } else {
6303 int has_tfdt = frag_stream_info->tfdt_dts != AV_NOPTS_VALUE;
6304 int has_sidx = frag_stream_info->sidx_pts != AV_NOPTS_VALUE;
6305 int fallback_tfdt = !c->use_tfdt && !has_sidx && has_tfdt;
6306 int fallback_sidx = c->use_tfdt && !has_tfdt && has_sidx;
6307
6308 if (fallback_sidx) {
6309 av_log(c->fc, AV_LOG_DEBUG, "use_tfdt set but no tfdt found, using sidx instead\n");
6310 }
6311 if (fallback_tfdt) {
6312 av_log(c->fc, AV_LOG_DEBUG, "use_tfdt not set but no sidx found, using tfdt instead\n");
6313 }
6314
6315 if (has_tfdt && c->use_tfdt || fallback_tfdt) {
6316 dts = frag_stream_info->tfdt_dts - sc->time_offset;
6317 av_log(c->fc, AV_LOG_DEBUG, "found tfdt time %"PRId64
6318 ", using it for dts\n", dts);
6319 } else if (has_sidx && !c->use_tfdt || fallback_sidx) {
6320 // FIXME: sidx earliest_presentation_time is *PTS*, s.b.
6321 // pts = frag_stream_info->sidx_pts;
6322 dts = frag_stream_info->sidx_pts;
6323 av_log(c->fc, AV_LOG_DEBUG, "found sidx time %"PRId64
6324 ", using it for dts\n", frag_stream_info->sidx_pts);
6325 } else {
6326 dts = sc->track_end - sc->time_offset;
6327 av_log(c->fc, AV_LOG_DEBUG, "found track end time %"PRId64
6328 ", using it for dts\n", dts);
6329 }
6330 }
6331 } else {
6332 dts = sc->track_end - sc->time_offset;
6333 av_log(c->fc, AV_LOG_DEBUG, "found track end time %"PRId64
6334 ", using it for dts\n", dts);
6335 }
6336 offset = frag->base_data_offset + data_offset;
6337 distance = 0;
6338 av_log(c->fc, AV_LOG_TRACE, "first sample flags 0x%x\n", first_sample_flags);
6339
6340 // realloc space for new index entries
6341 if ((uint64_t)sti->nb_index_entries + entries >= UINT_MAX / sizeof(AVIndexEntry)) {
6342 entries = UINT_MAX / sizeof(AVIndexEntry) - sti->nb_index_entries;
6343 av_log(c->fc, AV_LOG_ERROR, "Failed to add index entry\n");
6344 }
6345 if (entries == 0)
6346 return 0;
6347
6348 requested_size = (sti->nb_index_entries + entries) * sizeof(AVIndexEntry);
6349 new_entries = av_fast_realloc(sti->index_entries,
6351 requested_size);
6352 if (!new_entries)
6353 return AVERROR(ENOMEM);
6354 sti->index_entries= new_entries;
6355
6356 requested_size = (sti->nb_index_entries + entries) * sizeof(*sc->tts_data);
6357 old_allocated_size = sc->tts_allocated_size;
6358 tts_data = av_fast_realloc(sc->tts_data, &sc->tts_allocated_size,
6359 requested_size);
6360 if (!tts_data)
6361 return AVERROR(ENOMEM);
6362 sc->tts_data = tts_data;
6363
6364 // In case there were samples without time to sample entries, ensure they get
6365 // zero valued entries. This ensures clips which mix boxes with and
6366 // without time to sample entries don't pickup uninitialized data.
6367 memset((uint8_t*)(sc->tts_data) + old_allocated_size, 0,
6368 sc->tts_allocated_size - old_allocated_size);
6369
6370 if (index_entry_pos < sti->nb_index_entries) {
6371 // Make hole in index_entries and tts_data for new samples
6372 memmove(sti->index_entries + index_entry_pos + entries,
6373 sti->index_entries + index_entry_pos,
6374 sizeof(*sti->index_entries) *
6375 (sti->nb_index_entries - index_entry_pos));
6376 memmove(sc->tts_data + index_entry_pos + entries,
6377 sc->tts_data + index_entry_pos,
6378 sizeof(*sc->tts_data) * (sc->tts_count - index_entry_pos));
6379 if (index_entry_pos < sc->current_sample) {
6380 sc->current_sample += entries;
6381 }
6382 }
6383
6384 sti->nb_index_entries += entries;
6385 sc->tts_count = sti->nb_index_entries;
6386 sc->stts_count = sti->nb_index_entries;
6388 sc->ctts_count = sti->nb_index_entries;
6389
6390 // Record the index_entry position in frag_index of this fragment
6391 if (frag_stream_info) {
6392 frag_stream_info->index_entry = index_entry_pos;
6393 if (frag_stream_info->index_base < 0)
6394 frag_stream_info->index_base = index_entry_pos;
6395 }
6396
6397 if (index_entry_pos > 0)
6398 prev_dts = sti->index_entries[index_entry_pos-1].timestamp;
6399
6400 for (i = 0; i < entries && !pb->eof_reached; i++) {
6401 unsigned sample_size = frag->size;
6402 int sample_flags = i ? frag->flags : first_sample_flags;
6403 unsigned sample_duration = frag->duration;
6404 unsigned ctts_duration = 0;
6405 int keyframe = 0;
6406 int index_entry_flags = 0;
6407
6408 if (flags & MOV_TRUN_SAMPLE_DURATION) sample_duration = avio_rb32(pb);
6409 if (flags & MOV_TRUN_SAMPLE_SIZE) sample_size = avio_rb32(pb);
6410 if (flags & MOV_TRUN_SAMPLE_FLAGS) sample_flags = avio_rb32(pb);
6411 if (flags & MOV_TRUN_SAMPLE_CTS) ctts_duration = avio_rb32(pb);
6412
6413 if (sample_duration > c->max_stts_delta) {
6414 av_log(c->fc, AV_LOG_WARNING,
6415 "Too large sample duration %u in trun entry %u in st:%d. Clipping to 1.\n",
6416 sample_duration, i, st->index);
6417 sample_duration = 1;
6418 }
6419
6420 mov_update_dts_shift(sc, ctts_duration, c->fc);
6421 if (pts != AV_NOPTS_VALUE) {
6422 dts = pts - sc->dts_shift;
6423 if (flags & MOV_TRUN_SAMPLE_CTS) {
6424 dts -= ctts_duration;
6425 } else {
6426 dts -= sc->time_offset;
6427 }
6428 av_log(c->fc, AV_LOG_DEBUG,
6429 "pts %"PRId64" calculated dts %"PRId64
6430 " sc->dts_shift %d ctts.duration %d"
6431 " sc->time_offset %"PRId64
6432 " flags & MOV_TRUN_SAMPLE_CTS %d\n",
6433 pts, dts,
6434 sc->dts_shift, ctts_duration,
6437 }
6438
6439 keyframe =
6440 !(sample_flags & (MOV_FRAG_SAMPLE_FLAG_IS_NON_SYNC |
6442 if (keyframe) {
6443 distance = 0;
6444 index_entry_flags |= AVINDEX_KEYFRAME;
6445 }
6446 // Fragments can overlap in time. Discard overlapping frames after
6447 // decoding.
6448 if (prev_dts >= dts)
6449 index_entry_flags |= AVINDEX_DISCARD_FRAME;
6450
6451 sti->index_entries[index_entry_pos].pos = offset;
6452 sti->index_entries[index_entry_pos].timestamp = dts;
6453 sti->index_entries[index_entry_pos].size = sample_size;
6454 sti->index_entries[index_entry_pos].min_distance = distance;
6455 sti->index_entries[index_entry_pos].flags = index_entry_flags;
6456
6457 sc->tts_data[index_entry_pos].count = 1;
6458 sc->tts_data[index_entry_pos].offset = ctts_duration;
6459 sc->tts_data[index_entry_pos].duration = sample_duration;
6460 index_entry_pos++;
6461
6462 av_log(c->fc, AV_LOG_TRACE, "AVIndex stream %d, sample %d, offset %"PRIx64", dts %"PRId64", "
6463 "size %u, distance %d, keyframe %d\n", st->index,
6464 index_entry_pos, offset, dts, sample_size, distance, keyframe);
6465 distance++;
6466 if (av_sat_add64(dts, sample_duration) != dts + (uint64_t)sample_duration)
6467 return AVERROR_INVALIDDATA;
6468 if (!sample_size)
6469 return AVERROR_INVALIDDATA;
6470 dts += sample_duration;
6471 offset += sample_size;
6472 sc->data_size += sample_size;
6473
6474 if (sample_duration <= INT64_MAX - sc->duration_for_fps &&
6475 1 <= INT_MAX - sc->nb_frames_for_fps
6476 ) {
6477 sc->duration_for_fps += sample_duration;
6478 sc->nb_frames_for_fps ++;
6479 }
6480 }
6481 if (frag_stream_info)
6482 frag_stream_info->next_trun_dts = dts + sc->time_offset;
6483 if (i < entries) {
6484 // EOF found before reading all entries. Fix the hole this would
6485 // leave in index_entries and tts_data
6486 int gap = entries - i;
6487 memmove(sti->index_entries + index_entry_pos,
6488 sti->index_entries + index_entry_pos + gap,
6489 sizeof(*sti->index_entries) *
6490 (sti->nb_index_entries - (index_entry_pos + gap)));
6491 memmove(sc->tts_data + index_entry_pos,
6492 sc->tts_data + index_entry_pos + gap,
6493 sizeof(*sc->tts_data) *
6494 (sc->tts_count - (index_entry_pos + gap)));
6495
6496 sti->nb_index_entries -= gap;
6497 sc->tts_count -= gap;
6498 if (index_entry_pos < sc->current_sample) {
6499 sc->current_sample -= gap;
6500 }
6501 entries = i;
6502 }
6503
6504 // The end of this new fragment may overlap in time with the start
6505 // of the next fragment in index_entries. Mark the samples in the next
6506 // fragment that overlap with AVINDEX_DISCARD_FRAME
6507 prev_dts = AV_NOPTS_VALUE;
6508 if (index_entry_pos > 0)
6509 prev_dts = sti->index_entries[index_entry_pos-1].timestamp;
6510 for (int i = index_entry_pos; i < sti->nb_index_entries; i++) {
6511 if (prev_dts < sti->index_entries[i].timestamp)
6512 break;
6514 }
6515
6516 // If a hole was created to insert the new index_entries into,
6517 // the index_entry recorded for all subsequent moof must
6518 // be incremented by the number of entries inserted.
6519 fix_frag_index_entries(&c->frag_index, next_frag_index,
6520 frag->track_id, entries);
6521
6522 if (pb->eof_reached) {
6523 av_log(c->fc, AV_LOG_WARNING, "reached eof, corrupted TRUN atom\n");
6524 return AVERROR_EOF;
6525 }
6526
6527 frag->implicit_offset = offset;
6528
6529 sc->track_end = dts + sc->time_offset;
6530 if (st->duration < sc->track_end)
6531 st->duration = sc->track_end;
6532
6533 return 0;
6534}
6535
6537{
6538 int64_t stream_size = avio_size(pb);
6539 int64_t offset = av_sat_add64(avio_tell(pb), atom.size), pts, timestamp;
6540 uint8_t version, is_complete;
6541 int64_t offadd;
6542 unsigned i, j, track_id, item_count;
6543 AVStream *st = NULL;
6544 AVStream *ref_st = NULL;
6545 MOVStreamContext *sc, *ref_sc = NULL;
6546 AVRational timescale;
6547
6548 version = avio_r8(pb);
6549 if (version > 1) {
6550 avpriv_request_sample(c->fc, "sidx version %u", version);
6551 return 0;
6552 }
6553
6554 avio_rb24(pb); // flags
6555
6556 track_id = avio_rb32(pb); // Reference ID
6557 for (i = 0; i < c->fc->nb_streams; i++) {
6558 sc = c->fc->streams[i]->priv_data;
6559 if (sc->id == track_id) {
6560 st = c->fc->streams[i];
6561 break;
6562 }
6563 }
6564 if (!st) {
6565 av_log(c->fc, AV_LOG_WARNING, "could not find corresponding track id %d\n", track_id);
6566 return 0;
6567 }
6568
6569 sc = st->priv_data;
6570
6571 timescale = av_make_q(1, avio_rb32(pb));
6572
6573 if (timescale.den <= 0) {
6574 av_log(c->fc, AV_LOG_ERROR, "Invalid sidx timescale 1/%d\n", timescale.den);
6575 return AVERROR_INVALIDDATA;
6576 }
6577
6578 if (version == 0) {
6579 pts = avio_rb32(pb);
6580 offadd= avio_rb32(pb);
6581 } else {
6582 pts = avio_rb64(pb);
6583 offadd= avio_rb64(pb);
6584 }
6585 if (av_sat_add64(offset, offadd) != offset + (uint64_t)offadd)
6586 return AVERROR_INVALIDDATA;
6587
6588 offset += (uint64_t)offadd;
6589
6590 avio_rb16(pb); // reserved
6591
6592 item_count = avio_rb16(pb);
6593 if (item_count == 0)
6594 return AVERROR_INVALIDDATA;
6595
6596 for (i = 0; i < item_count; i++) {
6597 int index;
6598 MOVFragmentStreamInfo * frag_stream_info;
6599 uint32_t size = avio_rb32(pb);
6600 uint32_t duration = avio_rb32(pb);
6601 if (size & 0x80000000) {
6602 avpriv_request_sample(c->fc, "sidx reference_type 1");
6603 return AVERROR_PATCHWELCOME;
6604 }
6605 avio_rb32(pb); // sap_flags
6606 timestamp = av_rescale_q(pts, timescale, st->time_base);
6607
6609 frag_stream_info = get_frag_stream_info(&c->frag_index, index, track_id);
6610 if (frag_stream_info)
6611 frag_stream_info->sidx_pts = timestamp;
6612
6613 if (av_sat_add64(offset, size) != offset + (uint64_t)size ||
6614 av_sat_add64(pts, duration) != pts + (uint64_t)duration
6615 )
6616 return AVERROR_INVALIDDATA;
6617 offset += size;
6618 pts += duration;
6619 }
6620
6621 st->duration = sc->track_end = pts;
6622
6623 sc->has_sidx = 1;
6624
6625 // See if the remaining bytes are just an mfra which we can ignore.
6626 is_complete = offset == stream_size;
6627 if (!is_complete && (pb->seekable & AVIO_SEEKABLE_NORMAL) && stream_size > 0 ) {
6628 int64_t ret;
6629 int64_t original_pos = avio_tell(pb);
6630 if (!c->have_read_mfra_size) {
6631 if ((ret = avio_seek(pb, stream_size - 4, SEEK_SET)) < 0)
6632 return ret;
6633 c->mfra_size = avio_rb32(pb);
6634 c->have_read_mfra_size = 1;
6635 if ((ret = avio_seek(pb, original_pos, SEEK_SET)) < 0)
6636 return ret;
6637 }
6638 if (offset == stream_size - c->mfra_size)
6639 is_complete = 1;
6640 }
6641
6642 if (is_complete) {
6643 // Find first entry in fragment index that came from an sidx.
6644 // This will pretty much always be the first entry.
6645 for (i = 0; i < c->frag_index.nb_items; i++) {
6646 MOVFragmentIndexItem * item = &c->frag_index.item[i];
6647 for (j = 0; ref_st == NULL && j < item->nb_stream_info; j++) {
6649 si = &item->stream_info[j];
6650 if (si->sidx_pts != AV_NOPTS_VALUE) {
6651 ref_st = c->fc->streams[j];
6652 ref_sc = ref_st->priv_data;
6653 break;
6654 }
6655 }
6656 }
6657 if (ref_st) for (i = 0; i < c->fc->nb_streams; i++) {
6658 st = c->fc->streams[i];
6659 sc = st->priv_data;
6660 if (!sc->has_sidx) {
6661 st->duration = sc->track_end = av_rescale(ref_st->duration, sc->time_scale, ref_sc->time_scale);
6662 }
6663 }
6664
6665 if (offadd == 0)
6666 c->frag_index.complete = 1;
6667 }
6668
6669 return 0;
6670}
6671
6672/* this atom should be null (from specs), but some buggy files put the 'moov' atom inside it... */
6673/* like the files created with Adobe Premiere 5.0, for samples see */
6674/* http://graphics.tudelft.nl/~wouter/publications/soundtests/ */
6676{
6677 int err;
6678
6679 if (atom.size < 8)
6680 return 0; /* continue */
6681 if (avio_rb32(pb) != 0) { /* 0 sized mdat atom... use the 'wide' atom size */
6682 avio_skip(pb, atom.size - 4);
6683 return 0;
6684 }
6685 atom.type = avio_rl32(pb);
6686 atom.size -= 8;
6687 if (atom.type != MKTAG('m','d','a','t')) {
6688 avio_skip(pb, atom.size);
6689 return 0;
6690 }
6691 err = mov_read_mdat(c, pb, atom);
6692 return err;
6693}
6694
6696{
6697#if CONFIG_ZLIB
6699 uint8_t *cmov_data;
6700 uint8_t *moov_data; /* uncompressed data */
6701 long cmov_len, moov_len;
6702 int ret = -1;
6703
6704 avio_rb32(pb); /* dcom atom */
6705 if (avio_rl32(pb) != MKTAG('d','c','o','m'))
6706 return AVERROR_INVALIDDATA;
6707 if (avio_rl32(pb) != MKTAG('z','l','i','b')) {
6708 av_log(c->fc, AV_LOG_ERROR, "unknown compression for cmov atom !\n");
6709 return AVERROR_INVALIDDATA;
6710 }
6711 avio_rb32(pb); /* cmvd atom */
6712 if (avio_rl32(pb) != MKTAG('c','m','v','d'))
6713 return AVERROR_INVALIDDATA;
6714 moov_len = avio_rb32(pb); /* uncompressed size */
6715 cmov_len = atom.size - 6 * 4;
6716
6717 cmov_data = av_malloc(cmov_len);
6718 if (!cmov_data)
6719 return AVERROR(ENOMEM);
6720 moov_data = av_malloc(moov_len);
6721 if (!moov_data) {
6722 av_free(cmov_data);
6723 return AVERROR(ENOMEM);
6724 }
6725 ret = ffio_read_size(pb, cmov_data, cmov_len);
6726 if (ret < 0)
6727 goto free_and_return;
6728
6729 ret = AVERROR_INVALIDDATA;
6730 if (uncompress (moov_data, (uLongf *) &moov_len, (const Bytef *)cmov_data, cmov_len) != Z_OK)
6731 goto free_and_return;
6732 ffio_init_read_context(&ctx, moov_data, moov_len);
6733 ctx.pub.seekable = AVIO_SEEKABLE_NORMAL;
6734 atom.type = MKTAG('m','o','o','v');
6735 atom.size = moov_len;
6736 ret = mov_read_default(c, &ctx.pub, atom);
6737free_and_return:
6738 av_free(moov_data);
6739 av_free(cmov_data);
6740 return ret;
6741#else
6742 av_log(c->fc, AV_LOG_ERROR, "this file requires zlib support compiled in\n");
6743 return AVERROR(ENOSYS);
6744#endif
6745}
6746
6747/* edit list atom */
6749{
6750 MOVStreamContext *sc;
6751 int i, edit_count, version;
6752 int64_t elst_entry_size;
6753
6754 if (c->fc->nb_streams < 1 || c->ignore_editlist)
6755 return 0;
6756 sc = c->fc->streams[c->fc->nb_streams-1]->priv_data;
6757
6758 version = avio_r8(pb); /* version */
6759 avio_rb24(pb); /* flags */
6760 edit_count = avio_rb32(pb); /* entries */
6761 atom.size -= 8;
6762
6763 elst_entry_size = version == 1 ? 20 : 12;
6764 if (atom.size != edit_count * elst_entry_size) {
6765 if (c->fc->strict_std_compliance >= FF_COMPLIANCE_STRICT) {
6766 av_log(c->fc, AV_LOG_ERROR, "Invalid edit list entry_count: %d for elst atom of size: %"PRId64" bytes.\n",
6767 edit_count, atom.size + 8);
6768 return AVERROR_INVALIDDATA;
6769 } else {
6770 edit_count = atom.size / elst_entry_size;
6771 if (edit_count * elst_entry_size != atom.size) {
6772 av_log(c->fc, AV_LOG_WARNING, "ELST atom of %"PRId64" bytes, bigger than %d entries.\n", atom.size, edit_count);
6773 }
6774 }
6775 }
6776
6777 if (!edit_count)
6778 return 0;
6779 if (sc->elst_data)
6780 av_log(c->fc, AV_LOG_WARNING, "Duplicated ELST atom\n");
6781 av_free(sc->elst_data);
6782 sc->elst_count = 0;
6783 sc->elst_data = av_malloc_array(edit_count, sizeof(*sc->elst_data));
6784 if (!sc->elst_data)
6785 return AVERROR(ENOMEM);
6786
6787 av_log(c->fc, AV_LOG_TRACE, "track[%u].edit_count = %i\n", c->fc->nb_streams - 1, edit_count);
6788 for (i = 0; i < edit_count && atom.size > 0 && !pb->eof_reached; i++) {
6789 MOVElst *e = &sc->elst_data[i];
6790
6791 if (version == 1) {
6792 e->duration = avio_rb64(pb);
6793 e->time = avio_rb64(pb);
6794 atom.size -= 16;
6795 } else {
6796 e->duration = avio_rb32(pb); /* segment duration */
6797 e->time = (int32_t)avio_rb32(pb); /* media time */
6798 atom.size -= 8;
6799 }
6800 e->rate = avio_rb32(pb) / 65536.0;
6801 atom.size -= 4;
6802 av_log(c->fc, AV_LOG_TRACE, "duration=%"PRId64" time=%"PRId64" rate=%f\n",
6803 e->duration, e->time, e->rate);
6804
6805 if (e->time < 0 && e->time != -1 &&
6806 c->fc->strict_std_compliance >= FF_COMPLIANCE_STRICT) {
6807 av_log(c->fc, AV_LOG_ERROR, "Track %d, edit %d: Invalid edit list media time=%"PRId64"\n",
6808 c->fc->nb_streams-1, i, e->time);
6809 return AVERROR_INVALIDDATA;
6810 }
6811 if (e->duration < 0) {
6812 av_log(c->fc, AV_LOG_ERROR, "Track %d, edit %d: Invalid edit list duration=%"PRId64"\n",
6813 c->fc->nb_streams-1, i, e->duration);
6814 return AVERROR_INVALIDDATA;
6815 }
6816 }
6817 sc->elst_count = i;
6818
6819 return 0;
6820}
6821
6823{
6824 MOVStreamContext *sc;
6825 int err;
6826
6827 if (c->fc->nb_streams < 1)
6828 return AVERROR_INVALIDDATA;
6829 sc = c->fc->streams[c->fc->nb_streams - 1]->priv_data;
6830
6831 if (atom.size % sizeof(uint32_t))
6832 return AVERROR_INVALIDDATA;
6833
6834 MovTref *tag = mov_add_tref_tag(sc, atom.type);
6835 if (!tag)
6836 return AVERROR(ENOMEM);
6837
6838 int nb_timecode_track = atom.size >> 2;
6839 for (int i = 0; i < nb_timecode_track; i++) {
6840 if (avio_feof(pb))
6841 return AVERROR_INVALIDDATA;
6842 err = mov_add_tref_id(tag, avio_rb32(pb));
6843 if (err < 0)
6844 return err;
6845 }
6846
6847 return 0;
6848}
6849
6851{
6852 AVStream *st;
6853 int version, color_range, color_primaries, color_trc, color_space;
6854
6855 if (c->fc->nb_streams < 1)
6856 return 0;
6857 st = c->fc->streams[c->fc->nb_streams - 1];
6858
6859 if (atom.size < 5) {
6860 av_log(c->fc, AV_LOG_ERROR, "Empty VP Codec Configuration box\n");
6861 return AVERROR_INVALIDDATA;
6862 }
6863
6864 version = avio_r8(pb);
6865 if (version != 1) {
6866 av_log(c->fc, AV_LOG_WARNING, "Unsupported VP Codec Configuration box version %d\n", version);
6867 return 0;
6868 }
6869 avio_skip(pb, 3); /* flags */
6870
6871 avio_skip(pb, 2); /* profile + level */
6872 color_range = avio_r8(pb); /* bitDepth, chromaSubsampling, videoFullRangeFlag */
6874 color_trc = avio_r8(pb);
6875 color_space = avio_r8(pb);
6876 if (avio_rb16(pb)) /* codecIntializationDataSize */
6877 return AVERROR_INVALIDDATA;
6878
6881 if (!av_color_transfer_name(color_trc))
6882 color_trc = AVCOL_TRC_UNSPECIFIED;
6883 if (!av_color_space_name(color_space))
6884 color_space = AVCOL_SPC_UNSPECIFIED;
6885
6888 st->codecpar->color_trc = color_trc;
6889 st->codecpar->color_space = color_space;
6890
6891 return 0;
6892}
6893
6895{
6896 MOVStreamContext *sc;
6897 int i, version;
6898
6899 if (c->fc->nb_streams < 1)
6900 return AVERROR_INVALIDDATA;
6901
6902 sc = c->fc->streams[c->fc->nb_streams - 1]->priv_data;
6903
6904 if (atom.size < 5) {
6905 av_log(c->fc, AV_LOG_ERROR, "Empty Mastering Display Metadata box\n");
6906 return AVERROR_INVALIDDATA;
6907 }
6908
6909 version = avio_r8(pb);
6910 if (version) {
6911 av_log(c->fc, AV_LOG_WARNING, "Unsupported Mastering Display Metadata box version %d\n", version);
6912 return 0;
6913 }
6914 if (sc->mastering) {
6915 av_log(c->fc, AV_LOG_WARNING, "Ignoring duplicate Mastering Display Metadata\n");
6916 return 0;
6917 }
6918
6919 avio_skip(pb, 3); /* flags */
6920
6922 if (!sc->mastering)
6923 return AVERROR(ENOMEM);
6924
6925 for (i = 0; i < 3; i++) {
6926 sc->mastering->display_primaries[i][0] = av_make_q(avio_rb16(pb), 1 << 16);
6927 sc->mastering->display_primaries[i][1] = av_make_q(avio_rb16(pb), 1 << 16);
6928 }
6929 sc->mastering->white_point[0] = av_make_q(avio_rb16(pb), 1 << 16);
6930 sc->mastering->white_point[1] = av_make_q(avio_rb16(pb), 1 << 16);
6931
6932 sc->mastering->max_luminance = av_make_q(avio_rb32(pb), 1 << 8);
6933 sc->mastering->min_luminance = av_make_q(avio_rb32(pb), 1 << 14);
6934
6935 sc->mastering->has_primaries = 1;
6936 sc->mastering->has_luminance = 1;
6937
6938 return 0;
6939}
6940
6942{
6943 MOVStreamContext *sc;
6944 const int mapping[3] = {1, 2, 0};
6945 const int chroma_den = 50000;
6946 const int luma_den = 10000;
6947 int i;
6948
6949 if (c->fc->nb_streams < 1)
6950 return AVERROR_INVALIDDATA;
6951
6952 sc = c->fc->streams[c->fc->nb_streams - 1]->priv_data;
6953
6954 if (atom.size < 24) {
6955 av_log(c->fc, AV_LOG_ERROR, "Invalid Mastering Display Color Volume box\n");
6956 return AVERROR_INVALIDDATA;
6957 }
6958
6959 if (sc->mastering) {
6960 av_log(c->fc, AV_LOG_WARNING, "Ignoring duplicate Mastering Display Color Volume\n");
6961 return 0;
6962 }
6963
6965 if (!sc->mastering)
6966 return AVERROR(ENOMEM);
6967
6968 for (i = 0; i < 3; i++) {
6969 const int j = mapping[i];
6970 sc->mastering->display_primaries[j][0] = av_make_q(avio_rb16(pb), chroma_den);
6971 sc->mastering->display_primaries[j][1] = av_make_q(avio_rb16(pb), chroma_den);
6972 }
6973 sc->mastering->white_point[0] = av_make_q(avio_rb16(pb), chroma_den);
6974 sc->mastering->white_point[1] = av_make_q(avio_rb16(pb), chroma_den);
6975
6976 sc->mastering->max_luminance = av_make_q(avio_rb32(pb), luma_den);
6977 sc->mastering->min_luminance = av_make_q(avio_rb32(pb), luma_den);
6978
6979 sc->mastering->has_luminance = 1;
6980 sc->mastering->has_primaries = 1;
6981
6982 return 0;
6983}
6984
6986{
6987 MOVStreamContext *sc;
6988 int version;
6989
6990 if (c->fc->nb_streams < 1)
6991 return AVERROR_INVALIDDATA;
6992
6993 sc = c->fc->streams[c->fc->nb_streams - 1]->priv_data;
6994
6995 if (atom.size < 5) {
6996 av_log(c->fc, AV_LOG_ERROR, "Empty Content Light Level box\n");
6997 return AVERROR_INVALIDDATA;
6998 }
6999
7000 version = avio_r8(pb);
7001 if (version) {
7002 av_log(c->fc, AV_LOG_WARNING, "Unsupported Content Light Level box version %d\n", version);
7003 return 0;
7004 }
7005 avio_skip(pb, 3); /* flags */
7006
7007 if (sc->coll){
7008 av_log(c->fc, AV_LOG_WARNING, "Ignoring duplicate COLL\n");
7009 return 0;
7010 }
7011
7013 if (!sc->coll)
7014 return AVERROR(ENOMEM);
7015
7016 sc->coll->MaxCLL = avio_rb16(pb);
7017 sc->coll->MaxFALL = avio_rb16(pb);
7018
7019 return 0;
7020}
7021
7023{
7024 MOVStreamContext *sc;
7025
7026 if (c->fc->nb_streams < 1)
7027 return AVERROR_INVALIDDATA;
7028
7029 sc = c->fc->streams[c->fc->nb_streams - 1]->priv_data;
7030
7031 if (atom.size < 4) {
7032 av_log(c->fc, AV_LOG_ERROR, "Empty Content Light Level Info box\n");
7033 return AVERROR_INVALIDDATA;
7034 }
7035
7036 if (sc->coll){
7037 av_log(c->fc, AV_LOG_WARNING, "Ignoring duplicate CLLI/COLL\n");
7038 return 0;
7039 }
7040
7042 if (!sc->coll)
7043 return AVERROR(ENOMEM);
7044
7045 sc->coll->MaxCLL = avio_rb16(pb);
7046 sc->coll->MaxFALL = avio_rb16(pb);
7047
7048 return 0;
7049}
7050
7052{
7053 MOVStreamContext *sc;
7054 const int illuminance_den = 10000;
7055 const int ambient_den = 50000;
7056 if (c->fc->nb_streams < 1)
7057 return AVERROR_INVALIDDATA;
7058 sc = c->fc->streams[c->fc->nb_streams - 1]->priv_data;
7059 if (atom.size < 6) {
7060 av_log(c->fc, AV_LOG_ERROR, "Empty Ambient Viewing Environment Info box\n");
7061 return AVERROR_INVALIDDATA;
7062 }
7063 if (sc->ambient){
7064 av_log(c->fc, AV_LOG_WARNING, "Ignoring duplicate AMVE\n");
7065 return 0;
7066 }
7068 if (!sc->ambient)
7069 return AVERROR(ENOMEM);
7070 sc->ambient->ambient_illuminance = av_make_q(avio_rb32(pb), illuminance_den);
7071 sc->ambient->ambient_light_x = av_make_q(avio_rb16(pb), ambient_den);
7072 sc->ambient->ambient_light_y = av_make_q(avio_rb16(pb), ambient_den);
7073 return 0;
7074}
7075
7077{
7078 AVStream *st;
7079 MOVStreamContext *sc;
7080 enum AVStereo3DType type;
7081 int mode;
7082
7083 if (c->fc->nb_streams < 1)
7084 return 0;
7085
7086 st = c->fc->streams[c->fc->nb_streams - 1];
7087 sc = st->priv_data;
7088
7089 if (atom.size < 5) {
7090 av_log(c->fc, AV_LOG_ERROR, "Empty stereoscopic video box\n");
7091 return AVERROR_INVALIDDATA;
7092 }
7093
7094 if (sc->stereo3d)
7095 return AVERROR_INVALIDDATA;
7096
7097 avio_skip(pb, 4); /* version + flags */
7098
7099 mode = avio_r8(pb);
7100 switch (mode) {
7101 case 0:
7103 break;
7104 case 1:
7106 break;
7107 case 2:
7109 break;
7110 default:
7111 av_log(c->fc, AV_LOG_WARNING, "Unknown st3d mode value %d\n", mode);
7112 return 0;
7113 }
7114
7116 if (!sc->stereo3d)
7117 return AVERROR(ENOMEM);
7118
7119 sc->stereo3d->type = type;
7120 return 0;
7121}
7122
7124{
7125 AVStream *st;
7126 MOVStreamContext *sc;
7127 int size = 0;
7128 int64_t remaining;
7129 uint32_t tag = 0;
7131
7132 if (c->fc->nb_streams < 1)
7133 return 0;
7134
7135 st = c->fc->streams[c->fc->nb_streams - 1];
7136 sc = st->priv_data;
7137
7138 remaining = atom.size;
7139 while (remaining > 0) {
7140 size = avio_rb32(pb);
7141 if (size < 8 || size > remaining ) {
7142 av_log(c->fc, AV_LOG_ERROR, "Invalid child size in pack box\n");
7143 return AVERROR_INVALIDDATA;
7144 }
7145
7146 tag = avio_rl32(pb);
7147 switch (tag) {
7148 case MKTAG('p','k','i','n'): {
7149 if (size != 16) {
7150 av_log(c->fc, AV_LOG_ERROR, "Invalid size of pkin box: %d\n", size);
7151 return AVERROR_INVALIDDATA;
7152 }
7153 avio_skip(pb, 1); // version
7154 avio_skip(pb, 3); // flags
7155
7156 tag = avio_rl32(pb);
7157 switch (tag) {
7158 case MKTAG('s','i','d','e'):
7160 break;
7161 case MKTAG('o','v','e','r'):
7163 break;
7164 case 0:
7165 // This means value will be set in another layer
7166 break;
7167 default:
7168 av_log(c->fc, AV_LOG_WARNING, "Unknown tag in pkin: %s\n",
7170 avio_skip(pb, size - 8);
7171 break;
7172 }
7173
7174 break;
7175 }
7176 default:
7177 av_log(c->fc, AV_LOG_WARNING, "Unknown tag in pack: %s\n",
7179 avio_skip(pb, size - 8);
7180 break;
7181 }
7182 remaining -= size;
7183 }
7184
7185 if (remaining != 0) {
7186 av_log(c->fc, AV_LOG_ERROR, "Broken pack box\n");
7187 return AVERROR_INVALIDDATA;
7188 }
7189
7190 if (type == AV_STEREO3D_2D)
7191 return 0;
7192
7193 if (!sc->stereo3d) {
7195 if (!sc->stereo3d)
7196 return AVERROR(ENOMEM);
7197 }
7198
7199 sc->stereo3d->type = type;
7200
7201 return 0;
7202}
7203
7205{
7206 AVStream *st;
7207 MOVStreamContext *sc;
7208 int size, version, layout;
7209 int32_t yaw, pitch, roll;
7210 uint32_t l = 0, t = 0, r = 0, b = 0;
7211 uint32_t tag, padding = 0;
7212 enum AVSphericalProjection projection;
7213
7214 if (c->fc->nb_streams < 1)
7215 return 0;
7216
7217 st = c->fc->streams[c->fc->nb_streams - 1];
7218 sc = st->priv_data;
7219
7220 if (atom.size < 8) {
7221 av_log(c->fc, AV_LOG_ERROR, "Empty spherical video box\n");
7222 return AVERROR_INVALIDDATA;
7223 }
7224
7225 size = avio_rb32(pb);
7226 if (size <= 12 || size > atom.size)
7227 return AVERROR_INVALIDDATA;
7228
7229 tag = avio_rl32(pb);
7230 if (tag != MKTAG('s','v','h','d')) {
7231 av_log(c->fc, AV_LOG_ERROR, "Missing spherical video header\n");
7232 return 0;
7233 }
7234 version = avio_r8(pb);
7235 if (version != 0) {
7236 av_log(c->fc, AV_LOG_WARNING, "Unknown spherical version %d\n",
7237 version);
7238 return 0;
7239 }
7240 avio_skip(pb, 3); /* flags */
7241 avio_skip(pb, size - 12); /* metadata_source */
7242
7243 size = avio_rb32(pb);
7244 if (size > atom.size)
7245 return AVERROR_INVALIDDATA;
7246
7247 tag = avio_rl32(pb);
7248 if (tag != MKTAG('p','r','o','j')) {
7249 av_log(c->fc, AV_LOG_ERROR, "Missing projection box\n");
7250 return 0;
7251 }
7252
7253 size = avio_rb32(pb);
7254 if (size > atom.size)
7255 return AVERROR_INVALIDDATA;
7256
7257 tag = avio_rl32(pb);
7258 if (tag != MKTAG('p','r','h','d')) {
7259 av_log(c->fc, AV_LOG_ERROR, "Missing projection header box\n");
7260 return 0;
7261 }
7262 version = avio_r8(pb);
7263 if (version != 0) {
7264 av_log(c->fc, AV_LOG_WARNING, "Unknown spherical version %d\n",
7265 version);
7266 return 0;
7267 }
7268 avio_skip(pb, 3); /* flags */
7269
7270 /* 16.16 fixed point */
7271 yaw = avio_rb32(pb);
7272 pitch = avio_rb32(pb);
7273 roll = avio_rb32(pb);
7274
7275 size = avio_rb32(pb);
7276 if (size > atom.size)
7277 return AVERROR_INVALIDDATA;
7278
7279 tag = avio_rl32(pb);
7280 version = avio_r8(pb);
7281 if (version != 0) {
7282 av_log(c->fc, AV_LOG_WARNING, "Unknown spherical version %d\n",
7283 version);
7284 return 0;
7285 }
7286 avio_skip(pb, 3); /* flags */
7287 switch (tag) {
7288 case MKTAG('c','b','m','p'):
7289 layout = avio_rb32(pb);
7290 if (layout) {
7291 av_log(c->fc, AV_LOG_WARNING,
7292 "Unsupported cubemap layout %d\n", layout);
7293 return 0;
7294 }
7295 projection = AV_SPHERICAL_CUBEMAP;
7296 padding = avio_rb32(pb);
7297 break;
7298 case MKTAG('e','q','u','i'):
7299 t = avio_rb32(pb);
7300 b = avio_rb32(pb);
7301 l = avio_rb32(pb);
7302 r = avio_rb32(pb);
7303
7304 if (b >= UINT_MAX - t || r >= UINT_MAX - l) {
7305 av_log(c->fc, AV_LOG_ERROR,
7306 "Invalid bounding rectangle coordinates "
7307 "%"PRIu32",%"PRIu32",%"PRIu32",%"PRIu32"\n", l, t, r, b);
7308 return AVERROR_INVALIDDATA;
7309 }
7310
7311 if (l || t || r || b)
7313 else
7314 projection = AV_SPHERICAL_EQUIRECTANGULAR;
7315 break;
7316 default:
7317 av_log(c->fc, AV_LOG_ERROR, "Unknown projection type: %s\n", av_fourcc2str(tag));
7318 return 0;
7319 }
7320
7322 if (!sc->spherical)
7323 return AVERROR(ENOMEM);
7324
7325 sc->spherical->projection = projection;
7326
7327 sc->spherical->yaw = yaw;
7328 sc->spherical->pitch = pitch;
7329 sc->spherical->roll = roll;
7330
7331 sc->spherical->padding = padding;
7332
7333 sc->spherical->bound_left = l;
7334 sc->spherical->bound_top = t;
7335 sc->spherical->bound_right = r;
7336 sc->spherical->bound_bottom = b;
7337
7338 return 0;
7339}
7340
7342{
7343 AVStream *st;
7344 MOVStreamContext *sc;
7345 int size;
7346 uint32_t tag;
7347 enum AVSphericalProjection projection;
7348
7349 if (c->fc->nb_streams < 1)
7350 return 0;
7351
7352 st = c->fc->streams[c->fc->nb_streams - 1];
7353 sc = st->priv_data;
7354
7355 if (atom.size < 16) {
7356 av_log(c->fc, AV_LOG_ERROR, "Invalid size for proj box: %"PRIu64"\n", atom.size);
7357 return AVERROR_INVALIDDATA;
7358 }
7359
7360 size = avio_rb32(pb);
7361 if (size < 16) {
7362 av_log(c->fc, AV_LOG_ERROR, "Invalid size for prji box: %d\n", size);
7363 return AVERROR_INVALIDDATA;
7364 } else if (size > 16) {
7365 av_log(c->fc, AV_LOG_WARNING, "Box has more bytes (%d) than prji box required (16) \n", size);
7366 }
7367
7368 tag = avio_rl32(pb);
7369 if (tag != MKTAG('p','r','j','i')) {
7370 av_log(c->fc, AV_LOG_ERROR, "Invalid child box of proj box: %s\n",
7372 return AVERROR_INVALIDDATA;
7373 }
7374
7375 // version and flags, only support (0, 0)
7376 unsigned n = avio_rl32(pb);
7377 if (n != 0) {
7378 av_log(c->fc, AV_LOG_ERROR, "prji version %u, flag %u are not supported\n",
7379 n & 0xFF, n >> 8);
7380 return AVERROR_PATCHWELCOME;
7381 }
7382
7383 tag = avio_rl32(pb);
7384 switch (tag) {
7385 case MKTAG('r','e','c','t'):
7386 projection = AV_SPHERICAL_RECTILINEAR;
7387 break;
7388 case MKTAG('e','q','u','i'):
7389 projection = AV_SPHERICAL_EQUIRECTANGULAR;
7390 break;
7391 case MKTAG('h','e','q','u'):
7393 break;
7394 case MKTAG('f','i','s','h'):
7395 projection = AV_SPHERICAL_FISHEYE;
7396 break;
7397 case MKTAG('p','r','i','m'):
7399 break;
7400 default:
7401 av_log(c->fc, AV_LOG_ERROR, "Invalid projection type in prji box: %s\n", av_fourcc2str(tag));
7402 return AVERROR_INVALIDDATA;
7403 }
7404
7406 if (!sc->spherical)
7407 return AVERROR(ENOMEM);
7408
7409 sc->spherical->projection = projection;
7410
7411 return 0;
7412}
7413
7415{
7416 AVStream *st;
7417 MOVStreamContext *sc;
7418 int size, flags = 0;
7419 int64_t remaining;
7420 uint32_t tag, baseline = 0;
7423 enum AVStereo3DPrimaryEye primary_eye = AV_PRIMARY_EYE_NONE;
7424 AVRational horizontal_disparity_adjustment = { 0, 1 };
7425
7426 if (c->fc->nb_streams < 1)
7427 return 0;
7428
7429 st = c->fc->streams[c->fc->nb_streams - 1];
7430 sc = st->priv_data;
7431
7432 remaining = atom.size;
7433 while (remaining > 0) {
7434 size = avio_rb32(pb);
7435 if (size < 8 || size > remaining ) {
7436 av_log(c->fc, AV_LOG_ERROR, "Invalid child size in eyes box\n");
7437 return AVERROR_INVALIDDATA;
7438 }
7439
7440 tag = avio_rl32(pb);
7441 switch (tag) {
7442 case MKTAG('s','t','r','i'): {
7443 int has_right, has_left;
7444 uint8_t tmp;
7445 if (size != 13) {
7446 av_log(c->fc, AV_LOG_ERROR, "Invalid size of stri box: %d\n", size);
7447 return AVERROR_INVALIDDATA;
7448 }
7449 avio_skip(pb, 1); // version
7450 avio_skip(pb, 3); // flags
7451
7452 tmp = avio_r8(pb);
7453
7454 // eye_views_reversed
7455 if (tmp & 8) {
7457 }
7458 // has_additional_views
7459 if (tmp & 4) {
7460 // skip...
7461 }
7462
7463 has_right = tmp & 2; // has_right_eye_view
7464 has_left = tmp & 1; // has_left_eye_view
7465
7466 if (has_left && has_right)
7468 else if (has_left)
7469 view = AV_STEREO3D_VIEW_LEFT;
7470 else if (has_right)
7472 if (has_left || has_right)
7474
7475 break;
7476 }
7477 case MKTAG('h','e','r','o'): {
7478 int tmp;
7479 if (size != 13) {
7480 av_log(c->fc, AV_LOG_ERROR, "Invalid size of hero box: %d\n", size);
7481 return AVERROR_INVALIDDATA;
7482 }
7483 avio_skip(pb, 1); // version
7484 avio_skip(pb, 3); // flags
7485
7486 tmp = avio_r8(pb);
7487 if (tmp == 0)
7488 primary_eye = AV_PRIMARY_EYE_NONE;
7489 else if (tmp == 1)
7490 primary_eye = AV_PRIMARY_EYE_LEFT;
7491 else if (tmp == 2)
7492 primary_eye = AV_PRIMARY_EYE_RIGHT;
7493 else
7494 av_log(c->fc, AV_LOG_WARNING, "Unknown hero eye type: %d\n", tmp);
7495
7496 break;
7497 }
7498 case MKTAG('c','a','m','s'): {
7499 uint32_t subtag;
7500 int subsize;
7501 if (size != 24) {
7502 av_log(c->fc, AV_LOG_ERROR, "Invalid size of cams box: %d\n", size);
7503 return AVERROR_INVALIDDATA;
7504 }
7505
7506 subsize = avio_rb32(pb);
7507 if (subsize != 16) {
7508 av_log(c->fc, AV_LOG_ERROR, "Invalid size of blin box: %d\n", size);
7509 return AVERROR_INVALIDDATA;
7510 }
7511
7512 subtag = avio_rl32(pb);
7513 if (subtag != MKTAG('b','l','i','n')) {
7514 av_log(c->fc, AV_LOG_ERROR, "Expected blin box, got %s\n",
7515 av_fourcc2str(subtag));
7516 return AVERROR_INVALIDDATA;
7517 }
7518
7519 avio_skip(pb, 1); // version
7520 avio_skip(pb, 3); // flags
7521
7522 baseline = avio_rb32(pb);
7523
7524 break;
7525 }
7526 case MKTAG('c','m','f','y'): {
7527 uint32_t subtag;
7528 int subsize;
7529 int32_t adjustment;
7530 if (size != 24) {
7531 av_log(c->fc, AV_LOG_ERROR, "Invalid size of cmfy box: %d\n", size);
7532 return AVERROR_INVALIDDATA;
7533 }
7534
7535 subsize = avio_rb32(pb);
7536 if (subsize != 16) {
7537 av_log(c->fc, AV_LOG_ERROR, "Invalid size of dadj box: %d\n", size);
7538 return AVERROR_INVALIDDATA;
7539 }
7540
7541 subtag = avio_rl32(pb);
7542 if (subtag != MKTAG('d','a','d','j')) {
7543 av_log(c->fc, AV_LOG_ERROR, "Expected dadj box, got %s\n",
7544 av_fourcc2str(subtag));
7545 return AVERROR_INVALIDDATA;
7546 }
7547
7548 avio_skip(pb, 1); // version
7549 avio_skip(pb, 3); // flags
7550
7551 adjustment = (int32_t) avio_rb32(pb);
7552
7553 horizontal_disparity_adjustment.num = (int) adjustment;
7554 horizontal_disparity_adjustment.den = 10000;
7555
7556 break;
7557 }
7558 default:
7559 av_log(c->fc, AV_LOG_WARNING, "Unknown tag in eyes: %s\n",
7561 avio_skip(pb, size - 8);
7562 break;
7563 }
7564 remaining -= size;
7565 }
7566
7567 if (remaining != 0) {
7568 av_log(c->fc, AV_LOG_ERROR, "Broken eyes box\n");
7569 return AVERROR_INVALIDDATA;
7570 }
7571
7572 if (type == AV_STEREO3D_2D)
7573 return 0;
7574
7575 if (!sc->stereo3d) {
7577 if (!sc->stereo3d)
7578 return AVERROR(ENOMEM);
7579 }
7580
7581 sc->stereo3d->flags = flags;
7582 /* eyes/stri only records packed vs single-eye, not SBS/TB. Keep a more
7583 * specific type already set by st3d. */
7584 if (type != AV_STEREO3D_UNSPEC)
7585 sc->stereo3d->type = type;
7586 else if (sc->stereo3d->type == AV_STEREO3D_2D)
7587 sc->stereo3d->type = type;
7588 sc->stereo3d->view = view;
7589 sc->stereo3d->primary_eye = primary_eye;
7590 sc->stereo3d->baseline = baseline;
7591 sc->stereo3d->horizontal_disparity_adjustment = horizontal_disparity_adjustment;
7592
7593 return 0;
7594}
7595
7597{
7598 int size;
7599 int64_t remaining;
7600 uint32_t tag;
7601
7602 if (c->fc->nb_streams < 1)
7603 return 0;
7604
7605 if (atom.size < 8) {
7606 av_log(c->fc, AV_LOG_ERROR, "Empty video extension usage box\n");
7607 return AVERROR_INVALIDDATA;
7608 }
7609
7610 remaining = atom.size;
7611 while (remaining > 0) {
7612 size = avio_rb32(pb);
7613 if (size < 8 || size > remaining ) {
7614 av_log(c->fc, AV_LOG_ERROR, "Invalid child size in vexu box\n");
7615 return AVERROR_INVALIDDATA;
7616 }
7617
7618 tag = avio_rl32(pb);
7619 switch (tag) {
7620 case MKTAG('p','r','o','j'): {
7621 MOVAtom proj = { tag, size - 8 };
7622 int ret = mov_read_vexu_proj(c, pb, proj);
7623 if (ret < 0)
7624 return ret;
7625 break;
7626 }
7627 case MKTAG('e','y','e','s'): {
7628 MOVAtom eyes = { tag, size - 8 };
7629 int ret = mov_read_eyes(c, pb, eyes);
7630 if (ret < 0)
7631 return ret;
7632 break;
7633 }
7634 case MKTAG('p','a','c','k'): {
7635 MOVAtom pack = { tag, size - 8 };
7636 int ret = mov_read_pack(c, pb, pack);
7637 if (ret < 0)
7638 return ret;
7639 break;
7640 }
7641 default:
7642 av_log(c->fc, AV_LOG_WARNING, "Unknown tag in vexu: %s\n",
7644 avio_skip(pb, size - 8);
7645 break;
7646 }
7647 remaining -= size;
7648 }
7649
7650 if (remaining != 0) {
7651 av_log(c->fc, AV_LOG_ERROR, "Broken vexu box\n");
7652 return AVERROR_INVALIDDATA;
7653 }
7654
7655 return 0;
7656}
7657
7659{
7660 AVStream *st;
7661 MOVStreamContext *sc;
7662
7663 if (c->fc->nb_streams < 1)
7664 return 0;
7665
7666 st = c->fc->streams[c->fc->nb_streams - 1];
7667 sc = st->priv_data;
7668
7669 if (atom.size != 4) {
7670 av_log(c->fc, AV_LOG_ERROR, "Invalid size of hfov box: %"PRIu64"\n", atom.size);
7671 return AVERROR_INVALIDDATA;
7672 }
7673
7674
7675 if (!sc->stereo3d) {
7677 if (!sc->stereo3d)
7678 return AVERROR(ENOMEM);
7679 }
7680
7682 sc->stereo3d->horizontal_field_of_view.den = 1000; // thousands of a degree
7683
7684 return 0;
7685}
7686
7688{
7689 int ret = 0;
7690 uint8_t *buffer = av_malloc(len + 1);
7691 const char *val;
7692
7693 if (!buffer)
7694 return AVERROR(ENOMEM);
7695 buffer[len] = '\0';
7696
7697 ret = ffio_read_size(pb, buffer, len);
7698 if (ret < 0)
7699 goto out;
7700
7701 /* Check for mandatory keys and values, try to support XML as best-effort */
7702 if (!sc->spherical &&
7703 av_stristr(buffer, "<GSpherical:StitchingSoftware>") &&
7704 (val = av_stristr(buffer, "<GSpherical:Spherical>")) &&
7705 av_stristr(val, "true") &&
7706 (val = av_stristr(buffer, "<GSpherical:Stitched>")) &&
7707 av_stristr(val, "true") &&
7708 (val = av_stristr(buffer, "<GSpherical:ProjectionType>")) &&
7709 av_stristr(val, "equirectangular")) {
7711 if (!sc->spherical)
7712 goto out;
7713
7715
7716 if (av_stristr(buffer, "<GSpherical:StereoMode>") && !sc->stereo3d) {
7717 enum AVStereo3DType mode;
7718
7719 if (av_stristr(buffer, "left-right"))
7721 else if (av_stristr(buffer, "top-bottom"))
7723 else
7725
7727 if (!sc->stereo3d)
7728 goto out;
7729
7730 sc->stereo3d->type = mode;
7731 }
7732
7733 /* orientation */
7734 val = av_stristr(buffer, "<GSpherical:InitialViewHeadingDegrees>");
7735 if (val)
7736 sc->spherical->yaw = strtol(val, NULL, 10) * (1 << 16);
7737 val = av_stristr(buffer, "<GSpherical:InitialViewPitchDegrees>");
7738 if (val)
7739 sc->spherical->pitch = strtol(val, NULL, 10) * (1 << 16);
7740 val = av_stristr(buffer, "<GSpherical:InitialViewRollDegrees>");
7741 if (val)
7742 sc->spherical->roll = strtol(val, NULL, 10) * (1 << 16);
7743 }
7744
7745out:
7746 av_free(buffer);
7747 return ret;
7748}
7749
7751{
7752 AVStream *st;
7753 MOVStreamContext *sc;
7754 int64_t ret;
7755 AVUUID uuid;
7756 static const AVUUID uuid_isml_manifest = {
7757 0xa5, 0xd4, 0x0b, 0x30, 0xe8, 0x14, 0x11, 0xdd,
7758 0xba, 0x2f, 0x08, 0x00, 0x20, 0x0c, 0x9a, 0x66
7759 };
7760 static const AVUUID uuid_xmp = {
7761 0xbe, 0x7a, 0xcf, 0xcb, 0x97, 0xa9, 0x42, 0xe8,
7762 0x9c, 0x71, 0x99, 0x94, 0x91, 0xe3, 0xaf, 0xac
7763 };
7764 static const AVUUID uuid_spherical = {
7765 0xff, 0xcc, 0x82, 0x63, 0xf8, 0x55, 0x4a, 0x93,
7766 0x88, 0x14, 0x58, 0x7a, 0x02, 0x52, 0x1f, 0xdd,
7767 };
7768
7769 if (atom.size < AV_UUID_LEN || atom.size >= FFMIN(INT_MAX, SIZE_MAX))
7770 return AVERROR_INVALIDDATA;
7771
7772 if (c->fc->nb_streams < 1)
7773 return 0;
7774 st = c->fc->streams[c->fc->nb_streams - 1];
7775 sc = st->priv_data;
7776
7777 ret = ffio_read_size(pb, uuid, AV_UUID_LEN);
7778 if (ret < 0)
7779 return ret;
7780 if (av_uuid_equal(uuid, uuid_isml_manifest)) {
7781 uint8_t *buffer, *ptr;
7782 char *endptr;
7783 size_t len = atom.size - AV_UUID_LEN;
7784
7785 if (len < 4) {
7786 return AVERROR_INVALIDDATA;
7787 }
7788 ret = avio_skip(pb, 4); // zeroes
7789 len -= 4;
7790
7791 buffer = av_mallocz(len + 1);
7792 if (!buffer) {
7793 return AVERROR(ENOMEM);
7794 }
7795 ret = ffio_read_size(pb, buffer, len);
7796 if (ret < 0) {
7797 av_free(buffer);
7798 return ret;
7799 }
7800
7801 ptr = buffer;
7802 while ((ptr = av_stristr(ptr, "systemBitrate=\""))) {
7803 ptr += sizeof("systemBitrate=\"") - 1;
7804 c->bitrates_count++;
7805 c->bitrates = av_realloc_f(c->bitrates, c->bitrates_count, sizeof(*c->bitrates));
7806 if (!c->bitrates) {
7807 c->bitrates_count = 0;
7808 av_free(buffer);
7809 return AVERROR(ENOMEM);
7810 }
7811 errno = 0;
7812 ret = strtol(ptr, &endptr, 10);
7813 if (ret < 0 || errno || *endptr != '"') {
7814 c->bitrates[c->bitrates_count - 1] = 0;
7815 } else {
7816 c->bitrates[c->bitrates_count - 1] = ret;
7817 }
7818 }
7819
7820 av_free(buffer);
7821 } else if (av_uuid_equal(uuid, uuid_xmp)) {
7822 uint8_t *buffer;
7823 size_t len = atom.size - AV_UUID_LEN;
7824 if (c->export_xmp) {
7825 buffer = av_mallocz(len + 1);
7826 if (!buffer) {
7827 return AVERROR(ENOMEM);
7828 }
7829 ret = ffio_read_size(pb, buffer, len);
7830 if (ret < 0) {
7831 av_free(buffer);
7832 return ret;
7833 }
7834 buffer[len] = '\0';
7835 av_dict_set(&c->fc->metadata, "xmp",
7837 } else {
7838 // skip all uuid atom, which makes it fast for long uuid-xmp file
7839 ret = avio_skip(pb, len);
7840 if (ret < 0)
7841 return ret;
7842 }
7843 } else if (av_uuid_equal(uuid, uuid_spherical)) {
7844 size_t len = atom.size - AV_UUID_LEN;
7845 ret = mov_parse_uuid_spherical(sc, pb, len);
7846 if (ret < 0)
7847 return ret;
7848 if (!sc->spherical)
7849 av_log(c->fc, AV_LOG_WARNING, "Invalid spherical metadata found\n");
7850 }
7851
7852 return 0;
7853}
7854
7856{
7857 int ret;
7858 uint8_t content[16];
7859
7860 if (atom.size < 8)
7861 return 0;
7862
7863 ret = ffio_read_size(pb, content, FFMIN(sizeof(content), atom.size));
7864 if (ret < 0)
7865 return ret;
7866
7867 if ( !c->found_moov
7868 && !c->found_mdat
7869 && !memcmp(content, "Anevia\x1A\x1A", 8)
7870 && c->use_mfra_for == FF_MOV_FLAG_MFRA_AUTO) {
7871 c->use_mfra_for = FF_MOV_FLAG_MFRA_PTS;
7872 }
7873
7874 return 0;
7875}
7876
7878{
7879 uint32_t format = avio_rl32(pb);
7880 MOVStreamContext *sc;
7881 enum AVCodecID id;
7882 AVStream *st;
7883
7884 if (c->fc->nb_streams < 1)
7885 return 0;
7886 st = c->fc->streams[c->fc->nb_streams - 1];
7887 sc = st->priv_data;
7888
7889 switch (sc->format)
7890 {
7891 case MKTAG('e','n','c','v'): // encrypted video
7892 case MKTAG('e','n','c','a'): // encrypted audio
7893 id = mov_codec_id(st, format);
7894 if (st->codecpar->codec_id != AV_CODEC_ID_NONE &&
7895 st->codecpar->codec_id != id) {
7896 av_log(c->fc, AV_LOG_WARNING,
7897 "ignoring 'frma' atom of '%.4s', stream has codec id %d\n",
7898 (char*)&format, st->codecpar->codec_id);
7899 break;
7900 }
7901
7902 st->codecpar->codec_id = id;
7903 sc->format = format;
7904 break;
7905
7906 default:
7907 if (format != sc->format) {
7908 av_log(c->fc, AV_LOG_WARNING,
7909 "ignoring 'frma' atom of '%.4s', stream format is '%.4s'\n",
7910 (char*)&format, (char*)&sc->format);
7911 }
7912 break;
7913 }
7914
7915 return 0;
7916}
7917
7918/**
7919 * Gets the current encryption info and associated current stream context. If
7920 * we are parsing a track fragment, this will return the specific encryption
7921 * info for this fragment; otherwise this will return the global encryption
7922 * info for the current stream.
7923 */
7925{
7926 MOVFragmentStreamInfo *frag_stream_info;
7927 AVStream *st;
7928 int i;
7929
7930 frag_stream_info = get_current_frag_stream_info(&c->frag_index);
7931 if (frag_stream_info) {
7932 for (i = 0; i < c->fc->nb_streams; i++) {
7933 *sc = c->fc->streams[i]->priv_data;
7934 if ((*sc)->id == frag_stream_info->id) {
7935 st = c->fc->streams[i];
7936 break;
7937 }
7938 }
7939 if (i == c->fc->nb_streams)
7940 return 0;
7941 *sc = st->priv_data;
7942
7943 if (!frag_stream_info->encryption_index) {
7944 // If this stream isn't encrypted, don't create the index.
7945 if (!(*sc)->cenc.default_encrypted_sample)
7946 return 0;
7947 frag_stream_info->encryption_index = av_mallocz(sizeof(*frag_stream_info->encryption_index));
7948 if (!frag_stream_info->encryption_index)
7949 return AVERROR(ENOMEM);
7950 }
7951 *encryption_index = frag_stream_info->encryption_index;
7952 return 1;
7953 } else {
7954 // No current track fragment, using stream level encryption info.
7955
7956 if (c->fc->nb_streams < 1)
7957 return 0;
7958 st = c->fc->streams[c->fc->nb_streams - 1];
7959 *sc = st->priv_data;
7960
7961 if (!(*sc)->cenc.encryption_index) {
7962 // If this stream isn't encrypted, don't create the index.
7963 if (!(*sc)->cenc.default_encrypted_sample)
7964 return 0;
7965 (*sc)->cenc.encryption_index = av_mallocz(sizeof(*frag_stream_info->encryption_index));
7966 if (!(*sc)->cenc.encryption_index)
7967 return AVERROR(ENOMEM);
7968 }
7969
7970 *encryption_index = (*sc)->cenc.encryption_index;
7971 return 1;
7972 }
7973}
7974
7976{
7977 int i, ret;
7978 unsigned int subsample_count;
7979 AVSubsampleEncryptionInfo *subsamples;
7980
7981 if (!sc->cenc.default_encrypted_sample) {
7982 av_log(c->fc, AV_LOG_ERROR, "Missing schm or tenc\n");
7983 return AVERROR_INVALIDDATA;
7984 }
7985
7986 if (sc->cenc.per_sample_iv_size || use_subsamples) {
7988 if (!*sample)
7989 return AVERROR(ENOMEM);
7990 } else
7991 *sample = NULL;
7992
7993 if (sc->cenc.per_sample_iv_size != 0) {
7994 if ((ret = ffio_read_size(pb, (*sample)->iv, sc->cenc.per_sample_iv_size)) < 0) {
7995 av_log(c->fc, AV_LOG_ERROR, "failed to read the initialization vector\n");
7997 *sample = NULL;
7998 return ret;
7999 }
8000 }
8001
8002 if (use_subsamples) {
8003 subsample_count = avio_rb16(pb);
8004 av_free((*sample)->subsamples);
8005 (*sample)->subsamples = av_calloc(subsample_count, sizeof(*subsamples));
8006 if (!(*sample)->subsamples) {
8008 *sample = NULL;
8009 return AVERROR(ENOMEM);
8010 }
8011
8012 for (i = 0; i < subsample_count && !pb->eof_reached; i++) {
8013 (*sample)->subsamples[i].bytes_of_clear_data = avio_rb16(pb);
8014 (*sample)->subsamples[i].bytes_of_protected_data = avio_rb32(pb);
8015 }
8016
8017 if (pb->eof_reached) {
8018 av_log(c->fc, AV_LOG_ERROR, "hit EOF while reading sub-sample encryption info\n");
8020 *sample = NULL;
8021 return AVERROR_INVALIDDATA;
8022 }
8023 (*sample)->subsample_count = subsample_count;
8024 }
8025
8026 return 0;
8027}
8028
8030{
8031 AVEncryptionInfo **encrypted_samples;
8032 MOVEncryptionIndex *encryption_index;
8033 MOVStreamContext *sc;
8034 int use_subsamples, ret;
8035 unsigned int sample_count, i, alloc_size = 0;
8036
8037 ret = get_current_encryption_info(c, &encryption_index, &sc);
8038 if (ret != 1)
8039 return ret;
8040
8041 if (encryption_index->nb_encrypted_samples) {
8042 // This can happen if we have both saio/saiz and senc atoms.
8043 av_log(c->fc, AV_LOG_DEBUG, "Ignoring duplicate encryption info in senc\n");
8044 return 0;
8045 }
8046
8047 avio_r8(pb); /* version */
8048 use_subsamples = avio_rb24(pb) & 0x02; /* flags */
8049
8050 sample_count = avio_rb32(pb);
8051 if (sample_count >= INT_MAX / sizeof(*encrypted_samples))
8052 return AVERROR(ENOMEM);
8053
8054 for (i = 0; i < sample_count; i++) {
8055 unsigned int min_samples = FFMIN(FFMAX(i + 1, 1024 * 1024), sample_count);
8056 encrypted_samples = av_fast_realloc(encryption_index->encrypted_samples, &alloc_size,
8057 min_samples * sizeof(*encrypted_samples));
8058 if (encrypted_samples) {
8059 encryption_index->encrypted_samples = encrypted_samples;
8060
8062 c, pb, sc, &encryption_index->encrypted_samples[i], use_subsamples);
8063 } else {
8064 ret = AVERROR(ENOMEM);
8065 }
8066 if (pb->eof_reached) {
8067 av_log(c->fc, AV_LOG_ERROR, "Hit EOF while reading senc\n");
8068 if (ret >= 0)
8069 av_encryption_info_free(encryption_index->encrypted_samples[i]);
8070 ret = AVERROR_INVALIDDATA;
8071 }
8072
8073 if (ret < 0) {
8074 for (; i > 0; i--)
8075 av_encryption_info_free(encryption_index->encrypted_samples[i - 1]);
8076 av_freep(&encryption_index->encrypted_samples);
8077 return ret;
8078 }
8079 }
8080 encryption_index->nb_encrypted_samples = sample_count;
8081
8082 return 0;
8083}
8084
8086{
8087 AVEncryptionInfo **sample, **encrypted_samples;
8088 int64_t prev_pos;
8089 size_t sample_count, sample_info_size, i;
8090 int ret = 0;
8091 unsigned int alloc_size = 0;
8092
8093 if (encryption_index->nb_encrypted_samples)
8094 return 0;
8095 sample_count = encryption_index->auxiliary_info_sample_count;
8096 if (encryption_index->auxiliary_offsets_count != 1) {
8097 av_log(c->fc, AV_LOG_ERROR, "Multiple auxiliary info chunks are not supported\n");
8098 return AVERROR_PATCHWELCOME;
8099 }
8100 if (sample_count >= INT_MAX / sizeof(*encrypted_samples))
8101 return AVERROR(ENOMEM);
8102
8103 prev_pos = avio_tell(pb);
8104 if (!(pb->seekable & AVIO_SEEKABLE_NORMAL) ||
8105 avio_seek(pb, encryption_index->auxiliary_offsets[0], SEEK_SET) != encryption_index->auxiliary_offsets[0]) {
8106 av_log(c->fc, AV_LOG_INFO, "Failed to seek for auxiliary info, will only parse senc atoms for encryption info\n");
8107 goto finish;
8108 }
8109
8110 for (i = 0; i < sample_count && !pb->eof_reached; i++) {
8111 unsigned int min_samples = FFMIN(FFMAX(i + 1, 1024 * 1024), sample_count);
8112 encrypted_samples = av_fast_realloc(encryption_index->encrypted_samples, &alloc_size,
8113 min_samples * sizeof(*encrypted_samples));
8114 if (!encrypted_samples) {
8115 ret = AVERROR(ENOMEM);
8116 goto finish;
8117 }
8118 encryption_index->encrypted_samples = encrypted_samples;
8119
8120 sample = &encryption_index->encrypted_samples[i];
8121 sample_info_size = encryption_index->auxiliary_info_default_size
8122 ? encryption_index->auxiliary_info_default_size
8123 : encryption_index->auxiliary_info_sizes[i];
8124
8125 ret = mov_read_sample_encryption_info(c, pb, sc, sample, sample_info_size > sc->cenc.per_sample_iv_size);
8126 if (ret < 0)
8127 goto finish;
8128 }
8129 if (pb->eof_reached) {
8130 av_log(c->fc, AV_LOG_ERROR, "Hit EOF while reading auxiliary info\n");
8131 ret = AVERROR_INVALIDDATA;
8132 } else {
8133 encryption_index->nb_encrypted_samples = sample_count;
8134 }
8135
8136finish:
8137 avio_seek(pb, prev_pos, SEEK_SET);
8138 if (ret < 0) {
8139 for (; i > 0; i--) {
8140 av_encryption_info_free(encryption_index->encrypted_samples[i - 1]);
8141 }
8142 av_freep(&encryption_index->encrypted_samples);
8143 }
8144 return ret;
8145}
8146
8148{
8149 MOVEncryptionIndex *encryption_index;
8150 MOVStreamContext *sc;
8151 int ret;
8152 unsigned int sample_count, aux_info_type, aux_info_param;
8153
8154 ret = get_current_encryption_info(c, &encryption_index, &sc);
8155 if (ret != 1)
8156 return ret;
8157
8158 if (encryption_index->nb_encrypted_samples) {
8159 // This can happen if we have both saio/saiz and senc atoms.
8160 av_log(c->fc, AV_LOG_DEBUG, "Ignoring duplicate encryption info in saiz\n");
8161 return 0;
8162 }
8163
8164 if (encryption_index->auxiliary_info_sample_count) {
8165 av_log(c->fc, AV_LOG_ERROR, "Duplicate saiz atom\n");
8166 return AVERROR_INVALIDDATA;
8167 }
8168
8169 avio_r8(pb); /* version */
8170 if (avio_rb24(pb) & 0x01) { /* flags */
8171 aux_info_type = avio_rb32(pb);
8172 aux_info_param = avio_rb32(pb);
8174 if (aux_info_type != sc->cenc.default_encrypted_sample->scheme) {
8175 av_log(c->fc, AV_LOG_DEBUG, "Ignoring saiz box with non-zero aux_info_type\n");
8176 return 0;
8177 }
8178 if (aux_info_param != 0) {
8179 av_log(c->fc, AV_LOG_DEBUG, "Ignoring saiz box with non-zero aux_info_type_parameter\n");
8180 return 0;
8181 }
8182 } else {
8183 // Didn't see 'schm' or 'tenc', so this isn't encrypted.
8184 if ((aux_info_type == MKBETAG('c','e','n','c') ||
8185 aux_info_type == MKBETAG('c','e','n','s') ||
8186 aux_info_type == MKBETAG('c','b','c','1') ||
8187 aux_info_type == MKBETAG('c','b','c','s')) &&
8188 aux_info_param == 0) {
8189 av_log(c->fc, AV_LOG_ERROR, "Saw encrypted saiz without schm/tenc\n");
8190 return AVERROR_INVALIDDATA;
8191 } else {
8192 return 0;
8193 }
8194 }
8195 } else if (!sc->cenc.default_encrypted_sample) {
8196 // Didn't see 'schm' or 'tenc', so this isn't encrypted.
8197 return 0;
8198 }
8199
8200 encryption_index->auxiliary_info_default_size = avio_r8(pb);
8201 sample_count = avio_rb32(pb);
8202
8203 if (encryption_index->auxiliary_info_default_size == 0) {
8204 if (sample_count == 0)
8205 return AVERROR_INVALIDDATA;
8206
8207 encryption_index->auxiliary_info_sizes = av_malloc(sample_count);
8208 if (!encryption_index->auxiliary_info_sizes)
8209 return AVERROR(ENOMEM);
8210
8211 ret = avio_read(pb, encryption_index->auxiliary_info_sizes, sample_count);
8212 if (ret != sample_count) {
8213 av_freep(&encryption_index->auxiliary_info_sizes);
8214
8215 if (ret >= 0)
8216 ret = AVERROR_INVALIDDATA;
8217 av_log(c->fc, AV_LOG_ERROR, "Failed to read the auxiliary info, %s\n",
8218 av_err2str(ret));
8219 return ret;
8220 }
8221 }
8222 encryption_index->auxiliary_info_sample_count = sample_count;
8223
8224 if (encryption_index->auxiliary_offsets_count) {
8225 return mov_parse_auxiliary_info(c, sc, pb, encryption_index);
8226 }
8227
8228 return 0;
8229}
8230
8232{
8233 uint64_t *auxiliary_offsets;
8234 MOVEncryptionIndex *encryption_index;
8235 MOVStreamContext *sc;
8236 int i, ret;
8237 unsigned int version, entry_count, aux_info_type, aux_info_param;
8238 unsigned int alloc_size = 0;
8239
8240 ret = get_current_encryption_info(c, &encryption_index, &sc);
8241 if (ret != 1)
8242 return ret;
8243
8244 if (encryption_index->nb_encrypted_samples) {
8245 // This can happen if we have both saio/saiz and senc atoms.
8246 av_log(c->fc, AV_LOG_DEBUG, "Ignoring duplicate encryption info in saio\n");
8247 return 0;
8248 }
8249
8250 if (encryption_index->auxiliary_offsets_count) {
8251 av_log(c->fc, AV_LOG_ERROR, "Duplicate saio atom\n");
8252 return AVERROR_INVALIDDATA;
8253 }
8254
8255 version = avio_r8(pb); /* version */
8256 if (avio_rb24(pb) & 0x01) { /* flags */
8257 aux_info_type = avio_rb32(pb);
8258 aux_info_param = avio_rb32(pb);
8260 if (aux_info_type != sc->cenc.default_encrypted_sample->scheme) {
8261 av_log(c->fc, AV_LOG_DEBUG, "Ignoring saio box with non-zero aux_info_type\n");
8262 return 0;
8263 }
8264 if (aux_info_param != 0) {
8265 av_log(c->fc, AV_LOG_DEBUG, "Ignoring saio box with non-zero aux_info_type_parameter\n");
8266 return 0;
8267 }
8268 } else {
8269 // Didn't see 'schm' or 'tenc', so this isn't encrypted.
8270 if ((aux_info_type == MKBETAG('c','e','n','c') ||
8271 aux_info_type == MKBETAG('c','e','n','s') ||
8272 aux_info_type == MKBETAG('c','b','c','1') ||
8273 aux_info_type == MKBETAG('c','b','c','s')) &&
8274 aux_info_param == 0) {
8275 av_log(c->fc, AV_LOG_ERROR, "Saw encrypted saio without schm/tenc\n");
8276 return AVERROR_INVALIDDATA;
8277 } else {
8278 return 0;
8279 }
8280 }
8281 } else if (!sc->cenc.default_encrypted_sample) {
8282 // Didn't see 'schm' or 'tenc', so this isn't encrypted.
8283 return 0;
8284 }
8285
8286 entry_count = avio_rb32(pb);
8287 if (entry_count >= INT_MAX / sizeof(*auxiliary_offsets))
8288 return AVERROR(ENOMEM);
8289
8290 for (i = 0; i < entry_count && !pb->eof_reached; i++) {
8291 unsigned int min_offsets = FFMIN(FFMAX(i + 1, 1024), entry_count);
8292 auxiliary_offsets = av_fast_realloc(
8293 encryption_index->auxiliary_offsets, &alloc_size,
8294 min_offsets * sizeof(*auxiliary_offsets));
8295 if (!auxiliary_offsets) {
8296 av_freep(&encryption_index->auxiliary_offsets);
8297 return AVERROR(ENOMEM);
8298 }
8299 encryption_index->auxiliary_offsets = auxiliary_offsets;
8300
8301 if (version == 0) {
8302 encryption_index->auxiliary_offsets[i] = avio_rb32(pb);
8303 } else {
8304 encryption_index->auxiliary_offsets[i] = avio_rb64(pb);
8305 }
8306 if (c->frag_index.current >= 0) {
8307 encryption_index->auxiliary_offsets[i] += c->fragment.base_data_offset;
8308 }
8309 }
8310
8311 if (pb->eof_reached) {
8312 av_log(c->fc, AV_LOG_ERROR, "Hit EOF while reading saio\n");
8313 av_freep(&encryption_index->auxiliary_offsets);
8314 return AVERROR_INVALIDDATA;
8315 }
8316
8317 encryption_index->auxiliary_offsets_count = entry_count;
8318
8319 if (encryption_index->auxiliary_info_sample_count) {
8320 return mov_parse_auxiliary_info(c, sc, pb, encryption_index);
8321 }
8322
8323 return 0;
8324}
8325
8327{
8328 AVEncryptionInitInfo *info, *old_init_info;
8329 uint8_t **key_ids;
8330 AVStream *st;
8331 const AVPacketSideData *old_side_data;
8332 uint8_t *side_data, *extra_data;
8333 size_t side_data_size;
8334 int ret = 0;
8335 unsigned int version, kid_count, extra_data_size, alloc_size = 0;
8336
8337 if (c->fc->nb_streams < 1)
8338 return 0;
8339 st = c->fc->streams[c->fc->nb_streams-1];
8340
8341 version = avio_r8(pb); /* version */
8342 avio_rb24(pb); /* flags */
8343
8344 info = av_encryption_init_info_alloc(/* system_id_size */ 16, /* num_key_ids */ 0,
8345 /* key_id_size */ 16, /* data_size */ 0);
8346 if (!info)
8347 return AVERROR(ENOMEM);
8348
8349 if ((ret = ffio_read_size(pb, info->system_id, 16)) < 0) {
8350 av_log(c->fc, AV_LOG_ERROR, "Failed to read the system id\n");
8351 goto finish;
8352 }
8353
8354 if (version > 0) {
8355 kid_count = avio_rb32(pb);
8356 if (kid_count >= INT_MAX / sizeof(*key_ids)) {
8357 ret = AVERROR(ENOMEM);
8358 goto finish;
8359 }
8360
8361 for (unsigned int i = 0; i < kid_count && !pb->eof_reached; i++) {
8362 unsigned int min_kid_count = FFMIN(FFMAX(i + 1, 1024), kid_count);
8363 key_ids = av_fast_realloc(info->key_ids, &alloc_size,
8364 min_kid_count * sizeof(*key_ids));
8365 if (!key_ids) {
8366 ret = AVERROR(ENOMEM);
8367 goto finish;
8368 }
8369 info->key_ids = key_ids;
8370
8371 info->key_ids[i] = av_mallocz(16);
8372 if (!info->key_ids[i]) {
8373 ret = AVERROR(ENOMEM);
8374 goto finish;
8375 }
8376 info->num_key_ids = i + 1;
8377
8378 if ((ret = ffio_read_size(pb, info->key_ids[i], 16)) < 0) {
8379 av_log(c->fc, AV_LOG_ERROR, "Failed to read the key id\n");
8380 goto finish;
8381 }
8382 }
8383
8384 if (pb->eof_reached) {
8385 av_log(c->fc, AV_LOG_ERROR, "Hit EOF while reading pssh\n");
8386 ret = AVERROR_INVALIDDATA;
8387 goto finish;
8388 }
8389 }
8390
8391 extra_data_size = avio_rb32(pb);
8392 extra_data = av_malloc(extra_data_size);
8393 if (!extra_data) {
8394 ret = AVERROR(ENOMEM);
8395 goto finish;
8396 }
8397 ret = avio_read(pb, extra_data, extra_data_size);
8398 if (ret != extra_data_size) {
8399 av_free(extra_data);
8400
8401 if (ret >= 0)
8402 ret = AVERROR_INVALIDDATA;
8403 goto finish;
8404 }
8405
8406 av_freep(&info->data); // malloc(0) may still allocate something.
8407 info->data = extra_data;
8408 info->data_size = extra_data_size;
8409
8410 // If there is existing initialization data, append to the list.
8413 if (old_side_data) {
8414 old_init_info = av_encryption_init_info_get_side_data(old_side_data->data, old_side_data->size);
8415 if (old_init_info) {
8416 // Append to the end of the list.
8417 for (AVEncryptionInitInfo *cur = old_init_info;; cur = cur->next) {
8418 if (!cur->next) {
8419 cur->next = info;
8420 break;
8421 }
8422 }
8423 info = old_init_info;
8424 } else {
8425 // Assume existing side-data will be valid, so the only error we could get is OOM.
8426 ret = AVERROR(ENOMEM);
8427 goto finish;
8428 }
8429 }
8430
8431 side_data = av_encryption_init_info_add_side_data(info, &side_data_size);
8432 if (!side_data) {
8433 ret = AVERROR(ENOMEM);
8434 goto finish;
8435 }
8439 side_data, side_data_size, 0))
8440 av_free(side_data);
8441
8442finish:
8444 return ret;
8445}
8446
8448{
8449 AVStream *st;
8450 MOVStreamContext *sc;
8451
8452 if (c->fc->nb_streams < 1)
8453 return 0;
8454 st = c->fc->streams[c->fc->nb_streams-1];
8455 sc = st->priv_data;
8456
8457 if (sc->pseudo_stream_id != 0) {
8458 av_log(c->fc, AV_LOG_ERROR, "schm boxes are only supported in first sample descriptor\n");
8459 return AVERROR_PATCHWELCOME;
8460 }
8461
8462 if (atom.size < 8)
8463 return AVERROR_INVALIDDATA;
8464
8465 avio_rb32(pb); /* version and flags */
8466
8467 if (!sc->cenc.default_encrypted_sample) {
8469 if (!sc->cenc.default_encrypted_sample) {
8470 return AVERROR(ENOMEM);
8471 }
8472 }
8473
8475 return 0;
8476}
8477
8479{
8480 AVStream *st;
8481 MOVStreamContext *sc;
8482 unsigned int version, pattern, is_protected, iv_size;
8483
8484 if (c->fc->nb_streams < 1)
8485 return 0;
8486 st = c->fc->streams[c->fc->nb_streams-1];
8487 sc = st->priv_data;
8488
8489 if (sc->pseudo_stream_id != 0) {
8490 av_log(c->fc, AV_LOG_ERROR, "tenc atom are only supported in first sample descriptor\n");
8491 return AVERROR_PATCHWELCOME;
8492 }
8493
8494 if (!sc->cenc.default_encrypted_sample) {
8496 if (!sc->cenc.default_encrypted_sample) {
8497 return AVERROR(ENOMEM);
8498 }
8499 }
8500
8501 if (atom.size < 20)
8502 return AVERROR_INVALIDDATA;
8503
8504 version = avio_r8(pb); /* version */
8505 avio_rb24(pb); /* flags */
8506
8507 avio_r8(pb); /* reserved */
8508 pattern = avio_r8(pb);
8509
8510 if (version > 0) {
8512 sc->cenc.default_encrypted_sample->skip_byte_block = pattern & 0xf;
8513 }
8514
8515 is_protected = avio_r8(pb);
8516 if (is_protected && !sc->cenc.encryption_index) {
8517 // The whole stream should be by-default encrypted.
8519 if (!sc->cenc.encryption_index)
8520 return AVERROR(ENOMEM);
8521 }
8523 if (sc->cenc.per_sample_iv_size != 0 && sc->cenc.per_sample_iv_size != 8 &&
8524 sc->cenc.per_sample_iv_size != 16) {
8525 av_log(c->fc, AV_LOG_ERROR, "invalid per-sample IV size value\n");
8526 return AVERROR_INVALIDDATA;
8527 }
8528 if (avio_read(pb, sc->cenc.default_encrypted_sample->key_id, 16) != 16) {
8529 av_log(c->fc, AV_LOG_ERROR, "failed to read the default key ID\n");
8530 return AVERROR_INVALIDDATA;
8531 }
8532
8533 if (is_protected && !sc->cenc.per_sample_iv_size) {
8534 iv_size = avio_r8(pb);
8535 if (iv_size != 8 && iv_size != 16) {
8536 av_log(c->fc, AV_LOG_ERROR, "invalid default_constant_IV_size in tenc atom\n");
8537 return AVERROR_INVALIDDATA;
8538 }
8539
8540 if (avio_read(pb, sc->cenc.default_encrypted_sample->iv, iv_size) != iv_size) {
8541 av_log(c->fc, AV_LOG_ERROR, "failed to read the default IV\n");
8542 return AVERROR_INVALIDDATA;
8543 }
8544 }
8545
8546 return 0;
8547}
8548
8550{
8551 AVStream *st;
8552 int last, type, size, ret;
8553 uint8_t buf[4];
8554
8555 if (c->fc->nb_streams < 1)
8556 return 0;
8557 st = c->fc->streams[c->fc->nb_streams-1];
8558
8559 if ((uint64_t)atom.size > (1<<30) || atom.size < 42)
8560 return AVERROR_INVALIDDATA;
8561
8562 /* Check FlacSpecificBox version. */
8563 if (avio_r8(pb) != 0)
8564 return AVERROR_INVALIDDATA;
8565
8566 avio_rb24(pb); /* Flags */
8567
8568 if (avio_read(pb, buf, sizeof(buf)) != sizeof(buf)) {
8569 av_log(c->fc, AV_LOG_ERROR, "failed to read FLAC metadata block header\n");
8570 return pb->error < 0 ? pb->error : AVERROR_INVALIDDATA;
8571 }
8572 flac_parse_block_header(buf, &last, &type, &size);
8573
8575 av_log(c->fc, AV_LOG_ERROR, "STREAMINFO must be first FLACMetadataBlock\n");
8576 return AVERROR_INVALIDDATA;
8577 }
8578
8579 ret = ff_get_extradata(c->fc, st->codecpar, pb, size);
8580 if (ret < 0)
8581 return ret;
8582
8583 if (!last)
8584 av_log(c->fc, AV_LOG_WARNING, "non-STREAMINFO FLACMetadataBlock(s) ignored\n");
8585
8586 return 0;
8587}
8588
8590 AVDictionaryEntry *key_entry_hex;
8591 char kid_hex[16*2+1];
8592
8593 if (c->decryption_default_key && c->decryption_default_key_len != len) {
8594 av_log(c->fc, AV_LOG_ERROR, "invalid default decryption key length: got %d, expected %d\n", c->decryption_default_key_len, len);
8595 return -1;
8596 }
8597
8598 if (!c->decryption_keys) {
8599 av_assert0(c->decryption_default_key);
8600 memcpy(out, c->decryption_default_key, len);
8601 return 0;
8602 }
8603
8604 if (sample->key_id_size != 16) {
8605 av_log(c->fc, AV_LOG_ERROR, "invalid key ID size: got %u, expected 16\n", sample->key_id_size);
8606 return -1;
8607 }
8608
8609 ff_data_to_hex(kid_hex, sample->key_id, 16, 1);
8610 key_entry_hex = av_dict_get(c->decryption_keys, kid_hex, NULL, AV_DICT_DONT_STRDUP_KEY|AV_DICT_DONT_STRDUP_VAL);
8611 if (!key_entry_hex) {
8612 if (!c->decryption_default_key) {
8613 av_log(c->fc, AV_LOG_ERROR, "unable to find KID %s\n", kid_hex);
8614 return -1;
8615 }
8616 memcpy(out, c->decryption_default_key, len);
8617 return 0;
8618 }
8619 if (strlen(key_entry_hex->value) != len*2) {
8620 return -1;
8621 }
8622 ff_hex_to_data(out, key_entry_hex->value);
8623 return 0;
8624}
8625
8627{
8628 int i, ret;
8629 int bytes_of_protected_data;
8630 uint8_t decryption_key[AES_CTR_KEY_SIZE];
8631
8632 if (!sc->cenc.aes_ctr) {
8633 ret = get_key_from_kid(decryption_key, sizeof(decryption_key), c, sample);
8634 if (ret < 0) {
8635 return ret;
8636 }
8637
8638 /* initialize the cipher */
8640 if (!sc->cenc.aes_ctr) {
8641 return AVERROR(ENOMEM);
8642 }
8643
8644 ret = av_aes_ctr_init(sc->cenc.aes_ctr, decryption_key);
8645 if (ret < 0) {
8646 return ret;
8647 }
8648 }
8649
8651
8652 if (!sample->subsample_count) {
8653 /* decrypt the whole packet */
8654 av_aes_ctr_crypt(sc->cenc.aes_ctr, input, input, size);
8655 return 0;
8656 }
8657
8658 for (i = 0; i < sample->subsample_count; i++) {
8659 if (sample->subsamples[i].bytes_of_clear_data + (int64_t)sample->subsamples[i].bytes_of_protected_data > size) {
8660 av_log(c->fc, AV_LOG_ERROR, "subsample size exceeds the packet size left\n");
8661 return AVERROR_INVALIDDATA;
8662 }
8663
8664 /* skip the clear bytes */
8665 input += sample->subsamples[i].bytes_of_clear_data;
8666 size -= sample->subsamples[i].bytes_of_clear_data;
8667
8668 /* decrypt the encrypted bytes */
8669
8670 bytes_of_protected_data = sample->subsamples[i].bytes_of_protected_data;
8671 av_aes_ctr_crypt(sc->cenc.aes_ctr, input, input, bytes_of_protected_data);
8672
8673 input += bytes_of_protected_data;
8674 size -= bytes_of_protected_data;
8675 }
8676
8677 if (size > 0) {
8678 av_log(c->fc, AV_LOG_ERROR, "leftover packet bytes after subsample processing\n");
8679 return AVERROR_INVALIDDATA;
8680 }
8681
8682 return 0;
8683}
8684
8686{
8687 int i, ret;
8688 int num_of_encrypted_blocks;
8689 uint8_t iv[16];
8690 uint8_t decryption_key[16];
8691
8692 if (!sc->cenc.aes_ctx) {
8693 ret = get_key_from_kid(decryption_key, sizeof(decryption_key), c, sample);
8694 if (ret < 0) {
8695 return ret;
8696 }
8697
8698 /* initialize the cipher */
8699 sc->cenc.aes_ctx = av_aes_alloc();
8700 if (!sc->cenc.aes_ctx) {
8701 return AVERROR(ENOMEM);
8702 }
8703
8704 ret = av_aes_init(sc->cenc.aes_ctx, decryption_key, 16 * 8, 1);
8705 if (ret < 0) {
8706 return ret;
8707 }
8708 }
8709
8710 memcpy(iv, sample->iv, 16);
8711
8712 /* whole-block full sample encryption */
8713 if (!sample->subsample_count) {
8714 /* decrypt the whole packet */
8715 av_aes_crypt(sc->cenc.aes_ctx, input, input, size/16, iv, 1);
8716 return 0;
8717 }
8718
8719 for (i = 0; i < sample->subsample_count; i++) {
8720 if (sample->subsamples[i].bytes_of_clear_data + (int64_t)sample->subsamples[i].bytes_of_protected_data > size) {
8721 av_log(c->fc, AV_LOG_ERROR, "subsample size exceeds the packet size left\n");
8722 return AVERROR_INVALIDDATA;
8723 }
8724
8725 if (sample->subsamples[i].bytes_of_protected_data % 16) {
8726 av_log(c->fc, AV_LOG_ERROR, "subsample BytesOfProtectedData is not a multiple of 16\n");
8727 return AVERROR_INVALIDDATA;
8728 }
8729
8730 /* skip the clear bytes */
8731 input += sample->subsamples[i].bytes_of_clear_data;
8732 size -= sample->subsamples[i].bytes_of_clear_data;
8733
8734 /* decrypt the encrypted bytes */
8735 num_of_encrypted_blocks = sample->subsamples[i].bytes_of_protected_data/16;
8736 if (num_of_encrypted_blocks > 0) {
8737 av_aes_crypt(sc->cenc.aes_ctx, input, input, num_of_encrypted_blocks, iv, 1);
8738 }
8739 input += sample->subsamples[i].bytes_of_protected_data;
8740 size -= sample->subsamples[i].bytes_of_protected_data;
8741 }
8742
8743 if (size > 0) {
8744 av_log(c->fc, AV_LOG_ERROR, "leftover packet bytes after subsample processing\n");
8745 return AVERROR_INVALIDDATA;
8746 }
8747
8748 return 0;
8749}
8750
8752{
8753 int i, ret, rem_bytes;
8754 uint8_t *data;
8755 uint8_t decryption_key[AES_CTR_KEY_SIZE];
8756
8757 if (!sc->cenc.aes_ctr) {
8758 ret = get_key_from_kid(decryption_key, sizeof(decryption_key), c, sample);
8759 if (ret < 0) {
8760 return ret;
8761 }
8762
8763 /* initialize the cipher */
8765 if (!sc->cenc.aes_ctr) {
8766 return AVERROR(ENOMEM);
8767 }
8768
8769 ret = av_aes_ctr_init(sc->cenc.aes_ctr, decryption_key);
8770 if (ret < 0) {
8771 return ret;
8772 }
8773 }
8774
8776
8777 /* whole-block full sample encryption */
8778 if (!sample->subsample_count) {
8779 /* decrypt the whole packet */
8780 av_aes_ctr_crypt(sc->cenc.aes_ctr, input, input, size);
8781 return 0;
8782 } else if (!sample->crypt_byte_block && !sample->skip_byte_block) {
8783 av_log(c->fc, AV_LOG_ERROR, "pattern encryption is not present in 'cens' scheme\n");
8784 return AVERROR_INVALIDDATA;
8785 }
8786
8787 for (i = 0; i < sample->subsample_count; i++) {
8788 if (sample->subsamples[i].bytes_of_clear_data + (int64_t)sample->subsamples[i].bytes_of_protected_data > size) {
8789 av_log(c->fc, AV_LOG_ERROR, "subsample size exceeds the packet size left\n");
8790 return AVERROR_INVALIDDATA;
8791 }
8792
8793 /* skip the clear bytes */
8794 input += sample->subsamples[i].bytes_of_clear_data;
8795 size -= sample->subsamples[i].bytes_of_clear_data;
8796
8797 /* decrypt the encrypted bytes */
8798 data = input;
8799 rem_bytes = sample->subsamples[i].bytes_of_protected_data;
8800 while (rem_bytes > 0) {
8801 if (rem_bytes < 16*sample->crypt_byte_block) {
8802 break;
8803 }
8804 av_aes_ctr_crypt(sc->cenc.aes_ctr, data, data, 16*sample->crypt_byte_block);
8805 data += 16*sample->crypt_byte_block;
8806 rem_bytes -= 16*sample->crypt_byte_block;
8807 data += FFMIN(16*sample->skip_byte_block, rem_bytes);
8808 rem_bytes -= FFMIN(16*sample->skip_byte_block, rem_bytes);
8809 }
8810 input += sample->subsamples[i].bytes_of_protected_data;
8811 size -= sample->subsamples[i].bytes_of_protected_data;
8812 }
8813
8814 if (size > 0) {
8815 av_log(c->fc, AV_LOG_ERROR, "leftover packet bytes after subsample processing\n");
8816 return AVERROR_INVALIDDATA;
8817 }
8818
8819 return 0;
8820}
8821
8823{
8824 int i, ret, rem_bytes;
8825 uint8_t iv[16];
8826 uint8_t *data;
8827 uint8_t decryption_key[16];
8828
8829 if (!sc->cenc.aes_ctx) {
8830 ret = get_key_from_kid(decryption_key, sizeof(decryption_key), c, sample);
8831 if (ret < 0) {
8832 return ret;
8833 }
8834
8835 /* initialize the cipher */
8836 sc->cenc.aes_ctx = av_aes_alloc();
8837 if (!sc->cenc.aes_ctx) {
8838 return AVERROR(ENOMEM);
8839 }
8840
8841 ret = av_aes_init(sc->cenc.aes_ctx, decryption_key, 16 * 8, 1);
8842 if (ret < 0) {
8843 return ret;
8844 }
8845 }
8846
8847 /* whole-block full sample encryption */
8848 if (!sample->subsample_count) {
8849 /* decrypt the whole packet */
8850 memcpy(iv, sample->iv, 16);
8851 av_aes_crypt(sc->cenc.aes_ctx, input, input, size/16, iv, 1);
8852 return 0;
8853 } else if (!sample->crypt_byte_block && !sample->skip_byte_block) {
8854 av_log(c->fc, AV_LOG_ERROR, "pattern encryption is not present in 'cbcs' scheme\n");
8855 return AVERROR_INVALIDDATA;
8856 }
8857
8858 for (i = 0; i < sample->subsample_count; i++) {
8859 if (sample->subsamples[i].bytes_of_clear_data + (int64_t)sample->subsamples[i].bytes_of_protected_data > size) {
8860 av_log(c->fc, AV_LOG_ERROR, "subsample size exceeds the packet size left\n");
8861 return AVERROR_INVALIDDATA;
8862 }
8863
8864 /* skip the clear bytes */
8865 input += sample->subsamples[i].bytes_of_clear_data;
8866 size -= sample->subsamples[i].bytes_of_clear_data;
8867
8868 /* decrypt the encrypted bytes */
8869 memcpy(iv, sample->iv, 16);
8870 data = input;
8871 rem_bytes = sample->subsamples[i].bytes_of_protected_data;
8872 while (rem_bytes > 0) {
8873 if (rem_bytes < 16*sample->crypt_byte_block) {
8874 break;
8875 }
8876 av_aes_crypt(sc->cenc.aes_ctx, data, data, sample->crypt_byte_block, iv, 1);
8877 data += 16*sample->crypt_byte_block;
8878 rem_bytes -= 16*sample->crypt_byte_block;
8879 data += FFMIN(16*sample->skip_byte_block, rem_bytes);
8880 rem_bytes -= FFMIN(16*sample->skip_byte_block, rem_bytes);
8881 }
8882 input += sample->subsamples[i].bytes_of_protected_data;
8883 size -= sample->subsamples[i].bytes_of_protected_data;
8884 }
8885
8886 if (size > 0) {
8887 av_log(c->fc, AV_LOG_ERROR, "leftover packet bytes after subsample processing\n");
8888 return AVERROR_INVALIDDATA;
8889 }
8890
8891 return 0;
8892}
8893
8894static int cenc_decrypt(MOVContext *c, MOVStreamContext *sc, AVEncryptionInfo *sample, uint8_t *input, int size)
8895{
8896 if (sample->scheme == MKBETAG('c','e','n','c') && !sample->crypt_byte_block && !sample->skip_byte_block) {
8897 return cenc_scheme_decrypt(c, sc, sample, input, size);
8898 } else if (sample->scheme == MKBETAG('c','b','c','1') && !sample->crypt_byte_block && !sample->skip_byte_block) {
8899 return cbc1_scheme_decrypt(c, sc, sample, input, size);
8900 } else if (sample->scheme == MKBETAG('c','e','n','s')) {
8901 return cens_scheme_decrypt(c, sc, sample, input, size);
8902 } else if (sample->scheme == MKBETAG('c','b','c','s')) {
8903 return cbcs_scheme_decrypt(c, sc, sample, input, size);
8904 } else {
8905 av_log(c->fc, AV_LOG_ERROR, "invalid encryption scheme\n");
8906 return AVERROR_INVALIDDATA;
8907 }
8908}
8909
8911{
8912 int current = frag_index->current;
8913
8914 if (!frag_index->nb_items)
8915 return NULL;
8916
8917 // Check frag_index->current is the right one for pkt. It can out of sync.
8918 if (current >= 0 && current < frag_index->nb_items) {
8919 if (frag_index->item[current].moof_offset < pkt->pos &&
8920 (current + 1 == frag_index->nb_items ||
8921 frag_index->item[current + 1].moof_offset > pkt->pos))
8922 return get_frag_stream_info(frag_index, current, id);
8923 }
8924
8925
8926 for (int i = 0; i < frag_index->nb_items; i++) {
8927 if (frag_index->item[i].moof_offset > pkt->pos)
8928 break;
8929 current = i;
8930 }
8931 frag_index->current = current;
8932 return get_frag_stream_info(frag_index, current, id);
8933}
8934
8935static int cenc_filter(MOVContext *mov, AVStream* st, MOVStreamContext *sc, AVPacket *pkt, int current_index)
8936{
8937 MOVFragmentStreamInfo *frag_stream_info;
8938 MOVEncryptionIndex *encryption_index;
8939 AVEncryptionInfo *encrypted_sample;
8940 int encrypted_index, ret;
8941
8942 frag_stream_info = get_frag_stream_info_from_pkt(&mov->frag_index, pkt, sc->id);
8943 encrypted_index = current_index;
8944 encryption_index = NULL;
8945 if (frag_stream_info) {
8946 // Note this only supports encryption info in the first sample descriptor.
8947 if (frag_stream_info->stsd_id == 1) {
8948 if (frag_stream_info->encryption_index) {
8949 encrypted_index = current_index - frag_stream_info->index_base;
8950 encryption_index = frag_stream_info->encryption_index;
8951 } else {
8952 encryption_index = sc->cenc.encryption_index;
8953 }
8954 }
8955 } else {
8956 encryption_index = sc->cenc.encryption_index;
8957 }
8958
8959 if (encryption_index) {
8960 if (encryption_index->auxiliary_info_sample_count &&
8961 !encryption_index->nb_encrypted_samples) {
8962 av_log(mov->fc, AV_LOG_ERROR, "saiz atom found without saio\n");
8963 return AVERROR_INVALIDDATA;
8964 }
8965 if (encryption_index->auxiliary_offsets_count &&
8966 !encryption_index->nb_encrypted_samples) {
8967 av_log(mov->fc, AV_LOG_ERROR, "saio atom found without saiz\n");
8968 return AVERROR_INVALIDDATA;
8969 }
8970
8971 encrypted_sample = NULL;
8972 if (!encryption_index->nb_encrypted_samples) {
8973 // Full-sample encryption with default settings.
8974 encrypted_sample = sc->cenc.default_encrypted_sample;
8975 } else if (encrypted_index >= 0 && encrypted_index < encryption_index->nb_encrypted_samples) {
8976 // Per-sample setting override.
8977 encrypted_sample = encryption_index->encrypted_samples[encrypted_index];
8978 if (!encrypted_sample) {
8979 encrypted_sample = sc->cenc.default_encrypted_sample;
8980 }
8981 }
8982
8983 if (!encrypted_sample) {
8984 av_log(mov->fc, AV_LOG_ERROR, "Incorrect number of samples in encryption info\n");
8985 return AVERROR_INVALIDDATA;
8986 }
8987
8988 if (mov->decryption_keys || mov->decryption_default_key) {
8989 return cenc_decrypt(mov, sc, encrypted_sample, pkt->data, pkt->size);
8990 } else {
8991 size_t size;
8992 uint8_t *side_data = av_encryption_info_add_side_data(encrypted_sample, &size);
8993 if (!side_data)
8994 return AVERROR(ENOMEM);
8996 if (ret < 0)
8997 av_free(side_data);
8998 return ret;
8999 }
9000 }
9001
9002 return 0;
9003}
9004
9006{
9007 const int OPUS_SEEK_PREROLL_MS = 80;
9008 int ret;
9009 AVStream *st;
9010 size_t size;
9011 uint16_t pre_skip;
9012
9013 if (c->fc->nb_streams < 1)
9014 return 0;
9015 st = c->fc->streams[c->fc->nb_streams-1];
9016
9017 if ((uint64_t)atom.size > (1<<30) || atom.size < 11 || st->codecpar->extradata)
9018 return AVERROR_INVALIDDATA;
9019
9020 /* Check OpusSpecificBox version. */
9021 if (avio_r8(pb) != 0) {
9022 av_log(c->fc, AV_LOG_ERROR, "unsupported OpusSpecificBox version\n");
9023 return AVERROR_INVALIDDATA;
9024 }
9025
9026 /* OpusSpecificBox size plus magic for Ogg OpusHead header. */
9027 size = atom.size + 8;
9028
9029 if ((ret = ff_alloc_extradata(st->codecpar, size)) < 0)
9030 return ret;
9031
9032 AV_WL32A(st->codecpar->extradata, MKTAG('O','p','u','s'));
9033 AV_WL32A(st->codecpar->extradata + 4, MKTAG('H','e','a','d'));
9034 AV_WB8(st->codecpar->extradata + 8, 1); /* OpusHead version */
9035 if ((ret = ffio_read_size(pb, st->codecpar->extradata + 9, size - 9)) < 0) {
9037 st->codecpar->extradata_size = 0;
9038 return ret;
9039 }
9040
9041 /* OpusSpecificBox is stored in big-endian, but OpusHead is
9042 little-endian; aside from the preceding magic and version they're
9043 otherwise currently identical. Data after output gain at offset 16
9044 doesn't need to be bytewapped. */
9045 pre_skip = AV_RB16A(st->codecpar->extradata + 10);
9046 AV_WL16A(st->codecpar->extradata + 10, pre_skip);
9047 AV_WL32A(st->codecpar->extradata + 12, AV_RB32A(st->codecpar->extradata + 12));
9048 AV_WL16A(st->codecpar->extradata + 16, AV_RB16A(st->codecpar->extradata + 16));
9049
9050 st->codecpar->initial_padding = pre_skip;
9052 (AVRational){1, 1000},
9053 (AVRational){1, 48000});
9054
9055 return 0;
9056}
9057
9059{
9060 AVStream *st;
9061 unsigned format_info;
9062 int channel_assignment, channel_assignment1, channel_assignment2;
9063 int ratebits;
9064 uint64_t chmask;
9065
9066 if (c->fc->nb_streams < 1)
9067 return 0;
9068 st = c->fc->streams[c->fc->nb_streams-1];
9069
9070 if (atom.size < 10)
9071 return AVERROR_INVALIDDATA;
9072
9073 format_info = avio_rb32(pb);
9074
9075 ratebits = (format_info >> 28) & 0xF;
9076 channel_assignment1 = (format_info >> 15) & 0x1F;
9077 channel_assignment2 = format_info & 0x1FFF;
9078 if (channel_assignment2)
9079 channel_assignment = channel_assignment2;
9080 else
9081 channel_assignment = channel_assignment1;
9082
9083 st->codecpar->frame_size = 40 << (ratebits & 0x7);
9084 st->codecpar->sample_rate = mlp_samplerate(ratebits);
9085
9087 chmask = truehd_layout(channel_assignment);
9089
9090 return 0;
9091}
9092
9094{
9095 AVStream *st;
9096 uint8_t buf[ISOM_DVCC_DVVC_SIZE];
9097 int ret;
9098 int64_t read_size = atom.size;
9099
9100 if (c->fc->nb_streams < 1)
9101 return 0;
9102 st = c->fc->streams[c->fc->nb_streams-1];
9103
9104 // At most 24 bytes
9105 read_size = FFMIN(read_size, ISOM_DVCC_DVVC_SIZE);
9106
9107 if ((ret = ffio_read_size(pb, buf, read_size)) < 0)
9108 return ret;
9109
9110 return ff_isom_parse_dvcc_dvvc(c->fc, st, buf, read_size);
9111}
9112
9114{
9115 AVStream *st;
9116 AVPacketSideData *sd;
9117 int ret;
9118
9119 if (c->fc->nb_streams < 1)
9120 return 0;
9121 st = c->fc->streams[c->fc->nb_streams - 1];
9122
9123 if (atom.size < 23 || atom.size > INT_MAX - AV_INPUT_BUFFER_PADDING_SIZE)
9124 return AVERROR_INVALIDDATA;
9125
9129 atom.size, 0);
9130 if (!sd)
9131 return AVERROR(ENOMEM);
9132
9133 ret = ffio_read_size(pb, sd->data, atom.size);
9134 if (ret < 0)
9135 return ret;
9136
9137 return 0;
9138}
9139
9141{
9142 AVStream *st;
9143 uint8_t *buf;
9144 int ret, old_size, num_arrays;
9145
9146 if (c->fc->nb_streams < 1)
9147 return 0;
9148 st = c->fc->streams[c->fc->nb_streams-1];
9149
9150 if (!st->codecpar->extradata_size)
9151 // TODO: handle lhvC when present before hvcC
9152 return 0;
9153
9154 if (atom.size < 6 || st->codecpar->extradata_size < 23 ||
9155 atom.size > INT_MAX - AV_INPUT_BUFFER_PADDING_SIZE) {
9156 return AVERROR_INVALIDDATA;
9157 }
9158
9160 if (!buf)
9161 return AVERROR(ENOMEM);
9162 memset(buf + atom.size, 0, AV_INPUT_BUFFER_PADDING_SIZE);
9163
9164 ret = ffio_read_size(pb, buf, atom.size);
9165 if (ret < 0) {
9166 av_free(buf);
9167 av_log(c->fc, AV_LOG_WARNING, "lhvC atom truncated\n");
9168 return 0;
9169 }
9170
9171 num_arrays = buf[5];
9172 old_size = st->codecpar->extradata_size;
9173 atom.size -= 8 /* account for mov_realloc_extradata offsetting */
9174 + 6 /* lhvC bytes before the arrays*/;
9175
9176 ret = mov_realloc_extradata(st->codecpar, atom);
9177 if (ret < 0) {
9178 av_free(buf);
9179 return ret;
9180 }
9181
9182 st->codecpar->extradata[22] += num_arrays;
9183 memcpy(st->codecpar->extradata + old_size, buf + 6, atom.size + 8);
9184
9186
9187 av_free(buf);
9188 return 0;
9189}
9190
9192{
9193 AVFormatContext *ctx = c->fc;
9194 AVStream *st = NULL;
9195 AVBPrint scheme_buf, value_buf;
9196 int64_t scheme_str_len = 0, value_str_len = 0;
9197 int version, flags, ret = AVERROR_BUG;
9198 int64_t size = atom.size;
9199
9200 if (atom.size < 6)
9201 // 4 bytes for version + flags, 2x 1 byte for null
9202 return AVERROR_INVALIDDATA;
9203
9204 if (c->fc->nb_streams < 1)
9205 return 0;
9206 st = c->fc->streams[c->fc->nb_streams-1];
9207
9208 version = avio_r8(pb);
9209 flags = avio_rb24(pb);
9210 size -= 4;
9211
9212 if (version != 0 || flags != 0) {
9214 "Unsupported 'kind' box with version %d, flags: %x",
9215 version, flags);
9216 return AVERROR_INVALIDDATA;
9217 }
9218
9221
9222 if ((scheme_str_len = ff_read_string_to_bprint_overwrite(pb, &scheme_buf,
9223 size)) < 0) {
9224 ret = scheme_str_len;
9225 goto cleanup;
9226 }
9227
9228 if (scheme_str_len + 1 >= size) {
9229 // we need to have another string, even if nullptr.
9230 // we check with + 1 since we expect that if size was not hit,
9231 // an additional null was read.
9232 ret = AVERROR_INVALIDDATA;
9233 goto cleanup;
9234 }
9235
9236 size -= scheme_str_len + 1;
9237
9238 if ((value_str_len = ff_read_string_to_bprint_overwrite(pb, &value_buf,
9239 size)) < 0) {
9240 ret = value_str_len;
9241 goto cleanup;
9242 }
9243
9244 if (value_str_len == size) {
9245 // in case of no trailing null, box is not valid.
9246 ret = AVERROR_INVALIDDATA;
9247 goto cleanup;
9248 }
9249
9251 "%s stream %d KindBox(scheme: %s, value: %s)\n",
9253 st->index,
9254 scheme_buf.str, value_buf.str);
9255
9256 for (int i = 0; ff_mov_track_kind_table[i].scheme_uri; i++) {
9258 if (!av_strstart(scheme_buf.str, map.scheme_uri, NULL))
9259 continue;
9260
9261 for (int j = 0; map.value_maps[j].disposition; j++) {
9262 const struct MP4TrackKindValueMapping value_map = map.value_maps[j];
9263 if (!av_strstart(value_buf.str, value_map.value, NULL))
9264 continue;
9265
9266 st->disposition |= value_map.disposition;
9267 }
9268 }
9269
9270 ret = 0;
9271
9272cleanup:
9273
9274 av_bprint_finalize(&scheme_buf, NULL);
9275 av_bprint_finalize(&value_buf, NULL);
9276
9277 return ret;
9278}
9279
9281{
9282 AVStream *st;
9283 AVChannelLayout ch_layout = { 0 };
9284 int ret, i, version, type;
9285 int ambisonic_order, channel_order, normalization, channel_count;
9286 int ambi_channels, non_diegetic_channels;
9287
9288 if (c->fc->nb_streams < 1)
9289 return 0;
9290
9291 st = c->fc->streams[c->fc->nb_streams - 1];
9292
9293 if (atom.size < 16) {
9294 av_log(c->fc, AV_LOG_ERROR, "SA3D audio box too small\n");
9295 return AVERROR_INVALIDDATA;
9296 }
9297
9298 version = avio_r8(pb);
9299 if (version) {
9300 av_log(c->fc, AV_LOG_WARNING, "Unsupported SA3D box version %d\n", version);
9301 return 0;
9302 }
9303
9304 type = avio_r8(pb);
9305 if (type & 0x7f) {
9306 av_log(c->fc, AV_LOG_WARNING,
9307 "Unsupported ambisonic type %d\n", type & 0x7f);
9308 return 0;
9309 }
9310 non_diegetic_channels = (type >> 7) * 2; // head_locked_stereo
9311
9312 ambisonic_order = avio_rb32(pb);
9313
9314 channel_order = avio_r8(pb);
9315 if (channel_order) {
9316 av_log(c->fc, AV_LOG_WARNING,
9317 "Unsupported channel_order %d\n", channel_order);
9318 return 0;
9319 }
9320
9321 normalization = avio_r8(pb);
9322 if (normalization) {
9323 av_log(c->fc, AV_LOG_WARNING,
9324 "Unsupported normalization %d\n", normalization);
9325 return 0;
9326 }
9327
9328 channel_count = avio_rb32(pb);
9329 if (ambisonic_order < 0 || ambisonic_order > 31 ||
9330 channel_count != ((ambisonic_order + 1LL) * (ambisonic_order + 1LL) +
9331 non_diegetic_channels)) {
9332 av_log(c->fc, AV_LOG_ERROR,
9333 "Invalid number of channels (%d / %d)\n",
9334 channel_count, ambisonic_order);
9335 return 0;
9336 }
9337 ambi_channels = channel_count - non_diegetic_channels;
9338
9339 ret = av_channel_layout_custom_init(&ch_layout, channel_count);
9340 if (ret < 0)
9341 return 0;
9342
9343 for (i = 0; i < channel_count; i++) {
9344 unsigned channel = avio_rb32(pb);
9345
9346 if (channel >= channel_count) {
9347 av_log(c->fc, AV_LOG_ERROR, "Invalid channel index (%d / %d)\n",
9348 channel, ambisonic_order);
9349 av_channel_layout_uninit(&ch_layout);
9350 return 0;
9351 }
9352 if (channel >= ambi_channels)
9353 ch_layout.u.map[i].id = channel - ambi_channels;
9354 else
9355 ch_layout.u.map[i].id = AV_CHAN_AMBISONIC_BASE + channel;
9356 }
9357
9359 if (ret < 0) {
9360 av_channel_layout_uninit(&ch_layout);
9361 return 0;
9362 }
9363
9365 st->codecpar->ch_layout = ch_layout;
9366
9367 return 0;
9368}
9369
9371{
9372 AVStream *st;
9373 int version;
9374
9375 if (c->fc->nb_streams < 1)
9376 return 0;
9377
9378 st = c->fc->streams[c->fc->nb_streams - 1];
9379
9380 if (atom.size < 5) {
9381 av_log(c->fc, AV_LOG_ERROR, "Empty SAND audio box\n");
9382 return AVERROR_INVALIDDATA;
9383 }
9384
9385 version = avio_r8(pb);
9386 if (version) {
9387 av_log(c->fc, AV_LOG_WARNING, "Unsupported SAND box version %d\n", version);
9388 return 0;
9389 }
9390
9392
9393 return 0;
9394}
9395
9396static int rb_size(AVIOContext *pb, int64_t *value, int size)
9397{
9398 if (size == 0)
9399 *value = 0;
9400 else if (size == 1)
9401 *value = avio_r8(pb);
9402 else if (size == 2)
9403 *value = avio_rb16(pb);
9404 else if (size == 4)
9405 *value = avio_rb32(pb);
9406 else if (size == 8) {
9407 *value = avio_rb64(pb);
9408 if (*value < 0)
9409 return -1;
9410 } else
9411 return -1;
9412 return size;
9413}
9414
9416{
9417 avio_rb32(pb); // version & flags.
9418 c->primary_item_id = avio_rb16(pb);
9419 av_log(c->fc, AV_LOG_TRACE, "pitm: primary_item_id %d\n", c->primary_item_id);
9420 return atom.size;
9421}
9422
9424{
9425 c->idat_offset = avio_tell(pb);
9426 return 0;
9427}
9428
9430{
9431 HEIFItem **heif_item;
9432 int version, offset_size, length_size, base_offset_size, index_size;
9433 int item_count, extent_count;
9434 int64_t base_offset, extent_offset, extent_length;
9435 uint8_t value;
9436
9437 if (c->found_iloc) {
9438 av_log(c->fc, AV_LOG_INFO, "Duplicate iloc box found\n");
9439 return 0;
9440 }
9441
9442 version = avio_r8(pb);
9443 avio_rb24(pb); // flags.
9444
9445 value = avio_r8(pb);
9446 offset_size = (value >> 4) & 0xF;
9447 length_size = value & 0xF;
9448 value = avio_r8(pb);
9449 base_offset_size = (value >> 4) & 0xF;
9450 index_size = !version ? 0 : (value & 0xF);
9451 if (index_size) {
9452 avpriv_report_missing_feature(c->fc, "iloc: index_size != 0");
9453 return AVERROR_PATCHWELCOME;
9454 }
9455 item_count = (version < 2) ? avio_rb16(pb) : avio_rb32(pb);
9456
9457 if (item_count > atom.size)
9458 return AVERROR_INVALIDDATA;
9459
9460 heif_item = av_realloc_array(c->heif_item, FFMAX(item_count, c->nb_heif_item), sizeof(*c->heif_item));
9461 if (!heif_item)
9462 return AVERROR(ENOMEM);
9463 c->heif_item = heif_item;
9464 if (item_count > c->nb_heif_item)
9465 memset(&c->heif_item[c->nb_heif_item], 0,
9466 sizeof(*c->heif_item) * (item_count - c->nb_heif_item));
9467 c->nb_heif_item = FFMAX(c->nb_heif_item, item_count);
9468
9469 av_log(c->fc, AV_LOG_TRACE, "iloc: item_count %d\n", item_count);
9470 for (int i = 0; i < item_count; i++) {
9471 HEIFItem *item = NULL;
9472 int item_id = (version < 2) ? avio_rb16(pb) : avio_rb32(pb);
9473 int offset_type = (version > 0) ? avio_rb16(pb) & 0xf : 0;
9474 int j;
9475
9476 if (avio_feof(pb))
9477 return AVERROR_INVALIDDATA;
9478 if (offset_type > 1) {
9479 avpriv_report_missing_feature(c->fc, "iloc offset type %d", offset_type);
9480 return AVERROR_PATCHWELCOME;
9481 }
9482
9483 avio_rb16(pb); // data_reference_index.
9484 if (rb_size(pb, &base_offset, base_offset_size) < 0)
9485 return AVERROR_INVALIDDATA;
9486 extent_count = avio_rb16(pb);
9487 if (extent_count > 1) {
9488 // For still AVIF images, we only support one extent item.
9489 avpriv_report_missing_feature(c->fc, "iloc: extent_count > 1");
9490 return AVERROR_PATCHWELCOME;
9491 }
9492
9493 if (rb_size(pb, &extent_offset, offset_size) < 0 ||
9494 rb_size(pb, &extent_length, length_size) < 0 ||
9495 base_offset > INT64_MAX - extent_offset)
9496 return AVERROR_INVALIDDATA;
9497
9498 for (j = 0; j < c->nb_heif_item; j++) {
9499 item = c->heif_item[j];
9500 if (!item)
9501 item = c->heif_item[j] = av_mallocz(sizeof(*item));
9502 else if (item->item_id != item_id)
9503 continue;
9504 break;
9505 }
9506 if (!item)
9507 return AVERROR(ENOMEM);
9508 if (j == c->nb_heif_item)
9509 return AVERROR_INVALIDDATA;
9510
9511 item->item_id = item_id;
9512
9513 if (offset_type == 1)
9514 item->is_idat_relative = 1;
9515 item->extent_length = extent_length;
9516 item->extent_offset = base_offset + extent_offset;
9517 av_log(c->fc, AV_LOG_TRACE, "iloc: item_idx %d, item->item_id %d, offset_type %d, "
9518 "extent_offset %"PRId64", extent_length %"PRId64"\n",
9519 i, item->item_id, offset_type, item->extent_offset, item->extent_length);
9520 }
9521
9522 c->found_iloc = 1;
9523 return atom.size;
9524}
9525
9527{
9528 HEIFItem *item = NULL;
9529 AVBPrint item_name;
9530 int64_t size = atom.size;
9531 uint32_t item_type;
9532 int item_id;
9533 int i, version, ret;
9534
9535 version = avio_r8(pb);
9536 avio_rb24(pb); // flags.
9537 size -= 4;
9538 if (size < 0)
9539 return AVERROR_INVALIDDATA;
9540
9541 if (version < 2) {
9542 avpriv_report_missing_feature(c->fc, "infe version < 2");
9543 avio_skip(pb, size);
9544 return 1;
9545 }
9546
9547 item_id = version > 2 ? avio_rb32(pb) : avio_rb16(pb);
9548 avio_rb16(pb); // item_protection_index
9549 item_type = avio_rl32(pb);
9550 size -= 8;
9551 if (size < 1)
9552 return AVERROR_INVALIDDATA;
9553
9556 if (ret < 0) {
9558 return ret;
9559 }
9560
9561 av_log(c->fc, AV_LOG_TRACE, "infe: item_id %d, item_type %s, item_name %s\n",
9562 item_id, av_fourcc2str(item_type), item_name.str);
9563
9564 size -= ret + 1;
9565 if (size > 0)
9566 avio_skip(pb, size);
9567
9568 for (i = 0; i < c->nb_heif_item; i++) {
9569 item = c->heif_item[i];
9570 if (!item)
9571 item = c->heif_item[i] = av_mallocz(sizeof(*item));
9572 else if (item->item_id != item_id)
9573 continue;
9574 break;
9575 }
9576 if (!item) {
9578 return AVERROR(ENOMEM);
9579 }
9580 if (i == c->nb_heif_item) {
9582 return AVERROR_INVALIDDATA;
9583 }
9584
9585 av_freep(&item->name);
9586 av_bprint_finalize(&item_name, ret ? &item->name : NULL);
9587 item->item_id = item_id;
9588 item->type = item_type;
9589
9590 switch (item_type) {
9591 case MKTAG('a','v','0','1'):
9592 case MKTAG('j','p','e','g'):
9593 case MKTAG('h','v','c','1'):
9594 ret = heif_add_stream(c, item);
9595 if (ret < 0)
9596 return ret;
9597 break;
9598 }
9599
9600 return 0;
9601}
9602
9604{
9605 HEIFItem **heif_item;
9606 int entry_count;
9607 int version, got_stream = 0, ret, i;
9608
9609 if (c->found_iinf) {
9610 av_log(c->fc, AV_LOG_WARNING, "Duplicate iinf box found\n");
9611 return 0;
9612 }
9613
9614 version = avio_r8(pb);
9615 avio_rb24(pb); // flags.
9616 entry_count = version ? avio_rb32(pb) : avio_rb16(pb);
9617
9618 if (entry_count > atom.size)
9619 return AVERROR_INVALIDDATA;
9620
9621 heif_item = av_realloc_array(c->heif_item, FFMAX(entry_count, c->nb_heif_item), sizeof(*c->heif_item));
9622 if (!heif_item)
9623 return AVERROR(ENOMEM);
9624 c->heif_item = heif_item;
9625 if (entry_count > c->nb_heif_item)
9626 memset(&c->heif_item[c->nb_heif_item], 0,
9627 sizeof(*c->heif_item) * (entry_count - c->nb_heif_item));
9628 c->nb_heif_item = FFMAX(c->nb_heif_item, entry_count);
9629
9630 for (i = 0; i < entry_count; i++) {
9631 MOVAtom infe;
9632
9633 infe.size = avio_rb32(pb) - 8;
9634 infe.type = avio_rl32(pb);
9635 if (avio_feof(pb)) {
9636 ret = AVERROR_INVALIDDATA;
9637 goto fail;
9638 }
9639 ret = mov_read_infe(c, pb, infe);
9640 if (ret < 0)
9641 goto fail;
9642 if (!ret)
9643 got_stream = 1;
9644 }
9645
9646 c->found_iinf = got_stream;
9647 return 0;
9648fail:
9649 for (; i >= 0; i--) {
9650 HEIFItem *item = c->heif_item[i];
9651
9652 if (!item)
9653 continue;
9654
9655 av_freep(&item->name);
9656 }
9657 return ret;
9658}
9659
9661{
9662 HEIFItem *item = NULL;
9663 HEIFGrid *grid;
9664 int entries, i;
9665 int from_item_id = version ? avio_rb32(pb) : avio_rb16(pb);
9666 int ret = 0;
9667
9668 for (int i = 0; i < c->nb_heif_grid; i++) {
9669 if (c->heif_grid[i].item->item_id == from_item_id) {
9670 av_log(c->fc, AV_LOG_ERROR, "More than one 'dimg' box "
9671 "referencing the same Derived Image item\n");
9672 return AVERROR_INVALIDDATA;
9673 }
9674 }
9675 for (int i = 0; i < c->nb_heif_item; i++) {
9676 if (!c->heif_item[i] || c->heif_item[i]->item_id != from_item_id)
9677 continue;
9678 item = c->heif_item[i];
9679
9680 switch (item->type) {
9681 case MKTAG('g','r','i','d'):
9682 case MKTAG('i','o','v','l'):
9683 break;
9684 default:
9685 avpriv_report_missing_feature(c->fc, "Derived Image item of type %s",
9686 av_fourcc2str(item->type));
9687 return 0;
9688 }
9689 break;
9690 }
9691 if (!item) {
9692 av_log(c->fc, AV_LOG_ERROR, "Missing grid information\n");
9693 return AVERROR_INVALIDDATA;
9694 }
9695
9696 entries = avio_rb16(pb);
9697 if (!entries) {
9698 av_log(c->fc, AV_LOG_ERROR,
9699 "Derived image item references no input images\n");
9700 return AVERROR_INVALIDDATA;
9701 }
9702
9703 grid = av_realloc_array(c->heif_grid, c->nb_heif_grid + 1U,
9704 sizeof(*c->heif_grid));
9705 if (!grid)
9706 return AVERROR(ENOMEM);
9707 c->heif_grid = grid;
9708 grid = &grid[c->nb_heif_grid];
9709
9710 grid->tile_id_list = av_malloc_array(entries, sizeof(*grid->tile_id_list));
9711 grid->tile_idx_list = av_calloc(entries, sizeof(*grid->tile_idx_list));
9712 grid->tile_item_list = av_calloc(entries, sizeof(*grid->tile_item_list));
9713 if (!grid->tile_id_list || !grid->tile_item_list || !grid->tile_idx_list) {
9714 ret = AVERROR(ENOMEM);
9715 goto fail;
9716 }
9717 /* 'to' item ids */
9718 for (i = 0; i < entries; i++) {
9719 grid->tile_id_list[i] = version ? avio_rb32(pb) : avio_rb16(pb);
9720
9721 if (avio_feof(pb)) {
9722 ret = AVERROR_INVALIDDATA;
9723 goto fail;
9724 }
9725 }
9726
9727 grid->nb_tiles = entries;
9728 grid->item = item;
9729 ++c->nb_heif_grid;
9730
9731 av_log(c->fc, AV_LOG_TRACE, "dimg: from_item_id %d, entries %d\n",
9732 from_item_id, entries);
9733
9734 return 0;
9735fail:
9736 av_freep(&grid->tile_id_list);
9737 av_freep(&grid->tile_idx_list);
9738 av_freep(&grid->tile_item_list);
9739
9740 return ret;
9741}
9742
9743static int mov_read_iref_cdsc(MOVContext *c, AVIOContext *pb, uint32_t type, int version, uint32_t size)
9744{
9745 HEIFItem *from_item = NULL;
9746 int entries;
9747 int item_id_size = version ? 4 : 2;
9748 int from_item_id = version ? avio_rb32(pb) : avio_rb16(pb);
9749 const HEIFItemRef ref = { type, from_item_id };
9750
9751 from_item = get_heif_item(c, from_item_id);
9752 if (!from_item) {
9753 av_log(c->fc, AV_LOG_ERROR, "Missing stream referenced by thmb item\n");
9754 return AVERROR_INVALIDDATA;
9755 }
9756
9757 entries = avio_rb16(pb);
9758 if ((int64_t)entries * item_id_size > (int64_t)size - item_id_size - 2) {
9759 av_log(c->fc, AV_LOG_ERROR, "iref %s entry count %d exceeds the sub-box size\n",
9760 av_fourcc2str(type), entries);
9761 return AVERROR_INVALIDDATA;
9762 }
9763 /* 'to' item ids */
9764 for (int i = 0; i < entries; i++) {
9765 HEIFItem *item = get_heif_item(c, version ? avio_rb32(pb) : avio_rb16(pb));
9766
9767 if (avio_feof(pb))
9768 return AVERROR_INVALIDDATA;
9769
9770 if (!item) {
9771 av_log(c->fc, AV_LOG_WARNING, "Missing stream referenced by %s item\n",
9773 continue;
9774 }
9775
9776 if (!av_dynarray2_add((void **)&item->iref_list, &item->nb_iref_list,
9777 sizeof(*item->iref_list), (const uint8_t *)&ref))
9778 return AVERROR(ENOMEM);
9779 }
9780
9781 av_log(c->fc, AV_LOG_TRACE, "%s: from_item_id %d, entries %d\n",
9782 av_fourcc2str(type), from_item_id, entries);
9783
9784 return 0;
9785}
9786
9788{
9789 int version = avio_r8(pb);
9790 int ret;
9791
9792 avio_rb24(pb); // flags
9793 atom.size -= 4;
9794
9795 if (version > 1) {
9796 av_log(c->fc, AV_LOG_WARNING, "Unknown iref box version %d\n", version);
9797 return 0;
9798 }
9799
9800 while (atom.size) {
9801 int64_t next = avio_tell(pb);
9802 uint32_t type, size = avio_rb32(pb);
9803
9804 if (size < 14 || size > atom.size || next > INT64_MAX - size)
9805 return AVERROR_INVALIDDATA;
9806
9807 next += size;
9808 type = avio_rl32(pb);
9809 switch (type) {
9810 case MKTAG('d','i','m','g'):
9811 ret = mov_read_iref_dimg(c, pb, version);
9812 if (ret < 0)
9813 return ret;
9814 break;
9815 case MKTAG('c','d','s','c'):
9816 case MKTAG('t','h','m','b'):
9817 ret = mov_read_iref_cdsc(c, pb, type, version, size - 8);
9818 if (ret < 0)
9819 return ret;
9820 break;
9821 default:
9822 av_log(c->fc, AV_LOG_DEBUG, "Unknown iref type %s size %"PRIu32"\n",
9824 }
9825
9826 atom.size -= size;
9827 avio_seek(pb, next, SEEK_SET);
9828 }
9829 return 0;
9830}
9831
9833{
9834 HEIFItem *item;
9835 uint32_t width, height;
9836
9837 avio_r8(pb); /* version */
9838 avio_rb24(pb); /* flags */
9839 width = avio_rb32(pb);
9840 height = avio_rb32(pb);
9841
9842 av_log(c->fc, AV_LOG_TRACE, "ispe: item_id %d, width %"PRIu32", height %"PRIu32"\n",
9843 c->cur_item_id, width, height);
9844
9845 if (!width || !height || width > INT_MAX || height > INT_MAX) {
9846 av_log(c->fc, AV_LOG_ERROR, "Invalid ispe dimensions %"PRIu32"x%"PRIu32"\n",
9847 width, height);
9848 return AVERROR_INVALIDDATA;
9849 }
9850
9851 item = get_heif_item(c, c->cur_item_id);
9852 if (item) {
9853 item->width = width;
9854 item->height = height;
9855 }
9856
9857 return 0;
9858}
9859
9861{
9862 HEIFItem *item;
9863 int angle;
9864
9865 angle = avio_r8(pb) & 0x3;
9866
9867 av_log(c->fc, AV_LOG_TRACE, "irot: item_id %d, angle %u\n",
9868 c->cur_item_id, angle);
9869
9870 item = get_heif_item(c, c->cur_item_id);
9871 if (item) {
9872 // angle * 90 specifies the angle (in anti-clockwise direction)
9873 // in units of degrees.
9874 item->rotation = angle * 90;
9875 }
9876
9877 return 0;
9878}
9879
9881{
9882 HEIFItem *item;
9883 int axis;
9884
9885 axis = avio_r8(pb) & 0x1;
9886
9887 av_log(c->fc, AV_LOG_TRACE, "imir: item_id %d, axis %u\n",
9888 c->cur_item_id, axis);
9889
9890 item = get_heif_item(c, c->cur_item_id);
9891 if (item) {
9892 item->hflip = axis;
9893 item->vflip = !axis;
9894 }
9895
9896 return 0;
9897}
9898
9900{
9901 typedef struct MOVAtoms {
9902 FFIOContext b;
9903 uint32_t type;
9904 int64_t size;
9905 uint8_t *data;
9906 } MOVAtoms;
9907 MOVAtoms *atoms = NULL;
9908 MOVAtom a;
9909 unsigned count;
9910 int nb_atoms = 0;
9911 int version, flags;
9912 int ret;
9913
9914 a.size = avio_rb32(pb);
9915 a.type = avio_rl32(pb);
9916
9917 if (a.size < 8 || a.type != MKTAG('i','p','c','o'))
9918 return AVERROR_INVALIDDATA;
9919
9920 a.size -= 8;
9921 while (a.size >= 8) {
9922 MOVAtoms *ref = av_dynarray2_add((void**)&atoms, &nb_atoms, sizeof(MOVAtoms), NULL);
9923 if (!ref) {
9924 ret = AVERROR(ENOMEM);
9925 goto fail;
9926 }
9927 ref->data = NULL;
9928 ref->size = avio_rb32(pb);
9929 ref->type = avio_rl32(pb);
9930 if (ref->size > a.size || ref->size < 8)
9931 break;
9932 ref->data = av_malloc(ref->size);
9933 if (!ref->data) {
9934 ret = AVERROR_INVALIDDATA;
9935 goto fail;
9936 }
9937 av_log(c->fc, AV_LOG_TRACE, "ipco: index %d, box type %s\n", nb_atoms, av_fourcc2str(ref->type));
9938 avio_seek(pb, -8, SEEK_CUR);
9939 if (avio_read(pb, ref->data, ref->size) != ref->size) {
9940 ret = AVERROR_INVALIDDATA;
9941 goto fail;
9942 }
9943 ffio_init_read_context(&ref->b, ref->data, ref->size);
9944 a.size -= ref->size;
9945 }
9946
9947 if (a.size) {
9948 ret = AVERROR_INVALIDDATA;
9949 goto fail;
9950 }
9951
9952 a.size = avio_rb32(pb);
9953 a.type = avio_rl32(pb);
9954
9955 if (a.size < 8 || a.type != MKTAG('i','p','m','a')) {
9956 ret = AVERROR_INVALIDDATA;
9957 goto fail;
9958 }
9959
9960 version = avio_r8(pb);
9961 flags = avio_rb24(pb);
9962 count = avio_rb32(pb);
9963
9964 for (int i = 0; i < count; i++) {
9965 int item_id = version ? avio_rb32(pb) : avio_rb16(pb);
9966 int assoc_count = avio_r8(pb);
9967
9968 if (avio_feof(pb)) {
9969 ret = AVERROR_INVALIDDATA;
9970 goto fail;
9971 }
9972
9973 for (int j = 0; j < assoc_count; j++) {
9974 MOVAtoms *ref;
9975 int index = avio_r8(pb) & 0x7f;
9976 if (flags & 1) {
9977 index <<= 8;
9978 index |= avio_r8(pb);
9979 }
9980 if (index > nb_atoms || index <= 0) {
9981 ret = AVERROR_INVALIDDATA;
9982 goto fail;
9983 }
9984 ref = &atoms[--index];
9985
9986 av_log(c->fc, AV_LOG_TRACE, "ipma: property_index %d, item_id %d, item_type %s\n",
9987 index + 1, item_id, av_fourcc2str(ref->type));
9988
9989 c->cur_item_id = item_id;
9990
9991 ret = mov_read_default(c, &ref->b.pub,
9992 (MOVAtom) { .size = ref->size,
9993 .type = MKTAG('i','p','c','o') });
9994 if (ret < 0)
9995 goto fail;
9996 ffio_init_read_context(&ref->b, ref->data, ref->size);
9997 }
9998 }
9999
10000 ret = 0;
10001fail:
10002 c->cur_item_id = -1;
10003 for (int i = 0; i < nb_atoms; i++)
10004 av_free(atoms[i].data);
10005 av_free(atoms);
10006
10007 return ret;
10008}
10009
10011{
10012 avio_rb32(pb); // version & flags
10013 uint16_t graphics_mode = avio_rb16(pb);
10014 // ignored: opcolor[3]
10015
10016 if (c->fc->nb_streams < 1)
10017 return 0;
10018 AVStream *st = c->fc->streams[c->fc->nb_streams - 1];
10020 return 0;
10021
10022 switch (graphics_mode) {
10026 break;
10029 break;
10032 break;
10033 default:
10035 av_log(c->fc, AV_LOG_WARNING, "Unhandled graphics mode: 0x%x\n",
10036 graphics_mode);
10037 break;
10038 }
10039
10040 return 0;
10041}
10042
10044{ MKTAG('A','C','L','R'), mov_read_aclr },
10045{ MKTAG('A','P','R','G'), mov_read_avid },
10046{ MKTAG('A','A','L','P'), mov_read_avid },
10047{ MKTAG('A','R','E','S'), mov_read_ares },
10048{ MKTAG('a','v','s','s'), mov_read_avss },
10049{ MKTAG('a','v','1','C'), mov_read_glbl },
10050{ MKTAG('c','h','p','l'), mov_read_chpl },
10051{ MKTAG('c','o','6','4'), mov_read_stco },
10052{ MKTAG('c','o','l','r'), mov_read_colr },
10053{ MKTAG('c','t','t','s'), mov_read_ctts }, /* composition time to sample */
10054{ MKTAG('d','i','n','f'), mov_read_default },
10055{ MKTAG('D','p','x','E'), mov_read_dpxe },
10056{ MKTAG('d','r','e','f'), mov_read_dref },
10057{ MKTAG('e','d','t','s'), mov_read_default },
10058{ MKTAG('e','l','s','t'), mov_read_elst },
10059{ MKTAG('e','n','d','a'), mov_read_enda },
10060{ MKTAG('f','i','e','l'), mov_read_fiel },
10061{ MKTAG('a','d','r','m'), mov_read_adrm },
10062{ MKTAG('f','t','y','p'), mov_read_ftyp },
10063{ MKTAG('g','l','b','l'), mov_read_glbl },
10064{ MKTAG('h','d','l','r'), mov_read_hdlr },
10065{ MKTAG('i','l','s','t'), mov_read_ilst },
10066{ MKTAG('j','p','2','h'), mov_read_jp2h },
10067{ MKTAG('m','d','a','t'), mov_read_mdat },
10068{ MKTAG('m','d','h','d'), mov_read_mdhd },
10069{ MKTAG('m','d','i','a'), mov_read_default },
10070{ MKTAG('m','e','t','a'), mov_read_meta },
10071{ MKTAG('m','i','n','f'), mov_read_default },
10072{ MKTAG('m','o','o','f'), mov_read_moof },
10073{ MKTAG('m','o','o','v'), mov_read_moov },
10074{ MKTAG('m','v','e','x'), mov_read_default },
10075{ MKTAG('m','v','h','d'), mov_read_mvhd },
10076{ MKTAG('S','M','I',' '), mov_read_svq3 },
10077{ MKTAG('a','l','a','c'), mov_read_alac }, /* alac specific atom */
10078{ MKTAG('a','v','c','C'), mov_read_glbl },
10079{ MKTAG('p','a','s','p'), mov_read_pasp },
10080{ MKTAG('c','l','a','p'), mov_read_clap },
10081{ MKTAG('c','d','s','c'), mov_read_cdsc_rndr },
10082{ MKTAG('r','n','d','r'), mov_read_cdsc_rndr },
10083{ MKTAG('s','b','a','s'), mov_read_sbas },
10084{ MKTAG('v','d','e','p'), mov_read_vdep },
10085{ MKTAG('s','i','d','x'), mov_read_sidx },
10086{ MKTAG('s','t','b','l'), mov_read_default },
10087{ MKTAG('s','t','c','o'), mov_read_stco },
10088{ MKTAG('s','t','p','s'), mov_read_stps },
10089{ MKTAG('s','t','r','f'), mov_read_strf },
10090{ MKTAG('s','t','s','c'), mov_read_stsc },
10091{ MKTAG('s','t','s','d'), mov_read_stsd }, /* sample description */
10092{ MKTAG('s','t','s','s'), mov_read_stss }, /* sync sample */
10093{ MKTAG('s','t','s','z'), mov_read_stsz }, /* sample size */
10094{ MKTAG('s','t','t','s'), mov_read_stts },
10095{ MKTAG('s','t','z','2'), mov_read_stsz }, /* compact sample size */
10096{ MKTAG('s','d','t','p'), mov_read_sdtp }, /* independent and disposable samples */
10097{ MKTAG('t','k','h','d'), mov_read_tkhd }, /* track header */
10098{ MKTAG('t','f','d','t'), mov_read_tfdt },
10099{ MKTAG('t','f','h','d'), mov_read_tfhd }, /* track fragment header */
10100{ MKTAG('t','r','a','k'), mov_read_trak },
10101{ MKTAG('t','r','a','f'), mov_read_default },
10102{ MKTAG('t','r','e','f'), mov_read_default },
10103{ MKTAG('t','m','c','d'), mov_read_tmcd },
10104{ MKTAG('c','h','a','p'), mov_read_chap },
10105{ MKTAG('t','r','e','x'), mov_read_trex },
10106{ MKTAG('t','r','u','n'), mov_read_trun },
10107{ MKTAG('u','d','t','a'), mov_read_default },
10108{ MKTAG('w','a','v','e'), mov_read_wave },
10109{ MKTAG('e','s','d','s'), mov_read_esds },
10110{ MKTAG('d','a','c','3'), mov_read_dac3 }, /* AC-3 info */
10111{ MKTAG('d','e','c','3'), mov_read_dec3 }, /* EAC-3 info */
10112{ MKTAG('d','d','t','s'), mov_read_ddts }, /* DTS audio descriptor */
10113{ MKTAG('w','i','d','e'), mov_read_wide }, /* place holder */
10114{ MKTAG('w','f','e','x'), mov_read_wfex },
10115{ MKTAG('c','m','o','v'), mov_read_cmov },
10116{ MKTAG('c','h','a','n'), mov_read_chan }, /* channel layout from quicktime */
10117{ MKTAG('c','h','n','l'), mov_read_chnl }, /* channel layout from ISO-14496-12 */
10118{ MKTAG('d','v','c','1'), mov_read_dvc1 },
10119{ MKTAG('s','g','p','d'), mov_read_sgpd },
10120{ MKTAG('s','b','g','p'), mov_read_sbgp },
10121{ MKTAG('h','v','c','C'), mov_read_glbl },
10122{ MKTAG('v','v','c','C'), mov_read_glbl },
10123{ MKTAG('u','u','i','d'), mov_read_uuid },
10124{ MKTAG('C','i','n', 0x8e), mov_read_targa_y216 },
10125{ MKTAG('f','r','e','e'), mov_read_free },
10126{ MKTAG('-','-','-','-'), mov_read_custom },
10127{ MKTAG('s','i','n','f'), mov_read_default },
10128{ MKTAG('f','r','m','a'), mov_read_frma },
10129{ MKTAG('s','e','n','c'), mov_read_senc },
10130{ MKTAG('s','a','i','z'), mov_read_saiz },
10131{ MKTAG('s','a','i','o'), mov_read_saio },
10132{ MKTAG('p','s','s','h'), mov_read_pssh },
10133{ MKTAG('s','c','h','m'), mov_read_schm },
10134{ MKTAG('s','c','h','i'), mov_read_default },
10135{ MKTAG('t','e','n','c'), mov_read_tenc },
10136{ MKTAG('d','f','L','a'), mov_read_dfla },
10137{ MKTAG('s','t','3','d'), mov_read_st3d }, /* stereoscopic 3D video box */
10138{ MKTAG('s','v','3','d'), mov_read_sv3d }, /* spherical video box */
10139{ MKTAG('v','e','x','u'), mov_read_vexu }, /* video extension usage */
10140{ MKTAG('h','f','o','v'), mov_read_hfov },
10141{ MKTAG('d','O','p','s'), mov_read_dops },
10142{ MKTAG('d','m','l','p'), mov_read_dmlp },
10143{ MKTAG('S','m','D','m'), mov_read_smdm },
10144{ MKTAG('C','o','L','L'), mov_read_coll },
10145{ MKTAG('v','p','c','C'), mov_read_vpcc },
10146{ MKTAG('m','d','c','v'), mov_read_mdcv },
10147{ MKTAG('c','l','l','i'), mov_read_clli },
10148{ MKTAG('d','v','c','C'), mov_read_dvcc_dvvc },
10149{ MKTAG('d','v','v','C'), mov_read_dvcc_dvvc },
10150{ MKTAG('d','v','w','C'), mov_read_dvcc_dvvc },
10151{ MKTAG('h','v','c','E'), mov_read_hvce },
10152{ MKTAG('k','i','n','d'), mov_read_kind },
10153{ MKTAG('S','A','3','D'), mov_read_SA3D }, /* ambisonic audio box */
10154{ MKTAG('S','A','N','D'), mov_read_SAND }, /* non diegetic audio box */
10155{ MKTAG('i','l','o','c'), mov_read_iloc },
10156{ MKTAG('p','c','m','C'), mov_read_pcmc }, /* PCM configuration box */
10157{ MKTAG('p','i','t','m'), mov_read_pitm },
10158{ MKTAG('e','v','c','C'), mov_read_glbl },
10159{ MKTAG('i','d','a','t'), mov_read_idat },
10160{ MKTAG('i','m','i','r'), mov_read_imir },
10161{ MKTAG('i','r','e','f'), mov_read_iref },
10162{ MKTAG('i','s','p','e'), mov_read_ispe },
10163{ MKTAG('i','r','o','t'), mov_read_irot },
10164{ MKTAG('i','p','r','p'), mov_read_iprp },
10165{ MKTAG('i','i','n','f'), mov_read_iinf },
10166{ MKTAG('a','m','v','e'), mov_read_amve }, /* ambient viewing environment box */
10167{ MKTAG('l','h','v','C'), mov_read_lhvc },
10168{ MKTAG('l','v','c','C'), mov_read_glbl },
10169{ MKTAG('a','p','v','C'), mov_read_glbl },
10170#if CONFIG_IAMFDEC
10171{ MKTAG('i','a','c','b'), mov_read_iacb },
10172#endif
10173{ MKTAG('s','r','a','t'), mov_read_srat },
10174{ MKTAG('v','m','h','d'), mov_read_vmhd },
10175{ 0, NULL }
10176};
10177
10179{
10180 int64_t total_size = 0;
10181 MOVAtom a;
10182 int i;
10183
10184 if (c->atom_depth > 10) {
10185 av_log(c->fc, AV_LOG_ERROR, "Atoms too deeply nested\n");
10186 return AVERROR_INVALIDDATA;
10187 }
10188 c->atom_depth ++;
10189
10190 if (atom.size < 0)
10191 atom.size = INT64_MAX;
10192 while (total_size <= atom.size - 8) {
10193 int (*parse)(MOVContext*, AVIOContext*, MOVAtom) = NULL;
10194 a.size = avio_rb32(pb);
10195 a.type = avio_rl32(pb);
10196 if (avio_feof(pb))
10197 break;
10198 if (((a.type == MKTAG('f','r','e','e') && c->moov_retry) ||
10199 a.type == MKTAG('h','o','o','v')) &&
10200 a.size >= 8 &&
10201 c->fc->strict_std_compliance < FF_COMPLIANCE_STRICT) {
10202 uint32_t type;
10203 avio_skip(pb, 4);
10204 type = avio_rl32(pb);
10205 if (avio_feof(pb))
10206 break;
10207 avio_seek(pb, -8, SEEK_CUR);
10208 if (type == MKTAG('m','v','h','d') ||
10209 type == MKTAG('c','m','o','v')) {
10210 av_log(c->fc, AV_LOG_ERROR, "Detected moov in a free or hoov atom.\n");
10211 a.type = MKTAG('m','o','o','v');
10212 }
10213 }
10214 if (atom.type != MKTAG('r','o','o','t') &&
10215 atom.type != MKTAG('m','o','o','v')) {
10216 if (a.type == MKTAG('t','r','a','k') ||
10217 a.type == MKTAG('m','d','a','t')) {
10218 av_log(c->fc, AV_LOG_ERROR, "Broken file, trak/mdat not at top-level\n");
10219 avio_skip(pb, -8);
10220 c->atom_depth --;
10221 return 0;
10222 }
10223 }
10224 total_size += 8;
10225 if (a.size == 1 && total_size + 8 <= atom.size) { /* 64 bit extended size */
10226 a.size = avio_rb64(pb) - 8;
10227 total_size += 8;
10228 }
10229 av_log(c->fc, AV_LOG_TRACE, "type:'%s' parent:'%s' sz: %"PRId64" %"PRId64" %"PRId64"\n",
10230 av_fourcc2str(a.type), av_fourcc2str(atom.type), a.size, total_size, atom.size);
10231 if (a.size == 0) {
10232 a.size = atom.size - total_size + 8;
10233 }
10234 if (a.size < 0)
10235 break;
10236 a.size -= 8;
10237 if (a.size < 0)
10238 break;
10239 a.size = FFMIN(a.size, atom.size - total_size);
10240
10241 for (i = 0; mov_default_parse_table[i].type; i++)
10242 if (mov_default_parse_table[i].type == a.type) {
10244 break;
10245 }
10246
10247 // container is user data
10248 if (!parse && (atom.type == MKTAG('u','d','t','a') ||
10249 atom.type == MKTAG('i','l','s','t')))
10251
10252 // Supports parsing the QuickTime Metadata Keys.
10253 // https://developer.apple.com/library/mac/documentation/QuickTime/QTFF/Metadata/Metadata.html
10254 if (!parse && c->found_hdlr_mdta &&
10255 atom.type == MKTAG('m','e','t','a') &&
10256 a.type == MKTAG('k','e','y','s') &&
10257 c->meta_keys_count == 0) {
10259 }
10260
10261 if (!parse) { /* skip leaf atoms data */
10262 avio_skip(pb, a.size);
10263 } else {
10264 int64_t start_pos = avio_tell(pb);
10265 int64_t left;
10266 int err = parse(c, pb, a);
10267 if (err < 0) {
10268 c->atom_depth --;
10269 return err;
10270 }
10271 if (c->found_moov && c->found_mdat && a.size <= INT64_MAX - start_pos &&
10272 ((!(pb->seekable & AVIO_SEEKABLE_NORMAL) || c->fc->flags & AVFMT_FLAG_IGNIDX || c->frag_index.complete) ||
10273 start_pos + a.size == avio_size(pb))) {
10274 if (!(pb->seekable & AVIO_SEEKABLE_NORMAL) || c->fc->flags & AVFMT_FLAG_IGNIDX || c->frag_index.complete)
10275 c->next_root_atom = start_pos + a.size;
10276 c->atom_depth --;
10277 return 0;
10278 }
10279 left = a.size - avio_tell(pb) + start_pos;
10280 if (left > 0) /* skip garbage at atom end */
10281 avio_skip(pb, left);
10282 else if (left < 0) {
10283 av_log(c->fc, AV_LOG_WARNING,
10284 "overread end of atom '%s' by %"PRId64" bytes\n",
10285 av_fourcc2str(a.type), -left);
10286 avio_seek(pb, left, SEEK_CUR);
10287 }
10288 }
10289
10290 total_size += a.size;
10291 }
10292
10293 if (total_size < atom.size && atom.size < 0x7ffff)
10294 avio_skip(pb, atom.size - total_size);
10295
10296 c->atom_depth --;
10297 return 0;
10298}
10299
10300static int mov_probe(const AVProbeData *p)
10301{
10303 uint32_t tag;
10304 int score = 0;
10305 int moov_offset = -1;
10306
10307 /* check file header */
10308 offset = 0;
10309 for (;;) {
10310 int64_t size;
10311 int minsize = 8;
10312 /* ignore invalid offset */
10313 if ((offset + 8ULL) > (unsigned int)p->buf_size)
10314 break;
10315 size = AV_RB32(p->buf + offset);
10316 if (size == 1 && offset + 16 <= (unsigned int)p->buf_size) {
10317 size = AV_RB64(p->buf+offset + 8);
10318 minsize = 16;
10319 } else if (size == 0) {
10320 size = p->buf_size - offset;
10321 }
10322 if (size < minsize) {
10323 offset += 4;
10324 continue;
10325 }
10326 tag = AV_RL32(p->buf + offset + 4);
10327 switch(tag) {
10328 /* check for obvious tags */
10329 case MKTAG('m','o','o','v'):
10330 moov_offset = offset + 4;
10332 case MKTAG('m','d','a','t'):
10333 case MKTAG('p','n','o','t'): /* detect movs with preview pics like ew.mov and april.mov */
10334 case MKTAG('u','d','t','a'): /* Packet Video PVAuthor adds this and a lot of more junk */
10335 case MKTAG('f','t','y','p'):
10336 if (tag == MKTAG('f','t','y','p') &&
10337 ( AV_RL32(p->buf + offset + 8) == MKTAG('j','p','2',' ')
10338 || AV_RL32(p->buf + offset + 8) == MKTAG('j','p','x',' ')
10339 || AV_RL32(p->buf + offset + 8) == MKTAG('j','x','l',' ')
10340 )) {
10341 score = FFMAX(score, 5);
10342 } else {
10343 score = AVPROBE_SCORE_MAX;
10344 }
10345 break;
10346 /* those are more common words, so rate then a bit less */
10347 case MKTAG('e','d','i','w'): /* xdcam files have reverted first tags */
10348 case MKTAG('w','i','d','e'):
10349 case MKTAG('f','r','e','e'):
10350 case MKTAG('j','u','n','k'):
10351 case MKTAG('p','i','c','t'):
10352 score = FFMAX(score, AVPROBE_SCORE_MAX - 5);
10353 break;
10354 case MKTAG(0x82,0x82,0x7f,0x7d):
10355 score = FFMAX(score, AVPROBE_SCORE_EXTENSION - 5);
10356 break;
10357 case MKTAG('s','k','i','p'):
10358 case MKTAG('u','u','i','d'):
10359 case MKTAG('p','r','f','l'):
10360 /* if we only find those cause probedata is too small at least rate them */
10361 score = FFMAX(score, AVPROBE_SCORE_EXTENSION);
10362 break;
10363 }
10364 if (size > INT64_MAX - offset)
10365 break;
10366 offset += size;
10367 }
10368 if (score > AVPROBE_SCORE_MAX - 50 && moov_offset != -1) {
10369 /* moov atom in the header - we should make sure that this is not a
10370 * MOV-packed MPEG-PS */
10371 offset = moov_offset;
10372
10373 while (offset < (p->buf_size - 16)) { /* Sufficient space */
10374 /* We found an actual hdlr atom */
10375 if (AV_RL32(p->buf + offset ) == MKTAG('h','d','l','r') &&
10376 AV_RL32(p->buf + offset + 8) == MKTAG('m','h','l','r') &&
10377 AV_RL32(p->buf + offset + 12) == MKTAG('M','P','E','G')) {
10378 av_log(NULL, AV_LOG_WARNING, "Found media data tag MPEG indicating this is a MOV-packed MPEG-PS.\n");
10379 /* We found a media handler reference atom describing an
10380 * MPEG-PS-in-MOV, return a
10381 * low score to force expanding the probe window until
10382 * mpegps_probe finds what it needs */
10383 return 5;
10384 } else {
10385 /* Keep looking */
10386 offset += 2;
10387 }
10388 }
10389 }
10390
10391 return score;
10392}
10393
10394// must be done after parsing all trak because there's no order requirement
10396{
10397 MOVContext *mov = s->priv_data;
10398 MOVStreamContext *sc;
10399 int64_t cur_pos;
10400 int i, j;
10401 int chapter_track;
10402
10403 for (j = 0; j < mov->nb_chapter_tracks; j++) {
10404 AVStream *st = NULL;
10405 FFStream *sti = NULL;
10406 chapter_track = mov->chapter_tracks[j];
10407 for (i = 0; i < s->nb_streams; i++) {
10408 sc = mov->fc->streams[i]->priv_data;
10409 if (sc->id == chapter_track) {
10410 st = s->streams[i];
10411 break;
10412 }
10413 }
10414 if (!st) {
10415 av_log(s, AV_LOG_ERROR, "Referenced QT chapter track not found\n");
10416 continue;
10417 }
10418 sti = ffstream(st);
10419
10420 sc = st->priv_data;
10421 cur_pos = avio_tell(sc->pb);
10422
10425 if (!st->attached_pic.data && sti->nb_index_entries) {
10426 // Retrieve the first frame, if possible
10427 AVIndexEntry *sample = &sti->index_entries[0];
10428 if (avio_seek(sc->pb, sample->pos, SEEK_SET) != sample->pos) {
10429 av_log(s, AV_LOG_ERROR, "Failed to retrieve first frame\n");
10430 goto finish;
10431 }
10432
10433 if (ff_add_attached_pic(s, st, sc->pb, NULL, sample->size) < 0)
10434 goto finish;
10435 }
10436 } else {
10439 st->discard = AVDISCARD_ALL;
10440 for (int i = 0; i < sti->nb_index_entries; i++) {
10442 int64_t end = i+1 < sti->nb_index_entries ? sti->index_entries[i+1].timestamp : st->duration;
10443 uint8_t *title;
10444 uint16_t ch;
10445 int len, title_len;
10446
10447 if (end < sample->timestamp) {
10448 av_log(s, AV_LOG_WARNING, "ignoring stream duration which is shorter than chapters\n");
10449 end = AV_NOPTS_VALUE;
10450 }
10451
10452 if (avio_seek(sc->pb, sample->pos, SEEK_SET) != sample->pos) {
10453 av_log(s, AV_LOG_ERROR, "Chapter %d not found in file\n", i);
10454 goto finish;
10455 }
10456
10457 // the first two bytes are the length of the title
10458 len = avio_rb16(sc->pb);
10459 if (len > sample->size-2)
10460 continue;
10461 title_len = 2*len + 1;
10462 if (!(title = av_mallocz(title_len)))
10463 goto finish;
10464
10465 // The samples could theoretically be in any encoding if there's an encd
10466 // atom following, but in practice are only utf-8 or utf-16, distinguished
10467 // instead by the presence of a BOM
10468 if (!len) {
10469 title[0] = 0;
10470 } else {
10471 ch = avio_rb16(sc->pb);
10472 if (ch == 0xfeff)
10473 avio_get_str16be(sc->pb, len, title, title_len);
10474 else if (ch == 0xfffe)
10475 avio_get_str16le(sc->pb, len, title, title_len);
10476 else {
10477 AV_WB16(title, ch);
10478 if (len == 1 || len == 2)
10479 title[len] = 0;
10480 else
10481 avio_get_str(sc->pb, INT_MAX, title + 2, len - 1);
10482 }
10483 }
10484
10485 avpriv_new_chapter(s, i, st->time_base, sample->timestamp, end, title);
10486 av_freep(&title);
10487 }
10488 }
10489finish:
10490 avio_seek(sc->pb, cur_pos, SEEK_SET);
10491 }
10492}
10493
10495 int64_t value, int flags)
10496{
10497 AVTimecode tc;
10498 char buf[AV_TIMECODE_STR_SIZE];
10499 AVRational rate = st->avg_frame_rate;
10500 int ret = av_timecode_init(&tc, rate, flags, 0, s);
10501 if (ret < 0)
10502 return ret;
10503 av_dict_set(&st->metadata, "timecode",
10504 av_timecode_make_string(&tc, buf, value), 0);
10505 return 0;
10506}
10507
10509{
10510 MOVStreamContext *sc = st->priv_data;
10511 FFStream *const sti = ffstream(st);
10512 char buf[AV_TIMECODE_STR_SIZE];
10513 int64_t cur_pos = avio_tell(sc->pb);
10514 int hh, mm, ss, ff, drop;
10515
10516 if (!sti->nb_index_entries)
10517 return -1;
10518
10519 avio_seek(sc->pb, sti->index_entries->pos, SEEK_SET);
10520 avio_skip(s->pb, 13);
10521 hh = avio_r8(s->pb);
10522 mm = avio_r8(s->pb);
10523 ss = avio_r8(s->pb);
10524 drop = avio_r8(s->pb);
10525 ff = avio_r8(s->pb);
10526 snprintf(buf, AV_TIMECODE_STR_SIZE, "%02d:%02d:%02d%c%02d",
10527 hh, mm, ss, drop ? ';' : ':', ff);
10528 av_dict_set(&st->metadata, "timecode", buf, 0);
10529
10530 avio_seek(sc->pb, cur_pos, SEEK_SET);
10531 return 0;
10532}
10533
10535{
10536 MOVStreamContext *sc = st->priv_data;
10537 FFStream *const sti = ffstream(st);
10538 int flags = 0;
10539 int64_t cur_pos = avio_tell(sc->pb);
10540 int64_t value;
10541 AVRational tc_rate = st->avg_frame_rate;
10542 int tmcd_nb_frames = sc->tmcd_nb_frames;
10543 int rounded_tc_rate;
10544
10545 if (!sti->nb_index_entries)
10546 return -1;
10547
10548 if (!tc_rate.num || !tc_rate.den || !tmcd_nb_frames)
10549 return -1;
10550
10551 avio_seek(sc->pb, sti->index_entries->pos, SEEK_SET);
10552 value = avio_rb32(s->pb);
10553
10554 if (sc->tmcd_flags & 0x0001) flags |= AV_TIMECODE_FLAG_DROPFRAME;
10555 if (sc->tmcd_flags & 0x0002) flags |= AV_TIMECODE_FLAG_24HOURSMAX;
10556 if (sc->tmcd_flags & 0x0004) flags |= AV_TIMECODE_FLAG_ALLOWNEGATIVE;
10557
10558 /* Assume Counter flag is set to 1 in tmcd track (even though it is likely
10559 * not the case) and thus assume "frame number format" instead of QT one.
10560 * No sample with tmcd track can be found with a QT timecode at the moment,
10561 * despite what the tmcd track "suggests" (Counter flag set to 0 means QT
10562 * format). */
10563
10564 /* 60 fps content have tmcd_nb_frames set to 30 but tc_rate set to 60, so
10565 * we multiply the frame number with the quotient.
10566 * See tickets #9492, #9710. */
10567 rounded_tc_rate = (tc_rate.num + tc_rate.den / 2LL) / tc_rate.den;
10568 /* Work around files where tmcd_nb_frames is rounded down from frame rate
10569 * instead of up. See ticket #5978. */
10570 if (tmcd_nb_frames == tc_rate.num / tc_rate.den &&
10571 s->strict_std_compliance < FF_COMPLIANCE_STRICT)
10572 tmcd_nb_frames = rounded_tc_rate;
10573 value = av_rescale(value, rounded_tc_rate, tmcd_nb_frames);
10574
10576
10577 avio_seek(sc->pb, cur_pos, SEEK_SET);
10578 return 0;
10579}
10580
10582 int i;
10583 if (!index || !*index) return;
10584 for (i = 0; i < (*index)->nb_encrypted_samples; i++) {
10585 av_encryption_info_free((*index)->encrypted_samples[i]);
10586 }
10587 av_freep(&(*index)->encrypted_samples);
10588 av_freep(&(*index)->auxiliary_info_sizes);
10589 av_freep(&(*index)->auxiliary_offsets);
10590 av_freep(index);
10591}
10592
10594{
10595 MOVStreamContext *sc = st->priv_data;
10596
10597 if (!sc || --sc->refcount) {
10598 st->priv_data = NULL;
10599 return;
10600 }
10601
10602 av_freep(&sc->tts_data);
10603 for (int i = 0; i < sc->drefs_count; i++) {
10604 av_freep(&sc->drefs[i].path);
10605 av_freep(&sc->drefs[i].dir);
10606 }
10607 av_freep(&sc->drefs);
10608
10609 sc->drefs_count = 0;
10610
10611 if (!sc->pb_is_copied)
10612 ff_format_io_close(s, &sc->pb);
10613
10614 sc->pb = NULL;
10615 av_freep(&sc->chunk_offsets);
10616 av_freep(&sc->stsc_data);
10617 av_freep(&sc->sample_sizes);
10618 av_freep(&sc->keyframes);
10619 av_freep(&sc->ctts_data);
10620 av_freep(&sc->stts_data);
10621 av_freep(&sc->sdtp_data);
10622 av_freep(&sc->stps_data);
10623 av_freep(&sc->elst_data);
10624 av_freep(&sc->rap_group);
10625 av_freep(&sc->sync_group);
10626 av_freep(&sc->sgpd_sync);
10630 av_freep(&sc->index_ranges);
10631 for (int i = 0; i < sc->nb_tref_tags; i++)
10632 av_freep(&sc->tref_tags[i].id);
10633 av_freep(&sc->tref_tags);
10634
10635 if (sc->extradata)
10636 for (int i = 0; i < sc->stsd_count; i++)
10637 av_free(sc->extradata[i]);
10638 av_freep(&sc->extradata);
10640
10644
10645 av_freep(&sc->stereo3d);
10646 av_freep(&sc->spherical);
10647 av_freep(&sc->mastering);
10648 av_freep(&sc->coll);
10649 av_freep(&sc->ambient);
10650
10651#if CONFIG_IAMFDEC
10652 if (sc->iamf)
10654#endif
10655 av_freep(&sc->iamf);
10656}
10657
10659{
10660 MOVContext *mov = s->priv_data;
10661 int i, j;
10662
10663 for (i = 0; i < s->nb_streams; i++) {
10664 AVStream *st = s->streams[i];
10665
10667 }
10668
10669 av_freep(&mov->dv_demux);
10671 mov->dv_fctx = NULL;
10672
10673 if (mov->meta_keys) {
10674 for (i = 1; i < mov->meta_keys_count; i++) {
10675 av_freep(&mov->meta_keys[i]);
10676 }
10677 av_freep(&mov->meta_keys);
10678 }
10679
10680 av_freep(&mov->trex_data);
10681 av_freep(&mov->bitrates);
10682
10683 for (i = 0; i < mov->frag_index.nb_items; i++) {
10685 for (j = 0; j < mov->frag_index.item[i].nb_stream_info; j++) {
10686 mov_free_encryption_index(&frag[j].encryption_index);
10687 }
10689 }
10690 av_freep(&mov->frag_index.item);
10691
10692 av_freep(&mov->aes_decrypt);
10693 av_freep(&mov->chapter_tracks);
10694 for (i = 0; i < mov->nb_heif_item; i++) {
10695 if (!mov->heif_item[i])
10696 continue;
10697 av_freep(&mov->heif_item[i]->name);
10698 av_freep(&mov->heif_item[i]->iref_list);
10700 av_freep(&mov->heif_item[i]);
10701 }
10702 av_freep(&mov->heif_item);
10703 for (i = 0; i < mov->nb_heif_grid; i++) {
10707 }
10708 av_freep(&mov->heif_grid);
10709
10710 return 0;
10711}
10712
10713static int tmcd_is_referenced(AVFormatContext *s, int tmcd_id)
10714{
10715 int i;
10716
10717 for (i = 0; i < s->nb_streams; i++) {
10718 AVStream *st = s->streams[i];
10719 MOVStreamContext *sc = st->priv_data;
10720 MovTref *tag = mov_find_tref_tag(sc, MKTAG('t','m','c','d'));
10721
10722 if (!tag)
10723 continue;
10724 if (mov_find_tref_id(tag, tmcd_id))
10725 return 1;
10726 }
10727 return 0;
10728}
10729
10730/* look for a tmcd track not referenced by any video track, and export it globally */
10732{
10733 int i;
10734
10735 for (i = 0; i < s->nb_streams; i++) {
10736 AVStream *st = s->streams[i];
10737
10738 if (st->codecpar->codec_tag == MKTAG('t','m','c','d') &&
10739 !tmcd_is_referenced(s, st->id)) {
10740 AVDictionaryEntry *tcr = av_dict_get(st->metadata, "timecode", NULL, 0);
10741 if (tcr) {
10742 av_dict_set(&s->metadata, "timecode", tcr->value, 0);
10743 break;
10744 }
10745 }
10746 }
10747}
10748
10750{
10751 int version, fieldlength, i, j;
10753 uint32_t size = avio_rb32(f);
10754 unsigned track_id, item_count;
10755
10756 if (avio_rb32(f) != MKBETAG('t', 'f', 'r', 'a')) {
10757 return 1;
10758 }
10759 av_log(mov->fc, AV_LOG_VERBOSE, "found tfra\n");
10760
10761 version = avio_r8(f);
10762 avio_rb24(f);
10763 track_id = avio_rb32(f);
10764 fieldlength = avio_rb32(f);
10765 item_count = avio_rb32(f);
10766 for (i = 0; i < item_count; i++) {
10767 int64_t time, offset;
10768 int index;
10769 MOVFragmentStreamInfo * frag_stream_info;
10770
10771 if (avio_feof(f)) {
10772 return AVERROR_INVALIDDATA;
10773 }
10774
10775 if (version == 1) {
10776 time = avio_rb64(f);
10777 offset = avio_rb64(f);
10778 } else {
10779 time = avio_rb32(f);
10780 offset = avio_rb32(f);
10781 }
10782
10783 // The first sample of each stream in a fragment is always a random
10784 // access sample. So it's entry in the tfra can be used as the
10785 // initial PTS of the fragment.
10787 frag_stream_info = get_frag_stream_info(&mov->frag_index, index, track_id);
10788 if (frag_stream_info &&
10789 frag_stream_info->first_tfra_pts == AV_NOPTS_VALUE)
10790 frag_stream_info->first_tfra_pts = time;
10791
10792 for (j = 0; j < ((fieldlength >> 4) & 3) + 1; j++)
10793 avio_r8(f);
10794 for (j = 0; j < ((fieldlength >> 2) & 3) + 1; j++)
10795 avio_r8(f);
10796 for (j = 0; j < ((fieldlength >> 0) & 3) + 1; j++)
10797 avio_r8(f);
10798 }
10799
10800 avio_seek(f, pos + size, SEEK_SET);
10801 return 0;
10802}
10803
10805{
10806 int64_t stream_size = avio_size(f);
10807 int64_t original_pos = avio_tell(f);
10808 int64_t seek_ret;
10809 int ret = -1;
10810 if ((seek_ret = avio_seek(f, stream_size - 4, SEEK_SET)) < 0) {
10811 ret = seek_ret;
10812 goto fail;
10813 }
10814 c->mfra_size = avio_rb32(f);
10815 c->have_read_mfra_size = 1;
10816 if (!c->mfra_size || c->mfra_size > stream_size) {
10817 av_log(c->fc, AV_LOG_DEBUG, "doesn't look like mfra (unreasonable size)\n");
10818 goto fail;
10819 }
10820 if ((seek_ret = avio_seek(f, -((int64_t) c->mfra_size), SEEK_CUR)) < 0) {
10821 ret = seek_ret;
10822 goto fail;
10823 }
10824 if (avio_rb32(f) != c->mfra_size) {
10825 av_log(c->fc, AV_LOG_DEBUG, "doesn't look like mfra (size mismatch)\n");
10826 goto fail;
10827 }
10828 if (avio_rb32(f) != MKBETAG('m', 'f', 'r', 'a')) {
10829 av_log(c->fc, AV_LOG_DEBUG, "doesn't look like mfra (tag mismatch)\n");
10830 goto fail;
10831 }
10832 av_log(c->fc, AV_LOG_VERBOSE, "stream has mfra\n");
10833 do {
10834 ret = read_tfra(c, f);
10835 if (ret < 0)
10836 goto fail;
10837 } while (!ret);
10838 ret = 0;
10839 c->frag_index.complete = 1;
10840fail:
10841 seek_ret = avio_seek(f, original_pos, SEEK_SET);
10842 if (seek_ret < 0) {
10843 av_log(c->fc, AV_LOG_ERROR,
10844 "failed to seek back after looking for mfra\n");
10845 ret = seek_ret;
10846 }
10847 return ret;
10848}
10849
10850static int set_icc_profile_from_item(AVPacketSideData **coded_side_data, int *nb_coded_side_data,
10851 const HEIFItem *item)
10852{
10853 AVPacketSideData *sd = av_packet_side_data_new(coded_side_data, nb_coded_side_data,
10855 item->icc_profile_size, 0);
10856 if (!sd)
10857 return AVERROR(ENOMEM);
10858
10859 memcpy(sd->data, item->icc_profile, item->icc_profile_size);
10860
10861 return 0;
10862}
10863
10864static int set_display_matrix_from_item(AVPacketSideData **coded_side_data, int *nb_coded_side_data,
10865 const HEIFItem *item)
10866{
10867 int32_t *matrix;
10868 AVPacketSideData *sd = av_packet_side_data_new(coded_side_data,
10869 nb_coded_side_data,
10871 9 * sizeof(*matrix), 0);
10872 if (!sd)
10873 return AVERROR(ENOMEM);
10874
10875 matrix = (int32_t*)sd->data;
10876 /* rotation is in the counter-clockwise direction whereas
10877 * av_display_rotation_set() expects its argument to be
10878 * oriented clockwise, so we need to negate it. */
10881
10882 return 0;
10883}
10884
10886 AVStreamGroupTileGrid *tile_grid)
10887{
10888 MOVContext *c = s->priv_data;
10889 const HEIFItem *item = grid->item;
10890 int64_t coded_width = 0, coded_height = 0;
10891 int64_t offset = 0, pos = avio_tell(s->pb);
10892 int64_t x = 0, y = 0;
10893 int i = 0;
10894 int tile_rows, tile_cols;
10895 int flags, size;
10896
10897 if (!(s->pb->seekable & AVIO_SEEKABLE_NORMAL)) {
10898 av_log(c->fc, AV_LOG_INFO, "grid box with non seekable input\n");
10899 return AVERROR_PATCHWELCOME;
10900 }
10901 if (item->is_idat_relative) {
10902 if (!c->idat_offset) {
10903 av_log(c->fc, AV_LOG_ERROR, "missing idat box required by the image grid\n");
10904 return AVERROR_INVALIDDATA;
10905 }
10906 offset = c->idat_offset;
10907 }
10908
10909 if (offset > INT64_MAX - item->extent_offset)
10910 return AVERROR_INVALIDDATA;
10911
10912 avio_seek(s->pb, item->extent_offset + offset, SEEK_SET);
10913
10914 avio_r8(s->pb); /* version */
10915 flags = avio_r8(s->pb);
10916
10917 tile_rows = avio_r8(s->pb) + 1;
10918 tile_cols = avio_r8(s->pb) + 1;
10919 /* actual width and height of output image */
10920 tile_grid->width = (flags & 1) ? avio_rb32(s->pb) : avio_rb16(s->pb);
10921 tile_grid->height = (flags & 1) ? avio_rb32(s->pb) : avio_rb16(s->pb);
10922
10923 av_log(c->fc, AV_LOG_TRACE, "grid: grid_rows %d grid_cols %d output_width %d output_height %d\n",
10924 tile_rows, tile_cols, tile_grid->width, tile_grid->height);
10925
10926 avio_seek(s->pb, pos, SEEK_SET);
10927
10929 tile_grid->nb_tiles = grid->nb_tiles;
10930
10931 if (tile_grid->nb_tiles != size)
10932 return AVERROR_INVALIDDATA;
10933
10934 for (int i = 0; i < tile_cols; i++)
10935 coded_width += grid->tile_item_list[i]->width;
10936 for (int i = 0; i < size; i += tile_cols)
10937 coded_height += grid->tile_item_list[i]->height;
10938
10939 if (coded_width > INT_MAX || coded_height > INT_MAX)
10940 return AVERROR_INVALIDDATA;
10941
10942 tile_grid->coded_width = coded_width;
10943 tile_grid->coded_height = coded_height;
10944
10945 tile_grid->offsets = av_calloc(tile_grid->nb_tiles, sizeof(*tile_grid->offsets));
10946 if (!tile_grid->offsets)
10947 return AVERROR(ENOMEM);
10948
10949 while (y < tile_grid->coded_height) {
10950 int left_col = i;
10951
10952 while (x < tile_grid->coded_width) {
10953 if (i == tile_grid->nb_tiles)
10954 return AVERROR_INVALIDDATA;
10955
10956 tile_grid->offsets[i].idx = grid->tile_idx_list[i];
10957 tile_grid->offsets[i].horizontal = x;
10958 tile_grid->offsets[i].vertical = y;
10959
10960 x += grid->tile_item_list[i++]->width;
10961 }
10962
10963 if (x > tile_grid->coded_width) {
10964 av_log(c->fc, AV_LOG_ERROR, "Non uniform HEIF tiles\n");
10965 return AVERROR_INVALIDDATA;
10966 }
10967
10968 x = 0;
10969 y += grid->tile_item_list[left_col]->height;
10970 }
10971
10972 if (y > tile_grid->coded_height || i != tile_grid->nb_tiles) {
10973 av_log(c->fc, AV_LOG_ERROR, "Non uniform HEIF tiles\n");
10974 return AVERROR_INVALIDDATA;
10975 }
10976
10977 return 0;
10978}
10979
10981 AVStreamGroupTileGrid *tile_grid)
10982{
10983 MOVContext *c = s->priv_data;
10984 const HEIFItem *item = grid->item;
10985 uint16_t canvas_fill_value[4];
10986 int64_t offset = 0, pos = avio_tell(s->pb);
10987 int ret = 0, flags;
10988
10989 if (!(s->pb->seekable & AVIO_SEEKABLE_NORMAL)) {
10990 av_log(c->fc, AV_LOG_INFO, "iovl box with non seekable input\n");
10991 return AVERROR_PATCHWELCOME;
10992 }
10993 if (item->is_idat_relative) {
10994 if (!c->idat_offset) {
10995 av_log(c->fc, AV_LOG_ERROR, "missing idat box required by the image overlay\n");
10996 return AVERROR_INVALIDDATA;
10997 }
10998 offset = c->idat_offset;
10999 }
11000
11001 if (offset > INT64_MAX - item->extent_offset)
11002 return AVERROR_INVALIDDATA;
11003
11004 avio_seek(s->pb, item->extent_offset + offset, SEEK_SET);
11005
11006 avio_r8(s->pb); /* version */
11007 flags = avio_r8(s->pb);
11008
11009 for (int i = 0; i < 4; i++)
11010 canvas_fill_value[i] = avio_rb16(s->pb);
11011 av_log(c->fc, AV_LOG_TRACE, "iovl: canvas_fill_value { %u, %u, %u, %u }\n",
11012 canvas_fill_value[0], canvas_fill_value[1],
11013 canvas_fill_value[2], canvas_fill_value[3]);
11014 for (int i = 0; i < 4; i++)
11015 tile_grid->background[i] = canvas_fill_value[i];
11016
11017 /* actual width and height of output image */
11018 tile_grid->width =
11019 tile_grid->coded_width = (flags & 1) ? avio_rb32(s->pb) : avio_rb16(s->pb);
11020 tile_grid->height =
11021 tile_grid->coded_height = (flags & 1) ? avio_rb32(s->pb) : avio_rb16(s->pb);
11022
11023 av_log(c->fc, AV_LOG_TRACE, "iovl: output_width %d, output_height %d\n",
11024 tile_grid->width, tile_grid->height);
11025
11026 tile_grid->nb_tiles = grid->nb_tiles;
11027 tile_grid->offsets = av_malloc_array(tile_grid->nb_tiles, sizeof(*tile_grid->offsets));
11028 if (!tile_grid->offsets) {
11029 ret = AVERROR(ENOMEM);
11030 goto fail;
11031 }
11032
11033 for (int i = 0; i < tile_grid->nb_tiles; i++) {
11034 tile_grid->offsets[i].idx = grid->tile_idx_list[i];
11035 tile_grid->offsets[i].horizontal = (flags & 1) ? avio_rb32(s->pb) : avio_rb16(s->pb);
11036 tile_grid->offsets[i].vertical = (flags & 1) ? avio_rb32(s->pb) : avio_rb16(s->pb);
11037 av_log(c->fc, AV_LOG_TRACE, "iovl: stream_idx[%d] %u, "
11038 "horizontal_offset[%d] %d, vertical_offset[%d] %d\n",
11039 i, tile_grid->offsets[i].idx,
11040 i, tile_grid->offsets[i].horizontal, i, tile_grid->offsets[i].vertical);
11041 }
11042
11043fail:
11044 avio_seek(s->pb, pos, SEEK_SET);
11045
11046 return ret;
11047}
11048
11050 AVPacketSideData **coded_side_data, int *nb_coded_side_data,
11051 const HEIFItem *ref)
11052{
11053 MOVContext *c = s->priv_data;
11054 AVPacketSideData *sd;
11055 AVExifMetadata ifd = { 0 };
11056 AVBufferRef *buf;
11057 int64_t offset = 0, pos = avio_tell(s->pb);
11058 unsigned orientation_id = av_exif_get_tag_id("Orientation");
11059 int err;
11060
11061 if (!(s->pb->seekable & AVIO_SEEKABLE_NORMAL)) {
11062 av_log(c->fc, AV_LOG_WARNING, "Exif metadata with non seekable input\n");
11063 return AVERROR_PATCHWELCOME;
11064 }
11065 if (ref->is_idat_relative) {
11066 if (!c->idat_offset) {
11067 av_log(c->fc, AV_LOG_ERROR, "missing idat box required by the Exif metadata\n");
11068 return AVERROR_INVALIDDATA;
11069 }
11070 offset = c->idat_offset;
11071 }
11072
11073 buf = av_buffer_alloc(ref->extent_length);
11074 if (!buf)
11075 return AVERROR(ENOMEM);
11076
11077 if (offset > INT64_MAX - ref->extent_offset) {
11078 err = AVERROR(ENOMEM);
11079 goto fail;
11080 }
11081
11082 avio_seek(s->pb, ref->extent_offset + offset, SEEK_SET);
11083 err = avio_read(s->pb, buf->data, ref->extent_length);
11084 if (err != ref->extent_length) {
11085 if (err > 0)
11086 err = AVERROR_INVALIDDATA;
11087 goto fail;
11088 }
11089
11090 // HEIF spec states that Exif metadata is informative. The irot item property is
11091 // the normative source of rotation information. So we remove any Orientation tag
11092 // present in the Exif buffer.
11093 err = av_exif_parse_buffer(s, buf->data, ref->extent_length, &ifd, AV_EXIF_T_OFF);
11094 if (err < 0) {
11095 av_log(s, AV_LOG_ERROR, "Unable to parse Exif metadata\n");
11096 goto fail;
11097 }
11098
11099 err = av_exif_remove_entry(s, &ifd, orientation_id, 0);
11100 if (err < 0)
11101 goto fail;
11102 else if (!err)
11103 goto finish;
11104
11105 av_buffer_unref(&buf);
11106 err = av_exif_write(s, &ifd, &buf, AV_EXIF_T_OFF);
11107 if (err < 0)
11108 goto fail;
11109
11110finish:
11111 offset = AV_RB32(buf->data) + 4;
11112 if (offset >= buf->size) {
11113 err = AVERROR_INVALIDDATA;
11114 goto fail;
11115 }
11116 sd = av_packet_side_data_new(coded_side_data, nb_coded_side_data,
11117 AV_PKT_DATA_EXIF, buf->size - offset, 0);
11118 if (!sd) {
11119 err = AVERROR(ENOMEM);
11120 goto fail;
11121 }
11122 memcpy(sd->data, buf->data + offset, buf->size - offset);
11123
11124 err = 0;
11125fail:
11126 av_buffer_unref(&buf);
11127 av_exif_free(&ifd);
11128 avio_seek(s->pb, pos, SEEK_SET);
11129
11130 return err;
11131}
11132
11134{
11135 MOVContext *mov = s->priv_data;
11136
11137 for (int i = 0; i < mov->nb_heif_grid; i++) {
11139 AVStreamGroupTileGrid *tile_grid;
11140 const HEIFGrid *grid = &mov->heif_grid[i];
11141 int err, loop = 1;
11142
11143 if (!stg)
11144 return AVERROR(ENOMEM);
11145
11146 stg->id = grid->item->item_id;
11147 tile_grid = stg->params.tile_grid;
11148
11149 for (int j = 0; j < grid->nb_tiles; j++) {
11150 int tile_id = grid->tile_id_list[j];
11151 int k;
11152
11153 for (k = 0; k < mov->nb_heif_item; k++) {
11154 HEIFItem *item = mov->heif_item[k];
11155 AVStream *st;
11156
11157 if (!item || item->item_id != tile_id)
11158 continue;
11159 st = item->st;
11160 if (!st) {
11161 av_log(s, AV_LOG_WARNING, "HEIF item id %d from grid id %d doesn't "
11162 "reference a stream\n",
11163 tile_id, grid->item->item_id);
11165 loop = 0;
11166 break;
11167 }
11168
11169 grid->tile_item_list[j] = item;
11170 grid->tile_idx_list[j] = stg->nb_streams;
11171
11172 err = avformat_stream_group_add_stream(stg, st);
11173 if (err < 0) {
11174 int l;
11175 if (err != AVERROR(EEXIST))
11176 return err;
11177
11178 for (l = 0; l < stg->nb_streams; l++)
11179 if (stg->streams[l]->index == st->index)
11180 break;
11181 av_assert0(l < stg->nb_streams);
11182 grid->tile_idx_list[j] = l;
11183 }
11184
11185 if (item->item_id != mov->primary_item_id)
11187 break;
11188 }
11189
11190 if (k == mov->nb_heif_item) {
11192 av_log(s, AV_LOG_WARNING, "HEIF item id %d referenced by grid id %d doesn't "
11193 "exist\n",
11194 tile_id, grid->item->item_id);
11196 loop = 0;
11197 }
11198 if (!loop)
11199 break;
11200 }
11201
11202 if (!loop)
11203 continue;
11204
11205 switch (grid->item->type) {
11206 case MKTAG('g','r','i','d'):
11207 err = read_image_grid(s, grid, tile_grid);
11208 break;
11209 case MKTAG('i','o','v','l'):
11210 err = read_image_iovl(s, grid, tile_grid);
11211 break;
11212 default:
11213 av_assert0(0);
11214 }
11215 if (err < 0)
11216 return err;
11217
11218 for (int j = 0; j < grid->item->nb_iref_list; j++) {
11219 HEIFItem *ref = get_heif_item(mov, grid->item->iref_list[j].item_id);
11220
11221 av_assert0(ref);
11222 switch(ref->type) {
11223 case MKTAG('E','x','i','f'):
11224 err = mov_parse_exif_item(s, &tile_grid->coded_side_data,
11225 &tile_grid->nb_coded_side_data, ref);
11226 if (err < 0 && (s->error_recognition & AV_EF_EXPLODE))
11227 return err;
11228 break;
11229 default:
11230 break;
11231 }
11232 }
11233
11234 /* rotation */
11235 if (grid->item->rotation || grid->item->hflip || grid->item->vflip) {
11237 &tile_grid->nb_coded_side_data, grid->item);
11238 if (err < 0)
11239 return err;
11240 }
11241
11242 /* ICC profile */
11243 if (grid->item->icc_profile_size) {
11245 &tile_grid->nb_coded_side_data, grid->item);
11246 if (err < 0)
11247 return err;
11248 }
11249
11250 if (grid->item->name)
11251 av_dict_set(&stg->metadata, "title", grid->item->name, 0);
11252 if (grid->item->item_id == mov->primary_item_id)
11254 }
11255
11256 return 0;
11257}
11258
11260{
11261 MOVContext *mov = s->priv_data;
11262 int err;
11263
11264 for (int i = 0; i < mov->nb_heif_item; i++) {
11265 HEIFItem *item = mov->heif_item[i];
11266 MOVStreamContext *sc;
11267 AVStream *st;
11268 int64_t offset = 0;
11269
11270 if (!item)
11271 continue;
11272 if (!item->st) {
11273 continue;
11274 }
11275 if (item->is_idat_relative) {
11276 if (!mov->idat_offset) {
11277 av_log(s, AV_LOG_ERROR, "Missing idat box for item %d\n", item->item_id);
11278 return AVERROR_INVALIDDATA;
11279 }
11280 offset = mov->idat_offset;
11281 }
11282
11283 st = item->st;
11284 sc = st->priv_data;
11285 st->codecpar->width = item->width;
11286 st->codecpar->height = item->height;
11287
11288 sc->sample_size = sc->stsz_sample_size = item->extent_length;
11289 sc->sample_count = 1;
11290
11291 err = sanity_checks(s, sc, st->index);
11292 if (err)
11293 return AVERROR_INVALIDDATA;
11294
11295 if (offset > INT64_MAX - item->extent_offset)
11296 return AVERROR_INVALIDDATA;
11297
11298 sc->chunk_offsets[0] = item->extent_offset + offset;
11299
11300 if (item->item_id == mov->primary_item_id)
11302
11303 for (int j = 0; j < item->nb_iref_list; j++) {
11304 HEIFItem *ref = get_heif_item(mov, item->iref_list[j].item_id);
11305
11306 av_assert0(ref);
11307 switch(ref->type) {
11308 case MKTAG('E','x','i','f'):
11311 if (err < 0 && (s->error_recognition & AV_EF_EXPLODE))
11312 return err;
11313 break;
11314 default:
11315 break;
11316 }
11317 }
11318
11319 if (item->rotation || item->hflip || item->vflip) {
11321 &st->codecpar->nb_coded_side_data, item);
11322 if (err < 0)
11323 return err;
11324 }
11325
11326 mov_build_index(mov, st);
11327 }
11328
11329 if (mov->nb_heif_grid) {
11330 err = mov_parse_tiles(s);
11331 if (err < 0)
11332 return err;
11333 }
11334
11335 return 0;
11336}
11337
11339{
11340 int err;
11341
11342 for (int i = 0; i < s->nb_streams; i++) {
11343 AVStreamGroup *stg;
11344 const AVDictionaryEntry *tcr;
11345 AVStream *st = s->streams[i];
11346
11347 if (st->codecpar->codec_tag != MKTAG('t','m','c','d'))
11348 continue;
11349
11351 if (!stg)
11352 return AVERROR(ENOMEM);
11353
11354 stg->id = st->id;
11355 tcr = av_dict_get(st->metadata, "timecode", NULL, 0);
11356
11357 for (int j = 0; j < s->nb_streams; j++) {
11358 AVStream *st2 = s->streams[j];
11359 MOVStreamContext *sc2 = st2->priv_data;
11360 MovTref *tag = mov_find_tref_tag(sc2, MKTAG('t','m','c','d'));
11361
11362 if (!tag)
11363 continue;
11364
11365 for (int k = 0; k < tag->nb_id; k++) {
11366 if (tag->id[k] != st->id)
11367 continue;
11368
11369 err = avformat_stream_group_add_stream(stg, st2);
11370 if (err < 0)
11371 return err;
11372
11373 if (tcr)
11374 av_dict_set(&st2->metadata, "timecode", tcr->value, AV_DICT_DONT_OVERWRITE);
11375 }
11376 }
11377
11378 if (!stg->nb_streams) {
11380 continue;
11381 }
11382
11383 err = avformat_stream_group_add_stream(stg, st);
11384 if (err < 0)
11385 return err;
11386
11387 stg->params.tref->metadata_index = stg->nb_streams - 1;
11388 }
11390
11391 return 0;
11392}
11393
11395 uint32_t *tref_id, int nb_tref_id, int first_index)
11396{
11397 if (!nb_tref_id)
11398 return NULL;
11399
11400 for (int i = first_index; i < s->nb_streams; i++)
11401 for (int j = 0; j < nb_tref_id; j++)
11402 if (s->streams[i]->index != st->index &&
11403 s->streams[i]->id == tref_id[j])
11404 return s->streams[i];
11405
11406 return NULL;
11407}
11408
11410{
11411 static const uint32_t tref_tags[] = {
11412 MKTAG('c','d','s','c'),
11413 MKTAG('r','n','d','r'),
11414 };
11415
11416 int err;
11417
11418 // Don't try to add a group if there's only one track
11419 if (s->nb_streams <= 1)
11420 return 0;
11421
11422 for (int i = 0; i < s->nb_streams; i++) {
11423 AVStream *st = s->streams[i];
11424 MOVStreamContext *sc = st->priv_data;
11425
11426 for (int c = 0; c < FF_ARRAY_ELEMS(tref_tags); c++) {
11427 AVStreamGroup *stg;
11428 AVStream *st_ref;
11429 MovTref *tag = mov_find_tref_tag(sc, tref_tags[c]);
11430
11431 if (!tag)
11432 continue;
11433
11434 st_ref = mov_find_reference_track(s, st, tag->id, tag->nb_id, 0);
11435 if (!st_ref) {
11436 av_log(s, AV_LOG_WARNING, "Failed to find referenced stream\n");
11437 continue;
11438 }
11439
11441 if (!stg)
11442 return AVERROR(ENOMEM);
11443
11444 stg->id = st_ref->id;
11445
11446 err = avformat_stream_group_add_stream(stg, st_ref);
11447 if (err < 0)
11448 return err;
11449
11450 err = avformat_stream_group_add_stream(stg, st);
11451 if (err < 0)
11452 return err;
11453
11454 stg->params.tref->metadata_index = stg->nb_streams - 1;
11455 }
11456 }
11457
11458 return 0;
11459}
11460
11462{
11463 int err;
11464
11465 // Don't try to add a group if there's only one track
11466 if (s->nb_streams <= 1)
11467 return 0;
11468
11469 for (int i = 0; i < s->nb_streams; i++) {
11470 AVStreamGroup *stg;
11471 AVStream *st = s->streams[i];
11472 AVStream *st_base;
11473 MOVStreamContext *sc = st->priv_data;
11474 MovTref *tag = mov_find_tref_tag(sc, MKTAG('s','b','a','s'));
11475 int j = 0;
11476
11477 /* Find an enhancement stream. */
11478 if (st->codecpar->codec_id != AV_CODEC_ID_LCEVC || !tag)
11479 continue;
11480
11482 if (!stg)
11483 return AVERROR(ENOMEM);
11484
11485 stg->id = st->id;
11488
11489 while (st_base = mov_find_reference_track(s, st, tag->id, tag->nb_id, j)) {
11490 err = avformat_stream_group_add_stream(stg, st_base);
11491 if (err < 0)
11492 return err;
11493
11494 j = st_base->index + 1;
11495 }
11496 if (!j) {
11497 int loglevel = (s->error_recognition & AV_EF_EXPLODE) ? AV_LOG_ERROR : AV_LOG_WARNING;
11498 av_log(s, loglevel, "Failed to find base stream for LCEVC stream\n");
11500 if (s->error_recognition & AV_EF_EXPLODE)
11501 return AVERROR_INVALIDDATA;
11502 continue;
11503 }
11504
11505 err = avformat_stream_group_add_stream(stg, st);
11506 if (err < 0)
11507 return err;
11508
11509 stg->params.layered_video->el_index = stg->nb_streams - 1;
11510 }
11511
11512 return 0;
11513}
11514
11516{
11517 int err;
11518
11519 if (s->nb_streams <= 1)
11520 return 0;
11521
11522 /* Identify legacy dual-track Dolby Vision profile 7 carriage per Annex
11523 * C of "Dolby Vision Streams Within the ISO Base Media File Format",
11524 * v2.7.1. The 'vdep' track reference type is shared with depth video
11525 * and multi-view dependencies. The spec-mandated DV-specific sample
11526 * entry combined with the dvcC configuration record disambiguates
11527 * those uses. */
11528 for (int i = 0; i < s->nb_streams; i++) {
11529 AVStreamGroup *stg;
11530 AVStream *st = s->streams[i];
11531 AVStream *st_base;
11532 MOVStreamContext *sc = st->priv_data;
11533 MovTref *tag = mov_find_tref_tag(sc, MKTAG('v','d','e','p'));
11534 const AVPacketSideData *sd;
11536
11537 if (st->codecpar->codec_id != AV_CODEC_ID_HEVC || !tag)
11538 continue;
11539
11540 if (st->codecpar->codec_tag != MKTAG('d','v','h','e') &&
11541 st->codecpar->codec_tag != MKTAG('d','v','h','1'))
11542 continue;
11543
11547 if (!sd)
11548 continue;
11549 dovi = (const AVDOVIDecoderConfigurationRecord *)sd->data;
11550
11551 /* EL track of a dual-track stream: rpu_present_flag = 1,
11552 * el_present_flag = 1, bl_present_flag = 0, dv_profile = 7. */
11553 if (dovi->dv_profile != 7 || !dovi->rpu_present_flag ||
11554 !dovi->el_present_flag || dovi->bl_present_flag)
11555 continue;
11556
11557 st_base = mov_find_reference_track(s, st, tag->id, tag->nb_id, 0);
11558 if (!st_base) {
11559 int loglevel = (s->error_recognition & AV_EF_EXPLODE) ? AV_LOG_ERROR : AV_LOG_WARNING;
11560 av_log(s, loglevel, "Failed to find base layer for Dolby Vision EL stream\n");
11561 if (s->error_recognition & AV_EF_EXPLODE)
11562 return AVERROR_INVALIDDATA;
11563 continue;
11564 }
11565
11567 if (!stg)
11568 return AVERROR(ENOMEM);
11569
11570 stg->id = st->id;
11571
11572 err = avformat_stream_group_add_stream(stg, st_base);
11573 if (err < 0)
11574 return err;
11575
11576 err = avformat_stream_group_add_stream(stg, st);
11577 if (err < 0)
11578 return err;
11579
11580 stg->params.layered_video->el_index = stg->nb_streams - 1;
11581 stg->params.layered_video->width = st_base->codecpar->width;
11582 stg->params.layered_video->height = st_base->codecpar->height;
11583 }
11584
11585 return 0;
11586}
11587
11589{
11590 int highest_id = 0, lowest_iamf_id = INT_MAX;
11591
11592 for (int i = 0; i < s->nb_streams; i++) {
11593 const AVStream *st = s->streams[i];
11594 const MOVStreamContext *sc = st->priv_data;
11595 if (!sc->iamf)
11596 highest_id = FFMAX(highest_id, st->id);
11597 }
11598
11599 for (int i = 0; i < s->nb_stream_groups; i++) {
11600 AVStreamGroup *stg = s->stream_groups[i];
11602 continue;
11603 for (int j = 0; j < stg->nb_streams; j++) {
11604 AVStream *st = stg->streams[j];
11605 lowest_iamf_id = FFMIN(lowest_iamf_id, st->id);
11606 }
11607 }
11608
11609 if (highest_id < lowest_iamf_id)
11610 return;
11611
11612 highest_id += !lowest_iamf_id;
11613 for (int i = 0; highest_id > 1 && i < s->nb_stream_groups; i++) {
11614 AVStreamGroup *stg = s->stream_groups[i];
11616 continue;
11617 for (int j = 0; j < stg->nb_streams; j++) {
11618 AVStream *st = stg->streams[j];
11619 MOVStreamContext *sc = st->priv_data;
11620 st->id += highest_id;
11621 sc->iamf_stream_offset = highest_id;
11622 }
11623 }
11624}
11625
11627{
11628 MOVContext *mov = s->priv_data;
11629 AVIOContext *pb = s->pb;
11630 int j, err;
11631 MOVAtom atom = { AV_RL32("root") };
11632 int i;
11633
11634 mov->fc = s;
11635 mov->trak_index = -1;
11636 mov->primary_item_id = -1;
11637 mov->cur_item_id = -1;
11638 /* .mov and .mp4 aren't streamable anyway (only progressive download if moov is before mdat) */
11640 atom.size = avio_size(pb);
11641 else
11642 atom.size = INT64_MAX;
11643
11644 /* check MOV header */
11645 do {
11646 if (mov->moov_retry)
11647 avio_seek(pb, 0, SEEK_SET);
11648 if ((err = mov_read_default(mov, pb, atom)) < 0) {
11649 av_log(s, AV_LOG_ERROR, "error reading header\n");
11650 return err;
11651 }
11652 } while ((pb->seekable & AVIO_SEEKABLE_NORMAL) &&
11653 !mov->found_moov && (!mov->found_iloc || !mov->found_iinf) && !mov->moov_retry++);
11654 if (!mov->found_moov && !mov->found_iloc && !mov->found_iinf) {
11655 av_log(s, AV_LOG_ERROR, "moov atom not found\n");
11656 return AVERROR_INVALIDDATA;
11657 }
11658 av_log(mov->fc, AV_LOG_TRACE, "on_parse_exit_offset=%"PRId64"\n", avio_tell(pb));
11659
11660 if (mov->found_iloc && mov->found_iinf) {
11661 err = mov_parse_heif_items(s);
11662 if (err < 0)
11663 return err;
11664 }
11665 // prevent iloc and iinf boxes from being parsed while reading packets.
11666 // this is needed because an iinf box may have been parsed but ignored
11667 // for having old infe boxes which create no streams.
11668 mov->found_iloc = mov->found_iinf = 1;
11669
11670 if (pb->seekable & AVIO_SEEKABLE_NORMAL) {
11671 if (mov->nb_chapter_tracks > 0 && !mov->ignore_chapters)
11673 for (i = 0; i < s->nb_streams; i++)
11674 if (s->streams[i]->codecpar->codec_tag == AV_RL32("tmcd")) {
11675 mov_read_timecode_track(s, s->streams[i]);
11676 } else if (s->streams[i]->codecpar->codec_tag == AV_RL32("rtmd")) {
11677 mov_read_rtmd_track(s, s->streams[i]);
11678 }
11679 }
11680
11681 /* Create metadata stream groups. */
11683 if (err < 0)
11684 return err;
11685
11686 /* copy timecode metadata from tmcd tracks to the related video streams */
11688 if (err < 0)
11689 return err;
11690
11691 /* Create LCEVC stream groups. */
11693 if (err < 0)
11694 return err;
11695
11696 /* Create Dolby Vision Profile 7 stream groups. */
11698 if (err < 0)
11699 return err;
11700
11701 for (i = 0; i < s->nb_streams; i++) {
11702 AVStream *st = s->streams[i];
11703 FFStream *const sti = ffstream(st);
11704 MOVStreamContext *sc = st->priv_data;
11705 uint32_t dvdsub_clut[FF_DVDCLUT_CLUT_LEN] = {0};
11706 fix_timescale(mov, sc);
11707
11708 /* Set the primary extradata based on the first Sample if it doesn't reference the first stsd entry. */
11709 if (sc->stsc_count && sc->extradata_size && !sc->iamf &&
11710 sc->stsc_data[0].id > 1 && sc->stsc_data[0].id <= sc->stsd_count) {
11711 sc->last_stsd_index = sc->stsc_data[0].id - 1;
11714 if (sc->extradata_size[sc->last_stsd_index]) {
11716 if (!st->codecpar->extradata)
11717 return AVERROR(ENOMEM);
11719 }
11720 }
11721
11725 }
11728 sc->time_scale*(int64_t)sc->nb_frames_for_fps, sc->duration_for_fps, INT_MAX);
11730 if (st->codecpar->width <= 0 || st->codecpar->height <= 0) {
11731 st->codecpar->width = sc->width;
11732 st->codecpar->height = sc->height;
11733 }
11736
11737 for (j = 0; j < FF_DVDCLUT_CLUT_LEN; j++)
11738 dvdsub_clut[j] = AV_RB32(st->codecpar->extradata + j * 4);
11739
11740 err = ff_dvdclut_yuv_to_rgb(dvdsub_clut, FF_DVDCLUT_CLUT_SIZE);
11741 if (err < 0)
11742 return err;
11743
11745 st->codecpar->extradata_size = 0;
11746
11748 st->codecpar);
11749 if (err < 0)
11750 return err;
11751 }
11752 }
11753 if (mov->handbrake_version &&
11754 mov->handbrake_version <= 1000000*0 + 1000*10 + 2 && // 0.10.2
11756 av_log(s, AV_LOG_VERBOSE, "Forcing full parsing for mp3 stream\n");
11758 }
11759 }
11760
11761 if (mov->trex_data || mov->use_mfra_for > 0) {
11762 for (i = 0; i < s->nb_streams; i++) {
11763 AVStream *st = s->streams[i];
11764 MOVStreamContext *sc = st->priv_data;
11765 if (sc->duration_for_fps > 0) {
11766 /* Akin to sc->data_size * 8 * sc->time_scale / sc->duration_for_fps but accounting for overflows. */
11768 if (st->codecpar->bit_rate == INT64_MIN) {
11769 av_log(s, AV_LOG_WARNING, "Overflow during bit rate calculation %"PRId64" * 8 * %d\n",
11770 sc->data_size, sc->time_scale);
11771 st->codecpar->bit_rate = 0;
11772 if (s->error_recognition & AV_EF_EXPLODE)
11773 return AVERROR_INVALIDDATA;
11774 }
11775 }
11776 }
11777 }
11778
11779 for (i = 0; i < mov->bitrates_count && i < s->nb_streams; i++) {
11780 if (mov->bitrates[i]) {
11781 s->streams[i]->codecpar->bit_rate = mov->bitrates[i];
11782 }
11783 }
11784
11786
11787 for (i = 0; i < s->nb_streams; i++) {
11788 AVStream *st = s->streams[i];
11789 MOVStreamContext *sc = st->priv_data;
11790
11791 switch (st->codecpar->codec_type) {
11792 case AVMEDIA_TYPE_AUDIO:
11793 err = ff_replaygain_export(st, s->metadata);
11794 if (err < 0)
11795 return err;
11796 break;
11797 case AVMEDIA_TYPE_VIDEO:
11798 if (sc->display_matrix) {
11801 (uint8_t*)sc->display_matrix, sizeof(int32_t) * 9, 0))
11802 return AVERROR(ENOMEM);
11803
11804 sc->display_matrix = NULL;
11805 }
11806 if (sc->stereo3d) {
11809 (uint8_t *)sc->stereo3d, sc->stereo3d_size, 0))
11810 return AVERROR(ENOMEM);
11811
11812 sc->stereo3d = NULL;
11813 }
11814 if (sc->spherical) {
11817 (uint8_t *)sc->spherical, sc->spherical_size, 0))
11818 return AVERROR(ENOMEM);
11819
11820 sc->spherical = NULL;
11821 }
11822 if (sc->mastering) {
11825 (uint8_t *)sc->mastering, sc->mastering_size, 0))
11826 return AVERROR(ENOMEM);
11827
11828 sc->mastering = NULL;
11829 }
11830 if (sc->coll) {
11833 (uint8_t *)sc->coll, sc->coll_size, 0))
11834 return AVERROR(ENOMEM);
11835
11836 sc->coll = NULL;
11837 }
11838 if (sc->ambient) {
11841 (uint8_t *) sc->ambient, sc->ambient_size, 0))
11842 return AVERROR(ENOMEM);
11843
11844 sc->ambient = NULL;
11845 }
11846 break;
11847 }
11848 }
11849
11851
11853
11854 for (i = 0; i < mov->frag_index.nb_items; i++)
11855 if (mov->frag_index.item[i].moof_offset <= mov->fragment.moof_offset)
11856 mov->frag_index.item[i].headers_read = 1;
11857
11858 return 0;
11859}
11860
11862{
11864 int64_t best_dts = INT64_MAX;
11865 int i;
11866 MOVContext *mov = s->priv_data;
11867 int no_interleave = !mov->interleaved_read || !(s->pb->seekable & AVIO_SEEKABLE_NORMAL);
11868 for (i = 0; i < s->nb_streams; i++) {
11869 AVStream *avst = s->streams[i];
11870 FFStream *const avsti = ffstream(avst);
11871 MOVStreamContext *msc = avst->priv_data;
11872 if (msc->pb && msc->current_sample < avsti->nb_index_entries) {
11873 AVIndexEntry *current_sample = &avsti->index_entries[msc->current_sample];
11874 int64_t dts = av_rescale(current_sample->timestamp, AV_TIME_BASE, msc->time_scale);
11875 uint64_t dtsdiff = best_dts > dts ? best_dts - (uint64_t)dts : ((uint64_t)dts - best_dts);
11876 av_log(s, AV_LOG_TRACE, "stream %d, sample %d, dts %"PRId64"\n", i, msc->current_sample, dts);
11877 if (!sample || (no_interleave && current_sample->pos < sample->pos) ||
11878 ((s->pb->seekable & AVIO_SEEKABLE_NORMAL) &&
11879 ((msc->pb != s->pb && dts < best_dts) || (msc->pb == s->pb && dts != AV_NOPTS_VALUE &&
11880 ((dtsdiff <= AV_TIME_BASE && current_sample->pos < sample->pos) ||
11881 (dtsdiff > AV_TIME_BASE && dts < best_dts && mov->interleaved_read)))))) {
11882 sample = current_sample;
11883 best_dts = dts;
11884 *st = avst;
11885 }
11886 }
11887 }
11888 return sample;
11889}
11890
11891static int should_retry(AVIOContext *pb, int error_code) {
11892 if (error_code == AVERROR_EOF || avio_feof(pb))
11893 return 0;
11894
11895 return 1;
11896}
11897
11899{
11900 int ret;
11901 MOVContext *mov = s->priv_data;
11902
11903 if (index >= 0 && index < mov->frag_index.nb_items)
11904 target = mov->frag_index.item[index].moof_offset;
11905 if (target >= 0 && avio_seek(s->pb, target, SEEK_SET) != target) {
11906 av_log(mov->fc, AV_LOG_ERROR, "root atom offset 0x%"PRIx64": partial file\n", target);
11907 return AVERROR_INVALIDDATA;
11908 }
11909
11910 mov->next_root_atom = 0;
11911 if ((index < 0 && target >= 0) || index >= mov->frag_index.nb_items)
11912 index = search_frag_moof_offset(&mov->frag_index, target);
11913 if (index >= 0 && index < mov->frag_index.nb_items &&
11914 mov->frag_index.item[index].moof_offset == target) {
11915 if (index + 1 < mov->frag_index.nb_items)
11918 return 0;
11920 }
11921
11922 mov->found_mdat = 0;
11923
11924 ret = mov_read_default(mov, s->pb, (MOVAtom){ AV_RL32("root"), INT64_MAX });
11925 if (ret < 0)
11926 return ret;
11927 if (avio_feof(s->pb))
11928 return AVERROR_EOF;
11929 av_log(s, AV_LOG_TRACE, "read fragments, offset 0x%"PRIx64"\n", avio_tell(s->pb));
11930
11931 return 1;
11932}
11933
11935{
11936 MOVStreamContext *sc = st->priv_data;
11937 uint8_t *side, *extradata;
11938 int extradata_size;
11939
11940 /* Save the current index. */
11941 sc->last_stsd_index = sc->stsc_data[sc->stsc_index].id - 1;
11942
11943 /* Notify the decoder that extradata changed. */
11944 extradata_size = sc->extradata_size[sc->last_stsd_index];
11945 extradata = sc->extradata[sc->last_stsd_index];
11946 if (st->discard != AVDISCARD_ALL && extradata_size > 0 && extradata) {
11949 extradata_size);
11950 if (!side)
11951 return AVERROR(ENOMEM);
11952 memcpy(side, extradata, extradata_size);
11953 }
11954
11955 return 0;
11956}
11957
11958static int get_eia608_packet(AVIOContext *pb, AVPacket *pkt, int src_size)
11959{
11960 /* We can't make assumptions about the structure of the payload,
11961 because it may include multiple cdat and cdt2 samples. */
11962 const uint32_t cdat = AV_RB32("cdat");
11963 const uint32_t cdt2 = AV_RB32("cdt2");
11964 int ret, out_size = 0;
11965
11966 /* a valid payload must have size, 4cc, and at least 1 byte pair: */
11967 if (src_size < 10)
11968 return AVERROR_INVALIDDATA;
11969
11970 /* avoid an int overflow: */
11971 if ((src_size - 8) / 2 >= INT_MAX / 3)
11972 return AVERROR_INVALIDDATA;
11973
11974 ret = av_new_packet(pkt, ((src_size - 8) / 2) * 3);
11975 if (ret < 0)
11976 return ret;
11977
11978 /* parse and re-format the c608 payload in one pass. */
11979 while (src_size >= 10) {
11980 const uint32_t atom_size = avio_rb32(pb);
11981 const uint32_t atom_type = avio_rb32(pb);
11982 const uint32_t data_size = atom_size - 8;
11983 const uint8_t cc_field =
11984 atom_type == cdat ? 1 :
11985 atom_type == cdt2 ? 2 :
11986 0;
11987
11988 /* account for bytes consumed for atom size and type. */
11989 src_size -= 8;
11990
11991 /* make sure the data size stays within the buffer boundaries. */
11992 if (data_size < 2 || data_size > src_size) {
11993 ret = AVERROR_INVALIDDATA;
11994 break;
11995 }
11996
11997 /* make sure the data size is consistent with N byte pairs. */
11998 if (data_size % 2 != 0) {
11999 ret = AVERROR_INVALIDDATA;
12000 break;
12001 }
12002
12003 if (!cc_field) {
12004 /* neither cdat or cdt2 ... skip it */
12005 avio_skip(pb, data_size);
12006 src_size -= data_size;
12007 continue;
12008 }
12009
12010 for (uint32_t i = 0; i < data_size; i += 2) {
12011 pkt->data[out_size] = (0x1F << 3) | (1 << 2) | (cc_field - 1);
12012 pkt->data[out_size + 1] = avio_r8(pb);
12013 pkt->data[out_size + 2] = avio_r8(pb);
12014 out_size += 3;
12015 src_size -= 2;
12016 }
12017 }
12018
12019 if (src_size > 0)
12020 /* skip any remaining unread portion of the input payload */
12021 avio_skip(pb, src_size);
12022
12024 return ret;
12025}
12026
12028 int64_t current_index, AVPacket *pkt)
12029{
12030 MOVContext *mov = s->priv_data;
12031 MOVStreamContext *sc = st->priv_data;
12032
12033 pkt->stream_index = sc->ffindex;
12034 pkt->dts = sample->timestamp;
12035 if (sample->flags & AVINDEX_DISCARD_FRAME) {
12036 pkt->flags |= AV_PKT_FLAG_DISCARD;
12037 }
12038 if (sc->stts_count && sc->tts_index < sc->tts_count)
12039 pkt->duration = sc->tts_data[sc->tts_index].duration;
12040 if (sc->ctts_count && sc->tts_index < sc->tts_count) {
12041 pkt->pts = av_sat_add64(pkt->dts, av_sat_add64(sc->dts_shift, sc->tts_data[sc->tts_index].offset));
12042 } else {
12043 if (pkt->duration == 0) {
12044 int64_t next_dts = (sc->current_sample < ffstream(st)->nb_index_entries) ?
12046 if (next_dts >= pkt->dts)
12047 pkt->duration = next_dts - pkt->dts;
12048 }
12049 pkt->pts = pkt->dts;
12050 }
12051
12053 sc->current_sample >= ffstream(st)->nb_index_entries) {
12054 int64_t pts = av_rescale_q(pkt->pts, st->time_base, (AVRational){ 1, st->codecpar->sample_rate });
12055 int64_t total = av_rescale_q(st->duration, st->time_base, (AVRational){ 1, st->codecpar->sample_rate });
12056 int64_t duration = pkt->duration;
12057
12058 if (st->duration < pkt->pts) {
12059 duration = 0;
12060 } else
12061 duration = FFMIN(duration, (uint64_t)st->duration - pkt->pts);
12062
12063 duration = av_rescale_q(duration, st->time_base, (AVRational){ 1, st->codecpar->sample_rate });
12064
12065 if (!ffstream(st)->first_discard_sample)
12067 if (!ffstream(st)->last_discard_sample)
12068 ffstream(st)->last_discard_sample = total;
12069 }
12070
12071 if (sc->tts_data && sc->tts_index < sc->tts_count) {
12072 /* update tts context */
12073 sc->tts_sample++;
12074 if (sc->tts_index < sc->tts_count &&
12075 sc->tts_data[sc->tts_index].count == sc->tts_sample) {
12076 sc->tts_index++;
12077 sc->tts_sample = 0;
12078 }
12079 }
12080
12081 if (sc->sdtp_data && sc->current_sample <= sc->sdtp_count) {
12082 uint8_t sample_flags = sc->sdtp_data[sc->current_sample - 1];
12083 uint8_t sample_is_depended_on = (sample_flags >> 2) & 0x3;
12084 pkt->flags |= sample_is_depended_on == MOV_SAMPLE_DEPENDENCY_NO ? AV_PKT_FLAG_DISPOSABLE : 0;
12085 }
12086 pkt->flags |= sample->flags & AVINDEX_KEYFRAME ? AV_PKT_FLAG_KEY : 0;
12087 pkt->pos = sample->pos;
12088
12089 /* Multiple stsd handling. */
12090 if (sc->stsc_data) {
12091 if (sc->stsc_data[sc->stsc_index].id > 0 &&
12092 sc->stsc_data[sc->stsc_index].id - 1 < sc->stsd_count &&
12093 sc->stsc_data[sc->stsc_index].id - 1 != sc->last_stsd_index) {
12094 int ret = mov_change_extradata(st, pkt);
12095 if (ret < 0)
12096 return ret;
12097 }
12098
12099 /* Update the stsc index for the next sample */
12100 sc->stsc_sample++;
12103 sc->stsc_index++;
12104 sc->stsc_sample = 0;
12105 }
12106 }
12107
12108 return 0;
12109}
12110
12112{
12113 MOVContext *mov = s->priv_data;
12114 MOVStreamContext *sc;
12116 AVStream *st = NULL;
12117 FFStream *avsti = NULL;
12118 int64_t current_index;
12119 int ret;
12120 int i;
12121 mov->fc = s;
12122 retry:
12123 if (s->pb->pos == 0) {
12124
12125 // Discard current fragment index
12126 if (mov->frag_index.allocated_size > 0) {
12127 for(int i = 0; i < mov->frag_index.nb_items; i++) {
12129 }
12130 av_freep(&mov->frag_index.item);
12131 mov->frag_index.nb_items = 0;
12132 mov->frag_index.allocated_size = 0;
12133 mov->frag_index.current = -1;
12134 mov->frag_index.complete = 0;
12135 }
12136
12137 for (i = 0; i < s->nb_streams; i++) {
12138 AVStream *avst = s->streams[i];
12139 MOVStreamContext *msc = avst->priv_data;
12140
12141 // Clear current sample
12142 mov_current_sample_set(msc, 0);
12143 msc->tts_index = 0;
12144
12145 // Discard current index entries
12146 avsti = ffstream(avst);
12147 if (avsti->index_entries_allocated_size > 0) {
12148 av_freep(&avsti->index_entries);
12150 avsti->nb_index_entries = 0;
12151 }
12152 }
12153
12154 if ((ret = mov_switch_root(s, -1, -1)) < 0)
12155 return ret;
12156 }
12158 if (!sample || (mov->next_root_atom && sample->pos > mov->next_root_atom)) {
12159 if (!mov->next_root_atom)
12160 return AVERROR_EOF;
12161 if ((ret = mov_switch_root(s, mov->next_root_atom, -1)) < 0)
12162 return ret;
12163 goto retry;
12164 }
12165 sc = st->priv_data;
12166 /* must be done just before reading, to avoid infinite loop on sample */
12167 current_index = sc->current_index;
12169
12170 if (mov->next_root_atom) {
12171 sample->pos = FFMIN(sample->pos, mov->next_root_atom);
12172 sample->size = FFMIN(sample->size, (mov->next_root_atom - sample->pos));
12173 }
12174
12175 if (st->discard != AVDISCARD_ALL || sc->iamf) {
12176 int64_t ret64 = avio_seek(sc->pb, sample->pos, SEEK_SET);
12177 if (ret64 != sample->pos) {
12178 av_log(mov->fc, AV_LOG_ERROR, "stream %d, offset 0x%"PRIx64": partial file\n",
12179 sc->ffindex, sample->pos);
12180 if (should_retry(sc->pb, ret64)) {
12182 } else if (ret64 < 0) {
12183 return (int)ret64;
12184 }
12185 return AVERROR_INVALIDDATA;
12186 }
12187
12188 if (st->discard == AVDISCARD_NONKEY && !(sample->flags & AVINDEX_KEYFRAME)) {
12189 av_log(mov->fc, AV_LOG_DEBUG, "Nonkey frame from stream %d discarded due to AVDISCARD_NONKEY\n", sc->ffindex);
12190 goto retry;
12191 }
12192
12193 if (st->codecpar->codec_id == AV_CODEC_ID_EIA_608 && sample->size > 8)
12194 ret = get_eia608_packet(sc->pb, pkt, sample->size);
12195#if CONFIG_IAMFDEC
12196 else if (sc->iamf) {
12197 int64_t pts, dts, pos, duration;
12198 int flags, size = sample->size;
12199 ret = mov_finalize_packet(s, st, sample, current_index, pkt);
12200 pts = pkt->pts; dts = pkt->dts;
12201 pos = pkt->pos; flags = pkt->flags;
12202 duration = pkt->duration;
12203 while (!ret && size > 0) {
12204 ret = ff_iamf_read_packet(s, sc->iamf, sc->pb, size, sc->iamf_stream_offset, pkt);
12205 if (ret < 0) {
12206 if (should_retry(sc->pb, ret))
12208 return ret;
12209 }
12210 size -= ret;
12211
12212 if (pkt->flags & AV_PKT_FLAG_DISCARD) {
12214 ret = 0;
12215 continue;
12216 }
12217 pkt->pts = pts; pkt->dts = dts;
12218 pkt->pos = pos; pkt->flags |= flags;
12219 pkt->duration = duration;
12220 ret = ff_buffer_packet(s, pkt);
12221 }
12222 if (!ret)
12223 return FFERROR_REDO;
12224 }
12225#endif
12226 else if (st->codecpar->codec_id == AV_CODEC_ID_APV && sample->size > 4) {
12227 uint32_t au_size = avio_rb32(sc->pb);
12228 int explode = !!(mov->fc->error_recognition & AV_EF_EXPLODE);
12229 if (au_size > sample->size - 4) {
12230 av_log(s, explode ? AV_LOG_ERROR : AV_LOG_WARNING,
12231 "APV au_size %u exceeds sample body %d\n",
12232 au_size, sample->size - 4);
12233 if (explode)
12234 return AVERROR_INVALIDDATA;
12235 au_size = sample->size - 4;
12236 }
12237 ret = av_get_packet(sc->pb, pkt, au_size);
12238 } else
12239 ret = av_get_packet(sc->pb, pkt, sample->size);
12240 if (ret < 0) {
12241 if (should_retry(sc->pb, ret)) {
12243 }
12244 return ret;
12245 }
12246#if CONFIG_DV_DEMUXER
12247 if (mov->dv_demux && sc->dv_audio_container) {
12248 ret = avpriv_dv_produce_packet(mov->dv_demux, NULL, pkt->data, pkt->size, pkt->pos);
12250 if (ret < 0)
12251 return ret;
12252 ret = avpriv_dv_get_packet(mov->dv_demux, pkt);
12253 if (ret < 0)
12254 return ret;
12255 }
12256#endif
12257 if (sc->has_palette) {
12258 uint8_t *pal;
12259
12261 if (!pal) {
12262 av_log(mov->fc, AV_LOG_ERROR, "Cannot append palette to packet\n");
12263 } else {
12264 memcpy(pal, sc->palette, AVPALETTE_SIZE);
12265 sc->has_palette = 0;
12266 }
12267 }
12268 if (st->codecpar->codec_id == AV_CODEC_ID_MP3 && !ffstream(st)->need_parsing && pkt->size > 4) {
12269 if (ff_mpa_check_header(AV_RB32(pkt->data)) < 0)
12271 }
12272 }
12273
12274 ret = mov_finalize_packet(s, st, sample, current_index, pkt);
12275 if (ret < 0)
12276 return ret;
12277
12278 if (st->discard == AVDISCARD_ALL)
12279 goto retry;
12280
12281 if (mov->aax_mode)
12282 aax_filter(pkt->data, pkt->size, mov);
12283
12284 ret = cenc_filter(mov, st, sc, pkt, current_index);
12285 if (ret < 0) {
12286 return ret;
12287 }
12288
12289 return 0;
12290}
12291
12293{
12294 MOVContext *mov = s->priv_data;
12295 int index;
12296
12297 if (!mov->frag_index.complete)
12298 return 0;
12299
12300 index = search_frag_timestamp(s, &mov->frag_index, st, timestamp);
12301 if (index < 0)
12302 index = 0;
12303 if (!mov->frag_index.item[index].headers_read)
12304 return mov_switch_root(s, -1, index);
12305 if (index + 1 < mov->frag_index.nb_items)
12307
12308 return 0;
12309}
12310
12312{
12313 // TODO: a bisect search would scale much better
12314 for (int i = 0; i < sc->open_key_samples_count; i++) {
12315 const int oks = sc->open_key_samples[i];
12316 if (oks == sample)
12317 return 1;
12318 if (oks > sample) /* list is monotically increasing so we can stop early */
12319 break;
12320 }
12321 return 0;
12322}
12323
12324/*
12325 * Some key sample may be key frames but not IDR frames, so a random access to
12326 * them may not be allowed.
12327 */
12328static int can_seek_to_key_sample(AVStream *st, int sample, int64_t requested_pts)
12329{
12330 MOVStreamContext *sc = st->priv_data;
12331 FFStream *const sti = ffstream(st);
12332 int64_t key_sample_dts, key_sample_pts;
12333
12335 return 1;
12336
12337 if (sample >= sc->sample_offsets_count)
12338 return 1;
12339
12340 av_assert0(sample >= 0);
12341 key_sample_dts = sti->index_entries[sample].timestamp;
12342 key_sample_pts = key_sample_dts + sc->sample_offsets[sample] + sc->dts_shift;
12343
12344 /*
12345 * If the sample needs to be presented before an open key sample, they may
12346 * not be decodable properly, even though they come after in decoding
12347 * order.
12348 */
12349 if (is_open_key_sample(sc, sample) && key_sample_pts > requested_pts)
12350 return 0;
12351
12352 return 1;
12353}
12354
12355static int mov_seek_stream(AVFormatContext *s, AVStream *st, int64_t timestamp, int flags)
12356{
12357 MOVStreamContext *sc = st->priv_data;
12358 FFStream *const sti = ffstream(st);
12359 int sample, time_sample, ret, requested_sample;
12360 int64_t next_ts;
12361 unsigned int i;
12362
12363 // Here we consider timestamp to be PTS, hence try to offset it so that we
12364 // can search over the DTS timeline.
12365 timestamp -= (sc->min_corrected_pts + sc->dts_shift);
12366
12367 ret = mov_seek_fragment(s, st, timestamp);
12368 if (ret < 0)
12369 return ret;
12370
12371 for (;;) {
12372 sample = av_index_search_timestamp(st, timestamp, flags);
12373 av_log(s, AV_LOG_TRACE, "stream %d, timestamp %"PRId64", sample %d\n", st->index, timestamp, sample);
12374 if (sample < 0 && sti->nb_index_entries && timestamp < sti->index_entries[0].timestamp)
12375 sample = 0;
12376 if (sample < 0) /* not sure what to do */
12377 return AVERROR_INVALIDDATA;
12378
12379 if (!sample || can_seek_to_key_sample(st, sample, timestamp))
12380 break;
12381
12382 next_ts = timestamp - FFMAX(sc->min_sample_duration, 1);
12383 requested_sample = av_index_search_timestamp(st, next_ts, flags);
12384 if (requested_sample < 0)
12385 return AVERROR_INVALIDDATA;
12386
12387 // If we've reached a different sample trying to find a good pts to
12388 // seek to, give up searching because we'll end up seeking back to
12389 // sample 0 on every seek.
12390 if (sample != requested_sample && !can_seek_to_key_sample(st, requested_sample, next_ts))
12391 break;
12392
12393 timestamp = next_ts;
12394 }
12395
12397 av_log(s, AV_LOG_TRACE, "stream %d, found sample %d\n", st->index, sc->current_sample);
12398 /* adjust time to sample index */
12399 if (sc->tts_data) {
12400 time_sample = 0;
12401 for (i = 0; i < sc->tts_count; i++) {
12402 int next = time_sample + sc->tts_data[i].count;
12403 if (next > sc->current_sample) {
12404 sc->tts_index = i;
12405 sc->tts_sample = sc->current_sample - time_sample;
12406 break;
12407 }
12408 time_sample = next;
12409 }
12410 }
12411
12412 /* adjust stsd index */
12413 if (sc->chunk_count) {
12414 time_sample = 0;
12415 for (i = 0; i < sc->stsc_count; i++) {
12416 int64_t next = time_sample + mov_get_stsc_samples(sc, i);
12417 if (next > sc->current_sample) {
12418 sc->stsc_index = i;
12419 sc->stsc_sample = sc->current_sample - time_sample;
12420 break;
12421 }
12422 av_assert0(next == (int)next);
12423 time_sample = next;
12424 }
12425 }
12426
12427 return sample;
12428}
12429
12431{
12432 FFStream *const sti = ffstream(st);
12433 int64_t first_ts = sti->index_entries[0].timestamp;
12435 int64_t off;
12436
12438 return 0;
12439
12440 /* compute skip samples according to stream initial_padding, seek ts and first ts */
12441 off = av_rescale_q(ts - first_ts, st->time_base,
12442 (AVRational){1, st->codecpar->sample_rate});
12443 return FFMAX(st->codecpar->initial_padding - off, 0);
12444}
12445
12446static int mov_read_seek(AVFormatContext *s, int stream_index, int64_t sample_time, int flags)
12447{
12448 MOVContext *mc = s->priv_data;
12449 AVStream *st;
12450 FFStream *sti;
12451 int sample;
12452 int i;
12453
12454 if (stream_index >= s->nb_streams)
12455 return AVERROR_INVALIDDATA;
12456
12457 st = s->streams[stream_index];
12458 sti = ffstream(st);
12459 sample = mov_seek_stream(s, st, sample_time, flags);
12460 if (sample < 0)
12461 return sample;
12462
12463 if (mc->seek_individually) {
12464 /* adjust seek timestamp to found sample timestamp */
12465 int64_t seek_timestamp = sti->index_entries[sample].timestamp;
12467
12468 for (i = 0; i < s->nb_streams; i++) {
12469 AVStream *const st = s->streams[i];
12470 FFStream *const sti = ffstream(st);
12471 int64_t timestamp;
12472
12473 if (stream_index == i)
12474 continue;
12475
12476 timestamp = av_rescale_q(seek_timestamp, s->streams[stream_index]->time_base, st->time_base);
12477 sample = mov_seek_stream(s, st, timestamp, flags);
12478 if (sample >= 0)
12480 }
12481 } else {
12482 for (i = 0; i < s->nb_streams; i++) {
12483 MOVStreamContext *sc;
12484 st = s->streams[i];
12485 sc = st->priv_data;
12487 }
12488 while (1) {
12489 MOVStreamContext *sc;
12491 if (!entry)
12492 return AVERROR_INVALIDDATA;
12493 sc = st->priv_data;
12494 if (sc->ffindex == stream_index && sc->current_sample == sample)
12495 break;
12497 }
12498 }
12499 return 0;
12500}
12501
12502#define OFFSET(x) offsetof(MOVContext, x)
12503#define FLAGS AV_OPT_FLAG_VIDEO_PARAM | AV_OPT_FLAG_DECODING_PARAM
12504static const AVOption mov_options[] = {
12505 {"use_absolute_path",
12506 "allow using absolute path when opening alias, this is a possible security issue",
12507 OFFSET(use_absolute_path), AV_OPT_TYPE_BOOL, {.i64 = 0},
12508 0, 1, FLAGS},
12509 {"seek_streams_individually",
12510 "Seek each stream individually to the closest point",
12511 OFFSET(seek_individually), AV_OPT_TYPE_BOOL, { .i64 = 1 },
12512 0, 1, FLAGS},
12513 {"ignore_editlist", "Ignore the edit list atom.", OFFSET(ignore_editlist), AV_OPT_TYPE_BOOL, {.i64 = 0},
12514 0, 1, FLAGS},
12515 {"advanced_editlist",
12516 "Modify the AVIndex according to the editlists. Use this option to decode in the order specified by the edits.",
12517 OFFSET(advanced_editlist), AV_OPT_TYPE_BOOL, {.i64 = 1},
12518 0, 1, FLAGS},
12519 {"ignore_chapters", "", OFFSET(ignore_chapters), AV_OPT_TYPE_BOOL, {.i64 = 0},
12520 0, 1, FLAGS},
12521 {"use_mfra_for",
12522 "use mfra for fragment timestamps",
12523 OFFSET(use_mfra_for), AV_OPT_TYPE_INT, {.i64 = FF_MOV_FLAG_MFRA_AUTO},
12525 .unit = "use_mfra_for"},
12526 {"auto", "auto", 0, AV_OPT_TYPE_CONST, {.i64 = FF_MOV_FLAG_MFRA_AUTO}, 0, 0,
12527 FLAGS, .unit = "use_mfra_for" },
12528 {"dts", "dts", 0, AV_OPT_TYPE_CONST, {.i64 = FF_MOV_FLAG_MFRA_DTS}, 0, 0,
12529 FLAGS, .unit = "use_mfra_for" },
12530 {"pts", "pts", 0, AV_OPT_TYPE_CONST, {.i64 = FF_MOV_FLAG_MFRA_PTS}, 0, 0,
12531 FLAGS, .unit = "use_mfra_for" },
12532 {"use_tfdt", "use tfdt for fragment timestamps", OFFSET(use_tfdt), AV_OPT_TYPE_BOOL, {.i64 = 1},
12533 0, 1, FLAGS},
12534 { "export_all", "Export unrecognized metadata entries", OFFSET(export_all),
12535 AV_OPT_TYPE_BOOL, { .i64 = 0 }, 0, 1, .flags = FLAGS },
12536 { "export_xmp", "Export full XMP metadata", OFFSET(export_xmp),
12537 AV_OPT_TYPE_BOOL, { .i64 = 0 }, 0, 1, .flags = FLAGS },
12538 { "activation_bytes", "Secret bytes for Audible AAX files", OFFSET(activation_bytes),
12540 { "audible_key", "AES-128 Key for Audible AAXC files", OFFSET(audible_key),
12542 { "audible_iv", "AES-128 IV for Audible AAXC files", OFFSET(audible_iv),
12544 { "audible_fixed_key", // extracted from libAAX_SDK.so and AAXSDKWin.dll files!
12545 "Fixed key used for handling Audible AAX files", OFFSET(audible_fixed_key),
12546 AV_OPT_TYPE_BINARY, {.str="77214d4b196a87cd520045fd20a51d67"},
12547 .flags = AV_OPT_FLAG_DECODING_PARAM },
12548 { "decryption_key", "The default media decryption key (hex)", OFFSET(decryption_default_key), AV_OPT_TYPE_BINARY, .flags = AV_OPT_FLAG_DECODING_PARAM },
12549 { "decryption_keys", "The media decryption keys by KID (hex)", OFFSET(decryption_keys), AV_OPT_TYPE_DICT, .flags = AV_OPT_FLAG_DECODING_PARAM },
12550 { "enable_drefs", "Enable external track support.", OFFSET(enable_drefs), AV_OPT_TYPE_BOOL,
12551 {.i64 = 0}, 0, 1, FLAGS },
12552 { "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 },
12553 { "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 },
12554
12555 { NULL },
12556};
12557
12558static const AVClass mov_class = {
12559 .class_name = "mov,mp4,m4a,3gp,3g2,mj2",
12560 .item_name = av_default_item_name,
12561 .option = mov_options,
12562 .version = LIBAVUTIL_VERSION_INT,
12563};
12564
12566 .p.name = "mov,mp4,m4a,3gp,3g2,mj2",
12567 .p.long_name = NULL_IF_CONFIG_SMALL("QuickTime / MOV"),
12568 .p.priv_class = &mov_class,
12569 .p.extensions = "mov,mp4,m4a,3gp,3g2,mj2,psp,m4v,m4b,ism,ismv,isma,f4v,avif,heic,heif",
12571 .priv_data_size = sizeof(MOVContext),
12572 .flags_internal = FF_INFMT_FLAG_INIT_CLEANUP,
12578};
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:12565
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:964
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:837
void ff_remove_stream(AVFormatContext *s, AVStream *st)
Remove a stream from its AVFormatContext and free it.
Definition avformat.c:122
void ff_remove_stream_group(AVFormatContext *s, AVStreamGroup *stg)
Remove a stream group from its AVFormatContext and free it.
Definition avformat.c:130
Main libavformat public API header.
#define AVFMT_EVENT_FLAG_METADATA_UPDATED
Definition avformat.h:1729
#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:1488
@ AV_STREAM_GROUP_PARAMS_DOLBY_VISION
Definition avformat.h:1155
@ AV_STREAM_GROUP_PARAMS_TREF
Definition avformat.h:1154
@ AV_STREAM_GROUP_PARAMS_IAMF_MIX_PRESENTATION
Definition avformat.h:1151
@ AV_STREAM_GROUP_PARAMS_TILE_GRID
Definition avformat.h:1152
@ AV_STREAM_GROUP_PARAMS_IAMF_AUDIO_ELEMENT
Definition avformat.h:1150
@ AV_STREAM_GROUP_PARAMS_LCEVC
Definition avformat.h:1153
#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:2620
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:2618
#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:220
@ AV_FIELD_TT
Top coded_first, top displayed first.
Definition defs.h:223
@ AV_FIELD_BB
Bottom coded first, bottom displayed first.
Definition defs.h:224
@ AV_FIELD_UNKNOWN
Definition defs.h:221
@ AV_FIELD_PROGRESSIVE
Definition defs.h:222
@ AV_FIELD_BT
Bottom coded first, top displayed first.
Definition defs.h:226
@ AV_FIELD_TB
Top coded first, bottom displayed first.
Definition defs.h:225
#define AV_PROFILE_DTS_96_24
Definition defs.h:98
AVAudioServiceType
Definition defs.h:244
@ AV_AUDIO_SERVICE_TYPE_KARAOKE
Definition defs.h:253
#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:349
static int loop
Definition ffplay.c:357
static int64_t start_time
Definition ffplay.c:348
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:556
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:459
@ 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:494
@ 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:610
@ AV_CODEC_ID_PCM_S16LE
Definition codec_id.h:331
@ AV_CODEC_ID_GSM
as in Berlin toast format
Definition codec_id.h:472
@ AV_CODEC_ID_DVD_SUBTITLE
Definition codec_id.h:567
@ AV_CODEC_ID_TTML
Definition codec_id.h:591
@ 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:470
@ AV_CODEC_ID_EIA_608
Definition codec_id.h:577
@ AV_CODEC_ID_AMR_NB
Definition codec_id.h:435
@ 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:454
@ AV_CODEC_ID_DVAUDIO
Definition codec_id.h:460
@ 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:608
@ AV_CODEC_ID_AAC
Definition codec_id.h:456
@ 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:478
@ AV_CODEC_ID_AMR_WB
Definition codec_id.h:436
@ AV_CODEC_ID_AC3
Definition codec_id.h:457
@ AV_CODEC_ID_MACE3
Definition codec_id.h:463
@ AV_CODEC_ID_MACE6
Definition codec_id.h:464
@ AV_CODEC_ID_QDM2
Definition codec_id.h:473
@ 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:489
@ AV_CODEC_ID_AVUI
Definition codec_id.h:252
@ AV_CODEC_ID_ILBC
Definition codec_id.h:513
@ AV_CODEC_ID_MP3
preferred ID for decoding MPEG audio layer 1, 2 or 3
Definition codec_id.h:455
@ 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:504
@ AV_CODEC_ID_ITUT_T35
Definition codec_id.h:612
@ 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:241
@ AVDISCARD_NONKEY
discard all frames except keyframes
Definition defs.h:240
AVPacketSideData * av_packet_side_data_new(AVPacketSideData **psd, int *pnb_sd, enum AVPacketSideDataType type, size_t size, int flags)
Allocate a new packet side data.
Definition packet.c:620
AVPacketSideData * av_packet_side_data_add(AVPacketSideData **psd, int *pnb_sd, enum AVPacketSideDataType type, void *data, size_t size, int flags)
Wrap existing data as packet side data.
Definition packet.c:613
const AVPacketSideData * av_packet_side_data_get(const AVPacketSideData *sd, int nb_sd, enum AVPacketSideDataType type)
Get side information from a side data array.
Definition packet.c:570
@ AV_PKT_DATA_HEVC_CONF
Dolby Vision enhancement-layer HEVC decoder configuration.
Definition packet.h:384
@ AV_PKT_DATA_AMBIENT_VIEWING_ENVIRONMENT
Ambient viewing environment metadata, as defined by H.274.
Definition packet.h:327
@ AV_PKT_DATA_ICC_PROFILE
ICC profile data consisting of an opaque octet buffer following the format described by ISO 15076-1.
Definition packet.h:271
@ AV_PKT_DATA_MASTERING_DISPLAY_METADATA
Mastering display metadata (based on SMPTE-2086:2014).
Definition packet.h:219
@ AV_PKT_DATA_AUDIO_SERVICE_TYPE
This side data should be associated with an audio stream and corresponds to enum AVAudioServiceType.
Definition packet.h:117
@ AV_PKT_DATA_SPHERICAL
This side data should be associated with a video stream and corresponds to the AVSphericalMapping str...
Definition packet.h:225
@ AV_PKT_DATA_PALETTE
An AV_PKT_DATA_PALETTE side data packet contains exactly AVPALETTE_SIZE bytes worth of palette.
Definition packet.h:47
@ AV_PKT_DATA_ENCRYPTION_INFO
This side data contains encryption info for how to decrypt the packet.
Definition packet.h:252
@ AV_PKT_DATA_DISPLAYMATRIX
This side data contains a 3x3 transformation matrix describing an affine transformation that needs to...
Definition packet.h:105
@ AV_PKT_DATA_EXIF
Extensible image file format metadata.
Definition packet.h:369
@ AV_PKT_DATA_ENCRYPTION_INIT_INFO
This side data is encryption initialization data.
Definition packet.h:246
@ AV_PKT_DATA_NEW_EXTRADATA
The AV_PKT_DATA_NEW_EXTRADATA is used to notify the codec or the format that the extradata buffer was...
Definition packet.h:56
@ AV_PKT_DATA_STEREO3D
This side data should be associated with a video stream and contains Stereoscopic 3D information in f...
Definition packet.h:111
@ AV_PKT_DATA_FRAME_CROPPING
The number of pixels to discard from the top/bottom/left/right border of the decoded frame to obtain ...
Definition packet.h:340
@ AV_PKT_DATA_CONTENT_LIGHT_LEVEL
Content light level (based on CTA-861.3).
Definition packet.h:232
@ AV_PKT_DATA_DOVI_CONF
DOVI configuration ref: dolby-vision-bitstreams-within-the-iso-base-media-file-format-v2....
Definition packet.h:280
#define AV_PKT_FLAG_DISCARD
Flag is used to discard packets which are required to maintain valid decoder state but are not requir...
Definition packet.h:657
void av_packet_unref(AVPacket *pkt)
Wipe the packet.
Definition packet.c:434
uint8_t * av_packet_new_side_data(AVPacket *pkt, enum AVPacketSideDataType type, size_t size)
Allocate new information of a packet.
Definition packet.c:231
#define AV_PKT_FLAG_KEY
The packet contains a keyframe.
Definition packet.h:650
#define AV_PKT_FLAG_DISPOSABLE
Flag is used to indicate packets that contain frames that can be discarded by the decoder.
Definition packet.h:669
int av_packet_add_side_data(AVPacket *pkt, enum AVPacketSideDataType type, uint8_t *data, size_t size)
Wrap an existing array as a packet side data.
Definition packet.c:197
void av_shrink_packet(AVPacket *pkt, int size)
Reduce packet size, correctly zeroing padding.
Definition packet.c:113
int av_new_packet(AVPacket *pkt, int size)
Allocate the payload of a packet and initialize its fields with default values.
Definition packet.c:98
AVStreamGroup * avformat_stream_group_create(AVFormatContext *s, enum AVStreamGroupParamsType type, AVDictionary **options)
Add a new empty stream group to a media file.
Definition options.c:470
AVStream * avformat_new_stream(AVFormatContext *s, const struct AVCodec *c)
Add a new stream to a media file.
int avformat_stream_group_add_stream(AVStreamGroup *stg, AVStream *st)
Add an already allocated stream to a stream group.
Definition options.c:558
AVFormatContext * avformat_alloc_context(void)
Allocate an AVFormatContext.
Definition options.c:165
void avformat_free_context(AVFormatContext *s)
Free an AVFormatContext and all its streams.
Definition avformat.c:150
void av_url_split(char *proto, int proto_size, char *authorization, int authorization_size, char *hostname, int hostname_size, int *port_ptr, char *path, int path_size, const char *url)
Split a URL string into components.
Definition utils.c:361
int av_index_search_timestamp(AVStream *st, int64_t timestamp, int flags)
Get the index for a specific timestamp.
Definition seek.c:245
struct AVAESCTR * av_aes_ctr_alloc(void)
Allocate an AVAESCTR context.
Definition aes_ctr.c:41
int av_aes_ctr_init(struct AVAESCTR *a, const uint8_t *key)
Initialize an AVAESCTR context.
Definition aes_ctr.c:74
void av_aes_ctr_set_full_iv(struct AVAESCTR *a, const uint8_t *iv)
Forcefully change the "full" 16-byte iv, including the counter.
Definition aes_ctr.c:53
void av_aes_ctr_crypt(struct AVAESCTR *a, uint8_t *dst, const uint8_t *src, int count)
Process a buffer using a previously initialized context.
Definition aes_ctr.c:102
void av_aes_ctr_free(struct AVAESCTR *a)
Release an AVAESCTR context.
Definition aes_ctr.c:84
#define AES_CTR_KEY_SIZE
Definition aes_ctr.h:35
struct AVAES * av_aes_alloc(void)
Allocate an AVAES context.
Definition aes.c:37
int av_aes_init(AVAES *a, const uint8_t *key, int key_bits, int decrypt)
Initialize an AVAES context.
Definition aes.c:231
void av_aes_crypt(AVAES *a, uint8_t *dst, const uint8_t *src, int count, uint8_t *iv, int decrypt)
Encrypt or decrypt a buffer using a previously initialized context.
Definition aes.c:171
int av_channel_layout_retype(AVChannelLayout *channel_layout, enum AVChannelOrder order, int flags)
Change the AVChannelOrder of a channel layout.
#define AV_CHANNEL_LAYOUT_RETYPE_FLAG_CANONICAL
The specified retype target order is ignored and the simplest possible (canonical) order is used for ...
#define AV_CHANNEL_LAYOUT_STEREO
#define AV_CHANNEL_LAYOUT_MONO
int av_channel_layout_custom_init(AVChannelLayout *channel_layout, int nb_channels)
Initialize a custom channel layout with the specified number of channels.
void av_channel_layout_uninit(AVChannelLayout *channel_layout)
Free any allocated data in the channel layout and reset the channel count to 0.
int av_channel_layout_from_mask(AVChannelLayout *channel_layout, uint64_t mask)
Initialize a native channel layout from a bitmask indicating which channels are present.
@ AV_CHANNEL_ORDER_UNSPEC
Only the channel count is specified, without any further information about the channel order.
@ AV_CHAN_AMBISONIC_BASE
Range of channels between AV_CHAN_AMBISONIC_BASE and AV_CHAN_AMBISONIC_END represent Ambisonic compon...
int av_bprint_finalize(AVBPrint *buf, char **ret_str)
Finalize a print buffer.
Definition bprint.c: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:139
AVBufferRef * av_buffer_alloc(size_t size)
Allocate an AVBuffer of the given size using av_malloc().
Definition buffer.c:77
void av_dict_free(AVDictionary **pm)
Free all the memory allocated for an AVDictionary struct and all keys and values.
Definition dict.c:233
AVDictionaryEntry * av_dict_get(const AVDictionary *m, const char *key, const AVDictionaryEntry *prev, int flags)
Get a dictionary entry with matching key.
Definition dict.c:60
int av_dict_copy(AVDictionary **dst, const AVDictionary *src, int flags)
Copy entries from one AVDictionary struct into another.
Definition dict.c:247
#define AV_DICT_APPEND
If the entry already exists, append to it.
Definition dict.h:82
#define AV_DICT_DONT_STRDUP_VAL
Take ownership of a value that's been allocated with av_malloc() or another memory allocation functio...
Definition dict.h:79
int av_dict_set(AVDictionary **pm, const char *key, const char *value, int flags)
Set the given entry in *pm, overwriting an existing entry.
Definition dict.c:86
#define AV_DICT_DONT_OVERWRITE
Don't overwrite existing entries.
Definition dict.h:81
#define AV_DICT_DONT_STRDUP_KEY
Take ownership of a key that's been allocated with av_malloc() or another memory allocation function.
Definition dict.h:77
#define AV_DICT_MATCH_CASE
Only get an entry with exact-case key match.
Definition dict.h:74
int av_dict_set_int(AVDictionary **pm, const char *key, int64_t value, int flags)
Convenience wrapper for av_dict_set() that converts the value to a string and stores it.
Definition dict.c:177
#define AVERROR_PATCHWELCOME
Not yet implemented in FFmpeg, patches welcome.
Definition error.h:64
#define AVERROR_BUG
Internal bug, also see AVERROR_BUG2.
Definition error.h:52
#define AVERROR_INVALIDDATA
Invalid data found when processing input.
Definition error.h:61
#define AVERROR_EOF
End of file.
Definition error.h:57
#define av_err2str(errnum)
Convenience macro, the return value should be used only directly in function arguments but never stan...
Definition error.h:122
#define AVERROR(e)
Definition error.h:45
void av_iamf_audio_element_free(AVIAMFAudioElement **paudio_element)
Free an AVIAMFAudioElement and all its contents.
Definition iamf.c:338
@ AV_IAMF_AUDIO_ELEMENT_TYPE_SCENE
Definition iamf.h:349
void av_iamf_mix_presentation_free(AVIAMFMixPresentation **pmix_presentation)
Free an AVIAMFMixPresentation and all its contents.
Definition iamf.c:536
#define AV_LOG_TRACE
Extremely verbose debugging, useful for libav* development.
Definition log.h:236
#define AV_LOG_DEBUG
Stuff which is only useful for libav* developers.
Definition log.h:231
#define AV_LOG_WARNING
Something somehow does not look correct.
Definition log.h:216
#define AV_LOG_FATAL
Something went wrong and recovery is not possible.
Definition log.h:204
#define AV_LOG_VERBOSE
Detailed information.
Definition log.h:226
#define AV_LOG_INFO
Standard information.
Definition log.h:221
#define AV_LOG_ERROR
Something went wrong and cannot losslessly be recovered.
Definition log.h:210
const char * av_default_item_name(void *ptr)
Return the context name.
Definition log.c:241
AVRational av_add_q(AVRational b, AVRational c)
Add two rationals.
Definition rational.c:93
AVRational av_mul_q(AVRational b, AVRational c)
Multiply two rationals.
Definition rational.c:80
int av_reduce(int *dst_num, int *dst_den, int64_t num, int64_t den, int64_t max)
Reduce a fraction.
Definition rational.c:35
static AVRational av_make_q(int num, int den)
Create an AVRational.
Definition rational.h:71
AVRational av_d2q(double d, int max)
Convert a double precision floating point number to a rational.
Definition rational.c:110
static double av_q2d(AVRational a)
Convert an AVRational to a double.
Definition rational.h:104
static int av_cmp_q(AVRational a, AVRational b)
Compare two rationals.
Definition rational.h:89
AVRational av_sub_q(AVRational b, AVRational c)
Subtract one rational from another.
Definition rational.c:101
int64_t av_rescale(int64_t a, int64_t b, int64_t c)
Rescale a 64-bit integer with rounding to nearest.
int64_t av_rescale_q(int64_t a, AVRational bq, AVRational cq)
Rescale a 64-bit integer by 2 rational numbers.
void * av_dynarray2_add(void **tab_ptr, int *nb_ptr, size_t elem_size, const uint8_t *elem_data)
Add an element of size elem_size to a dynamic array.
Definition mem.c:341
void * av_fast_realloc(void *ptr, unsigned int *size, size_t min_size)
Reallocate the given buffer if it is not large enough, otherwise do nothing.
Definition mem.c:495
void * av_realloc_array(void *ptr, size_t nmemb, size_t size)
Definition mem.c:217
int av_reallocp(void *ptr, size_t size)
Allocate, reallocate, or free a block of memory through a pointer to a pointer.
Definition mem.c:188
int av_reallocp_array(void *ptr, size_t nmemb, size_t size)
Allocate, reallocate an array through a pointer to a pointer.
Definition mem.c:225
const char * av_get_media_type_string(enum AVMediaType media_type)
Return a string describing the media_type enum, NULL if media_type is unknown.
Definition utils.c:28
char * av_fourcc_make_string(char *buf, uint32_t fourcc)
Fill the provided buffer with a string containing a FourCC (four-character code) representation.
Definition utils.c:54
#define av_fourcc2str(fourcc)
Definition avutil.h:323
#define AV_FOURCC_MAX_STRING_SIZE
Definition avutil.h:321
@ AVMEDIA_TYPE_AUDIO
Definition avutil.h:201
@ AVMEDIA_TYPE_SUBTITLE
Definition avutil.h:203
@ AVMEDIA_TYPE_VIDEO
Definition avutil.h:200
@ AVMEDIA_TYPE_DATA
Opaque data information usually continuous.
Definition avutil.h:202
void av_sha_update(struct AVSHA *ctx, const uint8_t *data, size_t len)
Update hash value.
Definition sha.c:315
struct AVSHA * av_sha_alloc(void)
Allocate an AVSHA context.
Definition sha.c:46
void av_sha_final(AVSHA *ctx, uint8_t *digest)
Finish hashing and output digest value.
Definition sha.c:347
av_cold int av_sha_init(AVSHA *ctx, int bits)
Initialize SHA-1 or SHA-2 hashing.
Definition sha.c:274
size_t av_strlcat(char *dst, const char *src, size_t size)
Append the string src to the string dst, but to a total length of no more than size - 1 bytes,...
Definition avstring.c:95
char * av_stristr(const char *s1, const char *s2)
Locate the first case-independent occurrence in the string haystack of the string needle.
Definition avstring.c:58
int av_strstart(const char *str, const char *pfx, const char **ptr)
Return non-zero if pfx is a prefix of str.
Definition avstring.c:36
#define AV_NOPTS_VALUE
Undefined timestamp value.
Definition avutil.h:247
#define AV_TIME_BASE
Internal time base represented as integer.
Definition avutil.h:253
#define LIBAVUTIL_VERSION_INT
Definition version.h:85
void av_display_rotation_set(int32_t matrix[9], double angle)
Initialize a transformation matrix describing a pure clockwise rotation by the specified angle (in de...
Definition display.c: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
cl_device_type type
const VDPAUPixFmtMap * map
int ff_iamfdec_read_descriptors(IAMFContext *c, AVIOContext *pb, int max_size, void *log_ctx)
int ff_iamf_read_packet(AVFormatContext *s, IAMFDemuxContext *c, AVIOContext *pb, int max_size, int stream_id_offset, AVPacket *pkt)
void ff_iamf_read_deinit(IAMFDemuxContext *c)
const char *const ff_id3v1_genre_str[ID3v1_GENRE_MAX+1]
ID3v1 genres.
Definition id3v1.c:26
#define ID3v1_GENRE_MAX
Definition id3v1.h:29
#define r
Definition input.c:42
#define b
Definition input.c:43
static av_always_inline float av_int2float(uint32_t i)
Reinterpret a 32-bit integer as a float.
Definition intfloat.h:40
static av_always_inline double av_int2double(uint64_t i)
Reinterpret a 64-bit integer as a double.
Definition intfloat.h:60
#define AV_WB32(p, v)
#define AV_RB8(x)
#define AV_WL32(p, v)
#define AV_RL32(p)
#define AV_RB32(p)
#define AV_RB16A(p)
#define AV_WB64(p, v)
#define AV_WL32A(p, v)
#define AV_WB8(p, d)
#define AV_RB64(p)
#define AV_WB16(p, v)
#define AV_WL16A(p, v)
#define AV_RB16(p)
#define AV_RB32A(p)
int ff_mov_lang_to_iso639(unsigned code, char to[4])
Definition isom.c:261
const AVCodecTag ff_codec_movdata_tags[]
Definition isom.c:82
const struct MP4TrackKindMapping ff_mov_track_kind_table[]
Definition isom.c:465
const AVCodecTag ff_codec_movsubtitle_tags[]
Definition isom.c:75
#define MOV_TRUN_SAMPLE_DURATION
Definition isom.h:418
#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
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:264
Memory handling functions.
static int mlp_samplerate(int in)
Definition mlp_parse.h:87
static uint64_t truehd_layout(int chanmap)
Definition mlp_parse.h:105
static int mov_read_ilst(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition mov.c:5711
static int64_t mov_get_skip_samples(AVStream *st, int sample)
Definition mov.c:12430
static int search_frag_moof_offset(MOVFragmentIndex *frag_index, int64_t offset)
Definition mov.c:1769
static int mov_read_sbas(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition mov.c:2734
static int update_frag_index(MOVContext *c, int64_t offset)
Definition mov.c:1870
static int get_eia608_packet(AVIOContext *pb, AVPacket *pkt, int src_size)
Definition mov.c:11958
static int mov_read_iloc(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition mov.c:9429
static int mov_read_pack(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition mov.c:7123
static int find_prev_closest_index(AVStream *st, AVIndexEntry *e_old, int nb_old, MOVTimeToSample *tts_data, int64_t tts_count, int64_t timestamp_pts, int flag, int64_t *index, int64_t *tts_index, int64_t *tts_sample)
Find the closest previous frame to the timestamp_pts, in e_old index entries.
Definition mov.c:4223
static int mov_read_seek(AVFormatContext *s, int stream_index, int64_t sample_time, int flags)
Definition mov.c:12446
static HEIFItem * get_heif_item(MOVContext *c, unsigned id)
Get the requested item.
Definition mov.c:196
static void mov_free_stream_context(AVFormatContext *s, AVStream *st)
Definition mov.c:10593
static int mov_read_stsd(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition mov.c:3451
static void mov_parse_stsd_video(MOVContext *c, AVIOContext *pb, AVStream *st, MOVStreamContext *sc)
Definition mov.c:2925
static int heif_add_stream(MOVContext *c, HEIFItem *item)
Definition mov.c:5873
static int mov_read_dops(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition mov.c:9005
static int set_display_matrix_from_item(AVPacketSideData **coded_side_data, int *nb_coded_side_data, const HEIFItem *item)
Definition mov.c:10864
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:11898
static int mov_read_vexu_proj(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition mov.c:7341
static int mov_read_srat(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition mov.c:1093
static int get_key_from_kid(uint8_t *out, int len, MOVContext *c, AVEncryptionInfo *sample)
Definition mov.c:8589
static int mov_read_aclr(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition mov.c:2475
static int mov_read_idat(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition mov.c:9423
static int mov_parse_tmcd_streams(AVFormatContext *s)
Definition mov.c:11338
static int mov_read_lhvc(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition mov.c:9140
static int aax_filter(uint8_t *input, int size, MOVContext *c)
Definition mov.c:1634
static void mov_current_sample_dec(MOVStreamContext *sc)
Definition mov.c:4469
static int mov_finalize_stsd_entry(MOVContext *c, AVStream *st)
Definition mov.c:3329
static int mov_read_pitm(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition mov.c:9415
static int mov_seek_stream(AVFormatContext *s, AVStream *st, int64_t timestamp, int flags)
Definition mov.c:12355
static int mov_read_packet(AVFormatContext *s, AVPacket *pkt)
Definition mov.c:12111
static int mov_parse_lcevc_streams(AVFormatContext *s)
Definition mov.c:11461
static int mov_read_hvce(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition mov.c:9113
static int cbcs_scheme_decrypt(MOVContext *c, MOVStreamContext *sc, AVEncryptionInfo *sample, uint8_t *input, int size)
Definition mov.c:8822
static int mov_read_default(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition mov.c:10178
static int mov_finalize_packet(AVFormatContext *s, AVStream *st, AVIndexEntry *sample, int64_t current_index, AVPacket *pkt)
Definition mov.c:12027
static int mov_read_stss(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition mov.c:3659
static uint64_t mov_dts_channel_layout_to_mask(unsigned int code)
Definition mov.c:1209
static int64_t get_stream_info_time(MOVFragmentStreamInfo *frag_stream_info)
Definition mov.c:1793
static int mov_read_saio(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition mov.c:8231
static int mov_skip_multiple_stsd(MOVContext *c, AVIOContext *pb, int codec_tag, int format, int64_t size)
Definition mov.c:3303
#define DRM_BLOB_SIZE
Definition mov.c:1506
static int mov_add_tref_id(MovTref *tag, uint32_t id)
Definition mov.c:2660
static int mov_read_mdhd(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition mov.c:2002
static int mov_read_tmcd(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition mov.c:6822
int ff_mov_read_stsd_entries(MOVContext *c, AVIOContext *pb, int entries)
Definition mov.c:3350
static int mov_metadata_gnre(MOVContext *c, AVIOContext *pb, unsigned len, const char *key)
Definition mov.c:136
static int mov_read_dref(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition mov.c:654
static int mov_read_dpxe(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition mov.c:2403
static MovTref * mov_find_tref_tag(const MOVStreamContext *sc, uint32_t name)
Definition mov.c:2675
static int mov_read_eyes(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition mov.c:7414
static int cenc_scheme_decrypt(MOVContext *c, MOVStreamContext *sc, AVEncryptionInfo *sample, uint8_t *input, int size)
Definition mov.c:8626
static int mov_read_wave(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition mov.c:2523
static int read_image_iovl(AVFormatContext *s, const HEIFGrid *grid, AVStreamGroupTileGrid *tile_grid)
Definition mov.c:10980
static int mov_metadata_hmmt(MOVContext *c, AVIOContext *pb, unsigned len)
Definition mov.c:326
static int mov_read_iref_dimg(MOVContext *c, AVIOContext *pb, int version)
Definition mov.c:9660
static int mov_read_stsz(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition mov.c:3714
static int mov_dts_stream_construction_to_profile(unsigned int sc)
Definition mov.c:1176
static int rb_size(AVIOContext *pb, int64_t *value, int size)
Definition mov.c:9396
static int mov_read_chpl(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition mov.c:615
static int mov_read_header(AVFormatContext *s)
Definition mov.c:11626
static int mov_read_dfla(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition mov.c:8549
static int mov_read_stco(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition mov.c:2820
static int mov_read_st3d(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition mov.c:7076
static int mov_read_elst(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition mov.c:6748
static int test_same_origin(const char *src, const char *ref)
Definition mov.c:5379
static int sanity_checks(void *log_obj, MOVStreamContext *sc, int index)
Definition mov.c:5536
static void mov_current_sample_set(MOVStreamContext *sc, int current_sample)
Definition mov.c:4481
static int mov_merge_tts_data(MOVContext *mov, AVStream *st, int flags)
Definition mov.c:4897
static int mov_aaxc_crypto(MOVContext *c)
Definition mov.c:1609
static int mov_read_sv3d(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition mov.c:7204
static int mov_read_ddts(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition mov.c:1237
static int mov_read_sdtp(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition mov.c:3927
static int mov_read_stts(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition mov.c:3807
static int cenc_filter(MOVContext *mov, AVStream *st, MOVStreamContext *sc, AVPacket *pkt, int current_index)
Definition mov.c:8935
static const AVClass mov_class
Definition mov.c:12558
static int mov_read_sample_encryption_info(MOVContext *c, AVIOContext *pb, MOVStreamContext *sc, AVEncryptionInfo **sample, int use_subsamples)
Definition mov.c:7975
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:6894
static const uint32_t mac_to_unicode[128]
Definition mov.c:152
static int mov_read_sidx(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition mov.c:6536
static int mov_read_strf(MOVContext *c, AVIOContext *pb, MOVAtom atom)
An strf atom is a BITMAPINFOHEADER struct.
Definition mov.c:2798
static uint32_t get_sgpd_sync_index(const MOVStreamContext *sc, int nal_unit_type)
Definition mov.c:4819
static void fix_frag_index_entries(MOVFragmentIndex *frag_index, int index, int id, int entries)
Definition mov.c:1931
static int mov_read_rtmd_track(AVFormatContext *s, AVStream *st)
Definition mov.c:10508
static int mov_read_dec3(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition mov.c:1127
static int mov_read_dmlp(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition mov.c:9058
static int mov_metadata_int8_bypass_padding(MOVContext *c, AVIOContext *pb, unsigned len, const char *key)
Definition mov.c:113
static int mov_read_schm(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition mov.c:8447
static int mov_metadata_loci(MOVContext *c, AVIOContext *pb, unsigned len)
Definition mov.c:276
static int read_tfra(MOVContext *mov, AVIOContext *f)
Definition mov.c:10749
static int mov_seek_fragment(AVFormatContext *s, AVStream *st, int64_t timestamp)
Definition mov.c:12292
static int mov_read_extradata(MOVContext *c, AVIOContext *pb, MOVAtom atom, enum AVCodecID codec_id)
Definition mov.c:2362
static int mov_read_enda(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition mov.c:2116
static int mov_read_covr(MOVContext *c, AVIOContext *pb, int type, int len)
Definition mov.c:233
static int mov_read_adrm(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition mov.c:1508
static int mov_parse_dovi_streams(AVFormatContext *s)
Definition mov.c:11515
static int mov_read_chnl(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition mov.c:1318
static void mov_metadata_creation_time(MOVContext *c, AVIOContext *pb, AVDictionary **metadata, int version)
Definition mov.c:1972
static int mov_parse_exif_item(AVFormatContext *s, AVPacketSideData **coded_side_data, int *nb_coded_side_data, const HEIFItem *ref)
Definition mov.c:11049
static int mov_stsc_index_valid(unsigned int index, unsigned int count)
Definition mov.c:3597
static int mov_read_hdlr(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition mov.c:798
#define MOV_MERGE_STTS
Definition mov.c:4891
static int mov_read_dvcc_dvvc(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition mov.c:9093
static int should_retry(AVIOContext *pb, int error_code)
Definition mov.c:11891
static int mov_read_mvhd(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition mov.c:2048
static int mov_read_tfdt(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition mov.c:6157
static int mov_read_moov(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition mov.c:1696
static int mov_read_clli(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition mov.c:7022
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:3965
static int mov_read_kind(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition mov.c:9191
static int mov_read_sbgp(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition mov.c:4116
static int mov_metadata_track_or_disc_number(MOVContext *c, AVIOContext *pb, unsigned len, const char *key)
Definition mov.c:93
static int mov_read_ares(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition mov.c:2430
static int mov_read_pssh(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition mov.c:8326
static int mov_finalize_stsd_codec(MOVContext *c, AVIOContext *pb, AVStream *st, MOVStreamContext *sc)
Definition mov.c:3199
static int mov_read_tkhd(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition mov.c:5958
static int mov_read_iprp(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition mov.c:9899
static int mov_read_cdsc_rndr(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition mov.c:2703
static int cens_scheme_decrypt(MOVContext *c, MOVStreamContext *sc, AVEncryptionInfo *sample, uint8_t *input, int size)
Definition mov.c:8751
static int mov_read_alac(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition mov.c:2388
static int mov_read_mfra(MOVContext *c, AVIOContext *f)
Definition mov.c:10804
#define MIN_DATA_ENTRY_BOX_SIZE
Definition mov.c:653
static int mov_change_extradata(AVStream *st, AVPacket *pkt)
Definition mov.c:11934
static int mov_read_mdcv(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition mov.c:6941
static int mov_read_timecode_track(AVFormatContext *s, AVStream *st)
Definition mov.c:10534
static int mov_read_imir(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition mov.c:9880
static int mov_read_stps(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition mov.c:3618
static int mov_read_svq3(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition mov.c:2518
static int mov_read_pcmc(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition mov.c:2125
static int mov_parse_cdsc_and_rndr_streams(AVFormatContext *s)
Definition mov.c:11409
static const MOVParseTableEntry mov_default_parse_table[]
Definition mov.c:10043
static int mov_read_jp2h(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition mov.c:2398
static int mov_read_iref(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition mov.c:9787
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:8147
static int mov_read_hfov(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition mov.c:7658
static int mov_read_free(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition mov.c:7855
static int set_icc_profile_from_item(AVPacketSideData **coded_side_data, int *nb_coded_side_data, const HEIFItem *item)
Definition mov.c:10850
static int mov_read_infe(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition mov.c:9526
static int mov_read_stsc(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition mov.c:3517
static AVStream * get_curr_st(MOVContext *c)
Get the current stream in the parsing process.
Definition mov.c:215
static int mov_parse_stsd_data(MOVContext *c, AVIOContext *pb, AVStream *st, MOVStreamContext *sc, int64_t size)
Definition mov.c:3126
static int mov_read_mdat(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition mov.c:1498
static int cbc1_scheme_decrypt(MOVContext *c, MOVStreamContext *sc, AVEncryptionInfo *sample, uint8_t *input, int size)
Definition mov.c:8685
static int mov_metadata_int8_no_padding(MOVContext *c, AVIOContext *pb, unsigned len, const char *key)
Definition mov.c:127
static int search_frag_timestamp(AVFormatContext *s, MOVFragmentIndex *frag_index, AVStream *st, int64_t timestamp)
Definition mov.c:1845
static int mov_read_avid(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition mov.c:2408
static void fix_timescale(MOVContext *c, MOVStreamContext *sc)
Definition mov.c:5480
static int mov_read_custom(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition mov.c:5772
static int mov_read_dac3(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition mov.c:869
static int get_current_encryption_info(MOVContext *c, MOVEncryptionIndex **encryption_index, MOVStreamContext **sc)
Gets the current encryption info and associated current stream context.
Definition mov.c:7924
static int mov_read_close(AVFormatContext *s)
Definition mov.c:10658
static int mov_read_pasp(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition mov.c:1476
static int mov_open_dref(MOVContext *c, AVIOContext **pb, const char *src, MOVDref *ref)
Definition mov.c:5408
static MOVFragmentStreamInfo * get_frag_stream_info_from_pkt(MOVFragmentIndex *frag_index, AVPacket *pkt, int id)
Definition mov.c:8910
static int mov_read_avss(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition mov.c:2393
static int mov_read_tenc(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition mov.c:8478
static int mov_read_uuid(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition mov.c:7750
static int mov_read_chan(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition mov.c:1299
static int build_open_gop_key_points(AVStream *st)
Definition mov.c:4827
static void set_last_stream_little_endian(AVFormatContext *fc)
Definition mov.c:2087
static void mov_build_index(MOVContext *mov, AVStream *st)
Definition mov.c:4960
static void mov_update_sample_durations(MOVContext *mov, AVStream *st)
Definition mov.c:5294
static int mov_read_ctts(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition mov.c:3976
static int mov_find_tref_id(const MovTref *tag, uint32_t id)
Definition mov.c:2651
static int mov_read_amve(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition mov.c:7051
static int mov_read_keys(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition mov.c:5720
static int mov_read_wfex(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition mov.c:1352
static int mov_read_glbl(MOVContext *c, AVIOContext *pb, MOVAtom atom)
This function reads atom content and puts data in extradata without tag nor size unlike mov_read_extr...
Definition mov.c:2580
static int mov_read_ftyp(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition mov.c:1648
#define IS_MATRIX_IDENT(matrix)
Definition mov.c:5950
static int can_seek_to_key_sample(AVStream *st, int sample, int64_t requested_pts)
Definition mov.c:12328
static int mov_parse_auxiliary_info(MOVContext *c, MOVStreamContext *sc, AVIOContext *pb, MOVEncryptionIndex *encryption_index)
Definition mov.c:8085
static int64_t mov_get_stsc_samples(MOVStreamContext *sc, unsigned int index)
Definition mov.c:3603
static int mov_read_vpcc(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition mov.c:6850
static int64_t add_index_entry(AVStream *st, int64_t pos, int64_t timestamp, int size, int distance, int flags)
Add index entry with the given values, to the end of ffstream(st)->index_entries.
Definition mov.c:4319
static int mov_parse_tiles(AVFormatContext *s)
Definition mov.c:11133
static void mov_fix_index(MOVContext *mov, AVStream *st)
Fix ffstream(st)->index_entries, so that it contains only the entries (and the entries which are need...
Definition mov.c:4509
#define DDTS_SIZE
static int mov_read_iref_cdsc(MOVContext *c, AVIOContext *pb, uint32_t type, int version, uint32_t size)
Definition mov.c:9743
static int cenc_decrypt(MOVContext *c, MOVStreamContext *sc, AVEncryptionInfo *sample, uint8_t *input, int size)
Definition mov.c:8894
static int mov_read_senc(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition mov.c:8029
static int mov_read_sgpd(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition mov.c:4057
static AVStream * mov_find_reference_track(AVFormatContext *s, AVStream *st, uint32_t *tref_id, int nb_tref_id, int first_index)
Definition mov.c:11394
static void fix_index_entry_timestamps(AVStream *st, int end_index, int64_t end_ts, int64_t *frame_duration_buffer, int frame_duration_buffer_size)
Rewrite timestamps of index entries in the range [end_index - frame_duration_buffer_size,...
Definition mov.c:4360
static int mov_read_trak(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition mov.c:5555
static int mov_read_colr(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition mov.c:2202
static int add_tts_entry(MOVTimeToSample **tts_data, unsigned int *tts_count, unsigned int *allocated_size, int count, int offset, unsigned int duration)
Definition mov.c:4372
static void mov_parse_stsd_subtitle(MOVContext *c, AVIOContext *pb, AVStream *st, MOVStreamContext *sc, int64_t size)
Definition mov.c:3110
static int mov_read_clap(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition mov.c:1367
static int mov_read_dvc1(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition mov.c:2626
static int mov_read_vdep(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition mov.c:2766
static int mov_read_SAND(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition mov.c:9370
static int64_t mov_read_atom_into_extradata(MOVContext *c, AVIOContext *pb, MOVAtom atom, AVCodecParameters *par, uint8_t *buf)
Definition mov.c:2340
static void mov_free_encryption_index(MOVEncryptionIndex **index)
Definition mov.c:10581
static int mov_read_mac_string(MOVContext *c, AVIOContext *pb, int len, char *dst, int dstlen)
Definition mov.c:171
static void fix_stream_ids(AVFormatContext *s)
Definition mov.c:11588
#define OFFSET(x)
Definition mov.c:12502
static AVIndexEntry * mov_find_next_sample(AVFormatContext *s, AVStream **st)
Definition mov.c:11861
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:12311
static int mov_read_moof(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition mov.c:1946
static int mov_read_SA3D(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition mov.c:9280
static int mov_realloc_extradata(AVCodecParameters *par, MOVAtom atom)
Definition mov.c:2325
static int mov_read_udta_string(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition mov.c:347
static int mov_read_coll(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition mov.c:6985
static int mov_read_frma(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition mov.c:7877
static int mov_read_ispe(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition mov.c:9832
static int mov_codec_id(AVStream *st, uint32_t format)
Definition mov.c:2885
static void export_orphan_timecode(AVFormatContext *s)
Definition mov.c:10731
static int mov_parse_heif_items(AVFormatContext *s)
Definition mov.c:11259
static void mov_estimate_video_delay(MOVContext *c, AVStream *st)
Definition mov.c:4401
static int mov_read_vmhd(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition mov.c:10010
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:1714
static int mov_read_irot(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition mov.c:9860
static int read_image_grid(AVFormatContext *s, const HEIFGrid *grid, AVStreamGroupTileGrid *tile_grid)
Definition mov.c:10885
static int mov_probe(const AVProbeData *p)
Definition mov.c:10300
static int parse_timecode_in_framenum_format(AVFormatContext *s, AVStream *st, int64_t value, int flags)
Definition mov.c:10494
static int mov_parse_uuid_spherical(MOVStreamContext *sc, AVIOContext *pb, size_t len)
Definition mov.c:7687
static void mov_current_sample_inc(MOVStreamContext *sc)
Definition mov.c:4457
static int mov_read_fiel(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition mov.c:2291
static int mov_read_targa_y216(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition mov.c:2416
static int get_edit_list_entry(MOVContext *mov, const MOVStreamContext *msc, unsigned int edit_list_index, int64_t *edit_list_media_time, int64_t *edit_list_duration, int64_t global_timescale)
Get ith edit list entry (media time, duration).
Definition mov.c:4177
static void mov_parse_stsd_audio(MOVContext *c, AVIOContext *pb, AVStream *st, MOVStreamContext *sc)
Definition mov.c:2989
static int mov_read_wide(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition mov.c:6675
static int64_t get_frag_time(AVFormatContext *s, AVStream *dst_st, MOVFragmentIndex *frag_index, int index)
Definition mov.c:1803
static MOVFragmentStreamInfo * get_current_frag_stream_info(MOVFragmentIndex *frag_index)
Definition mov.c:1753
static int mov_read_esds(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition mov.c:864
static int mov_read_iinf(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition mov.c:9603
static int tmcd_is_referenced(AVFormatContext *s, int tmcd_id)
Definition mov.c:10713
static void mov_read_chapters(AVFormatContext *s)
Definition mov.c:10395
static int mov_read_cmov(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition mov.c:6695
static void set_frag_stream(MOVFragmentIndex *frag_index, int id)
Definition mov.c:1733
static const AVOption mov_options[]
Definition mov.c:12504
static MovTref * mov_add_tref_tag(MOVStreamContext *sc, uint32_t name)
Definition mov.c:2686
static int mov_read_vexu(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition mov.c:7596
int ff_mov_read_chan(AVFormatContext *s, AVIOContext *pb, AVStream *st, int64_t size)
Read 'chan' tag from the input stream.
Definition mov_chan.c:550
int ff_mov_read_chnl(AVFormatContext *s, AVIOContext *pb, AVStream *st, int version)
Read 'chnl' tag from the input stream.
Definition mov_chan.c:768
uint32_t tag
Definition movenc.c:2087
MPEG Audio header decoder.
static int ff_mpa_check_header(uint32_t header)
const char data[16]
Definition mxf.c:149
int profile
Definition mxfenc.c:2299
uint16_t cid
Definition mxfenc.c:2335
static float distance(float x, float y, int band)
#define OPUS_SEEK_PREROLL_MS
#define av_realloc(p, s)
Definition ops_static.c:54
#define av_malloc(s)
Definition ops_static.c:52
AVOptions.
const char * av_color_space_name(enum AVColorSpace space)
Definition pixdesc.c:3860
const char * av_color_transfer_name(enum AVColorTransferCharacteristic transfer)
Definition pixdesc.c:3827
const char * av_color_primaries_name(enum AVColorPrimaries primaries)
Definition pixdesc.c:3794
@ AVCOL_RANGE_MPEG
Narrow or limited range content.
Definition pixfmt.h:766
@ AVCOL_RANGE_JPEG
Full range content.
Definition pixfmt.h:783
@ 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:1335
AVStream ** streams
A list of all streams in the file.
Definition avformat.h:1403
int error_recognition
Error recognition; higher values will detect more errors but may misdetect some more or less valid pa...
Definition avformat.h:1609
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:1120
unsigned int el_index
Index of the enhancement layer stream in AVStreamGroup.
Definition avformat.h:1104
int width
Width of the final stream for presentation.
Definition avformat.h:1116
unsigned int metadata_index
Index of the metadata stream in the AVStreamGroup.
Definition avformat.h:1145
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:1188
struct AVIAMFMixPresentation * iamf_mix_presentation
Definition avformat.h:1195
struct AVStreamGroupTileGrid * tile_grid
Definition avformat.h:1196
unsigned int nb_streams
Number of elements in AVStreamGroup.streams.
Definition avformat.h:1223
struct AVStreamGroupTREF * tref
Definition avformat.h:1205
AVDictionary * metadata
Metadata that applies to the whole group.
Definition avformat.h:1216
struct AVIAMFAudioElement * iamf_audio_element
Definition avformat.h:1194
int disposition
Stream group disposition - a combination of AV_DISPOSITION_* flags.
Definition avformat.h:1246
int64_t id
Group type-specific group ID.
Definition avformat.h:1180
AVStream ** streams
A list of streams in the group.
Definition avformat.h:1236
struct AVStreamGroupLayeredVideo * layered_video
Definition avformat.h:1197
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:86
uint32_t type
Definition mov.c:85
unsigned int index
Definition isom.h:129
unsigned int count
Definition isom.h:128
int64_t time_offset
time offset of the edit list entries
Definition isom.h:217
int64_t duration_for_fps
Definition isom.h:257
AVIOContext * pb
Definition isom.h:180
size_t spherical_size
Definition isom.h:270
uint32_t min_sample_duration
Definition isom.h:254
uint8_t ** extradata
extradata array (and size) for multiple stsd
Definition isom.h:260
MOVSbgp * rap_group
Definition isom.h:245
int iamf_stream_offset
Definition isom.h:290
MOVEncryptionIndex * encryption_index
Definition isom.h:286
int64_t track_end
used for dts generation in fragmented movie files
Definition isom.h:243
int pseudo_stream_id
-1 means demux all ids
Definition isom.h:226
unsigned int rap_group_count
Definition isom.h:244
int height
tkhd height
Definition isom.h:234
int stsc_sample
Definition isom.h:202
MOVDref * drefs
Definition isom.h:229
int sample_offsets_count
Definition isom.h:251
unsigned int ctts_allocated_size
Definition isom.h:197
unsigned int per_sample_iv_size
Definition isom.h:284
int * extradata_size
Definition isom.h:261
size_t coll_size
Definition isom.h:274
int dv_audio_container
Definition isom.h:225
AVContentLightMetadata * coll
Definition isom.h:273
int64_t * chunk_offsets
Definition isom.h:187
size_t ambient_size
Definition isom.h:276
MOVStsc * stsc_data
Definition isom.h:200
uint8_t * sgpd_sync
Definition isom.h:248
size_t stereo3d_size
Definition isom.h:268
MOVTimeToSample * tts_data
Definition isom.h:190
AVStereo3D * stereo3d
Definition isom.h:267
int32_t * display_matrix
Definition isom.h:266
int current_sample
Definition isom.h:219
uint32_t sgpd_sync_count
Definition isom.h:249
unsigned int samples_per_frame
Definition isom.h:224
int nb_frames_for_fps
Definition isom.h:256
uint32_t format
Definition isom.h:278
int keyframe_absent
Definition isom.h:213
int open_key_samples_count
Definition isom.h:253
MOVElst * elst_data
Definition isom.h:205
int64_t current_index
Definition isom.h:220
int * open_key_samples
Definition isom.h:252
unsigned int stts_count
Definition isom.h:191
uint8_t * sdtp_data
Definition isom.h:195
unsigned int sample_size
may contain value calculated from stsd or value from stsz atom
Definition isom.h:209
AVEncryptionInfo * default_encrypted_sample
Definition isom.h:285
int nb_tref_tags
Definition isom.h:231
int16_t audio_cid
stsd audio compression id
Definition isom.h:227
struct AVAESCTR * aes_ctr
Definition isom.h:282
MOVStts * stts_data
Definition isom.h:193
int last_stsd_index
Definition isom.h:262
unsigned int chunk_count
Definition isom.h:186
size_t mastering_size
Definition isom.h:272
AVAmbientViewingEnvironment * ambient
Definition isom.h:275
int64_t data_size
Definition isom.h:240
int pb_is_copied
Definition isom.h:182
int * keyframes
Definition isom.h:215
struct MOVStreamContext::@212112112267365060330232277203165117121340225276 cenc
unsigned drefs_count
Definition isom.h:228
MOVIndexRange * current_index_range
Definition isom.h:222
unsigned int * sample_sizes
Definition isom.h:212
MOVCtts * ctts_data
Definition isom.h:198
AVMasteringDisplayMetadata * mastering
Definition isom.h:271
int width
tkhd width
Definition isom.h:233
int id
AVStream id.
Definition isom.h:183
uint8_t tmcd_nb_frames
tmcd number of frames per tick / second
Definition isom.h:242
unsigned int sdtp_count
Definition isom.h:194
int v_spacing
pasp vSpacing
Definition isom.h:236
unsigned int sample_count
Definition isom.h:211
MOVSbgp * sync_group
Definition isom.h:247
int dts_shift
dts shift when ctts is negative
Definition isom.h:237
unsigned int tts_count
Definition isom.h:188
int stsd_version
Definition isom.h:264
unsigned int stsc_index
Definition isom.h:201
int64_t min_corrected_pts
minimum Composition time shown by the edits excluding empty edits.
Definition isom.h:218
struct AVAES * aes_ctx
Definition isom.h:283
int32_t * sample_offsets
Definition isom.h:250
int has_palette
Definition isom.h:239
MovTref * tref_tags
Definition isom.h:232
uint32_t palette[256]
Definition isom.h:238
int ffindex
AVStream index.
Definition isom.h:184
AVSphericalMapping * spherical
Definition isom.h:269
unsigned int keyframe_count
Definition isom.h:214
unsigned int bytes_per_frame
Definition isom.h:223
uint32_t tmcd_flags
tmcd track flags
Definition isom.h:241
unsigned * stps_data
partial sync sample for mpeg-2 open gop
Definition isom.h:204
unsigned int stts_allocated_size
Definition isom.h:192
unsigned int sync_group_count
Definition isom.h:246
MOVIndexRange * index_ranges
Definition isom.h:221
struct IAMFDemuxContext * iamf
Definition isom.h:289
unsigned int stsc_count
Definition isom.h:199
unsigned int stsz_sample_size
always contains sample size from stsz atom
Definition isom.h:210
int h_spacing
pasp hSpacing
Definition isom.h:235
unsigned int elst_count
Definition isom.h:206
unsigned int ctts_count
Definition isom.h:196
unsigned int stps_count
Definition isom.h:203
unsigned int tts_allocated_size
Definition isom.h:189
int first
Definition isom.h:74
int count
Definition isom.h:75
int id
Definition isom.h:76
Definition isom.h:63
unsigned int count
Definition isom.h:64
unsigned int duration
Definition isom.h:65
unsigned int count
Definition isom.h:58
unsigned int duration
Definition isom.h:59
unsigned flags
Definition isom.h:124
unsigned duration
Definition isom.h:122
unsigned size
Definition isom.h:123
unsigned track_id
Definition isom.h:120
unsigned stsd_id
Definition isom.h:121
const char * value
Definition isom.h: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
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]