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 if (av_reallocp_array(&frame_duration_buffer, num_discarded_begin,
4708 sizeof(*frame_duration_buffer)) < 0) {
4709 av_log(mov->fc, AV_LOG_ERROR, "Cannot reallocate frame duration buffer\n");
4710 break;
4711 }
4712 frame_duration_buffer[num_discarded_begin - 1] = frame_duration;
4713
4714 // Increment skip_samples for the first non-zero audio edit list
4716 first_non_zero_audio_edit > 0 && st->codecpar->codec_id != AV_CODEC_ID_VORBIS) {
4717 sti->skip_samples += frame_duration;
4718 }
4719 }
4720 }
4721 } else {
4722 if (msc->min_corrected_pts < 0) {
4723 msc->min_corrected_pts = edit_list_dts_counter + curr_ctts + msc->dts_shift;
4724 } else {
4725 msc->min_corrected_pts = FFMIN(msc->min_corrected_pts, edit_list_dts_counter + curr_ctts + msc->dts_shift);
4726 }
4727 if (edit_list_start_encountered == 0) {
4728 edit_list_start_encountered = 1;
4729 // Make timestamps strictly monotonically increasing by rewriting timestamps for
4730 // discarded packets.
4731 if (frame_duration_buffer) {
4732 fix_index_entry_timestamps(st, sti->nb_index_entries, edit_list_dts_counter,
4733 frame_duration_buffer, num_discarded_begin);
4734 av_freep(&frame_duration_buffer);
4735 }
4736 }
4737 }
4738
4739 if (add_index_entry(st, current->pos, edit_list_dts_counter, current->size,
4740 current->min_distance, flags) == -1) {
4741 av_log(mov->fc, AV_LOG_ERROR, "Cannot add index entry\n");
4742 break;
4743 }
4744
4745 // Update the index ranges array
4746 if (!current_index_range || index != current_index_range->end) {
4747 current_index_range = current_index_range ? current_index_range + 1
4748 : msc->index_ranges;
4749 current_index_range->start = index;
4750 }
4751 current_index_range->end = index + 1;
4752
4753 // Only start incrementing DTS in frame_duration amounts, when we encounter a frame in edit list.
4754 if (edit_list_start_encountered > 0) {
4755 edit_list_dts_counter = edit_list_dts_counter + frame_duration;
4756 }
4757
4758 // Break when found first key frame after edit entry completion
4759 if ((curr_cts + frame_duration >= (edit_list_duration + edit_list_media_time)) &&
4761 if (msc->ctts_count) {
4762 // If we have CTTS and this is the first keyframe after edit elist,
4763 // wait for one more, because there might be trailing B-frames after this I-frame
4764 // that do belong to the edit.
4765 if (st->codecpar->codec_type != AVMEDIA_TYPE_AUDIO && found_keyframe_after_edit == 0) {
4766 found_keyframe_after_edit = 1;
4767 continue;
4768 }
4769 if (tts_sample_old != 0) {
4770 if (add_tts_entry(&msc->tts_data, &msc->tts_count,
4771 &msc->tts_allocated_size,
4772 tts_sample_old - edit_list_start_tts_sample,
4773 tts_data_old[tts_index_old].offset, tts_data_old[tts_index_old].duration) == -1) {
4774 av_log(mov->fc, AV_LOG_ERROR, "Cannot add Time To Sample entry %"PRId64" - {%"PRId64", %d}\n",
4775 tts_index_old, tts_sample_old - edit_list_start_tts_sample,
4776 tts_data_old[tts_index_old].offset);
4777 break;
4778 }
4779 }
4780 }
4781 break;
4782 }
4783 }
4784 }
4785 // If there are empty edits, then msc->min_corrected_pts might be positive
4786 // intentionally. So we subtract the sum duration of empty edits here.
4787 msc->min_corrected_pts -= empty_edits_sum_duration;
4788
4789 // If the minimum pts turns out to be greater than zero after fixing the index, then we subtract the
4790 // dts by that amount to make the first pts zero.
4792 if (msc->min_corrected_pts > 0) {
4793 av_log(mov->fc, AV_LOG_DEBUG, "Offset DTS by %"PRId64" to make first pts zero.\n", msc->min_corrected_pts);
4794 for (int i = 0; i < sti->nb_index_entries; ++i)
4796 }
4797 }
4798 // Start time should be equal to zero or the duration of any empty edits.
4799 st->start_time = empty_edits_sum_duration;
4800
4801 // Update av stream length, if it ends up shorter than the track's media duration
4802 st->duration = FFMIN(st->duration, edit_list_dts_entry_end - start_dts);
4804
4805 // Free the old index and the old CTTS structures
4806 av_free(e_old);
4807 av_free(tts_data_old);
4808 av_freep(&frame_duration_buffer);
4809
4810 // Null terminate the index ranges array
4811 current_index_range = current_index_range ? current_index_range + 1
4812 : msc->index_ranges;
4813 current_index_range->start = 0;
4814 current_index_range->end = 0;
4815 msc->current_index = msc->index_ranges[0].start;
4816}
4817
4818static uint32_t get_sgpd_sync_index(const MOVStreamContext *sc, int nal_unit_type)
4819{
4820 for (uint32_t i = 0; i < sc->sgpd_sync_count; i++)
4821 if (sc->sgpd_sync[i] == nal_unit_type)
4822 return i + 1;
4823 return 0;
4824}
4825
4827{
4828 int k;
4829 int sample_id = 0;
4830 uint32_t cra_index;
4831 MOVStreamContext *sc = st->priv_data;
4832
4834 return 0;
4835
4836 /* Build an unrolled index of the samples */
4837 sc->sample_offsets_count = 0;
4838 for (uint32_t i = 0; i < sc->ctts_count; i++) {
4839 if (sc->ctts_data[i].count > INT_MAX - sc->sample_offsets_count)
4840 return AVERROR(ENOMEM);
4842 }
4845 if (!sc->sample_offsets)
4846 return AVERROR(ENOMEM);
4847 k = 0;
4848 for (uint32_t i = 0; i < sc->ctts_count; i++)
4849 for (int j = 0; j < sc->ctts_data[i].count; j++)
4850 sc->sample_offsets[k++] = sc->ctts_data[i].offset;
4851
4852 /* The following HEVC NAL type reveal the use of open GOP sync points
4853 * (TODO: BLA types may also be concerned) */
4854 cra_index = get_sgpd_sync_index(sc, HEVC_NAL_CRA_NUT); /* Clean Random Access */
4855 if (!cra_index)
4856 return 0;
4857
4858 /* Build a list of open-GOP key samples */
4859 sc->open_key_samples_count = 0;
4860 for (uint32_t i = 0; i < sc->sync_group_count; i++)
4861 if (sc->sync_group[i].index == cra_index) {
4862 if (sc->sync_group[i].count > INT_MAX - sc->open_key_samples_count)
4863 return AVERROR(ENOMEM);
4865 }
4868 if (!sc->open_key_samples)
4869 return AVERROR(ENOMEM);
4870 k = 0;
4871 for (uint32_t i = 0; i < sc->sync_group_count; i++) {
4872 const MOVSbgp *sg = &sc->sync_group[i];
4873 if (sg->index == cra_index)
4874 for (uint32_t j = 0; j < sg->count; j++)
4875 sc->open_key_samples[k++] = sample_id;
4876 if (sg->count > INT_MAX - sample_id)
4877 return AVERROR_PATCHWELCOME;
4878 sample_id += sg->count;
4879 }
4880
4881 /* Identify the minimal time step between samples */
4882 sc->min_sample_duration = UINT_MAX;
4883 for (uint32_t i = 0; i < sc->stts_count; i++)
4885
4886 return 0;
4887}
4888
4889#define MOV_MERGE_CTTS 1
4890#define MOV_MERGE_STTS 2
4891/*
4892 * Merge stts and ctts arrays into a new combined array.
4893 * stts_count and ctts_count may be left untouched as they will be
4894 * used to check for the presence of either of them.
4895 */
4897{
4898 MOVStreamContext *sc = st->priv_data;
4899 int ctts = sc->ctts_data && (flags & MOV_MERGE_CTTS);
4900 int stts = sc->stts_data && (flags & MOV_MERGE_STTS);
4901 int idx = 0;
4902
4903 if (!sc->ctts_data && !sc->stts_data)
4904 return 0;
4905 // Expand time to sample entries such that we have a 1-1 mapping with samples
4906 if (!sc->sample_count || sc->sample_count >= UINT_MAX / sizeof(*sc->tts_data))
4907 return -1;
4908
4909 if (ctts) {
4911 sc->sample_count * sizeof(*sc->tts_data));
4912 if (!sc->tts_data)
4913 return -1;
4914
4915 memset(sc->tts_data, 0, sc->tts_allocated_size);
4916
4917 for (int i = 0; i < sc->ctts_count &&
4918 idx < sc->sample_count; i++)
4919 for (int j = 0; j < sc->ctts_data[i].count &&
4920 idx < sc->sample_count; j++) {
4921 sc->tts_data[idx].offset = sc->ctts_data[i].offset;
4922 sc->tts_data[idx++].count = 1;
4923 }
4924
4925 sc->tts_count = idx;
4926 } else
4927 sc->ctts_count = 0;
4928 av_freep(&sc->ctts_data);
4929 sc->ctts_allocated_size = 0;
4930
4931 idx = 0;
4932 if (stts) {
4934 sc->sample_count * sizeof(*sc->tts_data));
4935 if (!tts_data)
4936 return -1;
4937
4938 if (!sc->tts_data)
4939 memset(tts_data, 0, sc->tts_allocated_size);
4940 sc->tts_data = tts_data;
4941
4942 for (int i = 0; i < sc->stts_count &&
4943 idx < sc->sample_count; i++)
4944 for (int j = 0; j < sc->stts_data[i].count &&
4945 idx < sc->sample_count; j++) {
4946 sc->tts_data[idx].duration = sc->stts_data[i].duration;
4947 sc->tts_data[idx++].count = 1;
4948 }
4949
4950 sc->tts_count = FFMAX(sc->tts_count, idx);
4951 } else
4952 sc->stts_count = 0;
4953 av_freep(&sc->stts_data);
4954 sc->stts_allocated_size = 0;
4955
4956 return 0;
4957}
4958
4960{
4961 MOVStreamContext *sc = st->priv_data;
4962 FFStream *const sti = ffstream(st);
4963 int64_t current_offset;
4964 int64_t current_dts = 0;
4965 unsigned int stts_index = 0;
4966 unsigned int stsc_index = 0;
4967 unsigned int stss_index = 0;
4968 unsigned int stps_index = 0;
4969 unsigned int i, j;
4970 uint64_t stream_size = 0;
4971
4972 int ret = build_open_gop_key_points(st);
4973 if (ret < 0)
4974 return;
4975
4976 if (sc->elst_count) {
4977 int i, edit_start_index = 0, multiple_edits = 0;
4978 int64_t empty_duration = 0; // empty duration of the first edit list entry
4979 int64_t start_time = 0; // start time of the media
4980
4981 for (i = 0; i < sc->elst_count; i++) {
4982 const MOVElst *e = &sc->elst_data[i];
4983 if (i == 0 && e->time == -1) {
4984 /* if empty, the first entry is the start time of the stream
4985 * relative to the presentation itself */
4986 empty_duration = e->duration;
4987 edit_start_index = 1;
4988 } else if (i == edit_start_index && e->time >= 0) {
4989 start_time = e->time;
4990 } else {
4991 multiple_edits = 1;
4992 }
4993 }
4994
4995 if (multiple_edits && !mov->advanced_editlist) {
4997 av_log(mov->fc, AV_LOG_WARNING, "multiple edit list entries, "
4998 "not supported in fragmented MP4 files\n");
4999 else
5000 av_log(mov->fc, AV_LOG_WARNING, "multiple edit list entries, "
5001 "Use -advanced_editlist to correctly decode otherwise "
5002 "a/v desync might occur\n");
5003 }
5004
5005 /* adjust first dts according to edit list */
5006 if ((empty_duration || start_time) && mov->time_scale > 0) {
5007 if (empty_duration)
5008 empty_duration = av_rescale(empty_duration, sc->time_scale, mov->time_scale);
5009
5010 if (av_sat_sub64(start_time, empty_duration) != start_time - (uint64_t)empty_duration)
5011 av_log(mov->fc, AV_LOG_WARNING, "start_time - empty_duration is not representable\n");
5012
5013 sc->time_offset = start_time - (uint64_t)empty_duration;
5015 if (!mov->advanced_editlist)
5016 current_dts = -av_clip64(sc->time_offset, -INT64_MAX, INT64_MAX);
5017 }
5018
5019 if (!multiple_edits && !mov->advanced_editlist &&
5022 (AVRational){1, st->codecpar->sample_rate});
5023 }
5024
5025 /* only use old uncompressed audio chunk demuxing when stts specifies it */
5026 if (!(st->codecpar->codec_type == AVMEDIA_TYPE_AUDIO &&
5027 sc->stts_count == 1 && sc->stts_data && sc->stts_data[0].duration == 1)) {
5028 unsigned int current_sample = 0;
5029 unsigned int stts_sample = 0;
5030 unsigned int sample_size;
5031 unsigned int distance = 0;
5032 unsigned int rap_group_index = 0;
5033 unsigned int rap_group_sample = 0;
5034 int rap_group_present = sc->rap_group_count && sc->rap_group;
5035 int key_off = (sc->keyframe_count && sc->keyframes[0] > 0) || (sc->stps_count && sc->stps_data[0] > 0);
5036
5037 av_assert0(sc->dts_shift >= 0);
5038 if (current_dts < INT64_MIN + sc->dts_shift)
5039 return;
5040 current_dts -= sc->dts_shift;
5041 if (!sc->sample_count || sti->nb_index_entries || sc->tts_count)
5042 return;
5043 if (sc->sample_count >= UINT_MAX / sizeof(*sti->index_entries) - sti->nb_index_entries)
5044 return;
5046 sti->nb_index_entries + sc->sample_count,
5047 sizeof(*sti->index_entries)) < 0) {
5048 sti->nb_index_entries = 0;
5049 return;
5050 }
5051 sti->index_entries_allocated_size = (sti->nb_index_entries + sc->sample_count) * sizeof(*sti->index_entries);
5052
5054 if (ret < 0)
5055 return;
5056
5057 for (i = 0; i < sc->chunk_count; i++) {
5058 int64_t next_offset = i+1 < sc->chunk_count ? sc->chunk_offsets[i+1] : INT64_MAX;
5059 current_offset = sc->chunk_offsets[i];
5060 while (mov_stsc_index_valid(stsc_index, sc->stsc_count) &&
5061 i + 1 == sc->stsc_data[stsc_index + 1].first)
5062 stsc_index++;
5063
5064 if (next_offset > current_offset && sc->sample_size>0 && sc->sample_size < sc->stsz_sample_size &&
5065 sc->stsc_data[stsc_index].count * (int64_t)sc->stsz_sample_size > next_offset - current_offset) {
5066 av_log(mov->fc, AV_LOG_WARNING, "STSZ sample size %d invalid (too large), ignoring\n", sc->stsz_sample_size);
5067 sc->stsz_sample_size = sc->sample_size;
5068 }
5069 if (sc->stsz_sample_size>0 && sc->stsz_sample_size < sc->sample_size) {
5070 av_log(mov->fc, AV_LOG_WARNING, "STSZ sample size %d invalid (too small), ignoring\n", sc->stsz_sample_size);
5071 sc->stsz_sample_size = sc->sample_size;
5072 }
5073
5074 for (j = 0; j < sc->stsc_data[stsc_index].count; j++) {
5075 int keyframe = 0;
5076 if (current_sample >= sc->sample_count) {
5077 av_log(mov->fc, AV_LOG_ERROR, "wrong sample count\n");
5078 return;
5079 }
5080
5081 if (!sc->keyframe_absent && (!sc->keyframe_count || current_sample+key_off == sc->keyframes[stss_index])) {
5082 keyframe = 1;
5083 if (stss_index + 1 < sc->keyframe_count)
5084 stss_index++;
5085 } else if (sc->stps_count && current_sample+key_off == sc->stps_data[stps_index]) {
5086 keyframe = 1;
5087 if (stps_index + 1 < sc->stps_count)
5088 stps_index++;
5089 }
5090 if (rap_group_present && rap_group_index < sc->rap_group_count) {
5091 if (sc->rap_group[rap_group_index].index > 0)
5092 keyframe = 1;
5093 if (++rap_group_sample == sc->rap_group[rap_group_index].count) {
5094 rap_group_sample = 0;
5095 rap_group_index++;
5096 }
5097 }
5098 if (sc->keyframe_absent
5099 && !sc->stps_count
5100 && !rap_group_present
5101 && (st->codecpar->codec_type == AVMEDIA_TYPE_AUDIO || (i==0 && j==0)))
5102 keyframe = 1;
5103 if (keyframe)
5104 distance = 0;
5105 sample_size = sc->stsz_sample_size > 0 ? sc->stsz_sample_size : sc->sample_sizes[current_sample];
5106 if (current_offset > INT64_MAX - sample_size) {
5107 av_log(mov->fc, AV_LOG_ERROR, "Current offset %"PRId64" or sample size %u is too large\n",
5108 current_offset,
5109 sample_size);
5110 return;
5111 }
5112
5113 if (sc->pseudo_stream_id == -1 ||
5114 sc->stsc_data[stsc_index].id - 1 == sc->pseudo_stream_id) {
5115 AVIndexEntry *e;
5116 if (sample_size > 0x3FFFFFFF) {
5117 av_log(mov->fc, AV_LOG_ERROR, "Sample size %u is too large\n", sample_size);
5118 return;
5119 }
5120 e = &sti->index_entries[sti->nb_index_entries++];
5121 e->pos = current_offset;
5122 e->timestamp = current_dts;
5123 e->size = sample_size;
5125 e->flags = keyframe ? AVINDEX_KEYFRAME : 0;
5126 av_log(mov->fc, AV_LOG_TRACE, "AVIndex stream %d, sample %u, offset %"PRIx64", dts %"PRId64", "
5127 "size %u, distance %u, keyframe %d\n", st->index, current_sample,
5128 current_offset, current_dts, sample_size, distance, keyframe);
5129 if (st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO && sti->nb_index_entries < 100)
5130 ff_rfps_add_frame(mov->fc, st, current_dts);
5131 }
5132
5133 current_offset += sample_size;
5134 stream_size += sample_size;
5135
5136 if (current_dts > INT64_MAX - sc->tts_data[stts_index].duration)
5137 return;
5138 current_dts += sc->tts_data[stts_index].duration;
5139
5140 distance++;
5141 stts_sample++;
5142 current_sample++;
5143 if (stts_index + 1 < sc->tts_count && stts_sample == sc->tts_data[stts_index].count) {
5144 stts_sample = 0;
5145 stts_index++;
5146 }
5147 }
5148 }
5149 if (st->duration > 0)
5150 st->codecpar->bit_rate = stream_size*8*sc->time_scale/st->duration;
5151 } else {
5152 unsigned chunk_samples, total = 0;
5153
5154 if (!sc->chunk_count || sc->tts_count)
5155 return;
5156
5157 // compute total chunk count
5158 for (i = 0; i < sc->stsc_count; i++) {
5159 unsigned count, chunk_count;
5160
5161 chunk_samples = sc->stsc_data[i].count;
5162 if (i != sc->stsc_count - 1 &&
5163 sc->samples_per_frame && chunk_samples % sc->samples_per_frame) {
5164 av_log(mov->fc, AV_LOG_ERROR, "error unaligned chunk\n");
5165 return;
5166 }
5167
5168 if (sc->samples_per_frame >= 160) { // gsm
5169 count = chunk_samples / sc->samples_per_frame;
5170 } else if (sc->samples_per_frame > 1) {
5171 unsigned samples = (1024/sc->samples_per_frame)*sc->samples_per_frame;
5172 count = (chunk_samples+samples-1) / samples;
5173 } else {
5174 count = (chunk_samples+1023) / 1024;
5175 }
5176
5178 chunk_count = sc->stsc_data[i+1].first - sc->stsc_data[i].first;
5179 else
5180 chunk_count = sc->chunk_count - (sc->stsc_data[i].first - 1);
5181 total += chunk_count * count;
5182 }
5183
5184 av_log(mov->fc, AV_LOG_TRACE, "chunk count %u\n", total);
5185 if (total >= UINT_MAX / sizeof(*sti->index_entries) - sti->nb_index_entries)
5186 return;
5188 sti->nb_index_entries + total,
5189 sizeof(*sti->index_entries)) < 0) {
5190 sti->nb_index_entries = 0;
5191 return;
5192 }
5193 sti->index_entries_allocated_size = (sti->nb_index_entries + total) * sizeof(*sti->index_entries);
5194
5195 // populate index
5196 for (i = 0; i < sc->chunk_count; i++) {
5197 current_offset = sc->chunk_offsets[i];
5198 if (mov_stsc_index_valid(stsc_index, sc->stsc_count) &&
5199 i + 1 == sc->stsc_data[stsc_index + 1].first)
5200 stsc_index++;
5201 chunk_samples = sc->stsc_data[stsc_index].count;
5202
5203 while (chunk_samples > 0) {
5204 AVIndexEntry *e;
5205 unsigned size, samples;
5206
5207 if (sc->samples_per_frame > 1 && !sc->bytes_per_frame) {
5209 "Zero bytes per frame, but %d samples per frame",
5210 sc->samples_per_frame);
5211 return;
5212 }
5213
5214 if (sc->samples_per_frame >= 160) { // gsm
5215 samples = sc->samples_per_frame;
5216 size = sc->bytes_per_frame;
5217 } else {
5218 if (sc->samples_per_frame > 1) {
5219 samples = FFMIN((1024 / sc->samples_per_frame)*
5220 sc->samples_per_frame, chunk_samples);
5221 size = (samples / sc->samples_per_frame) * sc->bytes_per_frame;
5222 } else {
5223 samples = FFMIN(1024, chunk_samples);
5224 size = samples * sc->sample_size;
5225 }
5226 }
5227
5228 if (sti->nb_index_entries >= total) {
5229 av_log(mov->fc, AV_LOG_ERROR, "wrong chunk count %u\n", total);
5230 return;
5231 }
5232 if (size > 0x3FFFFFFF) {
5233 av_log(mov->fc, AV_LOG_ERROR, "Sample size %u is too large\n", size);
5234 return;
5235 }
5236 e = &sti->index_entries[sti->nb_index_entries++];
5237 e->pos = current_offset;
5238 e->timestamp = current_dts;
5239 e->size = size;
5240 e->min_distance = 0;
5242 av_log(mov->fc, AV_LOG_TRACE, "AVIndex stream %d, chunk %u, offset %"PRIx64", dts %"PRId64", "
5243 "size %u, duration %u\n", st->index, i, current_offset, current_dts,
5244 size, samples);
5245
5246 current_offset += size;
5247 if (current_dts > INT64_MAX - samples)
5248 return;
5249 current_dts += samples;
5250 chunk_samples -= samples;
5251 }
5252 }
5253
5254 ret = mov_merge_tts_data(mov, st, MOV_MERGE_CTTS);
5255 if (ret < 0)
5256 return;
5257 }
5258
5259 if (!mov->ignore_editlist && mov->advanced_editlist) {
5260 // Fix index according to edit lists.
5261 mov_fix_index(mov, st);
5262 }
5263
5264 // Update start time of the stream.
5267 if (sc->tts_data) {
5269 }
5270 }
5271
5272 mov_estimate_video_delay(mov, st);
5273}
5274
5279
5280static int mov_compare_presentation_samples(const void *a, const void *b)
5281{
5282 const MOVPresentationSample *sa = a;
5283 const MOVPresentationSample *sb = b;
5284
5285 if (sa->pts != sb->pts)
5286 return (sa->pts > sb->pts) - (sa->pts < sb->pts);
5287 return (sa->index > sb->index) - (sa->index < sb->index);
5288}
5289
5290/*
5291 * Set sample durations from adjacent presentation timestamps.
5292 */
5294{
5295 MOVStreamContext *sc = st->priv_data;
5296 FFStream *const sti = ffstream(st);
5297 MOVPresentationSample *samples = NULL;
5298 MOVTimeToSample *tts_data = NULL;
5299 unsigned int tts_index = 0, tts_sample = 0;
5300 int count = sti->nb_index_entries;
5301
5302 /* A single STTS entry describes a fixed sample delta. */
5304 !sc->ctts_count || sc->stts_count < 2 ||
5305 !sc->tts_data || count < 2 ||
5306 count >= UINT_MAX / sizeof(*tts_data))
5307 return;
5308
5309 samples = av_malloc_array(count, sizeof(*samples));
5310 tts_data = av_malloc_array(count, sizeof(*tts_data));
5311 if (!samples || !tts_data)
5312 goto fail;
5313
5314 for (int i = 0; i < count; i++) {
5315 int64_t dts, offset;
5316
5317 if (tts_index >= sc->tts_count || !sc->tts_data[tts_index].count)
5318 goto fail;
5319
5320 tts_data[i] = sc->tts_data[tts_index];
5321 tts_data[i].count = 1;
5322
5323 dts = sti->index_entries[i].timestamp;
5324 offset = (int64_t)sc->dts_shift + tts_data[i].offset;
5325 if (dts == AV_NOPTS_VALUE ||
5326 (offset > 0 && dts > INT64_MAX - offset) ||
5327 (offset < 0 && dts < INT64_MIN - offset))
5328 goto fail;
5329
5330 samples[i].index = i;
5331 samples[i].pts = dts + offset;
5332
5333 if (++tts_sample == sc->tts_data[tts_index].count) {
5334 tts_index++;
5335 tts_sample = 0;
5336 }
5337 }
5338 if (tts_index != sc->tts_count || tts_sample)
5339 goto fail;
5340
5341 qsort(samples, count, sizeof(*samples), mov_compare_presentation_samples);
5342
5343 for (int i = 0; i + 1 < count; i++) {
5344 uint64_t duration;
5345
5346 if (samples[i].pts >= samples[i + 1].pts)
5347 goto fail;
5348
5349 /*
5350 * In VFR streams with reordered frames, STTS deltas follow decode
5351 * order while AVPacket.duration follows presentation order. CTTS
5352 * may produce presentation intervals that cannot be obtained by
5353 * merely permuting the STTS deltas, so derive each known duration
5354 * from adjacent PTS.
5355 */
5356 duration = (uint64_t)samples[i + 1].pts - samples[i].pts;
5357 if (!duration || duration > UINT_MAX)
5358 goto fail;
5359
5360 tts_data[samples[i].index].duration = (unsigned int)duration;
5361 }
5362
5363 av_log(mov->fc, AV_LOG_DEBUG,
5364 "Updated sample durations in presentation order for stream %d\n",
5365 st->index);
5366
5367 av_freep(&sc->tts_data);
5368 sc->tts_data = tts_data;
5369 sc->tts_count = count;
5370 sc->tts_allocated_size = count * sizeof(*tts_data);
5371 tts_data = NULL;
5372
5373fail:
5374 av_free(samples);
5375 av_free(tts_data);
5376}
5377
5378static int test_same_origin(const char *src, const char *ref) {
5379 char src_proto[64];
5380 char ref_proto[64];
5381 char src_auth[256];
5382 char ref_auth[256];
5383 char src_host[256];
5384 char ref_host[256];
5385 int src_port=-1;
5386 int ref_port=-1;
5387
5388 av_url_split(src_proto, sizeof(src_proto), src_auth, sizeof(src_auth), src_host, sizeof(src_host), &src_port, NULL, 0, src);
5389 av_url_split(ref_proto, sizeof(ref_proto), ref_auth, sizeof(ref_auth), ref_host, sizeof(ref_host), &ref_port, NULL, 0, ref);
5390
5391 if (strlen(src) == 0) {
5392 return -1;
5393 } else if (strlen(src_auth) + 1 >= sizeof(src_auth) ||
5394 strlen(ref_auth) + 1 >= sizeof(ref_auth) ||
5395 strlen(src_host) + 1 >= sizeof(src_host) ||
5396 strlen(ref_host) + 1 >= sizeof(ref_host)) {
5397 return 0;
5398 } else if (strcmp(src_proto, ref_proto) ||
5399 strcmp(src_auth, ref_auth) ||
5400 strcmp(src_host, ref_host) ||
5401 src_port != ref_port) {
5402 return 0;
5403 } else
5404 return 1;
5405}
5406
5407static int mov_open_dref(MOVContext *c, AVIOContext **pb, const char *src, MOVDref *ref)
5408{
5409 /* try relative path, we do not try the absolute because it can leak information about our
5410 system to an attacker */
5411 if (ref->nlvl_to > 0 && ref->nlvl_from > 0) {
5412 char filename[1025];
5413 const char *src_path;
5414 int i, l;
5415
5416 /* find a source dir */
5417 src_path = strrchr(src, '/');
5418 if (src_path)
5419 src_path++;
5420 else
5421 src_path = src;
5422
5423 /* find a next level down to target */
5424 for (i = 0, l = strlen(ref->path) - 1; l >= 0; l--)
5425 if (ref->path[l] == '/') {
5426 if (i == ref->nlvl_to - 1)
5427 break;
5428 else
5429 i++;
5430 }
5431
5432 /* compose filename if next level down to target was found */
5433 if (i == ref->nlvl_to - 1 && src_path - src < sizeof(filename)) {
5434 memcpy(filename, src, src_path - src);
5435 filename[src_path - src] = 0;
5436
5437 for (i = 1; i < ref->nlvl_from; i++)
5438 av_strlcat(filename, "../", sizeof(filename));
5439
5440 av_strlcat(filename, ref->path + l + 1, sizeof(filename));
5441 if (!c->use_absolute_path) {
5442 int same_origin = test_same_origin(src, filename);
5443
5444 if (!same_origin) {
5445 av_log(c->fc, AV_LOG_ERROR,
5446 "Reference with mismatching origin, %s not tried for security reasons, "
5447 "set demuxer option use_absolute_path to allow it anyway\n",
5448 ref->path);
5449 return AVERROR(ENOENT);
5450 }
5451
5452 if (strstr(ref->path + l + 1, "..") ||
5453 strstr(ref->path + l + 1, ":") ||
5454 (ref->nlvl_from > 1 && same_origin < 0) ||
5455 (filename[0] == '/' && src_path == src))
5456 return AVERROR(ENOENT);
5457 }
5458
5459 if (strlen(filename) + 1 == sizeof(filename))
5460 return AVERROR(ENOENT);
5461 if (!c->fc->io_open(c->fc, pb, filename, AVIO_FLAG_READ, NULL))
5462 return 0;
5463 }
5464 } else if (c->use_absolute_path) {
5465 av_log(c->fc, AV_LOG_WARNING, "Using absolute path on user request, "
5466 "this is a possible security issue\n");
5467 if (!c->fc->io_open(c->fc, pb, ref->path, AVIO_FLAG_READ, NULL))
5468 return 0;
5469 } else {
5470 av_log(c->fc, AV_LOG_ERROR,
5471 "Absolute path %s not tried for security reasons, "
5472 "set demuxer option use_absolute_path to allow absolute paths\n",
5473 ref->path);
5474 }
5475
5476 return AVERROR(ENOENT);
5477}
5478
5480{
5481 if (sc->time_scale <= 0) {
5482 av_log(c->fc, AV_LOG_WARNING, "stream %d, timescale not set\n", sc->ffindex);
5483 sc->time_scale = c->time_scale;
5484 if (sc->time_scale <= 0)
5485 sc->time_scale = 1;
5486 }
5487}
5488
5489#if CONFIG_IAMFDEC
5490static int mov_update_iamf_streams(MOVContext *c, const AVStream *st)
5491{
5492 const MOVStreamContext *sc = st->priv_data;
5493 const IAMFContext *iamf = &sc->iamf->iamf;
5494
5495 for (int i = 0; i < iamf->nb_audio_elements; i++) {
5496 const AVStreamGroup *stg = NULL;
5497
5498 for (int j = 0; j < c->fc->nb_stream_groups; j++)
5499 if (c->fc->stream_groups[j]->id == iamf->audio_elements[i]->audio_element_id)
5500 stg = c->fc->stream_groups[j];
5501 av_assert0(stg);
5502
5503 for (int j = 0; j < stg->nb_streams; j++) {
5504 const FFStream *sti = cffstream(st);
5505 AVStream *out = stg->streams[j];
5506 FFStream *out_sti = ffstream(stg->streams[j]);
5507
5508 out->codecpar->bit_rate = 0;
5509
5510 if (out == st)
5511 continue;
5512
5513 out->time_base = st->time_base;
5514 out->start_time = st->start_time;
5515 out->duration = st->duration;
5516 out->nb_frames = st->nb_frames;
5517 out->discard = st->discard;
5518
5519 av_assert0(!out_sti->index_entries);
5521 if (!out_sti->index_entries)
5522 return AVERROR(ENOMEM);
5523
5525 out_sti->nb_index_entries = sti->nb_index_entries;
5526 out_sti->skip_samples = sti->skip_samples;
5527 memcpy(out_sti->index_entries, sti->index_entries, sti->index_entries_allocated_size);
5528 }
5529 }
5530
5531 return 0;
5532}
5533#endif
5534
5535static int sanity_checks(void *log_obj, MOVStreamContext *sc, int index)
5536{
5537 if ((sc->chunk_count && (!sc->stts_count || !sc->stsc_count ||
5538 (!sc->sample_size && !sc->sample_count))) ||
5539 (sc->sample_count && (!sc->chunk_count ||
5540 (!sc->sample_size && !sc->sample_sizes)))) {
5541 av_log(log_obj, AV_LOG_ERROR, "stream %d, missing mandatory atoms, broken header\n",
5542 index);
5543 return 1;
5544 }
5545
5546 if (sc->stsc_count && sc->stsc_data[ sc->stsc_count - 1 ].first > sc->chunk_count) {
5547 av_log(log_obj, AV_LOG_ERROR, "stream %d, contradictionary STSC and STCO\n",
5548 index);
5549 return 2;
5550 }
5551 return 0;
5552}
5553
5555{
5556 AVStream *st;
5557 MOVStreamContext *sc;
5558 int ret;
5559
5560 st = avformat_new_stream(c->fc, NULL);
5561 if (!st) return AVERROR(ENOMEM);
5562 st->id = -1;
5563 sc = av_mallocz(sizeof(MOVStreamContext));
5564 if (!sc) return AVERROR(ENOMEM);
5565
5566 st->priv_data = sc;
5568 sc->ffindex = st->index;
5569 c->trak_index = st->index;
5570 sc->refcount = 1;
5571
5572 if ((ret = mov_read_default(c, pb, atom)) < 0)
5573 return ret;
5574
5575 c->trak_index = -1;
5576
5577 // Here stsc refers to a chunk not described in stco. This is technically invalid,
5578 // but we can overlook it (clearing stsc) whenever stts_count == 0 (indicating no samples).
5579 if (!sc->chunk_count && !sc->stts_count && sc->stsc_count) {
5580 sc->stsc_count = 0;
5581 av_freep(&sc->stsc_data);
5582 }
5583
5584 ret = sanity_checks(c->fc, sc, st->index);
5585 if (ret)
5586 return ret > 1 ? AVERROR_INVALIDDATA : 0;
5587
5588 fix_timescale(c, sc);
5589
5590 avpriv_set_pts_info(st, 64, 1, sc->time_scale);
5591
5592 /*
5593 * Advanced edit list support does not work with fragemented MP4s, which
5594 * have stsc, stsz, stco, and stts with zero entries in the moov atom.
5595 * In these files, trun atoms may be streamed in.
5596 */
5597 if (!sc->stts_count && c->advanced_editlist) {
5598
5599 av_log(c->fc, AV_LOG_VERBOSE, "advanced_editlist does not work with fragmented "
5600 "MP4. disabling.\n");
5601 c->advanced_editlist = 0;
5602 c->advanced_editlist_autodisabled = 1;
5603 }
5604
5605 mov_build_index(c, st);
5606 /*
5607 * Fragment samples are appended later by mov_read_trun() and are not
5608 * covered by this non-fragmented track update.
5609 */
5611
5612#if CONFIG_IAMFDEC
5613 if (sc->iamf) {
5614 ret = mov_update_iamf_streams(c, st);
5615 if (ret < 0)
5616 return ret;
5617 }
5618#endif
5619
5620 if (sc->dref_id-1 < sc->drefs_count && sc->drefs[sc->dref_id-1].path) {
5621 MOVDref *dref = &sc->drefs[sc->dref_id - 1];
5622 if (c->enable_drefs) {
5623 if (mov_open_dref(c, &sc->pb, c->fc->url, dref) < 0)
5624 av_log(c->fc, AV_LOG_ERROR,
5625 "stream %d, error opening alias: path='%s', dir='%s', "
5626 "filename='%s', volume='%s', nlvl_from=%d, nlvl_to=%d\n",
5627 st->index, dref->path, dref->dir, dref->filename,
5628 dref->volume, dref->nlvl_from, dref->nlvl_to);
5629 } else {
5630 av_log(c->fc, AV_LOG_WARNING,
5631 "Skipped opening external track: "
5632 "stream %d, alias: path='%s', dir='%s', "
5633 "filename='%s', volume='%s', nlvl_from=%d, nlvl_to=%d."
5634 "Set enable_drefs to allow this.\n",
5635 st->index, dref->path, dref->dir, dref->filename,
5636 dref->volume, dref->nlvl_from, dref->nlvl_to);
5637 }
5638 } else {
5639 sc->pb = c->fc->pb;
5640 sc->pb_is_copied = 1;
5641 }
5642
5644 int stts_constant = sc->stts_count && sc->tts_count;
5645 if (sc->h_spacing && sc->v_spacing)
5647 sc->h_spacing, sc->v_spacing, INT_MAX);
5648 if (!st->sample_aspect_ratio.num && st->codecpar->width && st->codecpar->height &&
5649 sc->height && sc->width &&
5650 (st->codecpar->width != sc->width || st->codecpar->height != sc->height)) {
5652 (int64_t)st->codecpar->height * sc->width,
5653 (int64_t)st->codecpar->width * sc->height, INT_MAX);
5654 }
5655
5656#if FF_API_R_FRAME_RATE
5657 for (unsigned int i = 1; sc->stts_count && i + 1 < sc->tts_count; i++) {
5658 if (sc->tts_data[i].duration == sc->tts_data[0].duration)
5659 continue;
5660 stts_constant = 0;
5661 }
5662 if (stts_constant)
5664 sc->time_scale, sc->tts_data[0].duration, INT_MAX);
5665#endif
5666 }
5667
5668#if CONFIG_H261_DECODER || CONFIG_H263_DECODER || CONFIG_MPEG4_DECODER
5669 switch (st->codecpar->codec_id) {
5670#if CONFIG_H261_DECODER
5671 case AV_CODEC_ID_H261:
5672#endif
5673#if CONFIG_H263_DECODER
5674 case AV_CODEC_ID_H263:
5675#endif
5676#if CONFIG_MPEG4_DECODER
5677 case AV_CODEC_ID_MPEG4:
5678#endif
5679 st->codecpar->width = 0; /* let decoder init width/height */
5680 st->codecpar->height= 0;
5681 break;
5682 }
5683#endif
5684
5685 // If the duration of the mp3 packets is not constant, then they could need a parser
5687 && sc->time_scale == st->codecpar->sample_rate) {
5688 int stts_constant = 1;
5689 for (int i = 1; sc->stts_count && i < sc->tts_count; i++) {
5690 if (sc->tts_data[i].duration == sc->tts_data[0].duration)
5691 continue;
5692 stts_constant = 0;
5693 }
5694 if (!stts_constant)
5696 }
5697 /* Do not need those anymore. */
5698 av_freep(&sc->chunk_offsets);
5699 av_freep(&sc->sample_sizes);
5700 av_freep(&sc->keyframes);
5701 av_freep(&sc->stps_data);
5702 av_freep(&sc->elst_data);
5703 av_freep(&sc->rap_group);
5704 av_freep(&sc->sync_group);
5705 av_freep(&sc->sgpd_sync);
5706
5707 return 0;
5708}
5709
5711{
5712 int ret;
5713 c->itunes_metadata = 1;
5714 ret = mov_read_default(c, pb, atom);
5715 c->itunes_metadata = 0;
5716 return ret;
5717}
5718
5720{
5721 uint32_t count;
5722 uint32_t i;
5723
5724 if (atom.size < 8)
5725 return 0;
5726
5727 avio_skip(pb, 4);
5728 count = avio_rb32(pb);
5729 atom.size -= 8;
5730 if (count > atom.size / 8 || count >= UINT_MAX / sizeof(*c->meta_keys)) {
5731 av_log(c->fc, AV_LOG_ERROR,
5732 "The 'keys' atom with the invalid key count: %"PRIu32"\n", count);
5733 return AVERROR_INVALIDDATA;
5734 }
5735
5736 c->meta_keys = av_malloc_array(count + 1, sizeof(*c->meta_keys));
5737 if (!c->meta_keys)
5738 return AVERROR(ENOMEM);
5739
5740 c->meta_keys[0] = NULL;
5741 c->meta_keys_count = 1;
5742 for (i = 1; i <= count; ++i) {
5743 uint32_t key_size = avio_rb32(pb);
5744 uint32_t type = avio_rl32(pb);
5745 c->meta_keys[i] = NULL;
5746 c->meta_keys_count = i + 1;
5747 if (key_size < 8 || key_size > atom.size) {
5748 av_log(c->fc, AV_LOG_ERROR,
5749 "The key# %"PRIu32" in meta has invalid size:"
5750 "%"PRIu32"\n", i, key_size);
5751 return AVERROR_INVALIDDATA;
5752 }
5753 atom.size -= key_size;
5754 key_size -= 8;
5755 if (type != MKTAG('m','d','t','a')) {
5756 avio_skip(pb, key_size);
5757 continue;
5758 }
5759 c->meta_keys[i] = av_malloc(key_size + 1);
5760 if (!c->meta_keys[i])
5761 return AVERROR(ENOMEM);
5762 int ret = ffio_read_size(pb, c->meta_keys[i], key_size);
5763 if (ret < 0)
5764 return ret;
5765 c->meta_keys[i][key_size] = 0;
5766 }
5767
5768 return 0;
5769}
5770
5772{
5773 int64_t end = av_sat_add64(avio_tell(pb), atom.size);
5774 uint8_t *key = NULL, *val = NULL, *mean = NULL;
5775 int i;
5776 int ret = 0;
5777 AVStream *st;
5778
5779 if (c->fc->nb_streams < 1)
5780 return 0;
5781 st = c->fc->streams[c->fc->nb_streams-1];
5782
5783 for (i = 0; i < 3; i++) {
5784 uint8_t **p;
5785 uint32_t len, tag;
5786
5787 if (end - avio_tell(pb) <= 12)
5788 break;
5789
5790 len = avio_rb32(pb);
5791 tag = avio_rl32(pb);
5792 avio_skip(pb, 4); // flags
5793
5794 if (len < 12 || len - 12 > end - avio_tell(pb))
5795 break;
5796 len -= 12;
5797
5798 if (tag == MKTAG('m', 'e', 'a', 'n'))
5799 p = &mean;
5800 else if (tag == MKTAG('n', 'a', 'm', 'e'))
5801 p = &key;
5802 else if (tag == MKTAG('d', 'a', 't', 'a') && len > 4) {
5803 avio_skip(pb, 4);
5804 len -= 4;
5805 p = &val;
5806 } else
5807 break;
5808
5809 if (*p)
5810 break;
5811
5812 *p = av_malloc(len + 1);
5813 if (!*p) {
5814 ret = AVERROR(ENOMEM);
5815 break;
5816 }
5817 ret = ffio_read_size(pb, *p, len);
5818 if (ret < 0) {
5819 av_freep(p);
5820 break;
5821 }
5822 (*p)[len] = 0;
5823 }
5824
5825 if (mean && key && val) {
5826 if (strcmp(key, "iTunSMPB") == 0) {
5827 int64_t priming, remainder, samples;
5828 if (ff_itunes_parse_smpb(val, &priming, &remainder, &samples) >= 0) {
5829 if(priming>0 && priming<16384)
5830 st->codecpar->initial_padding = priming = av_rescale_q(priming, st->time_base,
5831 (AVRational){ 1, st->codecpar->sample_rate });
5832 if (remainder > 0) {
5834 (AVRational){ 1, st->codecpar->sample_rate });
5835 remainder = av_rescale_q(remainder, st->time_base,
5836 (AVRational){ 1, st->codecpar->sample_rate });
5837 samples = av_rescale_q(samples, st->time_base,
5838 (AVRational){ 1, st->codecpar->sample_rate });
5839 if (duration > remainder && duration > samples) {
5840 ffstream(st)->first_discard_sample = duration - remainder;
5842 }
5843 }
5844 av_log(c->fc, AV_LOG_DEBUG, "Parsed iTunSMPB: priming %"PRId64", "
5845 "remainder %"PRId64" samples %"PRId64"\n",
5846 priming, remainder, samples);
5847 }
5848 }
5849 if (strcmp(mean, "com.apple.iTunes") == 0 &&
5850 strcmp(key, "DISCSUBTITLE") == 0) {
5851 av_dict_set(&c->fc->metadata, "disc_subtitle", val,
5853 val = NULL;
5854 }
5855 if (strcmp(key, "cdec") != 0) {
5856 av_dict_set(&c->fc->metadata, key, val,
5858 key = val = NULL;
5859 }
5860 } else {
5861 av_log(c->fc, AV_LOG_VERBOSE,
5862 "Unhandled or malformed custom metadata of size %"PRId64"\n", atom.size);
5863 }
5864
5865 avio_seek(pb, end, SEEK_SET);
5866 av_freep(&key);
5867 av_freep(&val);
5868 av_freep(&mean);
5869 return ret;
5870}
5871
5873{
5874 MOVStreamContext *sc;
5875 AVStream *st;
5876
5877 st = avformat_new_stream(c->fc, NULL);
5878 if (!st)
5879 return AVERROR(ENOMEM);
5880 sc = av_mallocz(sizeof(MOVStreamContext));
5881 if (!sc)
5882 goto fail;
5883
5884 item->st = st;
5885 st->id = item->item_id;
5886 st->priv_data = sc;
5888 st->codecpar->codec_id = mov_codec_id(st, item->type);
5889 sc->id = st->id;
5890 sc->ffindex = st->index;
5891 st->avg_frame_rate.num = st->avg_frame_rate.den = 1;
5892 st->time_base.num = st->time_base.den = 1;
5893 st->nb_frames = 1;
5894 sc->time_scale = 1;
5895 sc->pb = c->fc->pb;
5896 sc->pb_is_copied = 1;
5897 sc->refcount = 1;
5898
5899 if (item->name)
5900 av_dict_set(&st->metadata, "title", item->name, 0);
5901
5902 // Populate the necessary fields used by mov_build_index.
5903 sc->stsc_data = av_malloc_array(1, sizeof(*sc->stsc_data));
5904 if (!sc->stsc_data)
5905 goto fail;
5906 sc->stsc_count = 1;
5907 sc->stsc_data[0].first = 1;
5908 sc->stsc_data[0].count = 1;
5909 sc->stsc_data[0].id = 1;
5910 sc->chunk_offsets = av_malloc_array(1, sizeof(*sc->chunk_offsets));
5911 if (!sc->chunk_offsets)
5912 goto fail;
5913 sc->chunk_count = 1;
5914 sc->stts_data = av_malloc_array(1, sizeof(*sc->stts_data));
5915 if (!sc->stts_data)
5916 goto fail;
5917 sc->stts_count = 1;
5918 sc->stts_data[0].count = 1;
5919 // Not used for still images. But needed by mov_build_index.
5920 sc->stts_data[0].duration = 0;
5921
5922 return 0;
5923fail:
5924 mov_free_stream_context(c->fc, st);
5925 ff_remove_stream(c->fc, st);
5926 item->st = NULL;
5927
5928 return AVERROR(ENOMEM);
5929}
5930
5932{
5933 while (atom.size > 8) {
5934 uint32_t tag;
5935 if (avio_feof(pb))
5936 return AVERROR_EOF;
5937 tag = avio_rl32(pb);
5938 atom.size -= 4;
5939 if (tag == MKTAG('h','d','l','r')) {
5940 avio_seek(pb, -8, SEEK_CUR);
5941 atom.size += 8;
5942 return mov_read_default(c, pb, atom);
5943 }
5944 }
5945 return 0;
5946}
5947
5948// return 1 when matrix is identity, 0 otherwise
5949#define IS_MATRIX_IDENT(matrix) \
5950 ( (matrix)[0][0] == (1 << 16) && \
5951 (matrix)[1][1] == (1 << 16) && \
5952 (matrix)[2][2] == (1 << 30) && \
5953 !(matrix)[0][1] && !(matrix)[0][2] && \
5954 !(matrix)[1][0] && !(matrix)[1][2] && \
5955 !(matrix)[2][0] && !(matrix)[2][1])
5956
5958{
5959 int i, j, e;
5960 int width;
5961 int height;
5962 int display_matrix[3][3];
5963 int res_display_matrix[3][3] = { { 0 } };
5964 AVStream *st;
5965 MOVStreamContext *sc;
5966 int version;
5967 int flags;
5968
5969 if (c->fc->nb_streams < 1)
5970 return 0;
5971 st = c->fc->streams[c->fc->nb_streams-1];
5972 sc = st->priv_data;
5973
5974 // Each stream (trak) should have exactly 1 tkhd. This catches bad files and
5975 // avoids corrupting AVStreams mapped to an earlier tkhd.
5976 if (st->id != -1)
5977 return AVERROR_INVALIDDATA;
5978
5979 version = avio_r8(pb);
5980 flags = avio_rb24(pb);
5982
5983 if (version == 1) {
5984 avio_rb64(pb);
5985 avio_rb64(pb);
5986 } else {
5987 avio_rb32(pb); /* creation time */
5988 avio_rb32(pb); /* modification time */
5989 }
5990 st->id = (int)avio_rb32(pb); /* track id (NOT 0 !)*/
5991 sc->id = st->id;
5992 avio_rb32(pb); /* reserved */
5993
5994 /* highlevel (considering edits) duration in movie timebase */
5995 (version == 1) ? avio_rb64(pb) : avio_rb32(pb);
5996 avio_rb32(pb); /* reserved */
5997 avio_rb32(pb); /* reserved */
5998
5999 avio_rb16(pb); /* layer */
6000 avio_rb16(pb); /* alternate group */
6001 avio_rb16(pb); /* volume */
6002 avio_rb16(pb); /* reserved */
6003
6004 //read in the display matrix (outlined in ISO 14496-12, Section 6.2.2)
6005 // they're kept in fixed point format through all calculations
6006 // save u,v,z to store the whole matrix in the AV_PKT_DATA_DISPLAYMATRIX
6007 // side data, but the scale factor is not needed to calculate aspect ratio
6008 for (i = 0; i < 3; i++) {
6009 display_matrix[i][0] = avio_rb32(pb); // 16.16 fixed point
6010 display_matrix[i][1] = avio_rb32(pb); // 16.16 fixed point
6011 display_matrix[i][2] = avio_rb32(pb); // 2.30 fixed point
6012 }
6013
6014 width = avio_rb32(pb); // 16.16 fixed point track width
6015 height = avio_rb32(pb); // 16.16 fixed point track height
6016 sc->width = width >> 16;
6017 sc->height = height >> 16;
6018
6019 // apply the moov display matrix (after the tkhd one)
6020 for (i = 0; i < 3; i++) {
6021 const int sh[3] = { 16, 16, 30 };
6022 for (j = 0; j < 3; j++) {
6023 for (e = 0; e < 3; e++) {
6024 res_display_matrix[i][j] +=
6025 ((int64_t) display_matrix[i][e] *
6026 c->movie_display_matrix[e][j]) >> sh[e];
6027 }
6028 }
6029 }
6030
6031 // save the matrix when it is not the default identity
6032 if (!IS_MATRIX_IDENT(res_display_matrix)) {
6034 sc->display_matrix = av_malloc(sizeof(int32_t) * 9);
6035 if (!sc->display_matrix)
6036 return AVERROR(ENOMEM);
6037
6038 for (i = 0; i < 3; i++)
6039 for (j = 0; j < 3; j++)
6040 sc->display_matrix[i * 3 + j] = res_display_matrix[i][j];
6041 }
6042
6043 // transform the display width/height according to the matrix
6044 // to keep the same scale, use [width height 1<<16]
6045 if (width && height && sc->display_matrix) {
6046 double disp_transform[2];
6047
6048 for (i = 0; i < 2; i++)
6049 disp_transform[i] = hypot(sc->display_matrix[0 + i],
6050 sc->display_matrix[3 + i]);
6051
6052 if (disp_transform[0] > 1 && disp_transform[1] > 1 &&
6053 disp_transform[0] < (1<<24) && disp_transform[1] < (1<<24) &&
6054 fabs((disp_transform[0] / disp_transform[1]) - 1.0) > 0.01)
6056 disp_transform[0] / disp_transform[1],
6057 INT_MAX);
6058 }
6059 return 0;
6060}
6061
6063{
6064 MOVFragment *frag = &c->fragment;
6065 MOVTrackExt *trex = NULL;
6066 int flags, track_id, i;
6067 MOVFragmentStreamInfo * frag_stream_info;
6068
6069 avio_r8(pb); /* version */
6070 flags = avio_rb24(pb);
6071
6072 track_id = avio_rb32(pb);
6073 if (!track_id)
6074 return AVERROR_INVALIDDATA;
6075 for (i = 0; i < c->trex_count; i++)
6076 if (c->trex_data[i].track_id == track_id) {
6077 trex = &c->trex_data[i];
6078 break;
6079 }
6080 if (!trex) {
6081 av_log(c->fc, AV_LOG_WARNING, "could not find corresponding trex (id %u)\n", track_id);
6082 return 0;
6083 }
6084 c->fragment.found_tfhd = 1;
6085 frag->track_id = track_id;
6086 set_frag_stream(&c->frag_index, track_id);
6087
6090 frag->moof_offset : frag->implicit_offset;
6091 frag->stsd_id = flags & MOV_TFHD_STSD_ID ? avio_rb32(pb) : trex->stsd_id;
6092
6094 avio_rb32(pb) : trex->duration;
6095 frag->size = flags & MOV_TFHD_DEFAULT_SIZE ?
6096 avio_rb32(pb) : trex->size;
6098 avio_rb32(pb) : trex->flags;
6099 av_log(c->fc, AV_LOG_TRACE, "frag flags 0x%x\n", frag->flags);
6100
6101 frag_stream_info = get_current_frag_stream_info(&c->frag_index);
6102 if (frag_stream_info) {
6103 frag_stream_info->next_trun_dts = AV_NOPTS_VALUE;
6104 frag_stream_info->stsd_id = frag->stsd_id;
6105 }
6106 return 0;
6107}
6108
6110{
6111 unsigned i, num;
6112 void *new_tracks;
6113
6114 num = atom.size / 4;
6115 if (!(new_tracks = av_malloc_array(num, sizeof(int))))
6116 return AVERROR(ENOMEM);
6117
6118 av_free(c->chapter_tracks);
6119 c->chapter_tracks = new_tracks;
6120 c->nb_chapter_tracks = num;
6121
6122 for (i = 0; i < num && !pb->eof_reached; i++)
6123 c->chapter_tracks[i] = avio_rb32(pb);
6124
6125 c->nb_chapter_tracks = i;
6126
6127 return 0;
6128}
6129
6131{
6132 MOVTrackExt *trex;
6133 int err;
6134
6135 if ((uint64_t)c->trex_count+1 >= UINT_MAX / sizeof(*c->trex_data))
6136 return AVERROR_INVALIDDATA;
6137 if ((err = av_reallocp_array(&c->trex_data, c->trex_count + 1,
6138 sizeof(*c->trex_data))) < 0) {
6139 c->trex_count = 0;
6140 return err;
6141 }
6142
6143 c->fc->duration = AV_NOPTS_VALUE; // the duration from mvhd is not representing the whole file when fragments are used.
6144
6145 trex = &c->trex_data[c->trex_count++];
6146 avio_r8(pb); /* version */
6147 avio_rb24(pb); /* flags */
6148 trex->track_id = avio_rb32(pb);
6149 trex->stsd_id = avio_rb32(pb);
6150 trex->duration = avio_rb32(pb);
6151 trex->size = avio_rb32(pb);
6152 trex->flags = avio_rb32(pb);
6153 return 0;
6154}
6155
6157{
6158 MOVFragment *frag = &c->fragment;
6159 AVStream *st = NULL;
6160 MOVStreamContext *sc;
6161 int version, i;
6162 MOVFragmentStreamInfo * frag_stream_info;
6163 int64_t base_media_decode_time;
6164
6165 for (i = 0; i < c->fc->nb_streams; i++) {
6166 sc = c->fc->streams[i]->priv_data;
6167 if (sc->id == frag->track_id) {
6168 st = c->fc->streams[i];
6169 break;
6170 }
6171 }
6172 if (!st) {
6173 av_log(c->fc, AV_LOG_WARNING, "could not find corresponding track id %u\n", frag->track_id);
6174 return 0;
6175 }
6176 sc = st->priv_data;
6177 if (sc->pseudo_stream_id + 1 != frag->stsd_id && sc->pseudo_stream_id != -1)
6178 return 0;
6179 version = avio_r8(pb);
6180 avio_rb24(pb); /* flags */
6181 if (version) {
6182 base_media_decode_time = avio_rb64(pb);
6183 } else {
6184 base_media_decode_time = avio_rb32(pb);
6185 }
6186
6187 frag_stream_info = get_current_frag_stream_info(&c->frag_index);
6188 if (frag_stream_info)
6189 frag_stream_info->tfdt_dts = base_media_decode_time;
6190 sc->track_end = base_media_decode_time;
6191
6192 return 0;
6193}
6194
6196{
6197 MOVFragment *frag = &c->fragment;
6198 AVStream *st = NULL;
6199 FFStream *sti = NULL;
6200 MOVStreamContext *sc;
6201 MOVTimeToSample *tts_data;
6202 uint64_t offset;
6203 int64_t dts, pts = AV_NOPTS_VALUE;
6204 int data_offset = 0;
6205 unsigned entries, first_sample_flags = frag->flags;
6206 int flags, distance, i;
6207 int64_t prev_dts = AV_NOPTS_VALUE;
6208 int next_frag_index = -1, index_entry_pos;
6209 size_t requested_size;
6210 size_t old_allocated_size;
6211 AVIndexEntry *new_entries;
6212 MOVFragmentStreamInfo * frag_stream_info;
6213
6214 if (!frag->found_tfhd) {
6215 av_log(c->fc, AV_LOG_ERROR, "trun track id unknown, no tfhd was found\n");
6216 return AVERROR_INVALIDDATA;
6217 }
6218
6219 for (i = 0; i < c->fc->nb_streams; i++) {
6220 sc = c->fc->streams[i]->priv_data;
6221 if (sc->id == frag->track_id) {
6222 st = c->fc->streams[i];
6223 sti = ffstream(st);
6224 break;
6225 }
6226 }
6227 if (!st) {
6228 av_log(c->fc, AV_LOG_WARNING, "could not find corresponding track id %u\n", frag->track_id);
6229 return 0;
6230 }
6231 sc = st->priv_data;
6232 if (sc->pseudo_stream_id+1 != frag->stsd_id && sc->pseudo_stream_id != -1)
6233 return 0;
6234
6235 // Find the next frag_index index that has a valid index_entry for
6236 // the current track_id.
6237 //
6238 // A valid index_entry means the trun for the fragment was read
6239 // and it's samples are in index_entries at the given position.
6240 // New index entries will be inserted before the index_entry found.
6241 index_entry_pos = sti->nb_index_entries;
6242 for (i = c->frag_index.current + 1; i < c->frag_index.nb_items; i++) {
6243 frag_stream_info = get_frag_stream_info(&c->frag_index, i, frag->track_id);
6244 if (frag_stream_info && frag_stream_info->index_entry >= 0) {
6245 next_frag_index = i;
6246 index_entry_pos = frag_stream_info->index_entry;
6247 break;
6248 }
6249 }
6250 av_assert0(index_entry_pos <= sti->nb_index_entries);
6251
6252 avio_r8(pb); /* version */
6253 flags = avio_rb24(pb);
6254 entries = avio_rb32(pb);
6255 av_log(c->fc, AV_LOG_TRACE, "flags 0x%x entries %u\n", flags, entries);
6256
6257 if ((uint64_t)entries+sc->tts_count >= UINT_MAX/sizeof(*sc->tts_data))
6258 return AVERROR_INVALIDDATA;
6259 if (flags & MOV_TRUN_DATA_OFFSET) data_offset = avio_rb32(pb);
6260 if (flags & MOV_TRUN_FIRST_SAMPLE_FLAGS) first_sample_flags = avio_rb32(pb);
6261
6262 int entry_size = !!(flags & MOV_TRUN_SAMPLE_DURATION) * 4
6263 + !!(flags & MOV_TRUN_SAMPLE_SIZE) * 4
6264 + !!(flags & MOV_TRUN_SAMPLE_FLAGS) * 4
6265 + !!(flags & MOV_TRUN_SAMPLE_CTS) * 4;
6266 int64_t sample_data_size = avio_size(sc->pb);
6267 int64_t max_entries = INT64_MAX;
6268
6269 if (sample_data_size > 0)
6270 max_entries = sample_data_size - sti->nb_index_entries;
6271 if (entry_size) {
6272 int64_t size = sc->pb == pb ? sample_data_size : avio_size(pb);
6273 int64_t pos = avio_tell(pb);
6274 int64_t left = atom.size - 8 - !!(flags & MOV_TRUN_DATA_OFFSET) * 4
6276
6277 if (pos >= 0 && size >= pos)
6278 left = FFMIN(left, size - pos);
6279 max_entries = FFMIN(max_entries, left / entry_size);
6280 }
6281 if (entries > max_entries) {
6282 av_log(c->fc, AV_LOG_ERROR, "trun sample count %u exceeds the %"PRId64" "
6283 "samples the input can hold\n", entries, max_entries);
6284 return AVERROR_INVALIDDATA;
6285 }
6286
6287 frag_stream_info = get_current_frag_stream_info(&c->frag_index);
6288 if (frag_stream_info) {
6289 if (frag_stream_info->next_trun_dts != AV_NOPTS_VALUE) {
6290 dts = frag_stream_info->next_trun_dts - sc->time_offset;
6291 } else if (frag_stream_info->first_tfra_pts != AV_NOPTS_VALUE &&
6292 c->use_mfra_for == FF_MOV_FLAG_MFRA_PTS) {
6293 pts = frag_stream_info->first_tfra_pts;
6294 av_log(c->fc, AV_LOG_DEBUG, "found mfra time %"PRId64
6295 ", using it for pts\n", pts);
6296 } else if (frag_stream_info->first_tfra_pts != AV_NOPTS_VALUE &&
6297 c->use_mfra_for == FF_MOV_FLAG_MFRA_DTS) {
6298 dts = frag_stream_info->first_tfra_pts;
6299 av_log(c->fc, AV_LOG_DEBUG, "found mfra time %"PRId64
6300 ", using it for dts\n", pts);
6301 } else {
6302 int has_tfdt = frag_stream_info->tfdt_dts != AV_NOPTS_VALUE;
6303 int has_sidx = frag_stream_info->sidx_pts != AV_NOPTS_VALUE;
6304 int fallback_tfdt = !c->use_tfdt && !has_sidx && has_tfdt;
6305 int fallback_sidx = c->use_tfdt && !has_tfdt && has_sidx;
6306
6307 if (fallback_sidx) {
6308 av_log(c->fc, AV_LOG_DEBUG, "use_tfdt set but no tfdt found, using sidx instead\n");
6309 }
6310 if (fallback_tfdt) {
6311 av_log(c->fc, AV_LOG_DEBUG, "use_tfdt not set but no sidx found, using tfdt instead\n");
6312 }
6313
6314 if (has_tfdt && c->use_tfdt || fallback_tfdt) {
6315 dts = frag_stream_info->tfdt_dts - sc->time_offset;
6316 av_log(c->fc, AV_LOG_DEBUG, "found tfdt time %"PRId64
6317 ", using it for dts\n", dts);
6318 } else if (has_sidx && !c->use_tfdt || fallback_sidx) {
6319 // FIXME: sidx earliest_presentation_time is *PTS*, s.b.
6320 // pts = frag_stream_info->sidx_pts;
6321 dts = frag_stream_info->sidx_pts;
6322 av_log(c->fc, AV_LOG_DEBUG, "found sidx time %"PRId64
6323 ", using it for dts\n", frag_stream_info->sidx_pts);
6324 } else {
6325 dts = sc->track_end - sc->time_offset;
6326 av_log(c->fc, AV_LOG_DEBUG, "found track end time %"PRId64
6327 ", using it for dts\n", dts);
6328 }
6329 }
6330 } else {
6331 dts = sc->track_end - sc->time_offset;
6332 av_log(c->fc, AV_LOG_DEBUG, "found track end time %"PRId64
6333 ", using it for dts\n", dts);
6334 }
6335 offset = frag->base_data_offset + data_offset;
6336 distance = 0;
6337 av_log(c->fc, AV_LOG_TRACE, "first sample flags 0x%x\n", first_sample_flags);
6338
6339 // realloc space for new index entries
6340 if ((uint64_t)sti->nb_index_entries + entries >= UINT_MAX / sizeof(AVIndexEntry)) {
6341 entries = UINT_MAX / sizeof(AVIndexEntry) - sti->nb_index_entries;
6342 av_log(c->fc, AV_LOG_ERROR, "Failed to add index entry\n");
6343 }
6344 if (entries == 0)
6345 return 0;
6346
6347 requested_size = (sti->nb_index_entries + entries) * sizeof(AVIndexEntry);
6348 new_entries = av_fast_realloc(sti->index_entries,
6350 requested_size);
6351 if (!new_entries)
6352 return AVERROR(ENOMEM);
6353 sti->index_entries= new_entries;
6354
6355 requested_size = (sti->nb_index_entries + entries) * sizeof(*sc->tts_data);
6356 old_allocated_size = sc->tts_allocated_size;
6357 tts_data = av_fast_realloc(sc->tts_data, &sc->tts_allocated_size,
6358 requested_size);
6359 if (!tts_data)
6360 return AVERROR(ENOMEM);
6361 sc->tts_data = tts_data;
6362
6363 // In case there were samples without time to sample entries, ensure they get
6364 // zero valued entries. This ensures clips which mix boxes with and
6365 // without time to sample entries don't pickup uninitialized data.
6366 memset((uint8_t*)(sc->tts_data) + old_allocated_size, 0,
6367 sc->tts_allocated_size - old_allocated_size);
6368
6369 if (index_entry_pos < sti->nb_index_entries) {
6370 // Make hole in index_entries and tts_data for new samples
6371 memmove(sti->index_entries + index_entry_pos + entries,
6372 sti->index_entries + index_entry_pos,
6373 sizeof(*sti->index_entries) *
6374 (sti->nb_index_entries - index_entry_pos));
6375 memmove(sc->tts_data + index_entry_pos + entries,
6376 sc->tts_data + index_entry_pos,
6377 sizeof(*sc->tts_data) * (sc->tts_count - index_entry_pos));
6378 if (index_entry_pos < sc->current_sample) {
6379 sc->current_sample += entries;
6380 }
6381 }
6382
6383 sti->nb_index_entries += entries;
6384 sc->tts_count = sti->nb_index_entries;
6385 sc->stts_count = sti->nb_index_entries;
6387 sc->ctts_count = sti->nb_index_entries;
6388
6389 // Record the index_entry position in frag_index of this fragment
6390 if (frag_stream_info) {
6391 frag_stream_info->index_entry = index_entry_pos;
6392 if (frag_stream_info->index_base < 0)
6393 frag_stream_info->index_base = index_entry_pos;
6394 }
6395
6396 if (index_entry_pos > 0)
6397 prev_dts = sti->index_entries[index_entry_pos-1].timestamp;
6398
6399 for (i = 0; i < entries && !pb->eof_reached; i++) {
6400 unsigned sample_size = frag->size;
6401 int sample_flags = i ? frag->flags : first_sample_flags;
6402 unsigned sample_duration = frag->duration;
6403 unsigned ctts_duration = 0;
6404 int keyframe = 0;
6405 int index_entry_flags = 0;
6406
6407 if (flags & MOV_TRUN_SAMPLE_DURATION) sample_duration = avio_rb32(pb);
6408 if (flags & MOV_TRUN_SAMPLE_SIZE) sample_size = avio_rb32(pb);
6409 if (flags & MOV_TRUN_SAMPLE_FLAGS) sample_flags = avio_rb32(pb);
6410 if (flags & MOV_TRUN_SAMPLE_CTS) ctts_duration = avio_rb32(pb);
6411
6412 if (sample_duration > c->max_stts_delta) {
6413 av_log(c->fc, AV_LOG_WARNING,
6414 "Too large sample duration %u in trun entry %u in st:%d. Clipping to 1.\n",
6415 sample_duration, i, st->index);
6416 sample_duration = 1;
6417 }
6418
6419 mov_update_dts_shift(sc, ctts_duration, c->fc);
6420 if (pts != AV_NOPTS_VALUE) {
6421 dts = pts - sc->dts_shift;
6422 if (flags & MOV_TRUN_SAMPLE_CTS) {
6423 dts -= ctts_duration;
6424 } else {
6425 dts -= sc->time_offset;
6426 }
6427 av_log(c->fc, AV_LOG_DEBUG,
6428 "pts %"PRId64" calculated dts %"PRId64
6429 " sc->dts_shift %d ctts.duration %d"
6430 " sc->time_offset %"PRId64
6431 " flags & MOV_TRUN_SAMPLE_CTS %d\n",
6432 pts, dts,
6433 sc->dts_shift, ctts_duration,
6436 }
6437
6438 keyframe =
6439 !(sample_flags & (MOV_FRAG_SAMPLE_FLAG_IS_NON_SYNC |
6441 if (keyframe) {
6442 distance = 0;
6443 index_entry_flags |= AVINDEX_KEYFRAME;
6444 }
6445 // Fragments can overlap in time. Discard overlapping frames after
6446 // decoding.
6447 if (prev_dts >= dts)
6448 index_entry_flags |= AVINDEX_DISCARD_FRAME;
6449
6450 sti->index_entries[index_entry_pos].pos = offset;
6451 sti->index_entries[index_entry_pos].timestamp = dts;
6452 sti->index_entries[index_entry_pos].size = sample_size;
6453 sti->index_entries[index_entry_pos].min_distance = distance;
6454 sti->index_entries[index_entry_pos].flags = index_entry_flags;
6455
6456 sc->tts_data[index_entry_pos].count = 1;
6457 sc->tts_data[index_entry_pos].offset = ctts_duration;
6458 sc->tts_data[index_entry_pos].duration = sample_duration;
6459 index_entry_pos++;
6460
6461 av_log(c->fc, AV_LOG_TRACE, "AVIndex stream %d, sample %d, offset %"PRIx64", dts %"PRId64", "
6462 "size %u, distance %d, keyframe %d\n", st->index,
6463 index_entry_pos, offset, dts, sample_size, distance, keyframe);
6464 distance++;
6465 if (av_sat_add64(dts, sample_duration) != dts + (uint64_t)sample_duration)
6466 return AVERROR_INVALIDDATA;
6467 if (!sample_size)
6468 return AVERROR_INVALIDDATA;
6469 dts += sample_duration;
6470 offset += sample_size;
6471 sc->data_size += sample_size;
6472
6473 if (sample_duration <= INT64_MAX - sc->duration_for_fps &&
6474 1 <= INT_MAX - sc->nb_frames_for_fps
6475 ) {
6476 sc->duration_for_fps += sample_duration;
6477 sc->nb_frames_for_fps ++;
6478 }
6479 }
6480 if (frag_stream_info)
6481 frag_stream_info->next_trun_dts = dts + sc->time_offset;
6482 if (i < entries) {
6483 // EOF found before reading all entries. Fix the hole this would
6484 // leave in index_entries and tts_data
6485 int gap = entries - i;
6486 memmove(sti->index_entries + index_entry_pos,
6487 sti->index_entries + index_entry_pos + gap,
6488 sizeof(*sti->index_entries) *
6489 (sti->nb_index_entries - (index_entry_pos + gap)));
6490 memmove(sc->tts_data + index_entry_pos,
6491 sc->tts_data + index_entry_pos + gap,
6492 sizeof(*sc->tts_data) *
6493 (sc->tts_count - (index_entry_pos + gap)));
6494
6495 sti->nb_index_entries -= gap;
6496 sc->tts_count -= gap;
6497 if (index_entry_pos < sc->current_sample) {
6498 sc->current_sample -= gap;
6499 }
6500 entries = i;
6501 }
6502
6503 // The end of this new fragment may overlap in time with the start
6504 // of the next fragment in index_entries. Mark the samples in the next
6505 // fragment that overlap with AVINDEX_DISCARD_FRAME
6506 prev_dts = AV_NOPTS_VALUE;
6507 if (index_entry_pos > 0)
6508 prev_dts = sti->index_entries[index_entry_pos-1].timestamp;
6509 for (int i = index_entry_pos; i < sti->nb_index_entries; i++) {
6510 if (prev_dts < sti->index_entries[i].timestamp)
6511 break;
6513 }
6514
6515 // If a hole was created to insert the new index_entries into,
6516 // the index_entry recorded for all subsequent moof must
6517 // be incremented by the number of entries inserted.
6518 fix_frag_index_entries(&c->frag_index, next_frag_index,
6519 frag->track_id, entries);
6520
6521 if (pb->eof_reached) {
6522 av_log(c->fc, AV_LOG_WARNING, "reached eof, corrupted TRUN atom\n");
6523 return AVERROR_EOF;
6524 }
6525
6526 frag->implicit_offset = offset;
6527
6528 sc->track_end = dts + sc->time_offset;
6529 if (st->duration < sc->track_end)
6530 st->duration = sc->track_end;
6531
6532 return 0;
6533}
6534
6536{
6537 int64_t stream_size = avio_size(pb);
6538 int64_t offset = av_sat_add64(avio_tell(pb), atom.size), pts, timestamp;
6539 uint8_t version, is_complete;
6540 int64_t offadd;
6541 unsigned i, j, track_id, item_count;
6542 AVStream *st = NULL;
6543 AVStream *ref_st = NULL;
6544 MOVStreamContext *sc, *ref_sc = NULL;
6545 AVRational timescale;
6546
6547 version = avio_r8(pb);
6548 if (version > 1) {
6549 avpriv_request_sample(c->fc, "sidx version %u", version);
6550 return 0;
6551 }
6552
6553 avio_rb24(pb); // flags
6554
6555 track_id = avio_rb32(pb); // Reference ID
6556 for (i = 0; i < c->fc->nb_streams; i++) {
6557 sc = c->fc->streams[i]->priv_data;
6558 if (sc->id == track_id) {
6559 st = c->fc->streams[i];
6560 break;
6561 }
6562 }
6563 if (!st) {
6564 av_log(c->fc, AV_LOG_WARNING, "could not find corresponding track id %d\n", track_id);
6565 return 0;
6566 }
6567
6568 sc = st->priv_data;
6569
6570 timescale = av_make_q(1, avio_rb32(pb));
6571
6572 if (timescale.den <= 0) {
6573 av_log(c->fc, AV_LOG_ERROR, "Invalid sidx timescale 1/%d\n", timescale.den);
6574 return AVERROR_INVALIDDATA;
6575 }
6576
6577 if (version == 0) {
6578 pts = avio_rb32(pb);
6579 offadd= avio_rb32(pb);
6580 } else {
6581 pts = avio_rb64(pb);
6582 offadd= avio_rb64(pb);
6583 }
6584 if (av_sat_add64(offset, offadd) != offset + (uint64_t)offadd)
6585 return AVERROR_INVALIDDATA;
6586
6587 offset += (uint64_t)offadd;
6588
6589 avio_rb16(pb); // reserved
6590
6591 item_count = avio_rb16(pb);
6592 if (item_count == 0)
6593 return AVERROR_INVALIDDATA;
6594
6595 for (i = 0; i < item_count; i++) {
6596 int index;
6597 MOVFragmentStreamInfo * frag_stream_info;
6598 uint32_t size = avio_rb32(pb);
6599 uint32_t duration = avio_rb32(pb);
6600 if (size & 0x80000000) {
6601 avpriv_request_sample(c->fc, "sidx reference_type 1");
6602 return AVERROR_PATCHWELCOME;
6603 }
6604 avio_rb32(pb); // sap_flags
6605 timestamp = av_rescale_q(pts, timescale, st->time_base);
6606
6608 frag_stream_info = get_frag_stream_info(&c->frag_index, index, track_id);
6609 if (frag_stream_info)
6610 frag_stream_info->sidx_pts = timestamp;
6611
6612 if (av_sat_add64(offset, size) != offset + (uint64_t)size ||
6613 av_sat_add64(pts, duration) != pts + (uint64_t)duration
6614 )
6615 return AVERROR_INVALIDDATA;
6616 offset += size;
6617 pts += duration;
6618 }
6619
6620 st->duration = sc->track_end = pts;
6621
6622 sc->has_sidx = 1;
6623
6624 // See if the remaining bytes are just an mfra which we can ignore.
6625 is_complete = offset == stream_size;
6626 if (!is_complete && (pb->seekable & AVIO_SEEKABLE_NORMAL) && stream_size > 0 ) {
6627 int64_t ret;
6628 int64_t original_pos = avio_tell(pb);
6629 if (!c->have_read_mfra_size) {
6630 if ((ret = avio_seek(pb, stream_size - 4, SEEK_SET)) < 0)
6631 return ret;
6632 c->mfra_size = avio_rb32(pb);
6633 c->have_read_mfra_size = 1;
6634 if ((ret = avio_seek(pb, original_pos, SEEK_SET)) < 0)
6635 return ret;
6636 }
6637 if (offset == stream_size - c->mfra_size)
6638 is_complete = 1;
6639 }
6640
6641 if (is_complete) {
6642 // Find first entry in fragment index that came from an sidx.
6643 // This will pretty much always be the first entry.
6644 for (i = 0; i < c->frag_index.nb_items; i++) {
6645 MOVFragmentIndexItem * item = &c->frag_index.item[i];
6646 for (j = 0; ref_st == NULL && j < item->nb_stream_info; j++) {
6648 si = &item->stream_info[j];
6649 if (si->sidx_pts != AV_NOPTS_VALUE) {
6650 ref_st = c->fc->streams[j];
6651 ref_sc = ref_st->priv_data;
6652 break;
6653 }
6654 }
6655 }
6656 if (ref_st) for (i = 0; i < c->fc->nb_streams; i++) {
6657 st = c->fc->streams[i];
6658 sc = st->priv_data;
6659 if (!sc->has_sidx) {
6660 st->duration = sc->track_end = av_rescale(ref_st->duration, sc->time_scale, ref_sc->time_scale);
6661 }
6662 }
6663
6664 if (offadd == 0)
6665 c->frag_index.complete = 1;
6666 }
6667
6668 return 0;
6669}
6670
6671/* this atom should be null (from specs), but some buggy files put the 'moov' atom inside it... */
6672/* like the files created with Adobe Premiere 5.0, for samples see */
6673/* http://graphics.tudelft.nl/~wouter/publications/soundtests/ */
6675{
6676 int err;
6677
6678 if (atom.size < 8)
6679 return 0; /* continue */
6680 if (avio_rb32(pb) != 0) { /* 0 sized mdat atom... use the 'wide' atom size */
6681 avio_skip(pb, atom.size - 4);
6682 return 0;
6683 }
6684 atom.type = avio_rl32(pb);
6685 atom.size -= 8;
6686 if (atom.type != MKTAG('m','d','a','t')) {
6687 avio_skip(pb, atom.size);
6688 return 0;
6689 }
6690 err = mov_read_mdat(c, pb, atom);
6691 return err;
6692}
6693
6695{
6696#if CONFIG_ZLIB
6698 uint8_t *cmov_data;
6699 uint8_t *moov_data; /* uncompressed data */
6700 long cmov_len, moov_len;
6701 int ret = -1;
6702
6703 avio_rb32(pb); /* dcom atom */
6704 if (avio_rl32(pb) != MKTAG('d','c','o','m'))
6705 return AVERROR_INVALIDDATA;
6706 if (avio_rl32(pb) != MKTAG('z','l','i','b')) {
6707 av_log(c->fc, AV_LOG_ERROR, "unknown compression for cmov atom !\n");
6708 return AVERROR_INVALIDDATA;
6709 }
6710 avio_rb32(pb); /* cmvd atom */
6711 if (avio_rl32(pb) != MKTAG('c','m','v','d'))
6712 return AVERROR_INVALIDDATA;
6713 moov_len = avio_rb32(pb); /* uncompressed size */
6714 cmov_len = atom.size - 6 * 4;
6715
6716 cmov_data = av_malloc(cmov_len);
6717 if (!cmov_data)
6718 return AVERROR(ENOMEM);
6719 moov_data = av_malloc(moov_len);
6720 if (!moov_data) {
6721 av_free(cmov_data);
6722 return AVERROR(ENOMEM);
6723 }
6724 ret = ffio_read_size(pb, cmov_data, cmov_len);
6725 if (ret < 0)
6726 goto free_and_return;
6727
6728 ret = AVERROR_INVALIDDATA;
6729 if (uncompress (moov_data, (uLongf *) &moov_len, (const Bytef *)cmov_data, cmov_len) != Z_OK)
6730 goto free_and_return;
6731 ffio_init_read_context(&ctx, moov_data, moov_len);
6732 ctx.pub.seekable = AVIO_SEEKABLE_NORMAL;
6733 atom.type = MKTAG('m','o','o','v');
6734 atom.size = moov_len;
6735 ret = mov_read_default(c, &ctx.pub, atom);
6736free_and_return:
6737 av_free(moov_data);
6738 av_free(cmov_data);
6739 return ret;
6740#else
6741 av_log(c->fc, AV_LOG_ERROR, "this file requires zlib support compiled in\n");
6742 return AVERROR(ENOSYS);
6743#endif
6744}
6745
6746/* edit list atom */
6748{
6749 MOVStreamContext *sc;
6750 int i, edit_count, version;
6751 int64_t elst_entry_size;
6752
6753 if (c->fc->nb_streams < 1 || c->ignore_editlist)
6754 return 0;
6755 sc = c->fc->streams[c->fc->nb_streams-1]->priv_data;
6756
6757 version = avio_r8(pb); /* version */
6758 avio_rb24(pb); /* flags */
6759 edit_count = avio_rb32(pb); /* entries */
6760 atom.size -= 8;
6761
6762 elst_entry_size = version == 1 ? 20 : 12;
6763 if (atom.size != edit_count * elst_entry_size) {
6764 if (c->fc->strict_std_compliance >= FF_COMPLIANCE_STRICT) {
6765 av_log(c->fc, AV_LOG_ERROR, "Invalid edit list entry_count: %d for elst atom of size: %"PRId64" bytes.\n",
6766 edit_count, atom.size + 8);
6767 return AVERROR_INVALIDDATA;
6768 } else {
6769 edit_count = atom.size / elst_entry_size;
6770 if (edit_count * elst_entry_size != atom.size) {
6771 av_log(c->fc, AV_LOG_WARNING, "ELST atom of %"PRId64" bytes, bigger than %d entries.\n", atom.size, edit_count);
6772 }
6773 }
6774 }
6775
6776 if (!edit_count)
6777 return 0;
6778 if (sc->elst_data)
6779 av_log(c->fc, AV_LOG_WARNING, "Duplicated ELST atom\n");
6780 av_free(sc->elst_data);
6781 sc->elst_count = 0;
6782 sc->elst_data = av_malloc_array(edit_count, sizeof(*sc->elst_data));
6783 if (!sc->elst_data)
6784 return AVERROR(ENOMEM);
6785
6786 av_log(c->fc, AV_LOG_TRACE, "track[%u].edit_count = %i\n", c->fc->nb_streams - 1, edit_count);
6787 for (i = 0; i < edit_count && atom.size > 0 && !pb->eof_reached; i++) {
6788 MOVElst *e = &sc->elst_data[i];
6789
6790 if (version == 1) {
6791 e->duration = avio_rb64(pb);
6792 e->time = avio_rb64(pb);
6793 atom.size -= 16;
6794 } else {
6795 e->duration = avio_rb32(pb); /* segment duration */
6796 e->time = (int32_t)avio_rb32(pb); /* media time */
6797 atom.size -= 8;
6798 }
6799 e->rate = avio_rb32(pb) / 65536.0;
6800 atom.size -= 4;
6801 av_log(c->fc, AV_LOG_TRACE, "duration=%"PRId64" time=%"PRId64" rate=%f\n",
6802 e->duration, e->time, e->rate);
6803
6804 if (e->time < 0 && e->time != -1 &&
6805 c->fc->strict_std_compliance >= FF_COMPLIANCE_STRICT) {
6806 av_log(c->fc, AV_LOG_ERROR, "Track %d, edit %d: Invalid edit list media time=%"PRId64"\n",
6807 c->fc->nb_streams-1, i, e->time);
6808 return AVERROR_INVALIDDATA;
6809 }
6810 if (e->duration < 0) {
6811 av_log(c->fc, AV_LOG_ERROR, "Track %d, edit %d: Invalid edit list duration=%"PRId64"\n",
6812 c->fc->nb_streams-1, i, e->duration);
6813 return AVERROR_INVALIDDATA;
6814 }
6815 }
6816 sc->elst_count = i;
6817
6818 return 0;
6819}
6820
6822{
6823 MOVStreamContext *sc;
6824 int err;
6825
6826 if (c->fc->nb_streams < 1)
6827 return AVERROR_INVALIDDATA;
6828 sc = c->fc->streams[c->fc->nb_streams - 1]->priv_data;
6829
6830 if (atom.size % sizeof(uint32_t))
6831 return AVERROR_INVALIDDATA;
6832
6833 MovTref *tag = mov_add_tref_tag(sc, atom.type);
6834 if (!tag)
6835 return AVERROR(ENOMEM);
6836
6837 int nb_timecode_track = atom.size >> 2;
6838 for (int i = 0; i < nb_timecode_track; i++) {
6839 if (avio_feof(pb))
6840 return AVERROR_INVALIDDATA;
6841 err = mov_add_tref_id(tag, avio_rb32(pb));
6842 if (err < 0)
6843 return err;
6844 }
6845
6846 return 0;
6847}
6848
6850{
6851 AVStream *st;
6852 int version, color_range, color_primaries, color_trc, color_space;
6853
6854 if (c->fc->nb_streams < 1)
6855 return 0;
6856 st = c->fc->streams[c->fc->nb_streams - 1];
6857
6858 if (atom.size < 5) {
6859 av_log(c->fc, AV_LOG_ERROR, "Empty VP Codec Configuration box\n");
6860 return AVERROR_INVALIDDATA;
6861 }
6862
6863 version = avio_r8(pb);
6864 if (version != 1) {
6865 av_log(c->fc, AV_LOG_WARNING, "Unsupported VP Codec Configuration box version %d\n", version);
6866 return 0;
6867 }
6868 avio_skip(pb, 3); /* flags */
6869
6870 avio_skip(pb, 2); /* profile + level */
6871 color_range = avio_r8(pb); /* bitDepth, chromaSubsampling, videoFullRangeFlag */
6873 color_trc = avio_r8(pb);
6874 color_space = avio_r8(pb);
6875 if (avio_rb16(pb)) /* codecIntializationDataSize */
6876 return AVERROR_INVALIDDATA;
6877
6880 if (!av_color_transfer_name(color_trc))
6881 color_trc = AVCOL_TRC_UNSPECIFIED;
6882 if (!av_color_space_name(color_space))
6883 color_space = AVCOL_SPC_UNSPECIFIED;
6884
6887 st->codecpar->color_trc = color_trc;
6888 st->codecpar->color_space = color_space;
6889
6890 return 0;
6891}
6892
6894{
6895 MOVStreamContext *sc;
6896 int i, version;
6897
6898 if (c->fc->nb_streams < 1)
6899 return AVERROR_INVALIDDATA;
6900
6901 sc = c->fc->streams[c->fc->nb_streams - 1]->priv_data;
6902
6903 if (atom.size < 5) {
6904 av_log(c->fc, AV_LOG_ERROR, "Empty Mastering Display Metadata box\n");
6905 return AVERROR_INVALIDDATA;
6906 }
6907
6908 version = avio_r8(pb);
6909 if (version) {
6910 av_log(c->fc, AV_LOG_WARNING, "Unsupported Mastering Display Metadata box version %d\n", version);
6911 return 0;
6912 }
6913 if (sc->mastering) {
6914 av_log(c->fc, AV_LOG_WARNING, "Ignoring duplicate Mastering Display Metadata\n");
6915 return 0;
6916 }
6917
6918 avio_skip(pb, 3); /* flags */
6919
6921 if (!sc->mastering)
6922 return AVERROR(ENOMEM);
6923
6924 for (i = 0; i < 3; i++) {
6925 sc->mastering->display_primaries[i][0] = av_make_q(avio_rb16(pb), 1 << 16);
6926 sc->mastering->display_primaries[i][1] = av_make_q(avio_rb16(pb), 1 << 16);
6927 }
6928 sc->mastering->white_point[0] = av_make_q(avio_rb16(pb), 1 << 16);
6929 sc->mastering->white_point[1] = av_make_q(avio_rb16(pb), 1 << 16);
6930
6931 sc->mastering->max_luminance = av_make_q(avio_rb32(pb), 1 << 8);
6932 sc->mastering->min_luminance = av_make_q(avio_rb32(pb), 1 << 14);
6933
6934 sc->mastering->has_primaries = 1;
6935 sc->mastering->has_luminance = 1;
6936
6937 return 0;
6938}
6939
6941{
6942 MOVStreamContext *sc;
6943 const int mapping[3] = {1, 2, 0};
6944 const int chroma_den = 50000;
6945 const int luma_den = 10000;
6946 int i;
6947
6948 if (c->fc->nb_streams < 1)
6949 return AVERROR_INVALIDDATA;
6950
6951 sc = c->fc->streams[c->fc->nb_streams - 1]->priv_data;
6952
6953 if (atom.size < 24) {
6954 av_log(c->fc, AV_LOG_ERROR, "Invalid Mastering Display Color Volume box\n");
6955 return AVERROR_INVALIDDATA;
6956 }
6957
6958 if (sc->mastering) {
6959 av_log(c->fc, AV_LOG_WARNING, "Ignoring duplicate Mastering Display Color Volume\n");
6960 return 0;
6961 }
6962
6964 if (!sc->mastering)
6965 return AVERROR(ENOMEM);
6966
6967 for (i = 0; i < 3; i++) {
6968 const int j = mapping[i];
6969 sc->mastering->display_primaries[j][0] = av_make_q(avio_rb16(pb), chroma_den);
6970 sc->mastering->display_primaries[j][1] = av_make_q(avio_rb16(pb), chroma_den);
6971 }
6972 sc->mastering->white_point[0] = av_make_q(avio_rb16(pb), chroma_den);
6973 sc->mastering->white_point[1] = av_make_q(avio_rb16(pb), chroma_den);
6974
6975 sc->mastering->max_luminance = av_make_q(avio_rb32(pb), luma_den);
6976 sc->mastering->min_luminance = av_make_q(avio_rb32(pb), luma_den);
6977
6978 sc->mastering->has_luminance = 1;
6979 sc->mastering->has_primaries = 1;
6980
6981 return 0;
6982}
6983
6985{
6986 MOVStreamContext *sc;
6987 int version;
6988
6989 if (c->fc->nb_streams < 1)
6990 return AVERROR_INVALIDDATA;
6991
6992 sc = c->fc->streams[c->fc->nb_streams - 1]->priv_data;
6993
6994 if (atom.size < 5) {
6995 av_log(c->fc, AV_LOG_ERROR, "Empty Content Light Level box\n");
6996 return AVERROR_INVALIDDATA;
6997 }
6998
6999 version = avio_r8(pb);
7000 if (version) {
7001 av_log(c->fc, AV_LOG_WARNING, "Unsupported Content Light Level box version %d\n", version);
7002 return 0;
7003 }
7004 avio_skip(pb, 3); /* flags */
7005
7006 if (sc->coll){
7007 av_log(c->fc, AV_LOG_WARNING, "Ignoring duplicate COLL\n");
7008 return 0;
7009 }
7010
7012 if (!sc->coll)
7013 return AVERROR(ENOMEM);
7014
7015 sc->coll->MaxCLL = avio_rb16(pb);
7016 sc->coll->MaxFALL = avio_rb16(pb);
7017
7018 return 0;
7019}
7020
7022{
7023 MOVStreamContext *sc;
7024
7025 if (c->fc->nb_streams < 1)
7026 return AVERROR_INVALIDDATA;
7027
7028 sc = c->fc->streams[c->fc->nb_streams - 1]->priv_data;
7029
7030 if (atom.size < 4) {
7031 av_log(c->fc, AV_LOG_ERROR, "Empty Content Light Level Info box\n");
7032 return AVERROR_INVALIDDATA;
7033 }
7034
7035 if (sc->coll){
7036 av_log(c->fc, AV_LOG_WARNING, "Ignoring duplicate CLLI/COLL\n");
7037 return 0;
7038 }
7039
7041 if (!sc->coll)
7042 return AVERROR(ENOMEM);
7043
7044 sc->coll->MaxCLL = avio_rb16(pb);
7045 sc->coll->MaxFALL = avio_rb16(pb);
7046
7047 return 0;
7048}
7049
7051{
7052 MOVStreamContext *sc;
7053 const int illuminance_den = 10000;
7054 const int ambient_den = 50000;
7055 if (c->fc->nb_streams < 1)
7056 return AVERROR_INVALIDDATA;
7057 sc = c->fc->streams[c->fc->nb_streams - 1]->priv_data;
7058 if (atom.size < 6) {
7059 av_log(c->fc, AV_LOG_ERROR, "Empty Ambient Viewing Environment Info box\n");
7060 return AVERROR_INVALIDDATA;
7061 }
7062 if (sc->ambient){
7063 av_log(c->fc, AV_LOG_WARNING, "Ignoring duplicate AMVE\n");
7064 return 0;
7065 }
7067 if (!sc->ambient)
7068 return AVERROR(ENOMEM);
7069 sc->ambient->ambient_illuminance = av_make_q(avio_rb32(pb), illuminance_den);
7070 sc->ambient->ambient_light_x = av_make_q(avio_rb16(pb), ambient_den);
7071 sc->ambient->ambient_light_y = av_make_q(avio_rb16(pb), ambient_den);
7072 return 0;
7073}
7074
7076{
7077 AVStream *st;
7078 MOVStreamContext *sc;
7079 enum AVStereo3DType type;
7080 int mode;
7081
7082 if (c->fc->nb_streams < 1)
7083 return 0;
7084
7085 st = c->fc->streams[c->fc->nb_streams - 1];
7086 sc = st->priv_data;
7087
7088 if (atom.size < 5) {
7089 av_log(c->fc, AV_LOG_ERROR, "Empty stereoscopic video box\n");
7090 return AVERROR_INVALIDDATA;
7091 }
7092
7093 if (sc->stereo3d)
7094 return AVERROR_INVALIDDATA;
7095
7096 avio_skip(pb, 4); /* version + flags */
7097
7098 mode = avio_r8(pb);
7099 switch (mode) {
7100 case 0:
7102 break;
7103 case 1:
7105 break;
7106 case 2:
7108 break;
7109 default:
7110 av_log(c->fc, AV_LOG_WARNING, "Unknown st3d mode value %d\n", mode);
7111 return 0;
7112 }
7113
7115 if (!sc->stereo3d)
7116 return AVERROR(ENOMEM);
7117
7118 sc->stereo3d->type = type;
7119 return 0;
7120}
7121
7123{
7124 AVStream *st;
7125 MOVStreamContext *sc;
7126 int size = 0;
7127 int64_t remaining;
7128 uint32_t tag = 0;
7130
7131 if (c->fc->nb_streams < 1)
7132 return 0;
7133
7134 st = c->fc->streams[c->fc->nb_streams - 1];
7135 sc = st->priv_data;
7136
7137 remaining = atom.size;
7138 while (remaining > 0) {
7139 size = avio_rb32(pb);
7140 if (size < 8 || size > remaining ) {
7141 av_log(c->fc, AV_LOG_ERROR, "Invalid child size in pack box\n");
7142 return AVERROR_INVALIDDATA;
7143 }
7144
7145 tag = avio_rl32(pb);
7146 switch (tag) {
7147 case MKTAG('p','k','i','n'): {
7148 if (size != 16) {
7149 av_log(c->fc, AV_LOG_ERROR, "Invalid size of pkin box: %d\n", size);
7150 return AVERROR_INVALIDDATA;
7151 }
7152 avio_skip(pb, 1); // version
7153 avio_skip(pb, 3); // flags
7154
7155 tag = avio_rl32(pb);
7156 switch (tag) {
7157 case MKTAG('s','i','d','e'):
7159 break;
7160 case MKTAG('o','v','e','r'):
7162 break;
7163 case 0:
7164 // This means value will be set in another layer
7165 break;
7166 default:
7167 av_log(c->fc, AV_LOG_WARNING, "Unknown tag in pkin: %s\n",
7169 avio_skip(pb, size - 8);
7170 break;
7171 }
7172
7173 break;
7174 }
7175 default:
7176 av_log(c->fc, AV_LOG_WARNING, "Unknown tag in pack: %s\n",
7178 avio_skip(pb, size - 8);
7179 break;
7180 }
7181 remaining -= size;
7182 }
7183
7184 if (remaining != 0) {
7185 av_log(c->fc, AV_LOG_ERROR, "Broken pack box\n");
7186 return AVERROR_INVALIDDATA;
7187 }
7188
7189 if (type == AV_STEREO3D_2D)
7190 return 0;
7191
7192 if (!sc->stereo3d) {
7194 if (!sc->stereo3d)
7195 return AVERROR(ENOMEM);
7196 }
7197
7198 sc->stereo3d->type = type;
7199
7200 return 0;
7201}
7202
7204{
7205 AVStream *st;
7206 MOVStreamContext *sc;
7207 int size, version, layout;
7208 int32_t yaw, pitch, roll;
7209 uint32_t l = 0, t = 0, r = 0, b = 0;
7210 uint32_t tag, padding = 0;
7211 enum AVSphericalProjection projection;
7212
7213 if (c->fc->nb_streams < 1)
7214 return 0;
7215
7216 st = c->fc->streams[c->fc->nb_streams - 1];
7217 sc = st->priv_data;
7218
7219 if (atom.size < 8) {
7220 av_log(c->fc, AV_LOG_ERROR, "Empty spherical video box\n");
7221 return AVERROR_INVALIDDATA;
7222 }
7223
7224 size = avio_rb32(pb);
7225 if (size <= 12 || size > atom.size)
7226 return AVERROR_INVALIDDATA;
7227
7228 tag = avio_rl32(pb);
7229 if (tag != MKTAG('s','v','h','d')) {
7230 av_log(c->fc, AV_LOG_ERROR, "Missing spherical video header\n");
7231 return 0;
7232 }
7233 version = avio_r8(pb);
7234 if (version != 0) {
7235 av_log(c->fc, AV_LOG_WARNING, "Unknown spherical version %d\n",
7236 version);
7237 return 0;
7238 }
7239 avio_skip(pb, 3); /* flags */
7240 avio_skip(pb, size - 12); /* metadata_source */
7241
7242 size = avio_rb32(pb);
7243 if (size > atom.size)
7244 return AVERROR_INVALIDDATA;
7245
7246 tag = avio_rl32(pb);
7247 if (tag != MKTAG('p','r','o','j')) {
7248 av_log(c->fc, AV_LOG_ERROR, "Missing projection box\n");
7249 return 0;
7250 }
7251
7252 size = avio_rb32(pb);
7253 if (size > atom.size)
7254 return AVERROR_INVALIDDATA;
7255
7256 tag = avio_rl32(pb);
7257 if (tag != MKTAG('p','r','h','d')) {
7258 av_log(c->fc, AV_LOG_ERROR, "Missing projection header box\n");
7259 return 0;
7260 }
7261 version = avio_r8(pb);
7262 if (version != 0) {
7263 av_log(c->fc, AV_LOG_WARNING, "Unknown spherical version %d\n",
7264 version);
7265 return 0;
7266 }
7267 avio_skip(pb, 3); /* flags */
7268
7269 /* 16.16 fixed point */
7270 yaw = avio_rb32(pb);
7271 pitch = avio_rb32(pb);
7272 roll = avio_rb32(pb);
7273
7274 size = avio_rb32(pb);
7275 if (size > atom.size)
7276 return AVERROR_INVALIDDATA;
7277
7278 tag = avio_rl32(pb);
7279 version = avio_r8(pb);
7280 if (version != 0) {
7281 av_log(c->fc, AV_LOG_WARNING, "Unknown spherical version %d\n",
7282 version);
7283 return 0;
7284 }
7285 avio_skip(pb, 3); /* flags */
7286 switch (tag) {
7287 case MKTAG('c','b','m','p'):
7288 layout = avio_rb32(pb);
7289 if (layout) {
7290 av_log(c->fc, AV_LOG_WARNING,
7291 "Unsupported cubemap layout %d\n", layout);
7292 return 0;
7293 }
7294 projection = AV_SPHERICAL_CUBEMAP;
7295 padding = avio_rb32(pb);
7296 break;
7297 case MKTAG('e','q','u','i'):
7298 t = avio_rb32(pb);
7299 b = avio_rb32(pb);
7300 l = avio_rb32(pb);
7301 r = avio_rb32(pb);
7302
7303 if (b >= UINT_MAX - t || r >= UINT_MAX - l) {
7304 av_log(c->fc, AV_LOG_ERROR,
7305 "Invalid bounding rectangle coordinates "
7306 "%"PRIu32",%"PRIu32",%"PRIu32",%"PRIu32"\n", l, t, r, b);
7307 return AVERROR_INVALIDDATA;
7308 }
7309
7310 if (l || t || r || b)
7312 else
7313 projection = AV_SPHERICAL_EQUIRECTANGULAR;
7314 break;
7315 default:
7316 av_log(c->fc, AV_LOG_ERROR, "Unknown projection type: %s\n", av_fourcc2str(tag));
7317 return 0;
7318 }
7319
7321 if (!sc->spherical)
7322 return AVERROR(ENOMEM);
7323
7324 sc->spherical->projection = projection;
7325
7326 sc->spherical->yaw = yaw;
7327 sc->spherical->pitch = pitch;
7328 sc->spherical->roll = roll;
7329
7330 sc->spherical->padding = padding;
7331
7332 sc->spherical->bound_left = l;
7333 sc->spherical->bound_top = t;
7334 sc->spherical->bound_right = r;
7335 sc->spherical->bound_bottom = b;
7336
7337 return 0;
7338}
7339
7341{
7342 AVStream *st;
7343 MOVStreamContext *sc;
7344 int size;
7345 uint32_t tag;
7346 enum AVSphericalProjection projection;
7347
7348 if (c->fc->nb_streams < 1)
7349 return 0;
7350
7351 st = c->fc->streams[c->fc->nb_streams - 1];
7352 sc = st->priv_data;
7353
7354 if (atom.size < 16) {
7355 av_log(c->fc, AV_LOG_ERROR, "Invalid size for proj box: %"PRIu64"\n", atom.size);
7356 return AVERROR_INVALIDDATA;
7357 }
7358
7359 size = avio_rb32(pb);
7360 if (size < 16) {
7361 av_log(c->fc, AV_LOG_ERROR, "Invalid size for prji box: %d\n", size);
7362 return AVERROR_INVALIDDATA;
7363 } else if (size > 16) {
7364 av_log(c->fc, AV_LOG_WARNING, "Box has more bytes (%d) than prji box required (16) \n", size);
7365 }
7366
7367 tag = avio_rl32(pb);
7368 if (tag != MKTAG('p','r','j','i')) {
7369 av_log(c->fc, AV_LOG_ERROR, "Invalid child box of proj box: %s\n",
7371 return AVERROR_INVALIDDATA;
7372 }
7373
7374 // version and flags, only support (0, 0)
7375 unsigned n = avio_rl32(pb);
7376 if (n != 0) {
7377 av_log(c->fc, AV_LOG_ERROR, "prji version %u, flag %u are not supported\n",
7378 n & 0xFF, n >> 8);
7379 return AVERROR_PATCHWELCOME;
7380 }
7381
7382 tag = avio_rl32(pb);
7383 switch (tag) {
7384 case MKTAG('r','e','c','t'):
7385 projection = AV_SPHERICAL_RECTILINEAR;
7386 break;
7387 case MKTAG('e','q','u','i'):
7388 projection = AV_SPHERICAL_EQUIRECTANGULAR;
7389 break;
7390 case MKTAG('h','e','q','u'):
7392 break;
7393 case MKTAG('f','i','s','h'):
7394 projection = AV_SPHERICAL_FISHEYE;
7395 break;
7396 case MKTAG('p','r','i','m'):
7398 break;
7399 default:
7400 av_log(c->fc, AV_LOG_ERROR, "Invalid projection type in prji box: %s\n", av_fourcc2str(tag));
7401 return AVERROR_INVALIDDATA;
7402 }
7403
7405 if (!sc->spherical)
7406 return AVERROR(ENOMEM);
7407
7408 sc->spherical->projection = projection;
7409
7410 return 0;
7411}
7412
7414{
7415 AVStream *st;
7416 MOVStreamContext *sc;
7417 int size, flags = 0;
7418 int64_t remaining;
7419 uint32_t tag, baseline = 0;
7422 enum AVStereo3DPrimaryEye primary_eye = AV_PRIMARY_EYE_NONE;
7423 AVRational horizontal_disparity_adjustment = { 0, 1 };
7424
7425 if (c->fc->nb_streams < 1)
7426 return 0;
7427
7428 st = c->fc->streams[c->fc->nb_streams - 1];
7429 sc = st->priv_data;
7430
7431 remaining = atom.size;
7432 while (remaining > 0) {
7433 size = avio_rb32(pb);
7434 if (size < 8 || size > remaining ) {
7435 av_log(c->fc, AV_LOG_ERROR, "Invalid child size in eyes box\n");
7436 return AVERROR_INVALIDDATA;
7437 }
7438
7439 tag = avio_rl32(pb);
7440 switch (tag) {
7441 case MKTAG('s','t','r','i'): {
7442 int has_right, has_left;
7443 uint8_t tmp;
7444 if (size != 13) {
7445 av_log(c->fc, AV_LOG_ERROR, "Invalid size of stri box: %d\n", size);
7446 return AVERROR_INVALIDDATA;
7447 }
7448 avio_skip(pb, 1); // version
7449 avio_skip(pb, 3); // flags
7450
7451 tmp = avio_r8(pb);
7452
7453 // eye_views_reversed
7454 if (tmp & 8) {
7456 }
7457 // has_additional_views
7458 if (tmp & 4) {
7459 // skip...
7460 }
7461
7462 has_right = tmp & 2; // has_right_eye_view
7463 has_left = tmp & 1; // has_left_eye_view
7464
7465 if (has_left && has_right)
7467 else if (has_left)
7468 view = AV_STEREO3D_VIEW_LEFT;
7469 else if (has_right)
7471 if (has_left || has_right)
7473
7474 break;
7475 }
7476 case MKTAG('h','e','r','o'): {
7477 int tmp;
7478 if (size != 13) {
7479 av_log(c->fc, AV_LOG_ERROR, "Invalid size of hero box: %d\n", size);
7480 return AVERROR_INVALIDDATA;
7481 }
7482 avio_skip(pb, 1); // version
7483 avio_skip(pb, 3); // flags
7484
7485 tmp = avio_r8(pb);
7486 if (tmp == 0)
7487 primary_eye = AV_PRIMARY_EYE_NONE;
7488 else if (tmp == 1)
7489 primary_eye = AV_PRIMARY_EYE_LEFT;
7490 else if (tmp == 2)
7491 primary_eye = AV_PRIMARY_EYE_RIGHT;
7492 else
7493 av_log(c->fc, AV_LOG_WARNING, "Unknown hero eye type: %d\n", tmp);
7494
7495 break;
7496 }
7497 case MKTAG('c','a','m','s'): {
7498 uint32_t subtag;
7499 int subsize;
7500 if (size != 24) {
7501 av_log(c->fc, AV_LOG_ERROR, "Invalid size of cams box: %d\n", size);
7502 return AVERROR_INVALIDDATA;
7503 }
7504
7505 subsize = avio_rb32(pb);
7506 if (subsize != 16) {
7507 av_log(c->fc, AV_LOG_ERROR, "Invalid size of blin box: %d\n", size);
7508 return AVERROR_INVALIDDATA;
7509 }
7510
7511 subtag = avio_rl32(pb);
7512 if (subtag != MKTAG('b','l','i','n')) {
7513 av_log(c->fc, AV_LOG_ERROR, "Expected blin box, got %s\n",
7514 av_fourcc2str(subtag));
7515 return AVERROR_INVALIDDATA;
7516 }
7517
7518 avio_skip(pb, 1); // version
7519 avio_skip(pb, 3); // flags
7520
7521 baseline = avio_rb32(pb);
7522
7523 break;
7524 }
7525 case MKTAG('c','m','f','y'): {
7526 uint32_t subtag;
7527 int subsize;
7528 int32_t adjustment;
7529 if (size != 24) {
7530 av_log(c->fc, AV_LOG_ERROR, "Invalid size of cmfy box: %d\n", size);
7531 return AVERROR_INVALIDDATA;
7532 }
7533
7534 subsize = avio_rb32(pb);
7535 if (subsize != 16) {
7536 av_log(c->fc, AV_LOG_ERROR, "Invalid size of dadj box: %d\n", size);
7537 return AVERROR_INVALIDDATA;
7538 }
7539
7540 subtag = avio_rl32(pb);
7541 if (subtag != MKTAG('d','a','d','j')) {
7542 av_log(c->fc, AV_LOG_ERROR, "Expected dadj box, got %s\n",
7543 av_fourcc2str(subtag));
7544 return AVERROR_INVALIDDATA;
7545 }
7546
7547 avio_skip(pb, 1); // version
7548 avio_skip(pb, 3); // flags
7549
7550 adjustment = (int32_t) avio_rb32(pb);
7551
7552 horizontal_disparity_adjustment.num = (int) adjustment;
7553 horizontal_disparity_adjustment.den = 10000;
7554
7555 break;
7556 }
7557 default:
7558 av_log(c->fc, AV_LOG_WARNING, "Unknown tag in eyes: %s\n",
7560 avio_skip(pb, size - 8);
7561 break;
7562 }
7563 remaining -= size;
7564 }
7565
7566 if (remaining != 0) {
7567 av_log(c->fc, AV_LOG_ERROR, "Broken eyes box\n");
7568 return AVERROR_INVALIDDATA;
7569 }
7570
7571 if (type == AV_STEREO3D_2D)
7572 return 0;
7573
7574 if (!sc->stereo3d) {
7576 if (!sc->stereo3d)
7577 return AVERROR(ENOMEM);
7578 }
7579
7580 sc->stereo3d->flags = flags;
7581 /* eyes/stri only records packed vs single-eye, not SBS/TB. Keep a more
7582 * specific type already set by st3d. */
7583 if (type != AV_STEREO3D_UNSPEC)
7584 sc->stereo3d->type = type;
7585 else if (sc->stereo3d->type == AV_STEREO3D_2D)
7586 sc->stereo3d->type = type;
7587 sc->stereo3d->view = view;
7588 sc->stereo3d->primary_eye = primary_eye;
7589 sc->stereo3d->baseline = baseline;
7590 sc->stereo3d->horizontal_disparity_adjustment = horizontal_disparity_adjustment;
7591
7592 return 0;
7593}
7594
7596{
7597 int size;
7598 int64_t remaining;
7599 uint32_t tag;
7600
7601 if (c->fc->nb_streams < 1)
7602 return 0;
7603
7604 if (atom.size < 8) {
7605 av_log(c->fc, AV_LOG_ERROR, "Empty video extension usage box\n");
7606 return AVERROR_INVALIDDATA;
7607 }
7608
7609 remaining = atom.size;
7610 while (remaining > 0) {
7611 size = avio_rb32(pb);
7612 if (size < 8 || size > remaining ) {
7613 av_log(c->fc, AV_LOG_ERROR, "Invalid child size in vexu box\n");
7614 return AVERROR_INVALIDDATA;
7615 }
7616
7617 tag = avio_rl32(pb);
7618 switch (tag) {
7619 case MKTAG('p','r','o','j'): {
7620 MOVAtom proj = { tag, size - 8 };
7621 int ret = mov_read_vexu_proj(c, pb, proj);
7622 if (ret < 0)
7623 return ret;
7624 break;
7625 }
7626 case MKTAG('e','y','e','s'): {
7627 MOVAtom eyes = { tag, size - 8 };
7628 int ret = mov_read_eyes(c, pb, eyes);
7629 if (ret < 0)
7630 return ret;
7631 break;
7632 }
7633 case MKTAG('p','a','c','k'): {
7634 MOVAtom pack = { tag, size - 8 };
7635 int ret = mov_read_pack(c, pb, pack);
7636 if (ret < 0)
7637 return ret;
7638 break;
7639 }
7640 default:
7641 av_log(c->fc, AV_LOG_WARNING, "Unknown tag in vexu: %s\n",
7643 avio_skip(pb, size - 8);
7644 break;
7645 }
7646 remaining -= size;
7647 }
7648
7649 if (remaining != 0) {
7650 av_log(c->fc, AV_LOG_ERROR, "Broken vexu box\n");
7651 return AVERROR_INVALIDDATA;
7652 }
7653
7654 return 0;
7655}
7656
7658{
7659 AVStream *st;
7660 MOVStreamContext *sc;
7661
7662 if (c->fc->nb_streams < 1)
7663 return 0;
7664
7665 st = c->fc->streams[c->fc->nb_streams - 1];
7666 sc = st->priv_data;
7667
7668 if (atom.size != 4) {
7669 av_log(c->fc, AV_LOG_ERROR, "Invalid size of hfov box: %"PRIu64"\n", atom.size);
7670 return AVERROR_INVALIDDATA;
7671 }
7672
7673
7674 if (!sc->stereo3d) {
7676 if (!sc->stereo3d)
7677 return AVERROR(ENOMEM);
7678 }
7679
7681 sc->stereo3d->horizontal_field_of_view.den = 1000; // thousands of a degree
7682
7683 return 0;
7684}
7685
7687{
7688 int ret = 0;
7689 uint8_t *buffer = av_malloc(len + 1);
7690 const char *val;
7691
7692 if (!buffer)
7693 return AVERROR(ENOMEM);
7694 buffer[len] = '\0';
7695
7696 ret = ffio_read_size(pb, buffer, len);
7697 if (ret < 0)
7698 goto out;
7699
7700 /* Check for mandatory keys and values, try to support XML as best-effort */
7701 if (!sc->spherical &&
7702 av_stristr(buffer, "<GSpherical:StitchingSoftware>") &&
7703 (val = av_stristr(buffer, "<GSpherical:Spherical>")) &&
7704 av_stristr(val, "true") &&
7705 (val = av_stristr(buffer, "<GSpherical:Stitched>")) &&
7706 av_stristr(val, "true") &&
7707 (val = av_stristr(buffer, "<GSpherical:ProjectionType>")) &&
7708 av_stristr(val, "equirectangular")) {
7710 if (!sc->spherical)
7711 goto out;
7712
7714
7715 if (av_stristr(buffer, "<GSpherical:StereoMode>") && !sc->stereo3d) {
7716 enum AVStereo3DType mode;
7717
7718 if (av_stristr(buffer, "left-right"))
7720 else if (av_stristr(buffer, "top-bottom"))
7722 else
7724
7726 if (!sc->stereo3d)
7727 goto out;
7728
7729 sc->stereo3d->type = mode;
7730 }
7731
7732 /* orientation */
7733 val = av_stristr(buffer, "<GSpherical:InitialViewHeadingDegrees>");
7734 if (val)
7735 sc->spherical->yaw = strtol(val, NULL, 10) * (1 << 16);
7736 val = av_stristr(buffer, "<GSpherical:InitialViewPitchDegrees>");
7737 if (val)
7738 sc->spherical->pitch = strtol(val, NULL, 10) * (1 << 16);
7739 val = av_stristr(buffer, "<GSpherical:InitialViewRollDegrees>");
7740 if (val)
7741 sc->spherical->roll = strtol(val, NULL, 10) * (1 << 16);
7742 }
7743
7744out:
7745 av_free(buffer);
7746 return ret;
7747}
7748
7750{
7751 AVStream *st;
7752 MOVStreamContext *sc;
7753 int64_t ret;
7754 AVUUID uuid;
7755 static const AVUUID uuid_isml_manifest = {
7756 0xa5, 0xd4, 0x0b, 0x30, 0xe8, 0x14, 0x11, 0xdd,
7757 0xba, 0x2f, 0x08, 0x00, 0x20, 0x0c, 0x9a, 0x66
7758 };
7759 static const AVUUID uuid_xmp = {
7760 0xbe, 0x7a, 0xcf, 0xcb, 0x97, 0xa9, 0x42, 0xe8,
7761 0x9c, 0x71, 0x99, 0x94, 0x91, 0xe3, 0xaf, 0xac
7762 };
7763 static const AVUUID uuid_spherical = {
7764 0xff, 0xcc, 0x82, 0x63, 0xf8, 0x55, 0x4a, 0x93,
7765 0x88, 0x14, 0x58, 0x7a, 0x02, 0x52, 0x1f, 0xdd,
7766 };
7767
7768 if (atom.size < AV_UUID_LEN || atom.size >= FFMIN(INT_MAX, SIZE_MAX))
7769 return AVERROR_INVALIDDATA;
7770
7771 if (c->fc->nb_streams < 1)
7772 return 0;
7773 st = c->fc->streams[c->fc->nb_streams - 1];
7774 sc = st->priv_data;
7775
7776 ret = ffio_read_size(pb, uuid, AV_UUID_LEN);
7777 if (ret < 0)
7778 return ret;
7779 if (av_uuid_equal(uuid, uuid_isml_manifest)) {
7780 uint8_t *buffer, *ptr;
7781 char *endptr;
7782 size_t len = atom.size - AV_UUID_LEN;
7783
7784 if (len < 4) {
7785 return AVERROR_INVALIDDATA;
7786 }
7787 ret = avio_skip(pb, 4); // zeroes
7788 len -= 4;
7789
7790 buffer = av_mallocz(len + 1);
7791 if (!buffer) {
7792 return AVERROR(ENOMEM);
7793 }
7794 ret = ffio_read_size(pb, buffer, len);
7795 if (ret < 0) {
7796 av_free(buffer);
7797 return ret;
7798 }
7799
7800 ptr = buffer;
7801 while ((ptr = av_stristr(ptr, "systemBitrate=\""))) {
7802 ptr += sizeof("systemBitrate=\"") - 1;
7803 c->bitrates_count++;
7804 c->bitrates = av_realloc_f(c->bitrates, c->bitrates_count, sizeof(*c->bitrates));
7805 if (!c->bitrates) {
7806 c->bitrates_count = 0;
7807 av_free(buffer);
7808 return AVERROR(ENOMEM);
7809 }
7810 errno = 0;
7811 ret = strtol(ptr, &endptr, 10);
7812 if (ret < 0 || errno || *endptr != '"') {
7813 c->bitrates[c->bitrates_count - 1] = 0;
7814 } else {
7815 c->bitrates[c->bitrates_count - 1] = ret;
7816 }
7817 }
7818
7819 av_free(buffer);
7820 } else if (av_uuid_equal(uuid, uuid_xmp)) {
7821 uint8_t *buffer;
7822 size_t len = atom.size - AV_UUID_LEN;
7823 if (c->export_xmp) {
7824 buffer = av_mallocz(len + 1);
7825 if (!buffer) {
7826 return AVERROR(ENOMEM);
7827 }
7828 ret = ffio_read_size(pb, buffer, len);
7829 if (ret < 0) {
7830 av_free(buffer);
7831 return ret;
7832 }
7833 buffer[len] = '\0';
7834 av_dict_set(&c->fc->metadata, "xmp",
7836 } else {
7837 // skip all uuid atom, which makes it fast for long uuid-xmp file
7838 ret = avio_skip(pb, len);
7839 if (ret < 0)
7840 return ret;
7841 }
7842 } else if (av_uuid_equal(uuid, uuid_spherical)) {
7843 size_t len = atom.size - AV_UUID_LEN;
7844 ret = mov_parse_uuid_spherical(sc, pb, len);
7845 if (ret < 0)
7846 return ret;
7847 if (!sc->spherical)
7848 av_log(c->fc, AV_LOG_WARNING, "Invalid spherical metadata found\n");
7849 }
7850
7851 return 0;
7852}
7853
7855{
7856 int ret;
7857 uint8_t content[16];
7858
7859 if (atom.size < 8)
7860 return 0;
7861
7862 ret = ffio_read_size(pb, content, FFMIN(sizeof(content), atom.size));
7863 if (ret < 0)
7864 return ret;
7865
7866 if ( !c->found_moov
7867 && !c->found_mdat
7868 && !memcmp(content, "Anevia\x1A\x1A", 8)
7869 && c->use_mfra_for == FF_MOV_FLAG_MFRA_AUTO) {
7870 c->use_mfra_for = FF_MOV_FLAG_MFRA_PTS;
7871 }
7872
7873 return 0;
7874}
7875
7877{
7878 uint32_t format = avio_rl32(pb);
7879 MOVStreamContext *sc;
7880 enum AVCodecID id;
7881 AVStream *st;
7882
7883 if (c->fc->nb_streams < 1)
7884 return 0;
7885 st = c->fc->streams[c->fc->nb_streams - 1];
7886 sc = st->priv_data;
7887
7888 switch (sc->format)
7889 {
7890 case MKTAG('e','n','c','v'): // encrypted video
7891 case MKTAG('e','n','c','a'): // encrypted audio
7892 id = mov_codec_id(st, format);
7893 if (st->codecpar->codec_id != AV_CODEC_ID_NONE &&
7894 st->codecpar->codec_id != id) {
7895 av_log(c->fc, AV_LOG_WARNING,
7896 "ignoring 'frma' atom of '%.4s', stream has codec id %d\n",
7897 (char*)&format, st->codecpar->codec_id);
7898 break;
7899 }
7900
7901 st->codecpar->codec_id = id;
7902 sc->format = format;
7903 break;
7904
7905 default:
7906 if (format != sc->format) {
7907 av_log(c->fc, AV_LOG_WARNING,
7908 "ignoring 'frma' atom of '%.4s', stream format is '%.4s'\n",
7909 (char*)&format, (char*)&sc->format);
7910 }
7911 break;
7912 }
7913
7914 return 0;
7915}
7916
7917/**
7918 * Gets the current encryption info and associated current stream context. If
7919 * we are parsing a track fragment, this will return the specific encryption
7920 * info for this fragment; otherwise this will return the global encryption
7921 * info for the current stream.
7922 */
7924{
7925 MOVFragmentStreamInfo *frag_stream_info;
7926 AVStream *st;
7927 int i;
7928
7929 frag_stream_info = get_current_frag_stream_info(&c->frag_index);
7930 if (frag_stream_info) {
7931 for (i = 0; i < c->fc->nb_streams; i++) {
7932 *sc = c->fc->streams[i]->priv_data;
7933 if ((*sc)->id == frag_stream_info->id) {
7934 st = c->fc->streams[i];
7935 break;
7936 }
7937 }
7938 if (i == c->fc->nb_streams)
7939 return 0;
7940 *sc = st->priv_data;
7941
7942 if (!frag_stream_info->encryption_index) {
7943 // If this stream isn't encrypted, don't create the index.
7944 if (!(*sc)->cenc.default_encrypted_sample)
7945 return 0;
7946 frag_stream_info->encryption_index = av_mallocz(sizeof(*frag_stream_info->encryption_index));
7947 if (!frag_stream_info->encryption_index)
7948 return AVERROR(ENOMEM);
7949 }
7950 *encryption_index = frag_stream_info->encryption_index;
7951 return 1;
7952 } else {
7953 // No current track fragment, using stream level encryption info.
7954
7955 if (c->fc->nb_streams < 1)
7956 return 0;
7957 st = c->fc->streams[c->fc->nb_streams - 1];
7958 *sc = st->priv_data;
7959
7960 if (!(*sc)->cenc.encryption_index) {
7961 // If this stream isn't encrypted, don't create the index.
7962 if (!(*sc)->cenc.default_encrypted_sample)
7963 return 0;
7964 (*sc)->cenc.encryption_index = av_mallocz(sizeof(*frag_stream_info->encryption_index));
7965 if (!(*sc)->cenc.encryption_index)
7966 return AVERROR(ENOMEM);
7967 }
7968
7969 *encryption_index = (*sc)->cenc.encryption_index;
7970 return 1;
7971 }
7972}
7973
7975{
7976 int i, ret;
7977 unsigned int subsample_count;
7978 AVSubsampleEncryptionInfo *subsamples;
7979
7980 if (!sc->cenc.default_encrypted_sample) {
7981 av_log(c->fc, AV_LOG_ERROR, "Missing schm or tenc\n");
7982 return AVERROR_INVALIDDATA;
7983 }
7984
7985 if (sc->cenc.per_sample_iv_size || use_subsamples) {
7987 if (!*sample)
7988 return AVERROR(ENOMEM);
7989 } else
7990 *sample = NULL;
7991
7992 if (sc->cenc.per_sample_iv_size != 0) {
7993 if ((ret = ffio_read_size(pb, (*sample)->iv, sc->cenc.per_sample_iv_size)) < 0) {
7994 av_log(c->fc, AV_LOG_ERROR, "failed to read the initialization vector\n");
7996 *sample = NULL;
7997 return ret;
7998 }
7999 }
8000
8001 if (use_subsamples) {
8002 subsample_count = avio_rb16(pb);
8003 av_free((*sample)->subsamples);
8004 (*sample)->subsamples = av_calloc(subsample_count, sizeof(*subsamples));
8005 if (!(*sample)->subsamples) {
8007 *sample = NULL;
8008 return AVERROR(ENOMEM);
8009 }
8010
8011 for (i = 0; i < subsample_count && !pb->eof_reached; i++) {
8012 (*sample)->subsamples[i].bytes_of_clear_data = avio_rb16(pb);
8013 (*sample)->subsamples[i].bytes_of_protected_data = avio_rb32(pb);
8014 }
8015
8016 if (pb->eof_reached) {
8017 av_log(c->fc, AV_LOG_ERROR, "hit EOF while reading sub-sample encryption info\n");
8019 *sample = NULL;
8020 return AVERROR_INVALIDDATA;
8021 }
8022 (*sample)->subsample_count = subsample_count;
8023 }
8024
8025 return 0;
8026}
8027
8029{
8030 AVEncryptionInfo **encrypted_samples;
8031 MOVEncryptionIndex *encryption_index;
8032 MOVStreamContext *sc;
8033 int use_subsamples, ret;
8034 unsigned int sample_count, i, alloc_size = 0;
8035
8036 ret = get_current_encryption_info(c, &encryption_index, &sc);
8037 if (ret != 1)
8038 return ret;
8039
8040 if (encryption_index->nb_encrypted_samples) {
8041 // This can happen if we have both saio/saiz and senc atoms.
8042 av_log(c->fc, AV_LOG_DEBUG, "Ignoring duplicate encryption info in senc\n");
8043 return 0;
8044 }
8045
8046 avio_r8(pb); /* version */
8047 use_subsamples = avio_rb24(pb) & 0x02; /* flags */
8048
8049 sample_count = avio_rb32(pb);
8050 if (sample_count >= INT_MAX / sizeof(*encrypted_samples))
8051 return AVERROR(ENOMEM);
8052
8053 for (i = 0; i < sample_count; i++) {
8054 unsigned int min_samples = FFMIN(FFMAX(i + 1, 1024 * 1024), sample_count);
8055 encrypted_samples = av_fast_realloc(encryption_index->encrypted_samples, &alloc_size,
8056 min_samples * sizeof(*encrypted_samples));
8057 if (encrypted_samples) {
8058 encryption_index->encrypted_samples = encrypted_samples;
8059
8061 c, pb, sc, &encryption_index->encrypted_samples[i], use_subsamples);
8062 } else {
8063 ret = AVERROR(ENOMEM);
8064 }
8065 if (pb->eof_reached) {
8066 av_log(c->fc, AV_LOG_ERROR, "Hit EOF while reading senc\n");
8067 if (ret >= 0)
8068 av_encryption_info_free(encryption_index->encrypted_samples[i]);
8069 ret = AVERROR_INVALIDDATA;
8070 }
8071
8072 if (ret < 0) {
8073 for (; i > 0; i--)
8074 av_encryption_info_free(encryption_index->encrypted_samples[i - 1]);
8075 av_freep(&encryption_index->encrypted_samples);
8076 return ret;
8077 }
8078 }
8079 encryption_index->nb_encrypted_samples = sample_count;
8080
8081 return 0;
8082}
8083
8085{
8086 AVEncryptionInfo **sample, **encrypted_samples;
8087 int64_t prev_pos;
8088 size_t sample_count, sample_info_size, i;
8089 int ret = 0;
8090 unsigned int alloc_size = 0;
8091
8092 if (encryption_index->nb_encrypted_samples)
8093 return 0;
8094 sample_count = encryption_index->auxiliary_info_sample_count;
8095 if (encryption_index->auxiliary_offsets_count != 1) {
8096 av_log(c->fc, AV_LOG_ERROR, "Multiple auxiliary info chunks are not supported\n");
8097 return AVERROR_PATCHWELCOME;
8098 }
8099 if (sample_count >= INT_MAX / sizeof(*encrypted_samples))
8100 return AVERROR(ENOMEM);
8101
8102 prev_pos = avio_tell(pb);
8103 if (!(pb->seekable & AVIO_SEEKABLE_NORMAL) ||
8104 avio_seek(pb, encryption_index->auxiliary_offsets[0], SEEK_SET) != encryption_index->auxiliary_offsets[0]) {
8105 av_log(c->fc, AV_LOG_INFO, "Failed to seek for auxiliary info, will only parse senc atoms for encryption info\n");
8106 goto finish;
8107 }
8108
8109 for (i = 0; i < sample_count && !pb->eof_reached; i++) {
8110 unsigned int min_samples = FFMIN(FFMAX(i + 1, 1024 * 1024), sample_count);
8111 encrypted_samples = av_fast_realloc(encryption_index->encrypted_samples, &alloc_size,
8112 min_samples * sizeof(*encrypted_samples));
8113 if (!encrypted_samples) {
8114 ret = AVERROR(ENOMEM);
8115 goto finish;
8116 }
8117 encryption_index->encrypted_samples = encrypted_samples;
8118
8119 sample = &encryption_index->encrypted_samples[i];
8120 sample_info_size = encryption_index->auxiliary_info_default_size
8121 ? encryption_index->auxiliary_info_default_size
8122 : encryption_index->auxiliary_info_sizes[i];
8123
8124 ret = mov_read_sample_encryption_info(c, pb, sc, sample, sample_info_size > sc->cenc.per_sample_iv_size);
8125 if (ret < 0)
8126 goto finish;
8127 }
8128 if (pb->eof_reached) {
8129 av_log(c->fc, AV_LOG_ERROR, "Hit EOF while reading auxiliary info\n");
8130 ret = AVERROR_INVALIDDATA;
8131 } else {
8132 encryption_index->nb_encrypted_samples = sample_count;
8133 }
8134
8135finish:
8136 avio_seek(pb, prev_pos, SEEK_SET);
8137 if (ret < 0) {
8138 for (; i > 0; i--) {
8139 av_encryption_info_free(encryption_index->encrypted_samples[i - 1]);
8140 }
8141 av_freep(&encryption_index->encrypted_samples);
8142 }
8143 return ret;
8144}
8145
8147{
8148 MOVEncryptionIndex *encryption_index;
8149 MOVStreamContext *sc;
8150 int ret;
8151 unsigned int sample_count, aux_info_type, aux_info_param;
8152
8153 ret = get_current_encryption_info(c, &encryption_index, &sc);
8154 if (ret != 1)
8155 return ret;
8156
8157 if (encryption_index->nb_encrypted_samples) {
8158 // This can happen if we have both saio/saiz and senc atoms.
8159 av_log(c->fc, AV_LOG_DEBUG, "Ignoring duplicate encryption info in saiz\n");
8160 return 0;
8161 }
8162
8163 if (encryption_index->auxiliary_info_sample_count) {
8164 av_log(c->fc, AV_LOG_ERROR, "Duplicate saiz atom\n");
8165 return AVERROR_INVALIDDATA;
8166 }
8167
8168 avio_r8(pb); /* version */
8169 if (avio_rb24(pb) & 0x01) { /* flags */
8170 aux_info_type = avio_rb32(pb);
8171 aux_info_param = avio_rb32(pb);
8173 if (aux_info_type != sc->cenc.default_encrypted_sample->scheme) {
8174 av_log(c->fc, AV_LOG_DEBUG, "Ignoring saiz box with non-zero aux_info_type\n");
8175 return 0;
8176 }
8177 if (aux_info_param != 0) {
8178 av_log(c->fc, AV_LOG_DEBUG, "Ignoring saiz box with non-zero aux_info_type_parameter\n");
8179 return 0;
8180 }
8181 } else {
8182 // Didn't see 'schm' or 'tenc', so this isn't encrypted.
8183 if ((aux_info_type == MKBETAG('c','e','n','c') ||
8184 aux_info_type == MKBETAG('c','e','n','s') ||
8185 aux_info_type == MKBETAG('c','b','c','1') ||
8186 aux_info_type == MKBETAG('c','b','c','s')) &&
8187 aux_info_param == 0) {
8188 av_log(c->fc, AV_LOG_ERROR, "Saw encrypted saiz without schm/tenc\n");
8189 return AVERROR_INVALIDDATA;
8190 } else {
8191 return 0;
8192 }
8193 }
8194 } else if (!sc->cenc.default_encrypted_sample) {
8195 // Didn't see 'schm' or 'tenc', so this isn't encrypted.
8196 return 0;
8197 }
8198
8199 encryption_index->auxiliary_info_default_size = avio_r8(pb);
8200 sample_count = avio_rb32(pb);
8201
8202 if (encryption_index->auxiliary_info_default_size == 0) {
8203 if (sample_count == 0)
8204 return AVERROR_INVALIDDATA;
8205
8206 encryption_index->auxiliary_info_sizes = av_malloc(sample_count);
8207 if (!encryption_index->auxiliary_info_sizes)
8208 return AVERROR(ENOMEM);
8209
8210 ret = avio_read(pb, encryption_index->auxiliary_info_sizes, sample_count);
8211 if (ret != sample_count) {
8212 av_freep(&encryption_index->auxiliary_info_sizes);
8213
8214 if (ret >= 0)
8215 ret = AVERROR_INVALIDDATA;
8216 av_log(c->fc, AV_LOG_ERROR, "Failed to read the auxiliary info, %s\n",
8217 av_err2str(ret));
8218 return ret;
8219 }
8220 }
8221 encryption_index->auxiliary_info_sample_count = sample_count;
8222
8223 if (encryption_index->auxiliary_offsets_count) {
8224 return mov_parse_auxiliary_info(c, sc, pb, encryption_index);
8225 }
8226
8227 return 0;
8228}
8229
8231{
8232 uint64_t *auxiliary_offsets;
8233 MOVEncryptionIndex *encryption_index;
8234 MOVStreamContext *sc;
8235 int i, ret;
8236 unsigned int version, entry_count, aux_info_type, aux_info_param;
8237 unsigned int alloc_size = 0;
8238
8239 ret = get_current_encryption_info(c, &encryption_index, &sc);
8240 if (ret != 1)
8241 return ret;
8242
8243 if (encryption_index->nb_encrypted_samples) {
8244 // This can happen if we have both saio/saiz and senc atoms.
8245 av_log(c->fc, AV_LOG_DEBUG, "Ignoring duplicate encryption info in saio\n");
8246 return 0;
8247 }
8248
8249 if (encryption_index->auxiliary_offsets_count) {
8250 av_log(c->fc, AV_LOG_ERROR, "Duplicate saio atom\n");
8251 return AVERROR_INVALIDDATA;
8252 }
8253
8254 version = avio_r8(pb); /* version */
8255 if (avio_rb24(pb) & 0x01) { /* flags */
8256 aux_info_type = avio_rb32(pb);
8257 aux_info_param = avio_rb32(pb);
8259 if (aux_info_type != sc->cenc.default_encrypted_sample->scheme) {
8260 av_log(c->fc, AV_LOG_DEBUG, "Ignoring saio box with non-zero aux_info_type\n");
8261 return 0;
8262 }
8263 if (aux_info_param != 0) {
8264 av_log(c->fc, AV_LOG_DEBUG, "Ignoring saio box with non-zero aux_info_type_parameter\n");
8265 return 0;
8266 }
8267 } else {
8268 // Didn't see 'schm' or 'tenc', so this isn't encrypted.
8269 if ((aux_info_type == MKBETAG('c','e','n','c') ||
8270 aux_info_type == MKBETAG('c','e','n','s') ||
8271 aux_info_type == MKBETAG('c','b','c','1') ||
8272 aux_info_type == MKBETAG('c','b','c','s')) &&
8273 aux_info_param == 0) {
8274 av_log(c->fc, AV_LOG_ERROR, "Saw encrypted saio without schm/tenc\n");
8275 return AVERROR_INVALIDDATA;
8276 } else {
8277 return 0;
8278 }
8279 }
8280 } else if (!sc->cenc.default_encrypted_sample) {
8281 // Didn't see 'schm' or 'tenc', so this isn't encrypted.
8282 return 0;
8283 }
8284
8285 entry_count = avio_rb32(pb);
8286 if (entry_count >= INT_MAX / sizeof(*auxiliary_offsets))
8287 return AVERROR(ENOMEM);
8288
8289 for (i = 0; i < entry_count && !pb->eof_reached; i++) {
8290 unsigned int min_offsets = FFMIN(FFMAX(i + 1, 1024), entry_count);
8291 auxiliary_offsets = av_fast_realloc(
8292 encryption_index->auxiliary_offsets, &alloc_size,
8293 min_offsets * sizeof(*auxiliary_offsets));
8294 if (!auxiliary_offsets) {
8295 av_freep(&encryption_index->auxiliary_offsets);
8296 return AVERROR(ENOMEM);
8297 }
8298 encryption_index->auxiliary_offsets = auxiliary_offsets;
8299
8300 if (version == 0) {
8301 encryption_index->auxiliary_offsets[i] = avio_rb32(pb);
8302 } else {
8303 encryption_index->auxiliary_offsets[i] = avio_rb64(pb);
8304 }
8305 if (c->frag_index.current >= 0) {
8306 encryption_index->auxiliary_offsets[i] += c->fragment.base_data_offset;
8307 }
8308 }
8309
8310 if (pb->eof_reached) {
8311 av_log(c->fc, AV_LOG_ERROR, "Hit EOF while reading saio\n");
8312 av_freep(&encryption_index->auxiliary_offsets);
8313 return AVERROR_INVALIDDATA;
8314 }
8315
8316 encryption_index->auxiliary_offsets_count = entry_count;
8317
8318 if (encryption_index->auxiliary_info_sample_count) {
8319 return mov_parse_auxiliary_info(c, sc, pb, encryption_index);
8320 }
8321
8322 return 0;
8323}
8324
8326{
8327 AVEncryptionInitInfo *info, *old_init_info;
8328 uint8_t **key_ids;
8329 AVStream *st;
8330 const AVPacketSideData *old_side_data;
8331 uint8_t *side_data, *extra_data;
8332 size_t side_data_size;
8333 int ret = 0;
8334 unsigned int version, kid_count, extra_data_size, alloc_size = 0;
8335
8336 if (c->fc->nb_streams < 1)
8337 return 0;
8338 st = c->fc->streams[c->fc->nb_streams-1];
8339
8340 version = avio_r8(pb); /* version */
8341 avio_rb24(pb); /* flags */
8342
8343 info = av_encryption_init_info_alloc(/* system_id_size */ 16, /* num_key_ids */ 0,
8344 /* key_id_size */ 16, /* data_size */ 0);
8345 if (!info)
8346 return AVERROR(ENOMEM);
8347
8348 if ((ret = ffio_read_size(pb, info->system_id, 16)) < 0) {
8349 av_log(c->fc, AV_LOG_ERROR, "Failed to read the system id\n");
8350 goto finish;
8351 }
8352
8353 if (version > 0) {
8354 kid_count = avio_rb32(pb);
8355 if (kid_count >= INT_MAX / sizeof(*key_ids)) {
8356 ret = AVERROR(ENOMEM);
8357 goto finish;
8358 }
8359
8360 for (unsigned int i = 0; i < kid_count && !pb->eof_reached; i++) {
8361 unsigned int min_kid_count = FFMIN(FFMAX(i + 1, 1024), kid_count);
8362 key_ids = av_fast_realloc(info->key_ids, &alloc_size,
8363 min_kid_count * sizeof(*key_ids));
8364 if (!key_ids) {
8365 ret = AVERROR(ENOMEM);
8366 goto finish;
8367 }
8368 info->key_ids = key_ids;
8369
8370 info->key_ids[i] = av_mallocz(16);
8371 if (!info->key_ids[i]) {
8372 ret = AVERROR(ENOMEM);
8373 goto finish;
8374 }
8375 info->num_key_ids = i + 1;
8376
8377 if ((ret = ffio_read_size(pb, info->key_ids[i], 16)) < 0) {
8378 av_log(c->fc, AV_LOG_ERROR, "Failed to read the key id\n");
8379 goto finish;
8380 }
8381 }
8382
8383 if (pb->eof_reached) {
8384 av_log(c->fc, AV_LOG_ERROR, "Hit EOF while reading pssh\n");
8385 ret = AVERROR_INVALIDDATA;
8386 goto finish;
8387 }
8388 }
8389
8390 extra_data_size = avio_rb32(pb);
8391 extra_data = av_malloc(extra_data_size);
8392 if (!extra_data) {
8393 ret = AVERROR(ENOMEM);
8394 goto finish;
8395 }
8396 ret = avio_read(pb, extra_data, extra_data_size);
8397 if (ret != extra_data_size) {
8398 av_free(extra_data);
8399
8400 if (ret >= 0)
8401 ret = AVERROR_INVALIDDATA;
8402 goto finish;
8403 }
8404
8405 av_freep(&info->data); // malloc(0) may still allocate something.
8406 info->data = extra_data;
8407 info->data_size = extra_data_size;
8408
8409 // If there is existing initialization data, append to the list.
8412 if (old_side_data) {
8413 old_init_info = av_encryption_init_info_get_side_data(old_side_data->data, old_side_data->size);
8414 if (old_init_info) {
8415 // Append to the end of the list.
8416 for (AVEncryptionInitInfo *cur = old_init_info;; cur = cur->next) {
8417 if (!cur->next) {
8418 cur->next = info;
8419 break;
8420 }
8421 }
8422 info = old_init_info;
8423 } else {
8424 // Assume existing side-data will be valid, so the only error we could get is OOM.
8425 ret = AVERROR(ENOMEM);
8426 goto finish;
8427 }
8428 }
8429
8430 side_data = av_encryption_init_info_add_side_data(info, &side_data_size);
8431 if (!side_data) {
8432 ret = AVERROR(ENOMEM);
8433 goto finish;
8434 }
8438 side_data, side_data_size, 0))
8439 av_free(side_data);
8440
8441finish:
8443 return ret;
8444}
8445
8447{
8448 AVStream *st;
8449 MOVStreamContext *sc;
8450
8451 if (c->fc->nb_streams < 1)
8452 return 0;
8453 st = c->fc->streams[c->fc->nb_streams-1];
8454 sc = st->priv_data;
8455
8456 if (sc->pseudo_stream_id != 0) {
8457 av_log(c->fc, AV_LOG_ERROR, "schm boxes are only supported in first sample descriptor\n");
8458 return AVERROR_PATCHWELCOME;
8459 }
8460
8461 if (atom.size < 8)
8462 return AVERROR_INVALIDDATA;
8463
8464 avio_rb32(pb); /* version and flags */
8465
8466 if (!sc->cenc.default_encrypted_sample) {
8468 if (!sc->cenc.default_encrypted_sample) {
8469 return AVERROR(ENOMEM);
8470 }
8471 }
8472
8474 return 0;
8475}
8476
8478{
8479 AVStream *st;
8480 MOVStreamContext *sc;
8481 unsigned int version, pattern, is_protected, iv_size;
8482
8483 if (c->fc->nb_streams < 1)
8484 return 0;
8485 st = c->fc->streams[c->fc->nb_streams-1];
8486 sc = st->priv_data;
8487
8488 if (sc->pseudo_stream_id != 0) {
8489 av_log(c->fc, AV_LOG_ERROR, "tenc atom are only supported in first sample descriptor\n");
8490 return AVERROR_PATCHWELCOME;
8491 }
8492
8493 if (!sc->cenc.default_encrypted_sample) {
8495 if (!sc->cenc.default_encrypted_sample) {
8496 return AVERROR(ENOMEM);
8497 }
8498 }
8499
8500 if (atom.size < 20)
8501 return AVERROR_INVALIDDATA;
8502
8503 version = avio_r8(pb); /* version */
8504 avio_rb24(pb); /* flags */
8505
8506 avio_r8(pb); /* reserved */
8507 pattern = avio_r8(pb);
8508
8509 if (version > 0) {
8511 sc->cenc.default_encrypted_sample->skip_byte_block = pattern & 0xf;
8512 }
8513
8514 is_protected = avio_r8(pb);
8515 if (is_protected && !sc->cenc.encryption_index) {
8516 // The whole stream should be by-default encrypted.
8518 if (!sc->cenc.encryption_index)
8519 return AVERROR(ENOMEM);
8520 }
8521 iv_size = avio_r8(pb);
8522 if (iv_size != 0 && iv_size != 8 && iv_size != 16) {
8523 av_log(c->fc, AV_LOG_ERROR, "invalid per-sample IV size value\n");
8524 return AVERROR_INVALIDDATA;
8525 }
8526 sc->cenc.per_sample_iv_size = iv_size;
8527 if (avio_read(pb, sc->cenc.default_encrypted_sample->key_id, 16) != 16) {
8528 av_log(c->fc, AV_LOG_ERROR, "failed to read the default key ID\n");
8529 return AVERROR_INVALIDDATA;
8530 }
8531
8532 if (is_protected && !sc->cenc.per_sample_iv_size) {
8533 iv_size = avio_r8(pb);
8534 if (iv_size != 8 && iv_size != 16) {
8535 av_log(c->fc, AV_LOG_ERROR, "invalid default_constant_IV_size in tenc atom\n");
8536 return AVERROR_INVALIDDATA;
8537 }
8538
8539 if (avio_read(pb, sc->cenc.default_encrypted_sample->iv, iv_size) != iv_size) {
8540 av_log(c->fc, AV_LOG_ERROR, "failed to read the default IV\n");
8541 return AVERROR_INVALIDDATA;
8542 }
8543 }
8544
8545 return 0;
8546}
8547
8549{
8550 AVStream *st;
8551 int last, type, size, ret;
8552 uint8_t buf[4];
8553
8554 if (c->fc->nb_streams < 1)
8555 return 0;
8556 st = c->fc->streams[c->fc->nb_streams-1];
8557
8558 if ((uint64_t)atom.size > (1<<30) || atom.size < 42)
8559 return AVERROR_INVALIDDATA;
8560
8561 /* Check FlacSpecificBox version. */
8562 if (avio_r8(pb) != 0)
8563 return AVERROR_INVALIDDATA;
8564
8565 avio_rb24(pb); /* Flags */
8566
8567 if (avio_read(pb, buf, sizeof(buf)) != sizeof(buf)) {
8568 av_log(c->fc, AV_LOG_ERROR, "failed to read FLAC metadata block header\n");
8569 return pb->error < 0 ? pb->error : AVERROR_INVALIDDATA;
8570 }
8571 flac_parse_block_header(buf, &last, &type, &size);
8572
8574 av_log(c->fc, AV_LOG_ERROR, "STREAMINFO must be first FLACMetadataBlock\n");
8575 return AVERROR_INVALIDDATA;
8576 }
8577
8578 ret = ff_get_extradata(c->fc, st->codecpar, pb, size);
8579 if (ret < 0)
8580 return ret;
8581
8582 if (!last)
8583 av_log(c->fc, AV_LOG_WARNING, "non-STREAMINFO FLACMetadataBlock(s) ignored\n");
8584
8585 return 0;
8586}
8587
8589 AVDictionaryEntry *key_entry_hex;
8590 char kid_hex[16*2+1];
8591
8592 if (c->decryption_default_key && c->decryption_default_key_len != len) {
8593 av_log(c->fc, AV_LOG_ERROR, "invalid default decryption key length: got %d, expected %d\n", c->decryption_default_key_len, len);
8594 return -1;
8595 }
8596
8597 if (!c->decryption_keys) {
8598 av_assert0(c->decryption_default_key);
8599 memcpy(out, c->decryption_default_key, len);
8600 return 0;
8601 }
8602
8603 if (sample->key_id_size != 16) {
8604 av_log(c->fc, AV_LOG_ERROR, "invalid key ID size: got %u, expected 16\n", sample->key_id_size);
8605 return -1;
8606 }
8607
8608 ff_data_to_hex(kid_hex, sample->key_id, 16, 1);
8609 key_entry_hex = av_dict_get(c->decryption_keys, kid_hex, NULL, AV_DICT_DONT_STRDUP_KEY|AV_DICT_DONT_STRDUP_VAL);
8610 if (!key_entry_hex) {
8611 if (!c->decryption_default_key) {
8612 av_log(c->fc, AV_LOG_ERROR, "unable to find KID %s\n", kid_hex);
8613 return -1;
8614 }
8615 memcpy(out, c->decryption_default_key, len);
8616 return 0;
8617 }
8618 if (strlen(key_entry_hex->value) != len*2) {
8619 return -1;
8620 }
8621 ff_hex_to_data(out, key_entry_hex->value);
8622 return 0;
8623}
8624
8626{
8627 int i, ret;
8628 int bytes_of_protected_data;
8629 uint8_t decryption_key[AES_CTR_KEY_SIZE];
8630
8631 if (!sc->cenc.aes_ctr) {
8632 ret = get_key_from_kid(decryption_key, sizeof(decryption_key), c, sample);
8633 if (ret < 0) {
8634 return ret;
8635 }
8636
8637 /* initialize the cipher */
8639 if (!sc->cenc.aes_ctr) {
8640 return AVERROR(ENOMEM);
8641 }
8642
8643 ret = av_aes_ctr_init(sc->cenc.aes_ctr, decryption_key);
8644 if (ret < 0) {
8645 return ret;
8646 }
8647 }
8648
8650
8651 if (!sample->subsample_count) {
8652 /* decrypt the whole packet */
8653 av_aes_ctr_crypt(sc->cenc.aes_ctr, input, input, size);
8654 return 0;
8655 }
8656
8657 for (i = 0; i < sample->subsample_count; i++) {
8658 if (sample->subsamples[i].bytes_of_clear_data + (int64_t)sample->subsamples[i].bytes_of_protected_data > size) {
8659 av_log(c->fc, AV_LOG_ERROR, "subsample size exceeds the packet size left\n");
8660 return AVERROR_INVALIDDATA;
8661 }
8662
8663 /* skip the clear bytes */
8664 input += sample->subsamples[i].bytes_of_clear_data;
8665 size -= sample->subsamples[i].bytes_of_clear_data;
8666
8667 /* decrypt the encrypted bytes */
8668
8669 bytes_of_protected_data = sample->subsamples[i].bytes_of_protected_data;
8670 av_aes_ctr_crypt(sc->cenc.aes_ctr, input, input, bytes_of_protected_data);
8671
8672 input += bytes_of_protected_data;
8673 size -= bytes_of_protected_data;
8674 }
8675
8676 if (size > 0) {
8677 av_log(c->fc, AV_LOG_ERROR, "leftover packet bytes after subsample processing\n");
8678 return AVERROR_INVALIDDATA;
8679 }
8680
8681 return 0;
8682}
8683
8685{
8686 int i, ret;
8687 int num_of_encrypted_blocks;
8688 uint8_t iv[16];
8689 uint8_t decryption_key[16];
8690
8691 if (!sc->cenc.aes_ctx) {
8692 ret = get_key_from_kid(decryption_key, sizeof(decryption_key), c, sample);
8693 if (ret < 0) {
8694 return ret;
8695 }
8696
8697 /* initialize the cipher */
8698 sc->cenc.aes_ctx = av_aes_alloc();
8699 if (!sc->cenc.aes_ctx) {
8700 return AVERROR(ENOMEM);
8701 }
8702
8703 ret = av_aes_init(sc->cenc.aes_ctx, decryption_key, 16 * 8, 1);
8704 if (ret < 0) {
8705 return ret;
8706 }
8707 }
8708
8709 memcpy(iv, sample->iv, 16);
8710
8711 /* whole-block full sample encryption */
8712 if (!sample->subsample_count) {
8713 /* decrypt the whole packet */
8714 av_aes_crypt(sc->cenc.aes_ctx, input, input, size/16, iv, 1);
8715 return 0;
8716 }
8717
8718 for (i = 0; i < sample->subsample_count; i++) {
8719 if (sample->subsamples[i].bytes_of_clear_data + (int64_t)sample->subsamples[i].bytes_of_protected_data > size) {
8720 av_log(c->fc, AV_LOG_ERROR, "subsample size exceeds the packet size left\n");
8721 return AVERROR_INVALIDDATA;
8722 }
8723
8724 if (sample->subsamples[i].bytes_of_protected_data % 16) {
8725 av_log(c->fc, AV_LOG_ERROR, "subsample BytesOfProtectedData is not a multiple of 16\n");
8726 return AVERROR_INVALIDDATA;
8727 }
8728
8729 /* skip the clear bytes */
8730 input += sample->subsamples[i].bytes_of_clear_data;
8731 size -= sample->subsamples[i].bytes_of_clear_data;
8732
8733 /* decrypt the encrypted bytes */
8734 num_of_encrypted_blocks = sample->subsamples[i].bytes_of_protected_data/16;
8735 if (num_of_encrypted_blocks > 0) {
8736 av_aes_crypt(sc->cenc.aes_ctx, input, input, num_of_encrypted_blocks, iv, 1);
8737 }
8738 input += sample->subsamples[i].bytes_of_protected_data;
8739 size -= sample->subsamples[i].bytes_of_protected_data;
8740 }
8741
8742 if (size > 0) {
8743 av_log(c->fc, AV_LOG_ERROR, "leftover packet bytes after subsample processing\n");
8744 return AVERROR_INVALIDDATA;
8745 }
8746
8747 return 0;
8748}
8749
8751{
8752 int i, ret, rem_bytes;
8753 uint8_t *data;
8754 uint8_t decryption_key[AES_CTR_KEY_SIZE];
8755
8756 if (!sc->cenc.aes_ctr) {
8757 ret = get_key_from_kid(decryption_key, sizeof(decryption_key), c, sample);
8758 if (ret < 0) {
8759 return ret;
8760 }
8761
8762 /* initialize the cipher */
8764 if (!sc->cenc.aes_ctr) {
8765 return AVERROR(ENOMEM);
8766 }
8767
8768 ret = av_aes_ctr_init(sc->cenc.aes_ctr, decryption_key);
8769 if (ret < 0) {
8770 return ret;
8771 }
8772 }
8773
8775
8776 /* whole-block full sample encryption */
8777 if (!sample->subsample_count) {
8778 /* decrypt the whole packet */
8779 av_aes_ctr_crypt(sc->cenc.aes_ctr, input, input, size);
8780 return 0;
8781 } else if (!sample->crypt_byte_block && !sample->skip_byte_block) {
8782 av_log(c->fc, AV_LOG_ERROR, "pattern encryption is not present in 'cens' scheme\n");
8783 return AVERROR_INVALIDDATA;
8784 }
8785
8786 for (i = 0; i < sample->subsample_count; i++) {
8787 if (sample->subsamples[i].bytes_of_clear_data + (int64_t)sample->subsamples[i].bytes_of_protected_data > size) {
8788 av_log(c->fc, AV_LOG_ERROR, "subsample size exceeds the packet size left\n");
8789 return AVERROR_INVALIDDATA;
8790 }
8791
8792 /* skip the clear bytes */
8793 input += sample->subsamples[i].bytes_of_clear_data;
8794 size -= sample->subsamples[i].bytes_of_clear_data;
8795
8796 /* decrypt the encrypted bytes */
8797 data = input;
8798 rem_bytes = sample->subsamples[i].bytes_of_protected_data;
8799 while (rem_bytes > 0) {
8800 if (rem_bytes < 16*sample->crypt_byte_block) {
8801 break;
8802 }
8803 av_aes_ctr_crypt(sc->cenc.aes_ctr, data, data, 16*sample->crypt_byte_block);
8804 data += 16*sample->crypt_byte_block;
8805 rem_bytes -= 16*sample->crypt_byte_block;
8806 data += FFMIN(16*sample->skip_byte_block, rem_bytes);
8807 rem_bytes -= FFMIN(16*sample->skip_byte_block, rem_bytes);
8808 }
8809 input += sample->subsamples[i].bytes_of_protected_data;
8810 size -= sample->subsamples[i].bytes_of_protected_data;
8811 }
8812
8813 if (size > 0) {
8814 av_log(c->fc, AV_LOG_ERROR, "leftover packet bytes after subsample processing\n");
8815 return AVERROR_INVALIDDATA;
8816 }
8817
8818 return 0;
8819}
8820
8822{
8823 int i, ret, rem_bytes;
8824 uint8_t iv[16];
8825 uint8_t *data;
8826 uint8_t decryption_key[16];
8827
8828 if (!sc->cenc.aes_ctx) {
8829 ret = get_key_from_kid(decryption_key, sizeof(decryption_key), c, sample);
8830 if (ret < 0) {
8831 return ret;
8832 }
8833
8834 /* initialize the cipher */
8835 sc->cenc.aes_ctx = av_aes_alloc();
8836 if (!sc->cenc.aes_ctx) {
8837 return AVERROR(ENOMEM);
8838 }
8839
8840 ret = av_aes_init(sc->cenc.aes_ctx, decryption_key, 16 * 8, 1);
8841 if (ret < 0) {
8842 return ret;
8843 }
8844 }
8845
8846 /* whole-block full sample encryption */
8847 if (!sample->subsample_count) {
8848 /* decrypt the whole packet */
8849 memcpy(iv, sample->iv, 16);
8850 av_aes_crypt(sc->cenc.aes_ctx, input, input, size/16, iv, 1);
8851 return 0;
8852 } else if (!sample->crypt_byte_block && !sample->skip_byte_block) {
8853 av_log(c->fc, AV_LOG_ERROR, "pattern encryption is not present in 'cbcs' scheme\n");
8854 return AVERROR_INVALIDDATA;
8855 }
8856
8857 for (i = 0; i < sample->subsample_count; i++) {
8858 if (sample->subsamples[i].bytes_of_clear_data + (int64_t)sample->subsamples[i].bytes_of_protected_data > size) {
8859 av_log(c->fc, AV_LOG_ERROR, "subsample size exceeds the packet size left\n");
8860 return AVERROR_INVALIDDATA;
8861 }
8862
8863 /* skip the clear bytes */
8864 input += sample->subsamples[i].bytes_of_clear_data;
8865 size -= sample->subsamples[i].bytes_of_clear_data;
8866
8867 /* decrypt the encrypted bytes */
8868 memcpy(iv, sample->iv, 16);
8869 data = input;
8870 rem_bytes = sample->subsamples[i].bytes_of_protected_data;
8871 while (rem_bytes > 0) {
8872 if (rem_bytes < 16*sample->crypt_byte_block) {
8873 break;
8874 }
8875 av_aes_crypt(sc->cenc.aes_ctx, data, data, sample->crypt_byte_block, iv, 1);
8876 data += 16*sample->crypt_byte_block;
8877 rem_bytes -= 16*sample->crypt_byte_block;
8878 data += FFMIN(16*sample->skip_byte_block, rem_bytes);
8879 rem_bytes -= FFMIN(16*sample->skip_byte_block, rem_bytes);
8880 }
8881 input += sample->subsamples[i].bytes_of_protected_data;
8882 size -= sample->subsamples[i].bytes_of_protected_data;
8883 }
8884
8885 if (size > 0) {
8886 av_log(c->fc, AV_LOG_ERROR, "leftover packet bytes after subsample processing\n");
8887 return AVERROR_INVALIDDATA;
8888 }
8889
8890 return 0;
8891}
8892
8893static int cenc_decrypt(MOVContext *c, MOVStreamContext *sc, AVEncryptionInfo *sample, uint8_t *input, int size)
8894{
8895 if (sample->scheme == MKBETAG('c','e','n','c') && !sample->crypt_byte_block && !sample->skip_byte_block) {
8896 return cenc_scheme_decrypt(c, sc, sample, input, size);
8897 } else if (sample->scheme == MKBETAG('c','b','c','1') && !sample->crypt_byte_block && !sample->skip_byte_block) {
8898 return cbc1_scheme_decrypt(c, sc, sample, input, size);
8899 } else if (sample->scheme == MKBETAG('c','e','n','s')) {
8900 return cens_scheme_decrypt(c, sc, sample, input, size);
8901 } else if (sample->scheme == MKBETAG('c','b','c','s')) {
8902 return cbcs_scheme_decrypt(c, sc, sample, input, size);
8903 } else {
8904 av_log(c->fc, AV_LOG_ERROR, "invalid encryption scheme\n");
8905 return AVERROR_INVALIDDATA;
8906 }
8907}
8908
8910{
8911 int current = frag_index->current;
8912
8913 if (!frag_index->nb_items)
8914 return NULL;
8915
8916 // Check frag_index->current is the right one for pkt. It can out of sync.
8917 if (current >= 0 && current < frag_index->nb_items) {
8918 if (frag_index->item[current].moof_offset < pkt->pos &&
8919 (current + 1 == frag_index->nb_items ||
8920 frag_index->item[current + 1].moof_offset > pkt->pos))
8921 return get_frag_stream_info(frag_index, current, id);
8922 }
8923
8924
8925 for (int i = 0; i < frag_index->nb_items; i++) {
8926 if (frag_index->item[i].moof_offset > pkt->pos)
8927 break;
8928 current = i;
8929 }
8930 frag_index->current = current;
8931 return get_frag_stream_info(frag_index, current, id);
8932}
8933
8934static int cenc_filter(MOVContext *mov, AVStream* st, MOVStreamContext *sc, AVPacket *pkt, int current_index)
8935{
8936 MOVFragmentStreamInfo *frag_stream_info;
8937 MOVEncryptionIndex *encryption_index;
8938 AVEncryptionInfo *encrypted_sample;
8939 int encrypted_index, ret;
8940
8941 frag_stream_info = get_frag_stream_info_from_pkt(&mov->frag_index, pkt, sc->id);
8942 encrypted_index = current_index;
8943 encryption_index = NULL;
8944 if (frag_stream_info) {
8945 // Note this only supports encryption info in the first sample descriptor.
8946 if (frag_stream_info->stsd_id == 1) {
8947 if (frag_stream_info->encryption_index) {
8948 encrypted_index = current_index - frag_stream_info->index_base;
8949 encryption_index = frag_stream_info->encryption_index;
8950 } else {
8951 encryption_index = sc->cenc.encryption_index;
8952 }
8953 }
8954 } else {
8955 encryption_index = sc->cenc.encryption_index;
8956 }
8957
8958 if (encryption_index) {
8959 if (encryption_index->auxiliary_info_sample_count &&
8960 !encryption_index->nb_encrypted_samples) {
8961 av_log(mov->fc, AV_LOG_ERROR, "saiz atom found without saio\n");
8962 return AVERROR_INVALIDDATA;
8963 }
8964 if (encryption_index->auxiliary_offsets_count &&
8965 !encryption_index->nb_encrypted_samples) {
8966 av_log(mov->fc, AV_LOG_ERROR, "saio atom found without saiz\n");
8967 return AVERROR_INVALIDDATA;
8968 }
8969
8970 encrypted_sample = NULL;
8971 if (!encryption_index->nb_encrypted_samples) {
8972 // Full-sample encryption with default settings.
8973 encrypted_sample = sc->cenc.default_encrypted_sample;
8974 } else if (encrypted_index >= 0 && encrypted_index < encryption_index->nb_encrypted_samples) {
8975 // Per-sample setting override.
8976 encrypted_sample = encryption_index->encrypted_samples[encrypted_index];
8977 if (!encrypted_sample) {
8978 encrypted_sample = sc->cenc.default_encrypted_sample;
8979 }
8980 }
8981
8982 if (!encrypted_sample) {
8983 av_log(mov->fc, AV_LOG_ERROR, "Incorrect number of samples in encryption info\n");
8984 return AVERROR_INVALIDDATA;
8985 }
8986
8987 if (mov->decryption_keys || mov->decryption_default_key) {
8988 return cenc_decrypt(mov, sc, encrypted_sample, pkt->data, pkt->size);
8989 } else {
8990 size_t size;
8991 uint8_t *side_data = av_encryption_info_add_side_data(encrypted_sample, &size);
8992 if (!side_data)
8993 return AVERROR(ENOMEM);
8995 if (ret < 0)
8996 av_free(side_data);
8997 return ret;
8998 }
8999 }
9000
9001 return 0;
9002}
9003
9005{
9006 const int OPUS_SEEK_PREROLL_MS = 80;
9007 int ret;
9008 AVStream *st;
9009 size_t size;
9010 uint16_t pre_skip;
9011
9012 if (c->fc->nb_streams < 1)
9013 return 0;
9014 st = c->fc->streams[c->fc->nb_streams-1];
9015
9016 if ((uint64_t)atom.size > (1<<30) || atom.size < 11 || st->codecpar->extradata)
9017 return AVERROR_INVALIDDATA;
9018
9019 /* Check OpusSpecificBox version. */
9020 if (avio_r8(pb) != 0) {
9021 av_log(c->fc, AV_LOG_ERROR, "unsupported OpusSpecificBox version\n");
9022 return AVERROR_INVALIDDATA;
9023 }
9024
9025 /* OpusSpecificBox size plus magic for Ogg OpusHead header. */
9026 size = atom.size + 8;
9027
9028 if ((ret = ff_alloc_extradata(st->codecpar, size)) < 0)
9029 return ret;
9030
9031 AV_WL32A(st->codecpar->extradata, MKTAG('O','p','u','s'));
9032 AV_WL32A(st->codecpar->extradata + 4, MKTAG('H','e','a','d'));
9033 AV_WB8(st->codecpar->extradata + 8, 1); /* OpusHead version */
9034 if ((ret = ffio_read_size(pb, st->codecpar->extradata + 9, size - 9)) < 0) {
9036 st->codecpar->extradata_size = 0;
9037 return ret;
9038 }
9039
9040 /* OpusSpecificBox is stored in big-endian, but OpusHead is
9041 little-endian; aside from the preceding magic and version they're
9042 otherwise currently identical. Data after output gain at offset 16
9043 doesn't need to be bytewapped. */
9044 pre_skip = AV_RB16A(st->codecpar->extradata + 10);
9045 AV_WL16A(st->codecpar->extradata + 10, pre_skip);
9046 AV_WL32A(st->codecpar->extradata + 12, AV_RB32A(st->codecpar->extradata + 12));
9047 AV_WL16A(st->codecpar->extradata + 16, AV_RB16A(st->codecpar->extradata + 16));
9048
9049 st->codecpar->initial_padding = pre_skip;
9051 (AVRational){1, 1000},
9052 (AVRational){1, 48000});
9053
9054 return 0;
9055}
9056
9058{
9059 AVStream *st;
9060 unsigned format_info;
9061 int channel_assignment, channel_assignment1, channel_assignment2;
9062 int ratebits;
9063 uint64_t chmask;
9064
9065 if (c->fc->nb_streams < 1)
9066 return 0;
9067 st = c->fc->streams[c->fc->nb_streams-1];
9068
9069 if (atom.size < 10)
9070 return AVERROR_INVALIDDATA;
9071
9072 format_info = avio_rb32(pb);
9073
9074 ratebits = (format_info >> 28) & 0xF;
9075 channel_assignment1 = (format_info >> 15) & 0x1F;
9076 channel_assignment2 = format_info & 0x1FFF;
9077 if (channel_assignment2)
9078 channel_assignment = channel_assignment2;
9079 else
9080 channel_assignment = channel_assignment1;
9081
9082 st->codecpar->frame_size = 40 << (ratebits & 0x7);
9083 st->codecpar->sample_rate = mlp_samplerate(ratebits);
9084
9086 chmask = truehd_layout(channel_assignment);
9088
9089 return 0;
9090}
9091
9093{
9094 AVStream *st;
9095 uint8_t buf[ISOM_DVCC_DVVC_SIZE];
9096 int ret;
9097 int64_t read_size = atom.size;
9098
9099 if (c->fc->nb_streams < 1)
9100 return 0;
9101 st = c->fc->streams[c->fc->nb_streams-1];
9102
9103 // At most 24 bytes
9104 read_size = FFMIN(read_size, ISOM_DVCC_DVVC_SIZE);
9105
9106 if ((ret = ffio_read_size(pb, buf, read_size)) < 0)
9107 return ret;
9108
9109 return ff_isom_parse_dvcc_dvvc(c->fc, st, buf, read_size);
9110}
9111
9113{
9114 AVStream *st;
9115 AVPacketSideData *sd;
9116 int ret;
9117
9118 if (c->fc->nb_streams < 1)
9119 return 0;
9120 st = c->fc->streams[c->fc->nb_streams - 1];
9121
9122 if (atom.size < 23 || atom.size > INT_MAX - AV_INPUT_BUFFER_PADDING_SIZE)
9123 return AVERROR_INVALIDDATA;
9124
9128 atom.size, 0);
9129 if (!sd)
9130 return AVERROR(ENOMEM);
9131
9132 ret = ffio_read_size(pb, sd->data, atom.size);
9133 if (ret < 0)
9134 return ret;
9135
9136 return 0;
9137}
9138
9140{
9141 AVStream *st;
9142 uint8_t *buf;
9143 int ret, old_size, num_arrays;
9144
9145 if (c->fc->nb_streams < 1)
9146 return 0;
9147 st = c->fc->streams[c->fc->nb_streams-1];
9148
9149 if (!st->codecpar->extradata_size)
9150 // TODO: handle lhvC when present before hvcC
9151 return 0;
9152
9153 if (atom.size < 6 || st->codecpar->extradata_size < 23 ||
9154 atom.size > INT_MAX - AV_INPUT_BUFFER_PADDING_SIZE) {
9155 return AVERROR_INVALIDDATA;
9156 }
9157
9159 if (!buf)
9160 return AVERROR(ENOMEM);
9161 memset(buf + atom.size, 0, AV_INPUT_BUFFER_PADDING_SIZE);
9162
9163 ret = ffio_read_size(pb, buf, atom.size);
9164 if (ret < 0) {
9165 av_free(buf);
9166 av_log(c->fc, AV_LOG_WARNING, "lhvC atom truncated\n");
9167 return 0;
9168 }
9169
9170 num_arrays = buf[5];
9171 old_size = st->codecpar->extradata_size;
9172 atom.size -= 8 /* account for mov_realloc_extradata offsetting */
9173 + 6 /* lhvC bytes before the arrays*/;
9174
9175 ret = mov_realloc_extradata(st->codecpar, atom);
9176 if (ret < 0) {
9177 av_free(buf);
9178 return ret;
9179 }
9180
9181 st->codecpar->extradata[22] += num_arrays;
9182 memcpy(st->codecpar->extradata + old_size, buf + 6, atom.size + 8);
9183
9185
9186 av_free(buf);
9187 return 0;
9188}
9189
9191{
9192 AVFormatContext *ctx = c->fc;
9193 AVStream *st = NULL;
9194 AVBPrint scheme_buf, value_buf;
9195 int64_t scheme_str_len = 0, value_str_len = 0;
9196 int version, flags, ret = AVERROR_BUG;
9197 int64_t size = atom.size;
9198
9199 if (atom.size < 6)
9200 // 4 bytes for version + flags, 2x 1 byte for null
9201 return AVERROR_INVALIDDATA;
9202
9203 if (c->fc->nb_streams < 1)
9204 return 0;
9205 st = c->fc->streams[c->fc->nb_streams-1];
9206
9207 version = avio_r8(pb);
9208 flags = avio_rb24(pb);
9209 size -= 4;
9210
9211 if (version != 0 || flags != 0) {
9213 "Unsupported 'kind' box with version %d, flags: %x",
9214 version, flags);
9215 return AVERROR_INVALIDDATA;
9216 }
9217
9220
9221 if ((scheme_str_len = ff_read_string_to_bprint_overwrite(pb, &scheme_buf,
9222 size)) < 0) {
9223 ret = scheme_str_len;
9224 goto cleanup;
9225 }
9226
9227 if (scheme_str_len + 1 >= size) {
9228 // we need to have another string, even if nullptr.
9229 // we check with + 1 since we expect that if size was not hit,
9230 // an additional null was read.
9231 ret = AVERROR_INVALIDDATA;
9232 goto cleanup;
9233 }
9234
9235 size -= scheme_str_len + 1;
9236
9237 if ((value_str_len = ff_read_string_to_bprint_overwrite(pb, &value_buf,
9238 size)) < 0) {
9239 ret = value_str_len;
9240 goto cleanup;
9241 }
9242
9243 if (value_str_len == size) {
9244 // in case of no trailing null, box is not valid.
9245 ret = AVERROR_INVALIDDATA;
9246 goto cleanup;
9247 }
9248
9250 "%s stream %d KindBox(scheme: %s, value: %s)\n",
9252 st->index,
9253 scheme_buf.str, value_buf.str);
9254
9255 for (int i = 0; ff_mov_track_kind_table[i].scheme_uri; i++) {
9257 if (!av_strstart(scheme_buf.str, map.scheme_uri, NULL))
9258 continue;
9259
9260 for (int j = 0; map.value_maps[j].disposition; j++) {
9261 const struct MP4TrackKindValueMapping value_map = map.value_maps[j];
9262 if (!av_strstart(value_buf.str, value_map.value, NULL))
9263 continue;
9264
9265 st->disposition |= value_map.disposition;
9266 }
9267 }
9268
9269 ret = 0;
9270
9271cleanup:
9272
9273 av_bprint_finalize(&scheme_buf, NULL);
9274 av_bprint_finalize(&value_buf, NULL);
9275
9276 return ret;
9277}
9278
9280{
9281 AVStream *st;
9282 AVChannelLayout ch_layout = { 0 };
9283 int ret, i, version, type;
9284 int ambisonic_order, channel_order, normalization, channel_count;
9285 int ambi_channels, non_diegetic_channels;
9286
9287 if (c->fc->nb_streams < 1)
9288 return 0;
9289
9290 st = c->fc->streams[c->fc->nb_streams - 1];
9291
9292 if (atom.size < 16) {
9293 av_log(c->fc, AV_LOG_ERROR, "SA3D audio box too small\n");
9294 return AVERROR_INVALIDDATA;
9295 }
9296
9297 version = avio_r8(pb);
9298 if (version) {
9299 av_log(c->fc, AV_LOG_WARNING, "Unsupported SA3D box version %d\n", version);
9300 return 0;
9301 }
9302
9303 type = avio_r8(pb);
9304 if (type & 0x7f) {
9305 av_log(c->fc, AV_LOG_WARNING,
9306 "Unsupported ambisonic type %d\n", type & 0x7f);
9307 return 0;
9308 }
9309 non_diegetic_channels = (type >> 7) * 2; // head_locked_stereo
9310
9311 ambisonic_order = avio_rb32(pb);
9312
9313 channel_order = avio_r8(pb);
9314 if (channel_order) {
9315 av_log(c->fc, AV_LOG_WARNING,
9316 "Unsupported channel_order %d\n", channel_order);
9317 return 0;
9318 }
9319
9320 normalization = avio_r8(pb);
9321 if (normalization) {
9322 av_log(c->fc, AV_LOG_WARNING,
9323 "Unsupported normalization %d\n", normalization);
9324 return 0;
9325 }
9326
9327 channel_count = avio_rb32(pb);
9328 if (ambisonic_order < 0 || ambisonic_order > 31 ||
9329 channel_count != ((ambisonic_order + 1LL) * (ambisonic_order + 1LL) +
9330 non_diegetic_channels)) {
9331 av_log(c->fc, AV_LOG_ERROR,
9332 "Invalid number of channels (%d / %d)\n",
9333 channel_count, ambisonic_order);
9334 return 0;
9335 }
9336 ambi_channels = channel_count - non_diegetic_channels;
9337
9338 ret = av_channel_layout_custom_init(&ch_layout, channel_count);
9339 if (ret < 0)
9340 return 0;
9341
9342 for (i = 0; i < channel_count; i++) {
9343 unsigned channel = avio_rb32(pb);
9344
9345 if (channel >= channel_count) {
9346 av_log(c->fc, AV_LOG_ERROR, "Invalid channel index (%d / %d)\n",
9347 channel, ambisonic_order);
9348 av_channel_layout_uninit(&ch_layout);
9349 return 0;
9350 }
9351 if (channel >= ambi_channels)
9352 ch_layout.u.map[i].id = channel - ambi_channels;
9353 else
9354 ch_layout.u.map[i].id = AV_CHAN_AMBISONIC_BASE + channel;
9355 }
9356
9358 if (ret < 0) {
9359 av_channel_layout_uninit(&ch_layout);
9360 return 0;
9361 }
9362
9364 st->codecpar->ch_layout = ch_layout;
9365
9366 return 0;
9367}
9368
9370{
9371 AVStream *st;
9372 int version;
9373
9374 if (c->fc->nb_streams < 1)
9375 return 0;
9376
9377 st = c->fc->streams[c->fc->nb_streams - 1];
9378
9379 if (atom.size < 5) {
9380 av_log(c->fc, AV_LOG_ERROR, "Empty SAND audio box\n");
9381 return AVERROR_INVALIDDATA;
9382 }
9383
9384 version = avio_r8(pb);
9385 if (version) {
9386 av_log(c->fc, AV_LOG_WARNING, "Unsupported SAND box version %d\n", version);
9387 return 0;
9388 }
9389
9391
9392 return 0;
9393}
9394
9395static int rb_size(AVIOContext *pb, int64_t *value, int size)
9396{
9397 if (size == 0)
9398 *value = 0;
9399 else if (size == 1)
9400 *value = avio_r8(pb);
9401 else if (size == 2)
9402 *value = avio_rb16(pb);
9403 else if (size == 4)
9404 *value = avio_rb32(pb);
9405 else if (size == 8) {
9406 *value = avio_rb64(pb);
9407 if (*value < 0)
9408 return -1;
9409 } else
9410 return -1;
9411 return size;
9412}
9413
9415{
9416 avio_rb32(pb); // version & flags.
9417 c->primary_item_id = avio_rb16(pb);
9418 av_log(c->fc, AV_LOG_TRACE, "pitm: primary_item_id %d\n", c->primary_item_id);
9419 return atom.size;
9420}
9421
9423{
9424 c->idat_offset = avio_tell(pb);
9425 return 0;
9426}
9427
9429{
9430 HEIFItem **heif_item;
9431 int version, offset_size, length_size, base_offset_size, index_size;
9432 int item_count, extent_count;
9433 int64_t base_offset, extent_offset, extent_length;
9434 uint8_t value;
9435
9436 if (c->found_iloc) {
9437 av_log(c->fc, AV_LOG_INFO, "Duplicate iloc box found\n");
9438 return 0;
9439 }
9440
9441 version = avio_r8(pb);
9442 avio_rb24(pb); // flags.
9443
9444 value = avio_r8(pb);
9445 offset_size = (value >> 4) & 0xF;
9446 length_size = value & 0xF;
9447 value = avio_r8(pb);
9448 base_offset_size = (value >> 4) & 0xF;
9449 index_size = !version ? 0 : (value & 0xF);
9450 if (index_size) {
9451 avpriv_report_missing_feature(c->fc, "iloc: index_size != 0");
9452 return AVERROR_PATCHWELCOME;
9453 }
9454 item_count = (version < 2) ? avio_rb16(pb) : avio_rb32(pb);
9455
9456 if (item_count > atom.size)
9457 return AVERROR_INVALIDDATA;
9458
9459 heif_item = av_realloc_array(c->heif_item, FFMAX(item_count, c->nb_heif_item), sizeof(*c->heif_item));
9460 if (!heif_item)
9461 return AVERROR(ENOMEM);
9462 c->heif_item = heif_item;
9463 if (item_count > c->nb_heif_item)
9464 memset(&c->heif_item[c->nb_heif_item], 0,
9465 sizeof(*c->heif_item) * (item_count - c->nb_heif_item));
9466 c->nb_heif_item = FFMAX(c->nb_heif_item, item_count);
9467
9468 av_log(c->fc, AV_LOG_TRACE, "iloc: item_count %d\n", item_count);
9469 for (int i = 0; i < item_count; i++) {
9470 HEIFItem *item = NULL;
9471 int item_id = (version < 2) ? avio_rb16(pb) : avio_rb32(pb);
9472 int offset_type = (version > 0) ? avio_rb16(pb) & 0xf : 0;
9473 int j;
9474
9475 if (avio_feof(pb))
9476 return AVERROR_INVALIDDATA;
9477 if (offset_type > 1) {
9478 avpriv_report_missing_feature(c->fc, "iloc offset type %d", offset_type);
9479 return AVERROR_PATCHWELCOME;
9480 }
9481
9482 avio_rb16(pb); // data_reference_index.
9483 if (rb_size(pb, &base_offset, base_offset_size) < 0)
9484 return AVERROR_INVALIDDATA;
9485 extent_count = avio_rb16(pb);
9486 if (extent_count > 1) {
9487 // For still AVIF images, we only support one extent item.
9488 avpriv_report_missing_feature(c->fc, "iloc: extent_count > 1");
9489 return AVERROR_PATCHWELCOME;
9490 }
9491
9492 if (rb_size(pb, &extent_offset, offset_size) < 0 ||
9493 rb_size(pb, &extent_length, length_size) < 0 ||
9494 base_offset > INT64_MAX - extent_offset)
9495 return AVERROR_INVALIDDATA;
9496
9497 for (j = 0; j < c->nb_heif_item; j++) {
9498 item = c->heif_item[j];
9499 if (!item)
9500 item = c->heif_item[j] = av_mallocz(sizeof(*item));
9501 else if (item->item_id != item_id)
9502 continue;
9503 break;
9504 }
9505 if (!item)
9506 return AVERROR(ENOMEM);
9507 if (j == c->nb_heif_item)
9508 return AVERROR_INVALIDDATA;
9509
9510 item->item_id = item_id;
9511
9512 if (offset_type == 1)
9513 item->is_idat_relative = 1;
9514 item->extent_length = extent_length;
9515 item->extent_offset = base_offset + extent_offset;
9516 av_log(c->fc, AV_LOG_TRACE, "iloc: item_idx %d, item->item_id %d, offset_type %d, "
9517 "extent_offset %"PRId64", extent_length %"PRId64"\n",
9518 i, item->item_id, offset_type, item->extent_offset, item->extent_length);
9519 }
9520
9521 c->found_iloc = 1;
9522 return atom.size;
9523}
9524
9526{
9527 HEIFItem *item = NULL;
9528 AVBPrint item_name;
9529 int64_t size = atom.size;
9530 uint32_t item_type;
9531 int item_id;
9532 int i, version, ret;
9533
9534 version = avio_r8(pb);
9535 avio_rb24(pb); // flags.
9536 size -= 4;
9537 if (size < 0)
9538 return AVERROR_INVALIDDATA;
9539
9540 if (version < 2) {
9541 avpriv_report_missing_feature(c->fc, "infe version < 2");
9542 avio_skip(pb, size);
9543 return 1;
9544 }
9545
9546 item_id = version > 2 ? avio_rb32(pb) : avio_rb16(pb);
9547 avio_rb16(pb); // item_protection_index
9548 item_type = avio_rl32(pb);
9549 size -= 8;
9550 if (size < 1)
9551 return AVERROR_INVALIDDATA;
9552
9555 if (ret < 0) {
9557 return ret;
9558 }
9559
9560 av_log(c->fc, AV_LOG_TRACE, "infe: item_id %d, item_type %s, item_name %s\n",
9561 item_id, av_fourcc2str(item_type), item_name.str);
9562
9563 size -= ret + 1;
9564 if (size > 0)
9565 avio_skip(pb, size);
9566
9567 for (i = 0; i < c->nb_heif_item; i++) {
9568 item = c->heif_item[i];
9569 if (!item)
9570 item = c->heif_item[i] = av_mallocz(sizeof(*item));
9571 else if (item->item_id != item_id)
9572 continue;
9573 break;
9574 }
9575 if (!item) {
9577 return AVERROR(ENOMEM);
9578 }
9579 if (i == c->nb_heif_item) {
9581 return AVERROR_INVALIDDATA;
9582 }
9583
9584 av_freep(&item->name);
9585 av_bprint_finalize(&item_name, ret ? &item->name : NULL);
9586 item->item_id = item_id;
9587 item->type = item_type;
9588
9589 switch (item_type) {
9590 case MKTAG('a','v','0','1'):
9591 case MKTAG('j','p','e','g'):
9592 case MKTAG('h','v','c','1'):
9593 ret = heif_add_stream(c, item);
9594 if (ret < 0)
9595 return ret;
9596 break;
9597 }
9598
9599 return 0;
9600}
9601
9603{
9604 HEIFItem **heif_item;
9605 int entry_count;
9606 int version, got_stream = 0, ret, i;
9607
9608 if (c->found_iinf) {
9609 av_log(c->fc, AV_LOG_WARNING, "Duplicate iinf box found\n");
9610 return 0;
9611 }
9612
9613 version = avio_r8(pb);
9614 avio_rb24(pb); // flags.
9615 entry_count = version ? avio_rb32(pb) : avio_rb16(pb);
9616
9617 if (entry_count > atom.size)
9618 return AVERROR_INVALIDDATA;
9619
9620 heif_item = av_realloc_array(c->heif_item, FFMAX(entry_count, c->nb_heif_item), sizeof(*c->heif_item));
9621 if (!heif_item)
9622 return AVERROR(ENOMEM);
9623 c->heif_item = heif_item;
9624 if (entry_count > c->nb_heif_item)
9625 memset(&c->heif_item[c->nb_heif_item], 0,
9626 sizeof(*c->heif_item) * (entry_count - c->nb_heif_item));
9627 c->nb_heif_item = FFMAX(c->nb_heif_item, entry_count);
9628
9629 for (i = 0; i < entry_count; i++) {
9630 MOVAtom infe;
9631
9632 infe.size = avio_rb32(pb) - 8;
9633 infe.type = avio_rl32(pb);
9634 if (avio_feof(pb)) {
9635 ret = AVERROR_INVALIDDATA;
9636 goto fail;
9637 }
9638 ret = mov_read_infe(c, pb, infe);
9639 if (ret < 0)
9640 goto fail;
9641 if (!ret)
9642 got_stream = 1;
9643 }
9644
9645 c->found_iinf = got_stream;
9646 return 0;
9647fail:
9648 for (; i >= 0; i--) {
9649 HEIFItem *item = c->heif_item[i];
9650
9651 if (!item)
9652 continue;
9653
9654 av_freep(&item->name);
9655 }
9656 return ret;
9657}
9658
9660{
9661 HEIFItem *item = NULL;
9662 HEIFGrid *grid;
9663 int entries, i;
9664 int from_item_id = version ? avio_rb32(pb) : avio_rb16(pb);
9665 int ret = 0;
9666
9667 for (int i = 0; i < c->nb_heif_grid; i++) {
9668 if (c->heif_grid[i].item->item_id == from_item_id) {
9669 av_log(c->fc, AV_LOG_ERROR, "More than one 'dimg' box "
9670 "referencing the same Derived Image item\n");
9671 return AVERROR_INVALIDDATA;
9672 }
9673 }
9674 for (int i = 0; i < c->nb_heif_item; i++) {
9675 if (!c->heif_item[i] || c->heif_item[i]->item_id != from_item_id)
9676 continue;
9677 item = c->heif_item[i];
9678
9679 switch (item->type) {
9680 case MKTAG('g','r','i','d'):
9681 case MKTAG('i','o','v','l'):
9682 break;
9683 default:
9684 avpriv_report_missing_feature(c->fc, "Derived Image item of type %s",
9685 av_fourcc2str(item->type));
9686 return 0;
9687 }
9688 break;
9689 }
9690 if (!item) {
9691 av_log(c->fc, AV_LOG_ERROR, "Missing grid information\n");
9692 return AVERROR_INVALIDDATA;
9693 }
9694
9695 entries = avio_rb16(pb);
9696 if (!entries) {
9697 av_log(c->fc, AV_LOG_ERROR,
9698 "Derived image item references no input images\n");
9699 return AVERROR_INVALIDDATA;
9700 }
9701
9702 grid = av_realloc_array(c->heif_grid, c->nb_heif_grid + 1U,
9703 sizeof(*c->heif_grid));
9704 if (!grid)
9705 return AVERROR(ENOMEM);
9706 c->heif_grid = grid;
9707 grid = &grid[c->nb_heif_grid];
9708
9709 grid->tile_id_list = av_malloc_array(entries, sizeof(*grid->tile_id_list));
9710 grid->tile_idx_list = av_calloc(entries, sizeof(*grid->tile_idx_list));
9711 grid->tile_item_list = av_calloc(entries, sizeof(*grid->tile_item_list));
9712 if (!grid->tile_id_list || !grid->tile_item_list || !grid->tile_idx_list) {
9713 ret = AVERROR(ENOMEM);
9714 goto fail;
9715 }
9716 /* 'to' item ids */
9717 for (i = 0; i < entries; i++) {
9718 grid->tile_id_list[i] = version ? avio_rb32(pb) : avio_rb16(pb);
9719
9720 if (avio_feof(pb)) {
9721 ret = AVERROR_INVALIDDATA;
9722 goto fail;
9723 }
9724 }
9725
9726 grid->nb_tiles = entries;
9727 grid->item = item;
9728 ++c->nb_heif_grid;
9729
9730 av_log(c->fc, AV_LOG_TRACE, "dimg: from_item_id %d, entries %d\n",
9731 from_item_id, entries);
9732
9733 return 0;
9734fail:
9735 av_freep(&grid->tile_id_list);
9736 av_freep(&grid->tile_idx_list);
9737 av_freep(&grid->tile_item_list);
9738
9739 return ret;
9740}
9741
9742static int mov_read_iref_cdsc(MOVContext *c, AVIOContext *pb, uint32_t type, int version, uint32_t size)
9743{
9744 HEIFItem *from_item = NULL;
9745 int entries;
9746 int item_id_size = version ? 4 : 2;
9747 int from_item_id = version ? avio_rb32(pb) : avio_rb16(pb);
9748 const HEIFItemRef ref = { type, from_item_id };
9749
9750 from_item = get_heif_item(c, from_item_id);
9751 if (!from_item) {
9752 av_log(c->fc, AV_LOG_ERROR, "Missing stream referenced by thmb item\n");
9753 return AVERROR_INVALIDDATA;
9754 }
9755
9756 entries = avio_rb16(pb);
9757 if ((int64_t)entries * item_id_size > (int64_t)size - item_id_size - 2) {
9758 av_log(c->fc, AV_LOG_ERROR, "iref %s entry count %d exceeds the sub-box size\n",
9759 av_fourcc2str(type), entries);
9760 return AVERROR_INVALIDDATA;
9761 }
9762 /* 'to' item ids */
9763 for (int i = 0; i < entries; i++) {
9764 HEIFItem *item = get_heif_item(c, version ? avio_rb32(pb) : avio_rb16(pb));
9765
9766 if (avio_feof(pb))
9767 return AVERROR_INVALIDDATA;
9768
9769 if (!item) {
9770 av_log(c->fc, AV_LOG_WARNING, "Missing stream referenced by %s item\n",
9772 continue;
9773 }
9774
9775 if (!av_dynarray2_add((void **)&item->iref_list, &item->nb_iref_list,
9776 sizeof(*item->iref_list), (const uint8_t *)&ref))
9777 return AVERROR(ENOMEM);
9778 }
9779
9780 av_log(c->fc, AV_LOG_TRACE, "%s: from_item_id %d, entries %d\n",
9781 av_fourcc2str(type), from_item_id, entries);
9782
9783 return 0;
9784}
9785
9787{
9788 int version = avio_r8(pb);
9789 int ret;
9790
9791 avio_rb24(pb); // flags
9792 atom.size -= 4;
9793
9794 if (version > 1) {
9795 av_log(c->fc, AV_LOG_WARNING, "Unknown iref box version %d\n", version);
9796 return 0;
9797 }
9798
9799 while (atom.size) {
9800 int64_t next = avio_tell(pb);
9801 uint32_t type, size = avio_rb32(pb);
9802
9803 if (size < 14 || size > atom.size || next > INT64_MAX - size)
9804 return AVERROR_INVALIDDATA;
9805
9806 next += size;
9807 type = avio_rl32(pb);
9808 switch (type) {
9809 case MKTAG('d','i','m','g'):
9810 ret = mov_read_iref_dimg(c, pb, version);
9811 if (ret < 0)
9812 return ret;
9813 break;
9814 case MKTAG('c','d','s','c'):
9815 case MKTAG('t','h','m','b'):
9816 ret = mov_read_iref_cdsc(c, pb, type, version, size - 8);
9817 if (ret < 0)
9818 return ret;
9819 break;
9820 default:
9821 av_log(c->fc, AV_LOG_DEBUG, "Unknown iref type %s size %"PRIu32"\n",
9823 }
9824
9825 atom.size -= size;
9826 avio_seek(pb, next, SEEK_SET);
9827 }
9828 return 0;
9829}
9830
9832{
9833 HEIFItem *item;
9834 uint32_t width, height;
9835
9836 avio_r8(pb); /* version */
9837 avio_rb24(pb); /* flags */
9838 width = avio_rb32(pb);
9839 height = avio_rb32(pb);
9840
9841 av_log(c->fc, AV_LOG_TRACE, "ispe: item_id %d, width %"PRIu32", height %"PRIu32"\n",
9842 c->cur_item_id, width, height);
9843
9844 if (!width || !height || width > INT_MAX || height > INT_MAX) {
9845 av_log(c->fc, AV_LOG_ERROR, "Invalid ispe dimensions %"PRIu32"x%"PRIu32"\n",
9846 width, height);
9847 return AVERROR_INVALIDDATA;
9848 }
9849
9850 item = get_heif_item(c, c->cur_item_id);
9851 if (item) {
9852 item->width = width;
9853 item->height = height;
9854 }
9855
9856 return 0;
9857}
9858
9860{
9861 HEIFItem *item;
9862 int angle;
9863
9864 angle = avio_r8(pb) & 0x3;
9865
9866 av_log(c->fc, AV_LOG_TRACE, "irot: item_id %d, angle %u\n",
9867 c->cur_item_id, angle);
9868
9869 item = get_heif_item(c, c->cur_item_id);
9870 if (item) {
9871 // angle * 90 specifies the angle (in anti-clockwise direction)
9872 // in units of degrees.
9873 item->rotation = angle * 90;
9874 }
9875
9876 return 0;
9877}
9878
9880{
9881 HEIFItem *item;
9882 int axis;
9883
9884 axis = avio_r8(pb) & 0x1;
9885
9886 av_log(c->fc, AV_LOG_TRACE, "imir: item_id %d, axis %u\n",
9887 c->cur_item_id, axis);
9888
9889 item = get_heif_item(c, c->cur_item_id);
9890 if (item) {
9891 item->hflip = axis;
9892 item->vflip = !axis;
9893 }
9894
9895 return 0;
9896}
9897
9899{
9900 typedef struct MOVAtoms {
9901 FFIOContext b;
9902 uint32_t type;
9903 int64_t size;
9904 uint8_t *data;
9905 } MOVAtoms;
9906 MOVAtoms *atoms = NULL;
9907 MOVAtom a;
9908 unsigned count;
9909 int nb_atoms = 0;
9910 int version, flags;
9911 int ret;
9912
9913 a.size = avio_rb32(pb);
9914 a.type = avio_rl32(pb);
9915
9916 if (a.size < 8 || a.type != MKTAG('i','p','c','o'))
9917 return AVERROR_INVALIDDATA;
9918
9919 a.size -= 8;
9920 while (a.size >= 8) {
9921 MOVAtoms *ref = av_dynarray2_add((void**)&atoms, &nb_atoms, sizeof(MOVAtoms), NULL);
9922 if (!ref) {
9923 ret = AVERROR(ENOMEM);
9924 goto fail;
9925 }
9926 ref->data = NULL;
9927 ref->size = avio_rb32(pb);
9928 ref->type = avio_rl32(pb);
9929 if (ref->size > a.size || ref->size < 8)
9930 break;
9931 ref->data = av_malloc(ref->size);
9932 if (!ref->data) {
9933 ret = AVERROR_INVALIDDATA;
9934 goto fail;
9935 }
9936 av_log(c->fc, AV_LOG_TRACE, "ipco: index %d, box type %s\n", nb_atoms, av_fourcc2str(ref->type));
9937 avio_seek(pb, -8, SEEK_CUR);
9938 if (avio_read(pb, ref->data, ref->size) != ref->size) {
9939 ret = AVERROR_INVALIDDATA;
9940 goto fail;
9941 }
9942 ffio_init_read_context(&ref->b, ref->data, ref->size);
9943 a.size -= ref->size;
9944 }
9945
9946 if (a.size) {
9947 ret = AVERROR_INVALIDDATA;
9948 goto fail;
9949 }
9950
9951 a.size = avio_rb32(pb);
9952 a.type = avio_rl32(pb);
9953
9954 if (a.size < 8 || a.type != MKTAG('i','p','m','a')) {
9955 ret = AVERROR_INVALIDDATA;
9956 goto fail;
9957 }
9958
9959 version = avio_r8(pb);
9960 flags = avio_rb24(pb);
9961 count = avio_rb32(pb);
9962
9963 for (int i = 0; i < count; i++) {
9964 int item_id = version ? avio_rb32(pb) : avio_rb16(pb);
9965 int assoc_count = avio_r8(pb);
9966
9967 if (avio_feof(pb)) {
9968 ret = AVERROR_INVALIDDATA;
9969 goto fail;
9970 }
9971
9972 for (int j = 0; j < assoc_count; j++) {
9973 MOVAtoms *ref;
9974 int index = avio_r8(pb) & 0x7f;
9975 if (flags & 1) {
9976 index <<= 8;
9977 index |= avio_r8(pb);
9978 }
9979 if (index > nb_atoms || index <= 0) {
9980 ret = AVERROR_INVALIDDATA;
9981 goto fail;
9982 }
9983 ref = &atoms[--index];
9984
9985 av_log(c->fc, AV_LOG_TRACE, "ipma: property_index %d, item_id %d, item_type %s\n",
9986 index + 1, item_id, av_fourcc2str(ref->type));
9987
9988 c->cur_item_id = item_id;
9989
9990 ret = mov_read_default(c, &ref->b.pub,
9991 (MOVAtom) { .size = ref->size,
9992 .type = MKTAG('i','p','c','o') });
9993 if (ret < 0)
9994 goto fail;
9995 ffio_init_read_context(&ref->b, ref->data, ref->size);
9996 }
9997 }
9998
9999 ret = 0;
10000fail:
10001 c->cur_item_id = -1;
10002 for (int i = 0; i < nb_atoms; i++)
10003 av_free(atoms[i].data);
10004 av_free(atoms);
10005
10006 return ret;
10007}
10008
10010{
10011 avio_rb32(pb); // version & flags
10012 uint16_t graphics_mode = avio_rb16(pb);
10013 // ignored: opcolor[3]
10014
10015 if (c->fc->nb_streams < 1)
10016 return 0;
10017 AVStream *st = c->fc->streams[c->fc->nb_streams - 1];
10019 return 0;
10020
10021 switch (graphics_mode) {
10025 break;
10028 break;
10031 break;
10032 default:
10034 av_log(c->fc, AV_LOG_WARNING, "Unhandled graphics mode: 0x%x\n",
10035 graphics_mode);
10036 break;
10037 }
10038
10039 return 0;
10040}
10041
10043{ MKTAG('A','C','L','R'), mov_read_aclr },
10044{ MKTAG('A','P','R','G'), mov_read_avid },
10045{ MKTAG('A','A','L','P'), mov_read_avid },
10046{ MKTAG('A','R','E','S'), mov_read_ares },
10047{ MKTAG('a','v','s','s'), mov_read_avss },
10048{ MKTAG('a','v','1','C'), mov_read_glbl },
10049{ MKTAG('c','h','p','l'), mov_read_chpl },
10050{ MKTAG('c','o','6','4'), mov_read_stco },
10051{ MKTAG('c','o','l','r'), mov_read_colr },
10052{ MKTAG('c','t','t','s'), mov_read_ctts }, /* composition time to sample */
10053{ MKTAG('d','i','n','f'), mov_read_default },
10054{ MKTAG('D','p','x','E'), mov_read_dpxe },
10055{ MKTAG('d','r','e','f'), mov_read_dref },
10056{ MKTAG('e','d','t','s'), mov_read_default },
10057{ MKTAG('e','l','s','t'), mov_read_elst },
10058{ MKTAG('e','n','d','a'), mov_read_enda },
10059{ MKTAG('f','i','e','l'), mov_read_fiel },
10060{ MKTAG('a','d','r','m'), mov_read_adrm },
10061{ MKTAG('f','t','y','p'), mov_read_ftyp },
10062{ MKTAG('g','l','b','l'), mov_read_glbl },
10063{ MKTAG('h','d','l','r'), mov_read_hdlr },
10064{ MKTAG('i','l','s','t'), mov_read_ilst },
10065{ MKTAG('j','p','2','h'), mov_read_jp2h },
10066{ MKTAG('m','d','a','t'), mov_read_mdat },
10067{ MKTAG('m','d','h','d'), mov_read_mdhd },
10068{ MKTAG('m','d','i','a'), mov_read_default },
10069{ MKTAG('m','e','t','a'), mov_read_meta },
10070{ MKTAG('m','i','n','f'), mov_read_default },
10071{ MKTAG('m','o','o','f'), mov_read_moof },
10072{ MKTAG('m','o','o','v'), mov_read_moov },
10073{ MKTAG('m','v','e','x'), mov_read_default },
10074{ MKTAG('m','v','h','d'), mov_read_mvhd },
10075{ MKTAG('S','M','I',' '), mov_read_svq3 },
10076{ MKTAG('a','l','a','c'), mov_read_alac }, /* alac specific atom */
10077{ MKTAG('a','v','c','C'), mov_read_glbl },
10078{ MKTAG('p','a','s','p'), mov_read_pasp },
10079{ MKTAG('c','l','a','p'), mov_read_clap },
10080{ MKTAG('c','d','s','c'), mov_read_cdsc_rndr },
10081{ MKTAG('r','n','d','r'), mov_read_cdsc_rndr },
10082{ MKTAG('s','b','a','s'), mov_read_sbas },
10083{ MKTAG('v','d','e','p'), mov_read_vdep },
10084{ MKTAG('s','i','d','x'), mov_read_sidx },
10085{ MKTAG('s','t','b','l'), mov_read_default },
10086{ MKTAG('s','t','c','o'), mov_read_stco },
10087{ MKTAG('s','t','p','s'), mov_read_stps },
10088{ MKTAG('s','t','r','f'), mov_read_strf },
10089{ MKTAG('s','t','s','c'), mov_read_stsc },
10090{ MKTAG('s','t','s','d'), mov_read_stsd }, /* sample description */
10091{ MKTAG('s','t','s','s'), mov_read_stss }, /* sync sample */
10092{ MKTAG('s','t','s','z'), mov_read_stsz }, /* sample size */
10093{ MKTAG('s','t','t','s'), mov_read_stts },
10094{ MKTAG('s','t','z','2'), mov_read_stsz }, /* compact sample size */
10095{ MKTAG('s','d','t','p'), mov_read_sdtp }, /* independent and disposable samples */
10096{ MKTAG('t','k','h','d'), mov_read_tkhd }, /* track header */
10097{ MKTAG('t','f','d','t'), mov_read_tfdt },
10098{ MKTAG('t','f','h','d'), mov_read_tfhd }, /* track fragment header */
10099{ MKTAG('t','r','a','k'), mov_read_trak },
10100{ MKTAG('t','r','a','f'), mov_read_default },
10101{ MKTAG('t','r','e','f'), mov_read_default },
10102{ MKTAG('t','m','c','d'), mov_read_tmcd },
10103{ MKTAG('c','h','a','p'), mov_read_chap },
10104{ MKTAG('t','r','e','x'), mov_read_trex },
10105{ MKTAG('t','r','u','n'), mov_read_trun },
10106{ MKTAG('u','d','t','a'), mov_read_default },
10107{ MKTAG('w','a','v','e'), mov_read_wave },
10108{ MKTAG('e','s','d','s'), mov_read_esds },
10109{ MKTAG('d','a','c','3'), mov_read_dac3 }, /* AC-3 info */
10110{ MKTAG('d','e','c','3'), mov_read_dec3 }, /* EAC-3 info */
10111{ MKTAG('d','d','t','s'), mov_read_ddts }, /* DTS audio descriptor */
10112{ MKTAG('w','i','d','e'), mov_read_wide }, /* place holder */
10113{ MKTAG('w','f','e','x'), mov_read_wfex },
10114{ MKTAG('c','m','o','v'), mov_read_cmov },
10115{ MKTAG('c','h','a','n'), mov_read_chan }, /* channel layout from quicktime */
10116{ MKTAG('c','h','n','l'), mov_read_chnl }, /* channel layout from ISO-14496-12 */
10117{ MKTAG('d','v','c','1'), mov_read_dvc1 },
10118{ MKTAG('s','g','p','d'), mov_read_sgpd },
10119{ MKTAG('s','b','g','p'), mov_read_sbgp },
10120{ MKTAG('h','v','c','C'), mov_read_glbl },
10121{ MKTAG('v','v','c','C'), mov_read_glbl },
10122{ MKTAG('u','u','i','d'), mov_read_uuid },
10123{ MKTAG('C','i','n', 0x8e), mov_read_targa_y216 },
10124{ MKTAG('f','r','e','e'), mov_read_free },
10125{ MKTAG('-','-','-','-'), mov_read_custom },
10126{ MKTAG('s','i','n','f'), mov_read_default },
10127{ MKTAG('f','r','m','a'), mov_read_frma },
10128{ MKTAG('s','e','n','c'), mov_read_senc },
10129{ MKTAG('s','a','i','z'), mov_read_saiz },
10130{ MKTAG('s','a','i','o'), mov_read_saio },
10131{ MKTAG('p','s','s','h'), mov_read_pssh },
10132{ MKTAG('s','c','h','m'), mov_read_schm },
10133{ MKTAG('s','c','h','i'), mov_read_default },
10134{ MKTAG('t','e','n','c'), mov_read_tenc },
10135{ MKTAG('d','f','L','a'), mov_read_dfla },
10136{ MKTAG('s','t','3','d'), mov_read_st3d }, /* stereoscopic 3D video box */
10137{ MKTAG('s','v','3','d'), mov_read_sv3d }, /* spherical video box */
10138{ MKTAG('v','e','x','u'), mov_read_vexu }, /* video extension usage */
10139{ MKTAG('h','f','o','v'), mov_read_hfov },
10140{ MKTAG('d','O','p','s'), mov_read_dops },
10141{ MKTAG('d','m','l','p'), mov_read_dmlp },
10142{ MKTAG('S','m','D','m'), mov_read_smdm },
10143{ MKTAG('C','o','L','L'), mov_read_coll },
10144{ MKTAG('v','p','c','C'), mov_read_vpcc },
10145{ MKTAG('m','d','c','v'), mov_read_mdcv },
10146{ MKTAG('c','l','l','i'), mov_read_clli },
10147{ MKTAG('d','v','c','C'), mov_read_dvcc_dvvc },
10148{ MKTAG('d','v','v','C'), mov_read_dvcc_dvvc },
10149{ MKTAG('d','v','w','C'), mov_read_dvcc_dvvc },
10150{ MKTAG('h','v','c','E'), mov_read_hvce },
10151{ MKTAG('k','i','n','d'), mov_read_kind },
10152{ MKTAG('S','A','3','D'), mov_read_SA3D }, /* ambisonic audio box */
10153{ MKTAG('S','A','N','D'), mov_read_SAND }, /* non diegetic audio box */
10154{ MKTAG('i','l','o','c'), mov_read_iloc },
10155{ MKTAG('p','c','m','C'), mov_read_pcmc }, /* PCM configuration box */
10156{ MKTAG('p','i','t','m'), mov_read_pitm },
10157{ MKTAG('e','v','c','C'), mov_read_glbl },
10158{ MKTAG('i','d','a','t'), mov_read_idat },
10159{ MKTAG('i','m','i','r'), mov_read_imir },
10160{ MKTAG('i','r','e','f'), mov_read_iref },
10161{ MKTAG('i','s','p','e'), mov_read_ispe },
10162{ MKTAG('i','r','o','t'), mov_read_irot },
10163{ MKTAG('i','p','r','p'), mov_read_iprp },
10164{ MKTAG('i','i','n','f'), mov_read_iinf },
10165{ MKTAG('a','m','v','e'), mov_read_amve }, /* ambient viewing environment box */
10166{ MKTAG('l','h','v','C'), mov_read_lhvc },
10167{ MKTAG('l','v','c','C'), mov_read_glbl },
10168{ MKTAG('a','p','v','C'), mov_read_glbl },
10169#if CONFIG_IAMFDEC
10170{ MKTAG('i','a','c','b'), mov_read_iacb },
10171#endif
10172{ MKTAG('s','r','a','t'), mov_read_srat },
10173{ MKTAG('v','m','h','d'), mov_read_vmhd },
10174{ 0, NULL }
10175};
10176
10178{
10179 int64_t total_size = 0;
10180 MOVAtom a;
10181 int i;
10182
10183 if (c->atom_depth > 10) {
10184 av_log(c->fc, AV_LOG_ERROR, "Atoms too deeply nested\n");
10185 return AVERROR_INVALIDDATA;
10186 }
10187 c->atom_depth ++;
10188
10189 if (atom.size < 0)
10190 atom.size = INT64_MAX;
10191 while (total_size <= atom.size - 8) {
10192 int (*parse)(MOVContext*, AVIOContext*, MOVAtom) = NULL;
10193 a.size = avio_rb32(pb);
10194 a.type = avio_rl32(pb);
10195 if (avio_feof(pb))
10196 break;
10197 if (((a.type == MKTAG('f','r','e','e') && c->moov_retry) ||
10198 a.type == MKTAG('h','o','o','v')) &&
10199 a.size >= 8 &&
10200 c->fc->strict_std_compliance < FF_COMPLIANCE_STRICT) {
10201 uint32_t type;
10202 avio_skip(pb, 4);
10203 type = avio_rl32(pb);
10204 if (avio_feof(pb))
10205 break;
10206 avio_seek(pb, -8, SEEK_CUR);
10207 if (type == MKTAG('m','v','h','d') ||
10208 type == MKTAG('c','m','o','v')) {
10209 av_log(c->fc, AV_LOG_ERROR, "Detected moov in a free or hoov atom.\n");
10210 a.type = MKTAG('m','o','o','v');
10211 }
10212 }
10213 if (atom.type != MKTAG('r','o','o','t') &&
10214 atom.type != MKTAG('m','o','o','v')) {
10215 if (a.type == MKTAG('t','r','a','k') ||
10216 a.type == MKTAG('m','d','a','t')) {
10217 av_log(c->fc, AV_LOG_ERROR, "Broken file, trak/mdat not at top-level\n");
10218 avio_skip(pb, -8);
10219 c->atom_depth --;
10220 return 0;
10221 }
10222 }
10223 total_size += 8;
10224 if (a.size == 1 && total_size + 8 <= atom.size) { /* 64 bit extended size */
10225 a.size = avio_rb64(pb) - 8;
10226 total_size += 8;
10227 }
10228 av_log(c->fc, AV_LOG_TRACE, "type:'%s' parent:'%s' sz: %"PRId64" %"PRId64" %"PRId64"\n",
10229 av_fourcc2str(a.type), av_fourcc2str(atom.type), a.size, total_size, atom.size);
10230 if (a.size == 0) {
10231 a.size = atom.size - total_size + 8;
10232 }
10233 if (a.size < 0)
10234 break;
10235 a.size -= 8;
10236 if (a.size < 0)
10237 break;
10238 a.size = FFMIN(a.size, atom.size - total_size);
10239
10240 for (i = 0; mov_default_parse_table[i].type; i++)
10241 if (mov_default_parse_table[i].type == a.type) {
10243 break;
10244 }
10245
10246 // container is user data
10247 if (!parse && (atom.type == MKTAG('u','d','t','a') ||
10248 atom.type == MKTAG('i','l','s','t')))
10250
10251 // Supports parsing the QuickTime Metadata Keys.
10252 // https://developer.apple.com/library/mac/documentation/QuickTime/QTFF/Metadata/Metadata.html
10253 if (!parse && c->found_hdlr_mdta &&
10254 atom.type == MKTAG('m','e','t','a') &&
10255 a.type == MKTAG('k','e','y','s') &&
10256 c->meta_keys_count == 0) {
10258 }
10259
10260 if (!parse) { /* skip leaf atoms data */
10261 avio_skip(pb, a.size);
10262 } else {
10263 int64_t start_pos = avio_tell(pb);
10264 int64_t left;
10265 int err = parse(c, pb, a);
10266 if (err < 0) {
10267 c->atom_depth --;
10268 return err;
10269 }
10270 if (c->found_moov && c->found_mdat && a.size <= INT64_MAX - start_pos &&
10271 ((!(pb->seekable & AVIO_SEEKABLE_NORMAL) || c->fc->flags & AVFMT_FLAG_IGNIDX || c->frag_index.complete) ||
10272 start_pos + a.size == avio_size(pb))) {
10273 if (!(pb->seekable & AVIO_SEEKABLE_NORMAL) || c->fc->flags & AVFMT_FLAG_IGNIDX || c->frag_index.complete)
10274 c->next_root_atom = start_pos + a.size;
10275 c->atom_depth --;
10276 return 0;
10277 }
10278 left = a.size - avio_tell(pb) + start_pos;
10279 if (left > 0) /* skip garbage at atom end */
10280 avio_skip(pb, left);
10281 else if (left < 0) {
10282 av_log(c->fc, AV_LOG_WARNING,
10283 "overread end of atom '%s' by %"PRId64" bytes\n",
10284 av_fourcc2str(a.type), -left);
10285 avio_seek(pb, left, SEEK_CUR);
10286 }
10287 }
10288
10289 total_size += a.size;
10290 }
10291
10292 if (total_size < atom.size && atom.size < 0x7ffff)
10293 avio_skip(pb, atom.size - total_size);
10294
10295 c->atom_depth --;
10296 return 0;
10297}
10298
10299static int mov_probe(const AVProbeData *p)
10300{
10302 uint32_t tag;
10303 int score = 0;
10304 int moov_offset = -1;
10305
10306 /* check file header */
10307 offset = 0;
10308 for (;;) {
10309 int64_t size;
10310 int minsize = 8;
10311 /* ignore invalid offset */
10312 if ((offset + 8ULL) > (unsigned int)p->buf_size)
10313 break;
10314 size = AV_RB32(p->buf + offset);
10315 if (size == 1 && offset + 16 <= (unsigned int)p->buf_size) {
10316 size = AV_RB64(p->buf+offset + 8);
10317 minsize = 16;
10318 } else if (size == 0) {
10319 size = p->buf_size - offset;
10320 }
10321 if (size < minsize) {
10322 offset += 4;
10323 continue;
10324 }
10325 tag = AV_RL32(p->buf + offset + 4);
10326 switch(tag) {
10327 /* check for obvious tags */
10328 case MKTAG('m','o','o','v'):
10329 moov_offset = offset + 4;
10331 case MKTAG('m','d','a','t'):
10332 case MKTAG('p','n','o','t'): /* detect movs with preview pics like ew.mov and april.mov */
10333 case MKTAG('u','d','t','a'): /* Packet Video PVAuthor adds this and a lot of more junk */
10334 case MKTAG('f','t','y','p'):
10335 if (tag == MKTAG('f','t','y','p') &&
10336 ( AV_RL32(p->buf + offset + 8) == MKTAG('j','p','2',' ')
10337 || AV_RL32(p->buf + offset + 8) == MKTAG('j','p','x',' ')
10338 || AV_RL32(p->buf + offset + 8) == MKTAG('j','x','l',' ')
10339 )) {
10340 score = FFMAX(score, 5);
10341 } else {
10342 score = AVPROBE_SCORE_MAX;
10343 }
10344 break;
10345 /* those are more common words, so rate then a bit less */
10346 case MKTAG('e','d','i','w'): /* xdcam files have reverted first tags */
10347 case MKTAG('w','i','d','e'):
10348 case MKTAG('f','r','e','e'):
10349 case MKTAG('j','u','n','k'):
10350 case MKTAG('p','i','c','t'):
10351 score = FFMAX(score, AVPROBE_SCORE_MAX - 5);
10352 break;
10353 case MKTAG(0x82,0x82,0x7f,0x7d):
10354 score = FFMAX(score, AVPROBE_SCORE_EXTENSION - 5);
10355 break;
10356 case MKTAG('s','k','i','p'):
10357 case MKTAG('u','u','i','d'):
10358 case MKTAG('p','r','f','l'):
10359 /* if we only find those cause probedata is too small at least rate them */
10360 score = FFMAX(score, AVPROBE_SCORE_EXTENSION);
10361 break;
10362 }
10363 if (size > INT64_MAX - offset)
10364 break;
10365 offset += size;
10366 }
10367 if (score > AVPROBE_SCORE_MAX - 50 && moov_offset != -1) {
10368 /* moov atom in the header - we should make sure that this is not a
10369 * MOV-packed MPEG-PS */
10370 offset = moov_offset;
10371
10372 while (offset < (p->buf_size - 16)) { /* Sufficient space */
10373 /* We found an actual hdlr atom */
10374 if (AV_RL32(p->buf + offset ) == MKTAG('h','d','l','r') &&
10375 AV_RL32(p->buf + offset + 8) == MKTAG('m','h','l','r') &&
10376 AV_RL32(p->buf + offset + 12) == MKTAG('M','P','E','G')) {
10377 av_log(NULL, AV_LOG_WARNING, "Found media data tag MPEG indicating this is a MOV-packed MPEG-PS.\n");
10378 /* We found a media handler reference atom describing an
10379 * MPEG-PS-in-MOV, return a
10380 * low score to force expanding the probe window until
10381 * mpegps_probe finds what it needs */
10382 return 5;
10383 } else {
10384 /* Keep looking */
10385 offset += 2;
10386 }
10387 }
10388 }
10389
10390 return score;
10391}
10392
10393// must be done after parsing all trak because there's no order requirement
10395{
10396 MOVContext *mov = s->priv_data;
10397 MOVStreamContext *sc;
10398 int64_t cur_pos;
10399 int i, j;
10400 int chapter_track;
10401
10402 for (j = 0; j < mov->nb_chapter_tracks; j++) {
10403 AVStream *st = NULL;
10404 FFStream *sti = NULL;
10405 chapter_track = mov->chapter_tracks[j];
10406 for (i = 0; i < s->nb_streams; i++) {
10407 sc = mov->fc->streams[i]->priv_data;
10408 if (sc->id == chapter_track) {
10409 st = s->streams[i];
10410 break;
10411 }
10412 }
10413 if (!st) {
10414 av_log(s, AV_LOG_ERROR, "Referenced QT chapter track not found\n");
10415 continue;
10416 }
10417 sti = ffstream(st);
10418
10419 sc = st->priv_data;
10420 cur_pos = avio_tell(sc->pb);
10421
10424 if (!st->attached_pic.data && sti->nb_index_entries) {
10425 // Retrieve the first frame, if possible
10426 AVIndexEntry *sample = &sti->index_entries[0];
10427 if (avio_seek(sc->pb, sample->pos, SEEK_SET) != sample->pos) {
10428 av_log(s, AV_LOG_ERROR, "Failed to retrieve first frame\n");
10429 goto finish;
10430 }
10431
10432 if (ff_add_attached_pic(s, st, sc->pb, NULL, sample->size) < 0)
10433 goto finish;
10434 }
10435 } else {
10438 st->discard = AVDISCARD_ALL;
10439 for (int i = 0; i < sti->nb_index_entries; i++) {
10441 int64_t end = i+1 < sti->nb_index_entries ? sti->index_entries[i+1].timestamp : st->duration;
10442 uint8_t *title;
10443 uint16_t ch;
10444 int len, title_len;
10445
10446 if (end < sample->timestamp) {
10447 av_log(s, AV_LOG_WARNING, "ignoring stream duration which is shorter than chapters\n");
10448 end = AV_NOPTS_VALUE;
10449 }
10450
10451 if (avio_seek(sc->pb, sample->pos, SEEK_SET) != sample->pos) {
10452 av_log(s, AV_LOG_ERROR, "Chapter %d not found in file\n", i);
10453 goto finish;
10454 }
10455
10456 // the first two bytes are the length of the title
10457 len = avio_rb16(sc->pb);
10458 if (len > sample->size-2)
10459 continue;
10460 title_len = 2*len + 1;
10461 if (!(title = av_mallocz(title_len)))
10462 goto finish;
10463
10464 // The samples could theoretically be in any encoding if there's an encd
10465 // atom following, but in practice are only utf-8 or utf-16, distinguished
10466 // instead by the presence of a BOM
10467 if (!len) {
10468 title[0] = 0;
10469 } else {
10470 ch = avio_rb16(sc->pb);
10471 if (ch == 0xfeff)
10472 avio_get_str16be(sc->pb, len, title, title_len);
10473 else if (ch == 0xfffe)
10474 avio_get_str16le(sc->pb, len, title, title_len);
10475 else {
10476 AV_WB16(title, ch);
10477 if (len == 1 || len == 2)
10478 title[len] = 0;
10479 else
10480 avio_get_str(sc->pb, INT_MAX, title + 2, len - 1);
10481 }
10482 }
10483
10484 avpriv_new_chapter(s, i, st->time_base, sample->timestamp, end, title);
10485 av_freep(&title);
10486 }
10487 }
10488finish:
10489 avio_seek(sc->pb, cur_pos, SEEK_SET);
10490 }
10491}
10492
10494 int64_t value, int flags)
10495{
10496 AVTimecode tc;
10497 char buf[AV_TIMECODE_STR_SIZE];
10498 AVRational rate = st->avg_frame_rate;
10499 int ret = av_timecode_init(&tc, rate, flags, 0, s);
10500 if (ret < 0)
10501 return ret;
10502 av_dict_set(&st->metadata, "timecode",
10503 av_timecode_make_string(&tc, buf, value), 0);
10504 return 0;
10505}
10506
10508{
10509 MOVStreamContext *sc = st->priv_data;
10510 FFStream *const sti = ffstream(st);
10511 char buf[AV_TIMECODE_STR_SIZE];
10512 int64_t cur_pos = avio_tell(sc->pb);
10513 int hh, mm, ss, ff, drop;
10514
10515 if (!sti->nb_index_entries)
10516 return -1;
10517
10518 avio_seek(sc->pb, sti->index_entries->pos, SEEK_SET);
10519 avio_skip(s->pb, 13);
10520 hh = avio_r8(s->pb);
10521 mm = avio_r8(s->pb);
10522 ss = avio_r8(s->pb);
10523 drop = avio_r8(s->pb);
10524 ff = avio_r8(s->pb);
10525 snprintf(buf, AV_TIMECODE_STR_SIZE, "%02d:%02d:%02d%c%02d",
10526 hh, mm, ss, drop ? ';' : ':', ff);
10527 av_dict_set(&st->metadata, "timecode", buf, 0);
10528
10529 avio_seek(sc->pb, cur_pos, SEEK_SET);
10530 return 0;
10531}
10532
10534{
10535 MOVStreamContext *sc = st->priv_data;
10536 FFStream *const sti = ffstream(st);
10537 int flags = 0;
10538 int64_t cur_pos = avio_tell(sc->pb);
10539 int64_t value;
10540 AVRational tc_rate = st->avg_frame_rate;
10541 int tmcd_nb_frames = sc->tmcd_nb_frames;
10542 int rounded_tc_rate;
10543
10544 if (!sti->nb_index_entries)
10545 return -1;
10546
10547 if (!tc_rate.num || !tc_rate.den || !tmcd_nb_frames)
10548 return -1;
10549
10550 avio_seek(sc->pb, sti->index_entries->pos, SEEK_SET);
10551 value = avio_rb32(s->pb);
10552
10553 if (sc->tmcd_flags & 0x0001) flags |= AV_TIMECODE_FLAG_DROPFRAME;
10554 if (sc->tmcd_flags & 0x0002) flags |= AV_TIMECODE_FLAG_24HOURSMAX;
10555 if (sc->tmcd_flags & 0x0004) flags |= AV_TIMECODE_FLAG_ALLOWNEGATIVE;
10556
10557 /* Assume Counter flag is set to 1 in tmcd track (even though it is likely
10558 * not the case) and thus assume "frame number format" instead of QT one.
10559 * No sample with tmcd track can be found with a QT timecode at the moment,
10560 * despite what the tmcd track "suggests" (Counter flag set to 0 means QT
10561 * format). */
10562
10563 /* 60 fps content have tmcd_nb_frames set to 30 but tc_rate set to 60, so
10564 * we multiply the frame number with the quotient.
10565 * See tickets #9492, #9710. */
10566 rounded_tc_rate = (tc_rate.num + tc_rate.den / 2LL) / tc_rate.den;
10567 /* Work around files where tmcd_nb_frames is rounded down from frame rate
10568 * instead of up. See ticket #5978. */
10569 if (tmcd_nb_frames == tc_rate.num / tc_rate.den &&
10570 s->strict_std_compliance < FF_COMPLIANCE_STRICT)
10571 tmcd_nb_frames = rounded_tc_rate;
10572 value = av_rescale(value, rounded_tc_rate, tmcd_nb_frames);
10573
10575
10576 avio_seek(sc->pb, cur_pos, SEEK_SET);
10577 return 0;
10578}
10579
10581 int i;
10582 if (!index || !*index) return;
10583 for (i = 0; i < (*index)->nb_encrypted_samples; i++) {
10584 av_encryption_info_free((*index)->encrypted_samples[i]);
10585 }
10586 av_freep(&(*index)->encrypted_samples);
10587 av_freep(&(*index)->auxiliary_info_sizes);
10588 av_freep(&(*index)->auxiliary_offsets);
10589 av_freep(index);
10590}
10591
10593{
10594 MOVStreamContext *sc = st->priv_data;
10595
10596 if (!sc || --sc->refcount) {
10597 st->priv_data = NULL;
10598 return;
10599 }
10600
10601 av_freep(&sc->tts_data);
10602 for (int i = 0; i < sc->drefs_count; i++) {
10603 av_freep(&sc->drefs[i].path);
10604 av_freep(&sc->drefs[i].dir);
10605 }
10606 av_freep(&sc->drefs);
10607
10608 sc->drefs_count = 0;
10609
10610 if (!sc->pb_is_copied)
10611 ff_format_io_close(s, &sc->pb);
10612
10613 sc->pb = NULL;
10614 av_freep(&sc->chunk_offsets);
10615 av_freep(&sc->stsc_data);
10616 av_freep(&sc->sample_sizes);
10617 av_freep(&sc->keyframes);
10618 av_freep(&sc->ctts_data);
10619 av_freep(&sc->stts_data);
10620 av_freep(&sc->sdtp_data);
10621 av_freep(&sc->stps_data);
10622 av_freep(&sc->elst_data);
10623 av_freep(&sc->rap_group);
10624 av_freep(&sc->sync_group);
10625 av_freep(&sc->sgpd_sync);
10629 av_freep(&sc->index_ranges);
10630 for (int i = 0; i < sc->nb_tref_tags; i++)
10631 av_freep(&sc->tref_tags[i].id);
10632 av_freep(&sc->tref_tags);
10633
10634 if (sc->extradata)
10635 for (int i = 0; i < sc->stsd_count; i++)
10636 av_free(sc->extradata[i]);
10637 av_freep(&sc->extradata);
10639
10643
10644 av_freep(&sc->stereo3d);
10645 av_freep(&sc->spherical);
10646 av_freep(&sc->mastering);
10647 av_freep(&sc->coll);
10648 av_freep(&sc->ambient);
10649
10650#if CONFIG_IAMFDEC
10651 if (sc->iamf)
10653#endif
10654 av_freep(&sc->iamf);
10655}
10656
10658{
10659 MOVContext *mov = s->priv_data;
10660 int i, j;
10661
10662 for (i = 0; i < s->nb_streams; i++) {
10663 AVStream *st = s->streams[i];
10664
10666 }
10667
10668 av_freep(&mov->dv_demux);
10670 mov->dv_fctx = NULL;
10671
10672 if (mov->meta_keys) {
10673 for (i = 1; i < mov->meta_keys_count; i++) {
10674 av_freep(&mov->meta_keys[i]);
10675 }
10676 av_freep(&mov->meta_keys);
10677 }
10678
10679 av_freep(&mov->trex_data);
10680 av_freep(&mov->bitrates);
10681
10682 for (i = 0; i < mov->frag_index.nb_items; i++) {
10684 for (j = 0; j < mov->frag_index.item[i].nb_stream_info; j++) {
10685 mov_free_encryption_index(&frag[j].encryption_index);
10686 }
10688 }
10689 av_freep(&mov->frag_index.item);
10690
10691 av_freep(&mov->aes_decrypt);
10692 av_freep(&mov->chapter_tracks);
10693 for (i = 0; i < mov->nb_heif_item; i++) {
10694 if (!mov->heif_item[i])
10695 continue;
10696 av_freep(&mov->heif_item[i]->name);
10697 av_freep(&mov->heif_item[i]->iref_list);
10699 av_freep(&mov->heif_item[i]);
10700 }
10701 av_freep(&mov->heif_item);
10702 for (i = 0; i < mov->nb_heif_grid; i++) {
10706 }
10707 av_freep(&mov->heif_grid);
10708
10709 return 0;
10710}
10711
10712static int tmcd_is_referenced(AVFormatContext *s, int tmcd_id)
10713{
10714 int i;
10715
10716 for (i = 0; i < s->nb_streams; i++) {
10717 AVStream *st = s->streams[i];
10718 MOVStreamContext *sc = st->priv_data;
10719 MovTref *tag = mov_find_tref_tag(sc, MKTAG('t','m','c','d'));
10720
10721 if (!tag)
10722 continue;
10723 if (mov_find_tref_id(tag, tmcd_id))
10724 return 1;
10725 }
10726 return 0;
10727}
10728
10729/* look for a tmcd track not referenced by any video track, and export it globally */
10731{
10732 int i;
10733
10734 for (i = 0; i < s->nb_streams; i++) {
10735 AVStream *st = s->streams[i];
10736
10737 if (st->codecpar->codec_tag == MKTAG('t','m','c','d') &&
10738 !tmcd_is_referenced(s, st->id)) {
10739 AVDictionaryEntry *tcr = av_dict_get(st->metadata, "timecode", NULL, 0);
10740 if (tcr) {
10741 av_dict_set(&s->metadata, "timecode", tcr->value, 0);
10742 break;
10743 }
10744 }
10745 }
10746}
10747
10749{
10750 int version, fieldlength, i, j;
10752 uint32_t size = avio_rb32(f);
10753 unsigned track_id, item_count;
10754
10755 if (avio_rb32(f) != MKBETAG('t', 'f', 'r', 'a')) {
10756 return 1;
10757 }
10758 av_log(mov->fc, AV_LOG_VERBOSE, "found tfra\n");
10759
10760 version = avio_r8(f);
10761 avio_rb24(f);
10762 track_id = avio_rb32(f);
10763 fieldlength = avio_rb32(f);
10764 item_count = avio_rb32(f);
10765 for (i = 0; i < item_count; i++) {
10766 int64_t time, offset;
10767 int index;
10768 MOVFragmentStreamInfo * frag_stream_info;
10769
10770 if (avio_feof(f)) {
10771 return AVERROR_INVALIDDATA;
10772 }
10773
10774 if (version == 1) {
10775 time = avio_rb64(f);
10776 offset = avio_rb64(f);
10777 } else {
10778 time = avio_rb32(f);
10779 offset = avio_rb32(f);
10780 }
10781
10782 // The first sample of each stream in a fragment is always a random
10783 // access sample. So it's entry in the tfra can be used as the
10784 // initial PTS of the fragment.
10786 frag_stream_info = get_frag_stream_info(&mov->frag_index, index, track_id);
10787 if (frag_stream_info &&
10788 frag_stream_info->first_tfra_pts == AV_NOPTS_VALUE)
10789 frag_stream_info->first_tfra_pts = time;
10790
10791 for (j = 0; j < ((fieldlength >> 4) & 3) + 1; j++)
10792 avio_r8(f);
10793 for (j = 0; j < ((fieldlength >> 2) & 3) + 1; j++)
10794 avio_r8(f);
10795 for (j = 0; j < ((fieldlength >> 0) & 3) + 1; j++)
10796 avio_r8(f);
10797 }
10798
10799 avio_seek(f, pos + size, SEEK_SET);
10800 return 0;
10801}
10802
10804{
10805 int64_t stream_size = avio_size(f);
10806 int64_t original_pos = avio_tell(f);
10807 int64_t seek_ret;
10808 int ret = -1;
10809 if ((seek_ret = avio_seek(f, stream_size - 4, SEEK_SET)) < 0) {
10810 ret = seek_ret;
10811 goto fail;
10812 }
10813 c->mfra_size = avio_rb32(f);
10814 c->have_read_mfra_size = 1;
10815 if (!c->mfra_size || c->mfra_size > stream_size) {
10816 av_log(c->fc, AV_LOG_DEBUG, "doesn't look like mfra (unreasonable size)\n");
10817 goto fail;
10818 }
10819 if ((seek_ret = avio_seek(f, -((int64_t) c->mfra_size), SEEK_CUR)) < 0) {
10820 ret = seek_ret;
10821 goto fail;
10822 }
10823 if (avio_rb32(f) != c->mfra_size) {
10824 av_log(c->fc, AV_LOG_DEBUG, "doesn't look like mfra (size mismatch)\n");
10825 goto fail;
10826 }
10827 if (avio_rb32(f) != MKBETAG('m', 'f', 'r', 'a')) {
10828 av_log(c->fc, AV_LOG_DEBUG, "doesn't look like mfra (tag mismatch)\n");
10829 goto fail;
10830 }
10831 av_log(c->fc, AV_LOG_VERBOSE, "stream has mfra\n");
10832 do {
10833 ret = read_tfra(c, f);
10834 if (ret < 0)
10835 goto fail;
10836 } while (!ret);
10837 ret = 0;
10838 c->frag_index.complete = 1;
10839fail:
10840 seek_ret = avio_seek(f, original_pos, SEEK_SET);
10841 if (seek_ret < 0) {
10842 av_log(c->fc, AV_LOG_ERROR,
10843 "failed to seek back after looking for mfra\n");
10844 ret = seek_ret;
10845 }
10846 return ret;
10847}
10848
10849static int set_icc_profile_from_item(AVPacketSideData **coded_side_data, int *nb_coded_side_data,
10850 const HEIFItem *item)
10851{
10852 AVPacketSideData *sd = av_packet_side_data_new(coded_side_data, nb_coded_side_data,
10854 item->icc_profile_size, 0);
10855 if (!sd)
10856 return AVERROR(ENOMEM);
10857
10858 memcpy(sd->data, item->icc_profile, item->icc_profile_size);
10859
10860 return 0;
10861}
10862
10863static int set_display_matrix_from_item(AVPacketSideData **coded_side_data, int *nb_coded_side_data,
10864 const HEIFItem *item)
10865{
10866 int32_t *matrix;
10867 AVPacketSideData *sd = av_packet_side_data_new(coded_side_data,
10868 nb_coded_side_data,
10870 9 * sizeof(*matrix), 0);
10871 if (!sd)
10872 return AVERROR(ENOMEM);
10873
10874 matrix = (int32_t*)sd->data;
10875 /* rotation is in the counter-clockwise direction whereas
10876 * av_display_rotation_set() expects its argument to be
10877 * oriented clockwise, so we need to negate it. */
10880
10881 return 0;
10882}
10883
10885 AVStreamGroupTileGrid *tile_grid)
10886{
10887 MOVContext *c = s->priv_data;
10888 const HEIFItem *item = grid->item;
10889 int64_t coded_width = 0, coded_height = 0;
10890 int64_t offset = 0, pos = avio_tell(s->pb);
10891 int64_t x = 0, y = 0;
10892 int i = 0;
10893 int tile_rows, tile_cols;
10894 int flags, size;
10895
10896 if (!(s->pb->seekable & AVIO_SEEKABLE_NORMAL)) {
10897 av_log(c->fc, AV_LOG_INFO, "grid box with non seekable input\n");
10898 return AVERROR_PATCHWELCOME;
10899 }
10900 if (item->is_idat_relative) {
10901 if (!c->idat_offset) {
10902 av_log(c->fc, AV_LOG_ERROR, "missing idat box required by the image grid\n");
10903 return AVERROR_INVALIDDATA;
10904 }
10905 offset = c->idat_offset;
10906 }
10907
10908 if (offset > INT64_MAX - item->extent_offset)
10909 return AVERROR_INVALIDDATA;
10910
10911 avio_seek(s->pb, item->extent_offset + offset, SEEK_SET);
10912
10913 avio_r8(s->pb); /* version */
10914 flags = avio_r8(s->pb);
10915
10916 tile_rows = avio_r8(s->pb) + 1;
10917 tile_cols = avio_r8(s->pb) + 1;
10918 /* actual width and height of output image */
10919 tile_grid->width = (flags & 1) ? avio_rb32(s->pb) : avio_rb16(s->pb);
10920 tile_grid->height = (flags & 1) ? avio_rb32(s->pb) : avio_rb16(s->pb);
10921
10922 av_log(c->fc, AV_LOG_TRACE, "grid: grid_rows %d grid_cols %d output_width %d output_height %d\n",
10923 tile_rows, tile_cols, tile_grid->width, tile_grid->height);
10924
10925 avio_seek(s->pb, pos, SEEK_SET);
10926
10928 tile_grid->nb_tiles = grid->nb_tiles;
10929
10930 if (tile_grid->nb_tiles != size)
10931 return AVERROR_INVALIDDATA;
10932
10933 for (int i = 0; i < tile_cols; i++)
10934 coded_width += grid->tile_item_list[i]->width;
10935 for (int i = 0; i < size; i += tile_cols)
10936 coded_height += grid->tile_item_list[i]->height;
10937
10938 if (coded_width > INT_MAX || coded_height > INT_MAX)
10939 return AVERROR_INVALIDDATA;
10940
10941 tile_grid->coded_width = coded_width;
10942 tile_grid->coded_height = coded_height;
10943
10944 tile_grid->offsets = av_calloc(tile_grid->nb_tiles, sizeof(*tile_grid->offsets));
10945 if (!tile_grid->offsets)
10946 return AVERROR(ENOMEM);
10947
10948 while (y < tile_grid->coded_height) {
10949 int left_col = i;
10950
10951 while (x < tile_grid->coded_width) {
10952 if (i == tile_grid->nb_tiles)
10953 return AVERROR_INVALIDDATA;
10954
10955 tile_grid->offsets[i].idx = grid->tile_idx_list[i];
10956 tile_grid->offsets[i].horizontal = x;
10957 tile_grid->offsets[i].vertical = y;
10958
10959 x += grid->tile_item_list[i++]->width;
10960 }
10961
10962 if (x > tile_grid->coded_width) {
10963 av_log(c->fc, AV_LOG_ERROR, "Non uniform HEIF tiles\n");
10964 return AVERROR_INVALIDDATA;
10965 }
10966
10967 x = 0;
10968 y += grid->tile_item_list[left_col]->height;
10969 }
10970
10971 if (y > tile_grid->coded_height || i != tile_grid->nb_tiles) {
10972 av_log(c->fc, AV_LOG_ERROR, "Non uniform HEIF tiles\n");
10973 return AVERROR_INVALIDDATA;
10974 }
10975
10976 return 0;
10977}
10978
10980 AVStreamGroupTileGrid *tile_grid)
10981{
10982 MOVContext *c = s->priv_data;
10983 const HEIFItem *item = grid->item;
10984 uint16_t canvas_fill_value[4];
10985 int64_t offset = 0, pos = avio_tell(s->pb);
10986 int ret = 0, flags;
10987
10988 if (!(s->pb->seekable & AVIO_SEEKABLE_NORMAL)) {
10989 av_log(c->fc, AV_LOG_INFO, "iovl box with non seekable input\n");
10990 return AVERROR_PATCHWELCOME;
10991 }
10992 if (item->is_idat_relative) {
10993 if (!c->idat_offset) {
10994 av_log(c->fc, AV_LOG_ERROR, "missing idat box required by the image overlay\n");
10995 return AVERROR_INVALIDDATA;
10996 }
10997 offset = c->idat_offset;
10998 }
10999
11000 if (offset > INT64_MAX - item->extent_offset)
11001 return AVERROR_INVALIDDATA;
11002
11003 avio_seek(s->pb, item->extent_offset + offset, SEEK_SET);
11004
11005 avio_r8(s->pb); /* version */
11006 flags = avio_r8(s->pb);
11007
11008 for (int i = 0; i < 4; i++)
11009 canvas_fill_value[i] = avio_rb16(s->pb);
11010 av_log(c->fc, AV_LOG_TRACE, "iovl: canvas_fill_value { %u, %u, %u, %u }\n",
11011 canvas_fill_value[0], canvas_fill_value[1],
11012 canvas_fill_value[2], canvas_fill_value[3]);
11013 for (int i = 0; i < 4; i++)
11014 tile_grid->background[i] = canvas_fill_value[i];
11015
11016 /* actual width and height of output image */
11017 tile_grid->width =
11018 tile_grid->coded_width = (flags & 1) ? avio_rb32(s->pb) : avio_rb16(s->pb);
11019 tile_grid->height =
11020 tile_grid->coded_height = (flags & 1) ? avio_rb32(s->pb) : avio_rb16(s->pb);
11021
11022 av_log(c->fc, AV_LOG_TRACE, "iovl: output_width %d, output_height %d\n",
11023 tile_grid->width, tile_grid->height);
11024
11025 tile_grid->nb_tiles = grid->nb_tiles;
11026 tile_grid->offsets = av_malloc_array(tile_grid->nb_tiles, sizeof(*tile_grid->offsets));
11027 if (!tile_grid->offsets) {
11028 ret = AVERROR(ENOMEM);
11029 goto fail;
11030 }
11031
11032 for (int i = 0; i < tile_grid->nb_tiles; i++) {
11033 tile_grid->offsets[i].idx = grid->tile_idx_list[i];
11034 tile_grid->offsets[i].horizontal = (flags & 1) ? avio_rb32(s->pb) : avio_rb16(s->pb);
11035 tile_grid->offsets[i].vertical = (flags & 1) ? avio_rb32(s->pb) : avio_rb16(s->pb);
11036 av_log(c->fc, AV_LOG_TRACE, "iovl: stream_idx[%d] %u, "
11037 "horizontal_offset[%d] %d, vertical_offset[%d] %d\n",
11038 i, tile_grid->offsets[i].idx,
11039 i, tile_grid->offsets[i].horizontal, i, tile_grid->offsets[i].vertical);
11040 }
11041
11042fail:
11043 avio_seek(s->pb, pos, SEEK_SET);
11044
11045 return ret;
11046}
11047
11049 AVPacketSideData **coded_side_data, int *nb_coded_side_data,
11050 const HEIFItem *ref)
11051{
11052 MOVContext *c = s->priv_data;
11053 AVPacketSideData *sd;
11054 AVExifMetadata ifd = { 0 };
11055 AVBufferRef *buf;
11056 int64_t offset = 0, pos = avio_tell(s->pb);
11057 unsigned orientation_id = av_exif_get_tag_id("Orientation");
11058 int err;
11059
11060 if (!(s->pb->seekable & AVIO_SEEKABLE_NORMAL)) {
11061 av_log(c->fc, AV_LOG_WARNING, "Exif metadata with non seekable input\n");
11062 return AVERROR_PATCHWELCOME;
11063 }
11064 if (ref->is_idat_relative) {
11065 if (!c->idat_offset) {
11066 av_log(c->fc, AV_LOG_ERROR, "missing idat box required by the Exif metadata\n");
11067 return AVERROR_INVALIDDATA;
11068 }
11069 offset = c->idat_offset;
11070 }
11071
11072 buf = av_buffer_alloc(ref->extent_length);
11073 if (!buf)
11074 return AVERROR(ENOMEM);
11075
11076 if (offset > INT64_MAX - ref->extent_offset) {
11077 err = AVERROR(ENOMEM);
11078 goto fail;
11079 }
11080
11081 avio_seek(s->pb, ref->extent_offset + offset, SEEK_SET);
11082 err = avio_read(s->pb, buf->data, ref->extent_length);
11083 if (err != ref->extent_length) {
11084 if (err > 0)
11085 err = AVERROR_INVALIDDATA;
11086 goto fail;
11087 }
11088
11089 // HEIF spec states that Exif metadata is informative. The irot item property is
11090 // the normative source of rotation information. So we remove any Orientation tag
11091 // present in the Exif buffer.
11092 err = av_exif_parse_buffer(s, buf->data, ref->extent_length, &ifd, AV_EXIF_T_OFF);
11093 if (err < 0) {
11094 av_log(s, AV_LOG_ERROR, "Unable to parse Exif metadata\n");
11095 goto fail;
11096 }
11097
11098 err = av_exif_remove_entry(s, &ifd, orientation_id, 0);
11099 if (err < 0)
11100 goto fail;
11101 else if (!err)
11102 goto finish;
11103
11104 av_buffer_unref(&buf);
11105 err = av_exif_write(s, &ifd, &buf, AV_EXIF_T_OFF);
11106 if (err < 0)
11107 goto fail;
11108
11109finish:
11110 offset = AV_RB32(buf->data) + 4;
11111 if (offset >= buf->size) {
11112 err = AVERROR_INVALIDDATA;
11113 goto fail;
11114 }
11115 sd = av_packet_side_data_new(coded_side_data, nb_coded_side_data,
11116 AV_PKT_DATA_EXIF, buf->size - offset, 0);
11117 if (!sd) {
11118 err = AVERROR(ENOMEM);
11119 goto fail;
11120 }
11121 memcpy(sd->data, buf->data + offset, buf->size - offset);
11122
11123 err = 0;
11124fail:
11125 av_buffer_unref(&buf);
11126 av_exif_free(&ifd);
11127 avio_seek(s->pb, pos, SEEK_SET);
11128
11129 return err;
11130}
11131
11133{
11134 MOVContext *mov = s->priv_data;
11135
11136 for (int i = 0; i < mov->nb_heif_grid; i++) {
11138 AVStreamGroupTileGrid *tile_grid;
11139 const HEIFGrid *grid = &mov->heif_grid[i];
11140 int err, loop = 1;
11141
11142 if (!stg)
11143 return AVERROR(ENOMEM);
11144
11145 stg->id = grid->item->item_id;
11146 tile_grid = stg->params.tile_grid;
11147
11148 for (int j = 0; j < grid->nb_tiles; j++) {
11149 int tile_id = grid->tile_id_list[j];
11150 int k;
11151
11152 for (k = 0; k < mov->nb_heif_item; k++) {
11153 HEIFItem *item = mov->heif_item[k];
11154 AVStream *st;
11155
11156 if (!item || item->item_id != tile_id)
11157 continue;
11158 st = item->st;
11159 if (!st) {
11160 av_log(s, AV_LOG_WARNING, "HEIF item id %d from grid id %d doesn't "
11161 "reference a stream\n",
11162 tile_id, grid->item->item_id);
11164 loop = 0;
11165 break;
11166 }
11167
11168 grid->tile_item_list[j] = item;
11169 grid->tile_idx_list[j] = stg->nb_streams;
11170
11171 err = avformat_stream_group_add_stream(stg, st);
11172 if (err < 0) {
11173 int l;
11174 if (err != AVERROR(EEXIST))
11175 return err;
11176
11177 for (l = 0; l < stg->nb_streams; l++)
11178 if (stg->streams[l]->index == st->index)
11179 break;
11180 av_assert0(l < stg->nb_streams);
11181 grid->tile_idx_list[j] = l;
11182 }
11183
11184 if (item->item_id != mov->primary_item_id)
11186 break;
11187 }
11188
11189 if (k == mov->nb_heif_item) {
11191 av_log(s, AV_LOG_WARNING, "HEIF item id %d referenced by grid id %d doesn't "
11192 "exist\n",
11193 tile_id, grid->item->item_id);
11195 loop = 0;
11196 }
11197 if (!loop)
11198 break;
11199 }
11200
11201 if (!loop)
11202 continue;
11203
11204 switch (grid->item->type) {
11205 case MKTAG('g','r','i','d'):
11206 err = read_image_grid(s, grid, tile_grid);
11207 break;
11208 case MKTAG('i','o','v','l'):
11209 err = read_image_iovl(s, grid, tile_grid);
11210 break;
11211 default:
11212 av_assert0(0);
11213 }
11214 if (err < 0)
11215 return err;
11216
11217 for (int j = 0; j < grid->item->nb_iref_list; j++) {
11218 HEIFItem *ref = get_heif_item(mov, grid->item->iref_list[j].item_id);
11219
11220 av_assert0(ref);
11221 switch(ref->type) {
11222 case MKTAG('E','x','i','f'):
11223 err = mov_parse_exif_item(s, &tile_grid->coded_side_data,
11224 &tile_grid->nb_coded_side_data, ref);
11225 if (err < 0 && (s->error_recognition & AV_EF_EXPLODE))
11226 return err;
11227 break;
11228 default:
11229 break;
11230 }
11231 }
11232
11233 /* rotation */
11234 if (grid->item->rotation || grid->item->hflip || grid->item->vflip) {
11236 &tile_grid->nb_coded_side_data, grid->item);
11237 if (err < 0)
11238 return err;
11239 }
11240
11241 /* ICC profile */
11242 if (grid->item->icc_profile_size) {
11244 &tile_grid->nb_coded_side_data, grid->item);
11245 if (err < 0)
11246 return err;
11247 }
11248
11249 if (grid->item->name)
11250 av_dict_set(&stg->metadata, "title", grid->item->name, 0);
11251 if (grid->item->item_id == mov->primary_item_id)
11253 }
11254
11255 return 0;
11256}
11257
11259{
11260 MOVContext *mov = s->priv_data;
11261 int err;
11262
11263 for (int i = 0; i < mov->nb_heif_item; i++) {
11264 HEIFItem *item = mov->heif_item[i];
11265 MOVStreamContext *sc;
11266 AVStream *st;
11267 int64_t offset = 0;
11268
11269 if (!item)
11270 continue;
11271 if (!item->st) {
11272 continue;
11273 }
11274 if (item->is_idat_relative) {
11275 if (!mov->idat_offset) {
11276 av_log(s, AV_LOG_ERROR, "Missing idat box for item %d\n", item->item_id);
11277 return AVERROR_INVALIDDATA;
11278 }
11279 offset = mov->idat_offset;
11280 }
11281
11282 st = item->st;
11283 sc = st->priv_data;
11284 st->codecpar->width = item->width;
11285 st->codecpar->height = item->height;
11286
11287 sc->sample_size = sc->stsz_sample_size = item->extent_length;
11288 sc->sample_count = 1;
11289
11290 err = sanity_checks(s, sc, st->index);
11291 if (err)
11292 return AVERROR_INVALIDDATA;
11293
11294 if (offset > INT64_MAX - item->extent_offset)
11295 return AVERROR_INVALIDDATA;
11296
11297 sc->chunk_offsets[0] = item->extent_offset + offset;
11298
11299 if (item->item_id == mov->primary_item_id)
11301
11302 for (int j = 0; j < item->nb_iref_list; j++) {
11303 HEIFItem *ref = get_heif_item(mov, item->iref_list[j].item_id);
11304
11305 av_assert0(ref);
11306 switch(ref->type) {
11307 case MKTAG('E','x','i','f'):
11310 if (err < 0 && (s->error_recognition & AV_EF_EXPLODE))
11311 return err;
11312 break;
11313 default:
11314 break;
11315 }
11316 }
11317
11318 if (item->rotation || item->hflip || item->vflip) {
11320 &st->codecpar->nb_coded_side_data, item);
11321 if (err < 0)
11322 return err;
11323 }
11324
11325 mov_build_index(mov, st);
11326 }
11327
11328 if (mov->nb_heif_grid) {
11329 err = mov_parse_tiles(s);
11330 if (err < 0)
11331 return err;
11332 }
11333
11334 return 0;
11335}
11336
11338{
11339 int err;
11340
11341 for (int i = 0; i < s->nb_streams; i++) {
11342 AVStreamGroup *stg;
11343 const AVDictionaryEntry *tcr;
11344 AVStream *st = s->streams[i];
11345
11346 if (st->codecpar->codec_tag != MKTAG('t','m','c','d'))
11347 continue;
11348
11350 if (!stg)
11351 return AVERROR(ENOMEM);
11352
11353 stg->id = st->id;
11354 tcr = av_dict_get(st->metadata, "timecode", NULL, 0);
11355
11356 for (int j = 0; j < s->nb_streams; j++) {
11357 AVStream *st2 = s->streams[j];
11358 MOVStreamContext *sc2 = st2->priv_data;
11359 MovTref *tag = mov_find_tref_tag(sc2, MKTAG('t','m','c','d'));
11360
11361 if (!tag)
11362 continue;
11363
11364 for (int k = 0; k < tag->nb_id; k++) {
11365 if (tag->id[k] != st->id)
11366 continue;
11367
11368 err = avformat_stream_group_add_stream(stg, st2);
11369 if (err < 0)
11370 return err;
11371
11372 if (tcr)
11373 av_dict_set(&st2->metadata, "timecode", tcr->value, AV_DICT_DONT_OVERWRITE);
11374 }
11375 }
11376
11377 if (!stg->nb_streams) {
11379 continue;
11380 }
11381
11382 err = avformat_stream_group_add_stream(stg, st);
11383 if (err < 0)
11384 return err;
11385
11386 stg->params.tref->metadata_index = stg->nb_streams - 1;
11387 }
11389
11390 return 0;
11391}
11392
11394 uint32_t *tref_id, int nb_tref_id, int first_index)
11395{
11396 if (!nb_tref_id)
11397 return NULL;
11398
11399 for (int i = first_index; i < s->nb_streams; i++)
11400 for (int j = 0; j < nb_tref_id; j++)
11401 if (s->streams[i]->index != st->index &&
11402 s->streams[i]->id == tref_id[j])
11403 return s->streams[i];
11404
11405 return NULL;
11406}
11407
11409{
11410 static const uint32_t tref_tags[] = {
11411 MKTAG('c','d','s','c'),
11412 MKTAG('r','n','d','r'),
11413 };
11414
11415 int err;
11416
11417 // Don't try to add a group if there's only one track
11418 if (s->nb_streams <= 1)
11419 return 0;
11420
11421 for (int i = 0; i < s->nb_streams; i++) {
11422 AVStream *st = s->streams[i];
11423 MOVStreamContext *sc = st->priv_data;
11424
11425 for (int c = 0; c < FF_ARRAY_ELEMS(tref_tags); c++) {
11426 AVStreamGroup *stg;
11427 AVStream *st_ref;
11428 MovTref *tag = mov_find_tref_tag(sc, tref_tags[c]);
11429
11430 if (!tag)
11431 continue;
11432
11433 st_ref = mov_find_reference_track(s, st, tag->id, tag->nb_id, 0);
11434 if (!st_ref) {
11435 av_log(s, AV_LOG_WARNING, "Failed to find referenced stream\n");
11436 continue;
11437 }
11438
11440 if (!stg)
11441 return AVERROR(ENOMEM);
11442
11443 stg->id = st_ref->id;
11444
11445 err = avformat_stream_group_add_stream(stg, st_ref);
11446 if (err < 0)
11447 return err;
11448
11449 err = avformat_stream_group_add_stream(stg, st);
11450 if (err < 0)
11451 return err;
11452
11453 stg->params.tref->metadata_index = stg->nb_streams - 1;
11454 }
11455 }
11456
11457 return 0;
11458}
11459
11461{
11462 int err;
11463
11464 // Don't try to add a group if there's only one track
11465 if (s->nb_streams <= 1)
11466 return 0;
11467
11468 for (int i = 0; i < s->nb_streams; i++) {
11469 AVStreamGroup *stg;
11470 AVStream *st = s->streams[i];
11471 AVStream *st_base;
11472 MOVStreamContext *sc = st->priv_data;
11473 MovTref *tag = mov_find_tref_tag(sc, MKTAG('s','b','a','s'));
11474 int j = 0;
11475
11476 /* Find an enhancement stream. */
11477 if (st->codecpar->codec_id != AV_CODEC_ID_LCEVC || !tag)
11478 continue;
11479
11481 if (!stg)
11482 return AVERROR(ENOMEM);
11483
11484 stg->id = st->id;
11487
11488 while (st_base = mov_find_reference_track(s, st, tag->id, tag->nb_id, j)) {
11489 err = avformat_stream_group_add_stream(stg, st_base);
11490 if (err < 0)
11491 return err;
11492
11493 j = st_base->index + 1;
11494 }
11495 if (!j) {
11496 int loglevel = (s->error_recognition & AV_EF_EXPLODE) ? AV_LOG_ERROR : AV_LOG_WARNING;
11497 av_log(s, loglevel, "Failed to find base stream for LCEVC stream\n");
11499 if (s->error_recognition & AV_EF_EXPLODE)
11500 return AVERROR_INVALIDDATA;
11501 continue;
11502 }
11503
11504 err = avformat_stream_group_add_stream(stg, st);
11505 if (err < 0)
11506 return err;
11507
11508 stg->params.layered_video->el_index = stg->nb_streams - 1;
11509 }
11510
11511 return 0;
11512}
11513
11515{
11516 int err;
11517
11518 if (s->nb_streams <= 1)
11519 return 0;
11520
11521 /* Identify legacy dual-track Dolby Vision profile 7 carriage per Annex
11522 * C of "Dolby Vision Streams Within the ISO Base Media File Format",
11523 * v2.7.1. The 'vdep' track reference type is shared with depth video
11524 * and multi-view dependencies. The spec-mandated DV-specific sample
11525 * entry combined with the dvcC configuration record disambiguates
11526 * those uses. */
11527 for (int i = 0; i < s->nb_streams; i++) {
11528 AVStreamGroup *stg;
11529 AVStream *st = s->streams[i];
11530 AVStream *st_base;
11531 MOVStreamContext *sc = st->priv_data;
11532 MovTref *tag = mov_find_tref_tag(sc, MKTAG('v','d','e','p'));
11533 const AVPacketSideData *sd;
11535
11536 if (st->codecpar->codec_id != AV_CODEC_ID_HEVC || !tag)
11537 continue;
11538
11539 if (st->codecpar->codec_tag != MKTAG('d','v','h','e') &&
11540 st->codecpar->codec_tag != MKTAG('d','v','h','1'))
11541 continue;
11542
11546 if (!sd)
11547 continue;
11548 dovi = (const AVDOVIDecoderConfigurationRecord *)sd->data;
11549
11550 /* EL track of a dual-track stream: rpu_present_flag = 1,
11551 * el_present_flag = 1, bl_present_flag = 0, dv_profile = 7. */
11552 if (dovi->dv_profile != 7 || !dovi->rpu_present_flag ||
11553 !dovi->el_present_flag || dovi->bl_present_flag)
11554 continue;
11555
11556 st_base = mov_find_reference_track(s, st, tag->id, tag->nb_id, 0);
11557 if (!st_base) {
11558 int loglevel = (s->error_recognition & AV_EF_EXPLODE) ? AV_LOG_ERROR : AV_LOG_WARNING;
11559 av_log(s, loglevel, "Failed to find base layer for Dolby Vision EL stream\n");
11560 if (s->error_recognition & AV_EF_EXPLODE)
11561 return AVERROR_INVALIDDATA;
11562 continue;
11563 }
11564
11566 if (!stg)
11567 return AVERROR(ENOMEM);
11568
11569 stg->id = st->id;
11570
11571 err = avformat_stream_group_add_stream(stg, st_base);
11572 if (err < 0)
11573 return err;
11574
11575 err = avformat_stream_group_add_stream(stg, st);
11576 if (err < 0)
11577 return err;
11578
11579 stg->params.layered_video->el_index = stg->nb_streams - 1;
11580 stg->params.layered_video->width = st_base->codecpar->width;
11581 stg->params.layered_video->height = st_base->codecpar->height;
11582 }
11583
11584 return 0;
11585}
11586
11588{
11589 int highest_id = 0, lowest_iamf_id = INT_MAX;
11590
11591 for (int i = 0; i < s->nb_streams; i++) {
11592 const AVStream *st = s->streams[i];
11593 const MOVStreamContext *sc = st->priv_data;
11594 if (!sc->iamf)
11595 highest_id = FFMAX(highest_id, st->id);
11596 }
11597
11598 for (int i = 0; i < s->nb_stream_groups; i++) {
11599 AVStreamGroup *stg = s->stream_groups[i];
11601 continue;
11602 for (int j = 0; j < stg->nb_streams; j++) {
11603 AVStream *st = stg->streams[j];
11604 lowest_iamf_id = FFMIN(lowest_iamf_id, st->id);
11605 }
11606 }
11607
11608 if (highest_id < lowest_iamf_id)
11609 return;
11610
11611 highest_id += !lowest_iamf_id;
11612 for (int i = 0; highest_id > 1 && i < s->nb_stream_groups; i++) {
11613 AVStreamGroup *stg = s->stream_groups[i];
11615 continue;
11616 for (int j = 0; j < stg->nb_streams; j++) {
11617 AVStream *st = stg->streams[j];
11618 MOVStreamContext *sc = st->priv_data;
11619 st->id += highest_id;
11620 sc->iamf_stream_offset = highest_id;
11621 }
11622 }
11623}
11624
11626{
11627 MOVContext *mov = s->priv_data;
11628 AVIOContext *pb = s->pb;
11629 int j, err;
11630 MOVAtom atom = { AV_RL32("root") };
11631 int i;
11632
11633 mov->fc = s;
11634 mov->trak_index = -1;
11635 mov->primary_item_id = -1;
11636 mov->cur_item_id = -1;
11637 /* .mov and .mp4 aren't streamable anyway (only progressive download if moov is before mdat) */
11639 atom.size = avio_size(pb);
11640 else
11641 atom.size = INT64_MAX;
11642
11643 /* check MOV header */
11644 do {
11645 if (mov->moov_retry)
11646 avio_seek(pb, 0, SEEK_SET);
11647 if ((err = mov_read_default(mov, pb, atom)) < 0) {
11648 av_log(s, AV_LOG_ERROR, "error reading header\n");
11649 return err;
11650 }
11651 } while ((pb->seekable & AVIO_SEEKABLE_NORMAL) &&
11652 !mov->found_moov && (!mov->found_iloc || !mov->found_iinf) && !mov->moov_retry++);
11653 if (!mov->found_moov && !mov->found_iloc && !mov->found_iinf) {
11654 av_log(s, AV_LOG_ERROR, "moov atom not found\n");
11655 return AVERROR_INVALIDDATA;
11656 }
11657 av_log(mov->fc, AV_LOG_TRACE, "on_parse_exit_offset=%"PRId64"\n", avio_tell(pb));
11658
11659 if (mov->found_iloc && mov->found_iinf) {
11660 err = mov_parse_heif_items(s);
11661 if (err < 0)
11662 return err;
11663 }
11664 // prevent iloc and iinf boxes from being parsed while reading packets.
11665 // this is needed because an iinf box may have been parsed but ignored
11666 // for having old infe boxes which create no streams.
11667 mov->found_iloc = mov->found_iinf = 1;
11668
11669 if (pb->seekable & AVIO_SEEKABLE_NORMAL) {
11670 if (mov->nb_chapter_tracks > 0 && !mov->ignore_chapters)
11672 for (i = 0; i < s->nb_streams; i++)
11673 if (s->streams[i]->codecpar->codec_tag == AV_RL32("tmcd")) {
11674 mov_read_timecode_track(s, s->streams[i]);
11675 } else if (s->streams[i]->codecpar->codec_tag == AV_RL32("rtmd")) {
11676 mov_read_rtmd_track(s, s->streams[i]);
11677 }
11678 }
11679
11680 /* Create metadata stream groups. */
11682 if (err < 0)
11683 return err;
11684
11685 /* copy timecode metadata from tmcd tracks to the related video streams */
11687 if (err < 0)
11688 return err;
11689
11690 /* Create LCEVC stream groups. */
11692 if (err < 0)
11693 return err;
11694
11695 /* Create Dolby Vision Profile 7 stream groups. */
11697 if (err < 0)
11698 return err;
11699
11700 for (i = 0; i < s->nb_streams; i++) {
11701 AVStream *st = s->streams[i];
11702 FFStream *const sti = ffstream(st);
11703 MOVStreamContext *sc = st->priv_data;
11704 uint32_t dvdsub_clut[FF_DVDCLUT_CLUT_LEN] = {0};
11705 fix_timescale(mov, sc);
11706
11707 /* Set the primary extradata based on the first Sample if it doesn't reference the first stsd entry. */
11708 if (sc->stsc_count && sc->extradata_size && !sc->iamf &&
11709 sc->stsc_data[0].id > 1 && sc->stsc_data[0].id <= sc->stsd_count) {
11710 sc->last_stsd_index = sc->stsc_data[0].id - 1;
11713 if (sc->extradata_size[sc->last_stsd_index]) {
11715 if (!st->codecpar->extradata)
11716 return AVERROR(ENOMEM);
11718 }
11719 }
11720
11724 }
11727 sc->time_scale*(int64_t)sc->nb_frames_for_fps, sc->duration_for_fps, INT_MAX);
11729 if (st->codecpar->width <= 0 || st->codecpar->height <= 0) {
11730 st->codecpar->width = sc->width;
11731 st->codecpar->height = sc->height;
11732 }
11735
11736 for (j = 0; j < FF_DVDCLUT_CLUT_LEN; j++)
11737 dvdsub_clut[j] = AV_RB32(st->codecpar->extradata + j * 4);
11738
11739 err = ff_dvdclut_yuv_to_rgb(dvdsub_clut, FF_DVDCLUT_CLUT_SIZE);
11740 if (err < 0)
11741 return err;
11742
11744 st->codecpar->extradata_size = 0;
11745
11747 st->codecpar);
11748 if (err < 0)
11749 return err;
11750 }
11751 }
11752 if (mov->handbrake_version &&
11753 mov->handbrake_version <= 1000000*0 + 1000*10 + 2 && // 0.10.2
11755 av_log(s, AV_LOG_VERBOSE, "Forcing full parsing for mp3 stream\n");
11757 }
11758 }
11759
11760 if (mov->trex_data || mov->use_mfra_for > 0) {
11761 for (i = 0; i < s->nb_streams; i++) {
11762 AVStream *st = s->streams[i];
11763 MOVStreamContext *sc = st->priv_data;
11764 if (sc->duration_for_fps > 0) {
11765 /* Akin to sc->data_size * 8 * sc->time_scale / sc->duration_for_fps but accounting for overflows. */
11767 if (st->codecpar->bit_rate == INT64_MIN) {
11768 av_log(s, AV_LOG_WARNING, "Overflow during bit rate calculation %"PRId64" * 8 * %d\n",
11769 sc->data_size, sc->time_scale);
11770 st->codecpar->bit_rate = 0;
11771 if (s->error_recognition & AV_EF_EXPLODE)
11772 return AVERROR_INVALIDDATA;
11773 }
11774 }
11775 }
11776 }
11777
11778 for (i = 0; i < mov->bitrates_count && i < s->nb_streams; i++) {
11779 if (mov->bitrates[i]) {
11780 s->streams[i]->codecpar->bit_rate = mov->bitrates[i];
11781 }
11782 }
11783
11785
11786 for (i = 0; i < s->nb_streams; i++) {
11787 AVStream *st = s->streams[i];
11788 MOVStreamContext *sc = st->priv_data;
11789
11790 switch (st->codecpar->codec_type) {
11791 case AVMEDIA_TYPE_AUDIO:
11792 err = ff_replaygain_export(st, s->metadata);
11793 if (err < 0)
11794 return err;
11795 break;
11796 case AVMEDIA_TYPE_VIDEO:
11797 if (sc->display_matrix) {
11800 (uint8_t*)sc->display_matrix, sizeof(int32_t) * 9, 0))
11801 return AVERROR(ENOMEM);
11802
11803 sc->display_matrix = NULL;
11804 }
11805 if (sc->stereo3d) {
11808 (uint8_t *)sc->stereo3d, sc->stereo3d_size, 0))
11809 return AVERROR(ENOMEM);
11810
11811 sc->stereo3d = NULL;
11812 }
11813 if (sc->spherical) {
11816 (uint8_t *)sc->spherical, sc->spherical_size, 0))
11817 return AVERROR(ENOMEM);
11818
11819 sc->spherical = NULL;
11820 }
11821 if (sc->mastering) {
11824 (uint8_t *)sc->mastering, sc->mastering_size, 0))
11825 return AVERROR(ENOMEM);
11826
11827 sc->mastering = NULL;
11828 }
11829 if (sc->coll) {
11832 (uint8_t *)sc->coll, sc->coll_size, 0))
11833 return AVERROR(ENOMEM);
11834
11835 sc->coll = NULL;
11836 }
11837 if (sc->ambient) {
11840 (uint8_t *) sc->ambient, sc->ambient_size, 0))
11841 return AVERROR(ENOMEM);
11842
11843 sc->ambient = NULL;
11844 }
11845 break;
11846 }
11847 }
11848
11850
11852
11853 for (i = 0; i < mov->frag_index.nb_items; i++)
11854 if (mov->frag_index.item[i].moof_offset <= mov->fragment.moof_offset)
11855 mov->frag_index.item[i].headers_read = 1;
11856
11857 return 0;
11858}
11859
11861{
11863 int64_t best_dts = INT64_MAX;
11864 int i;
11865 MOVContext *mov = s->priv_data;
11866 int no_interleave = !mov->interleaved_read || !(s->pb->seekable & AVIO_SEEKABLE_NORMAL);
11867 for (i = 0; i < s->nb_streams; i++) {
11868 AVStream *avst = s->streams[i];
11869 FFStream *const avsti = ffstream(avst);
11870 MOVStreamContext *msc = avst->priv_data;
11871 if (msc->pb && msc->current_sample < avsti->nb_index_entries) {
11872 AVIndexEntry *current_sample = &avsti->index_entries[msc->current_sample];
11873 int64_t dts = av_rescale(current_sample->timestamp, AV_TIME_BASE, msc->time_scale);
11874 uint64_t dtsdiff = best_dts > dts ? best_dts - (uint64_t)dts : ((uint64_t)dts - best_dts);
11875 av_log(s, AV_LOG_TRACE, "stream %d, sample %d, dts %"PRId64"\n", i, msc->current_sample, dts);
11876 if (!sample || (no_interleave && current_sample->pos < sample->pos) ||
11877 ((s->pb->seekable & AVIO_SEEKABLE_NORMAL) &&
11878 ((msc->pb != s->pb && dts < best_dts) || (msc->pb == s->pb && dts != AV_NOPTS_VALUE &&
11879 ((dtsdiff <= AV_TIME_BASE && current_sample->pos < sample->pos) ||
11880 (dtsdiff > AV_TIME_BASE && dts < best_dts && mov->interleaved_read)))))) {
11881 sample = current_sample;
11882 best_dts = dts;
11883 *st = avst;
11884 }
11885 }
11886 }
11887 return sample;
11888}
11889
11890static int should_retry(AVIOContext *pb, int error_code) {
11891 if (error_code == AVERROR_EOF || avio_feof(pb))
11892 return 0;
11893
11894 return 1;
11895}
11896
11898{
11899 int ret;
11900 MOVContext *mov = s->priv_data;
11901
11902 if (index >= 0 && index < mov->frag_index.nb_items)
11903 target = mov->frag_index.item[index].moof_offset;
11904 if (target >= 0 && avio_seek(s->pb, target, SEEK_SET) != target) {
11905 av_log(mov->fc, AV_LOG_ERROR, "root atom offset 0x%"PRIx64": partial file\n", target);
11906 return AVERROR_INVALIDDATA;
11907 }
11908
11909 mov->next_root_atom = 0;
11910 if ((index < 0 && target >= 0) || index >= mov->frag_index.nb_items)
11911 index = search_frag_moof_offset(&mov->frag_index, target);
11912 if (index >= 0 && index < mov->frag_index.nb_items &&
11913 mov->frag_index.item[index].moof_offset == target) {
11914 if (index + 1 < mov->frag_index.nb_items)
11917 return 0;
11919 }
11920
11921 mov->found_mdat = 0;
11922
11923 ret = mov_read_default(mov, s->pb, (MOVAtom){ AV_RL32("root"), INT64_MAX });
11924 if (ret < 0)
11925 return ret;
11926 if (avio_feof(s->pb))
11927 return AVERROR_EOF;
11928 av_log(s, AV_LOG_TRACE, "read fragments, offset 0x%"PRIx64"\n", avio_tell(s->pb));
11929
11930 return 1;
11931}
11932
11934{
11935 MOVStreamContext *sc = st->priv_data;
11936 uint8_t *side, *extradata;
11937 int extradata_size;
11938
11939 /* Save the current index. */
11940 sc->last_stsd_index = sc->stsc_data[sc->stsc_index].id - 1;
11941
11942 /* Notify the decoder that extradata changed. */
11943 extradata_size = sc->extradata_size[sc->last_stsd_index];
11944 extradata = sc->extradata[sc->last_stsd_index];
11945 if (st->discard != AVDISCARD_ALL && extradata_size > 0 && extradata) {
11948 extradata_size);
11949 if (!side)
11950 return AVERROR(ENOMEM);
11951 memcpy(side, extradata, extradata_size);
11952 }
11953
11954 return 0;
11955}
11956
11957static int get_eia608_packet(AVIOContext *pb, AVPacket *pkt, int src_size)
11958{
11959 /* We can't make assumptions about the structure of the payload,
11960 because it may include multiple cdat and cdt2 samples. */
11961 const uint32_t cdat = AV_RB32("cdat");
11962 const uint32_t cdt2 = AV_RB32("cdt2");
11963 int ret, out_size = 0;
11964
11965 /* a valid payload must have size, 4cc, and at least 1 byte pair: */
11966 if (src_size < 10)
11967 return AVERROR_INVALIDDATA;
11968
11969 /* avoid an int overflow: */
11970 if ((src_size - 8) / 2 >= INT_MAX / 3)
11971 return AVERROR_INVALIDDATA;
11972
11973 ret = av_new_packet(pkt, ((src_size - 8) / 2) * 3);
11974 if (ret < 0)
11975 return ret;
11976
11977 /* parse and re-format the c608 payload in one pass. */
11978 while (src_size >= 10) {
11979 const uint32_t atom_size = avio_rb32(pb);
11980 const uint32_t atom_type = avio_rb32(pb);
11981 const uint32_t data_size = atom_size - 8;
11982 const uint8_t cc_field =
11983 atom_type == cdat ? 1 :
11984 atom_type == cdt2 ? 2 :
11985 0;
11986
11987 /* account for bytes consumed for atom size and type. */
11988 src_size -= 8;
11989
11990 /* make sure the data size stays within the buffer boundaries. */
11991 if (data_size < 2 || data_size > src_size) {
11992 ret = AVERROR_INVALIDDATA;
11993 break;
11994 }
11995
11996 /* make sure the data size is consistent with N byte pairs. */
11997 if (data_size % 2 != 0) {
11998 ret = AVERROR_INVALIDDATA;
11999 break;
12000 }
12001
12002 if (!cc_field) {
12003 /* neither cdat or cdt2 ... skip it */
12004 avio_skip(pb, data_size);
12005 src_size -= data_size;
12006 continue;
12007 }
12008
12009 for (uint32_t i = 0; i < data_size; i += 2) {
12010 pkt->data[out_size] = (0x1F << 3) | (1 << 2) | (cc_field - 1);
12011 pkt->data[out_size + 1] = avio_r8(pb);
12012 pkt->data[out_size + 2] = avio_r8(pb);
12013 out_size += 3;
12014 src_size -= 2;
12015 }
12016 }
12017
12018 if (src_size > 0)
12019 /* skip any remaining unread portion of the input payload */
12020 avio_skip(pb, src_size);
12021
12023 return ret;
12024}
12025
12027 int64_t current_index, AVPacket *pkt)
12028{
12029 MOVContext *mov = s->priv_data;
12030 MOVStreamContext *sc = st->priv_data;
12031
12032 pkt->stream_index = sc->ffindex;
12033 pkt->dts = sample->timestamp;
12034 if (sample->flags & AVINDEX_DISCARD_FRAME) {
12035 pkt->flags |= AV_PKT_FLAG_DISCARD;
12036 }
12037 if (sc->stts_count && sc->tts_index < sc->tts_count)
12038 pkt->duration = sc->tts_data[sc->tts_index].duration;
12039 if (sc->ctts_count && sc->tts_index < sc->tts_count) {
12040 pkt->pts = av_sat_add64(pkt->dts, av_sat_add64(sc->dts_shift, sc->tts_data[sc->tts_index].offset));
12041 } else {
12042 if (pkt->duration == 0) {
12043 int64_t next_dts = (sc->current_sample < ffstream(st)->nb_index_entries) ?
12045 if (next_dts >= pkt->dts)
12046 pkt->duration = next_dts - pkt->dts;
12047 }
12048 pkt->pts = pkt->dts;
12049 }
12050
12052 sc->current_sample >= ffstream(st)->nb_index_entries) {
12053 int64_t pts = av_rescale_q(pkt->pts, st->time_base, (AVRational){ 1, st->codecpar->sample_rate });
12054 int64_t total = av_rescale_q(st->duration, st->time_base, (AVRational){ 1, st->codecpar->sample_rate });
12055 int64_t duration = pkt->duration;
12056
12057 if (st->duration < pkt->pts) {
12058 duration = 0;
12059 } else
12060 duration = FFMIN(duration, (uint64_t)st->duration - pkt->pts);
12061
12062 duration = av_rescale_q(duration, st->time_base, (AVRational){ 1, st->codecpar->sample_rate });
12063
12064 if (!ffstream(st)->first_discard_sample)
12066 if (!ffstream(st)->last_discard_sample)
12067 ffstream(st)->last_discard_sample = total;
12068 }
12069
12070 if (sc->tts_data && sc->tts_index < sc->tts_count) {
12071 /* update tts context */
12072 sc->tts_sample++;
12073 if (sc->tts_index < sc->tts_count &&
12074 sc->tts_data[sc->tts_index].count == sc->tts_sample) {
12075 sc->tts_index++;
12076 sc->tts_sample = 0;
12077 }
12078 }
12079
12080 if (sc->sdtp_data && sc->current_sample <= sc->sdtp_count) {
12081 uint8_t sample_flags = sc->sdtp_data[sc->current_sample - 1];
12082 uint8_t sample_is_depended_on = (sample_flags >> 2) & 0x3;
12083 pkt->flags |= sample_is_depended_on == MOV_SAMPLE_DEPENDENCY_NO ? AV_PKT_FLAG_DISPOSABLE : 0;
12084 }
12085 pkt->flags |= sample->flags & AVINDEX_KEYFRAME ? AV_PKT_FLAG_KEY : 0;
12086 pkt->pos = sample->pos;
12087
12088 /* Multiple stsd handling. */
12089 if (sc->stsc_data) {
12090 if (sc->stsc_data[sc->stsc_index].id > 0 &&
12091 sc->stsc_data[sc->stsc_index].id - 1 < sc->stsd_count &&
12092 sc->stsc_data[sc->stsc_index].id - 1 != sc->last_stsd_index) {
12093 int ret = mov_change_extradata(st, pkt);
12094 if (ret < 0)
12095 return ret;
12096 }
12097
12098 /* Update the stsc index for the next sample */
12099 sc->stsc_sample++;
12102 sc->stsc_index++;
12103 sc->stsc_sample = 0;
12104 }
12105 }
12106
12107 return 0;
12108}
12109
12111{
12112 MOVContext *mov = s->priv_data;
12113 MOVStreamContext *sc;
12115 AVStream *st = NULL;
12116 FFStream *avsti = NULL;
12117 int64_t current_index;
12118 int ret;
12119 int i;
12120 mov->fc = s;
12121 retry:
12122 if (s->pb->pos == 0) {
12123
12124 // Discard current fragment index
12125 if (mov->frag_index.allocated_size > 0) {
12126 for(int i = 0; i < mov->frag_index.nb_items; i++) {
12128 }
12129 av_freep(&mov->frag_index.item);
12130 mov->frag_index.nb_items = 0;
12131 mov->frag_index.allocated_size = 0;
12132 mov->frag_index.current = -1;
12133 mov->frag_index.complete = 0;
12134 }
12135
12136 for (i = 0; i < s->nb_streams; i++) {
12137 AVStream *avst = s->streams[i];
12138 MOVStreamContext *msc = avst->priv_data;
12139
12140 // Clear current sample
12141 mov_current_sample_set(msc, 0);
12142 msc->tts_index = 0;
12143
12144 // Discard current index entries
12145 avsti = ffstream(avst);
12146 if (avsti->index_entries_allocated_size > 0) {
12147 av_freep(&avsti->index_entries);
12149 avsti->nb_index_entries = 0;
12150 }
12151 }
12152
12153 if ((ret = mov_switch_root(s, -1, -1)) < 0)
12154 return ret;
12155 }
12157 if (!sample || (mov->next_root_atom && sample->pos > mov->next_root_atom)) {
12158 if (!mov->next_root_atom)
12159 return AVERROR_EOF;
12160 if ((ret = mov_switch_root(s, mov->next_root_atom, -1)) < 0)
12161 return ret;
12162 goto retry;
12163 }
12164 sc = st->priv_data;
12165 /* must be done just before reading, to avoid infinite loop on sample */
12166 current_index = sc->current_index;
12168
12169 if (mov->next_root_atom) {
12170 sample->pos = FFMIN(sample->pos, mov->next_root_atom);
12171 sample->size = FFMIN(sample->size, (mov->next_root_atom - sample->pos));
12172 }
12173
12174 if (st->discard != AVDISCARD_ALL || sc->iamf) {
12175 int64_t ret64 = avio_seek(sc->pb, sample->pos, SEEK_SET);
12176 if (ret64 != sample->pos) {
12177 av_log(mov->fc, AV_LOG_ERROR, "stream %d, offset 0x%"PRIx64": partial file\n",
12178 sc->ffindex, sample->pos);
12179 if (should_retry(sc->pb, ret64)) {
12181 } else if (ret64 < 0) {
12182 return (int)ret64;
12183 }
12184 return AVERROR_INVALIDDATA;
12185 }
12186
12187 if (st->discard == AVDISCARD_NONKEY && !(sample->flags & AVINDEX_KEYFRAME)) {
12188 av_log(mov->fc, AV_LOG_DEBUG, "Nonkey frame from stream %d discarded due to AVDISCARD_NONKEY\n", sc->ffindex);
12189 goto retry;
12190 }
12191
12192 if (st->codecpar->codec_id == AV_CODEC_ID_EIA_608 && sample->size > 8)
12193 ret = get_eia608_packet(sc->pb, pkt, sample->size);
12194#if CONFIG_IAMFDEC
12195 else if (sc->iamf) {
12196 int64_t pts, dts, pos, duration;
12197 int flags, size = sample->size;
12198 ret = mov_finalize_packet(s, st, sample, current_index, pkt);
12199 pts = pkt->pts; dts = pkt->dts;
12200 pos = pkt->pos; flags = pkt->flags;
12201 duration = pkt->duration;
12202 while (!ret && size > 0) {
12203 ret = ff_iamf_read_packet(s, sc->iamf, sc->pb, size, sc->iamf_stream_offset, pkt);
12204 if (ret < 0) {
12205 if (should_retry(sc->pb, ret))
12207 return ret;
12208 }
12209 size -= ret;
12210
12211 if (pkt->flags & AV_PKT_FLAG_DISCARD) {
12213 ret = 0;
12214 continue;
12215 }
12216 pkt->pts = pts; pkt->dts = dts;
12217 pkt->pos = pos; pkt->flags |= flags;
12218 pkt->duration = duration;
12219 ret = ff_buffer_packet(s, pkt);
12220 }
12221 if (!ret)
12222 return FFERROR_REDO;
12223 }
12224#endif
12225 else if (st->codecpar->codec_id == AV_CODEC_ID_APV && sample->size > 4) {
12226 uint32_t au_size = avio_rb32(sc->pb);
12227 int explode = !!(mov->fc->error_recognition & AV_EF_EXPLODE);
12228 if (au_size > sample->size - 4) {
12229 av_log(s, explode ? AV_LOG_ERROR : AV_LOG_WARNING,
12230 "APV au_size %u exceeds sample body %d\n",
12231 au_size, sample->size - 4);
12232 if (explode)
12233 return AVERROR_INVALIDDATA;
12234 au_size = sample->size - 4;
12235 }
12236 ret = av_get_packet(sc->pb, pkt, au_size);
12237 } else
12238 ret = av_get_packet(sc->pb, pkt, sample->size);
12239 if (ret < 0) {
12240 if (should_retry(sc->pb, ret)) {
12242 }
12243 return ret;
12244 }
12245#if CONFIG_DV_DEMUXER
12246 if (mov->dv_demux && sc->dv_audio_container) {
12247 ret = avpriv_dv_produce_packet(mov->dv_demux, NULL, pkt->data, pkt->size, pkt->pos);
12249 if (ret < 0)
12250 return ret;
12251 ret = avpriv_dv_get_packet(mov->dv_demux, pkt);
12252 if (ret < 0)
12253 return ret;
12254 }
12255#endif
12256 if (sc->has_palette) {
12257 uint8_t *pal;
12258
12260 if (!pal) {
12261 av_log(mov->fc, AV_LOG_ERROR, "Cannot append palette to packet\n");
12262 } else {
12263 memcpy(pal, sc->palette, AVPALETTE_SIZE);
12264 sc->has_palette = 0;
12265 }
12266 }
12267 if (st->codecpar->codec_id == AV_CODEC_ID_MP3 && !ffstream(st)->need_parsing && pkt->size > 4) {
12268 if (ff_mpa_check_header(AV_RB32(pkt->data)) < 0)
12270 }
12271 }
12272
12273 ret = mov_finalize_packet(s, st, sample, current_index, pkt);
12274 if (ret < 0)
12275 return ret;
12276
12277 if (st->discard == AVDISCARD_ALL)
12278 goto retry;
12279
12280 if (mov->aax_mode)
12281 aax_filter(pkt->data, pkt->size, mov);
12282
12283 ret = cenc_filter(mov, st, sc, pkt, current_index);
12284 if (ret < 0) {
12285 return ret;
12286 }
12287
12288 return 0;
12289}
12290
12292{
12293 MOVContext *mov = s->priv_data;
12294 int index;
12295
12296 if (!mov->frag_index.complete)
12297 return 0;
12298
12299 index = search_frag_timestamp(s, &mov->frag_index, st, timestamp);
12300 if (index < 0)
12301 index = 0;
12302 if (!mov->frag_index.item[index].headers_read)
12303 return mov_switch_root(s, -1, index);
12304 if (index + 1 < mov->frag_index.nb_items)
12306
12307 return 0;
12308}
12309
12311{
12312 // TODO: a bisect search would scale much better
12313 for (int i = 0; i < sc->open_key_samples_count; i++) {
12314 const int oks = sc->open_key_samples[i];
12315 if (oks == sample)
12316 return 1;
12317 if (oks > sample) /* list is monotically increasing so we can stop early */
12318 break;
12319 }
12320 return 0;
12321}
12322
12323/*
12324 * Some key sample may be key frames but not IDR frames, so a random access to
12325 * them may not be allowed.
12326 */
12327static int can_seek_to_key_sample(AVStream *st, int sample, int64_t requested_pts)
12328{
12329 MOVStreamContext *sc = st->priv_data;
12330 FFStream *const sti = ffstream(st);
12331 int64_t key_sample_dts, key_sample_pts;
12332
12334 return 1;
12335
12336 if (sample >= sc->sample_offsets_count)
12337 return 1;
12338
12339 av_assert0(sample >= 0);
12340 key_sample_dts = sti->index_entries[sample].timestamp;
12341 key_sample_pts = key_sample_dts + sc->sample_offsets[sample] + sc->dts_shift;
12342
12343 /*
12344 * If the sample needs to be presented before an open key sample, they may
12345 * not be decodable properly, even though they come after in decoding
12346 * order.
12347 */
12348 if (is_open_key_sample(sc, sample) && key_sample_pts > requested_pts)
12349 return 0;
12350
12351 return 1;
12352}
12353
12354static int mov_seek_stream(AVFormatContext *s, AVStream *st, int64_t timestamp, int flags)
12355{
12356 MOVStreamContext *sc = st->priv_data;
12357 FFStream *const sti = ffstream(st);
12358 int sample, time_sample, ret, requested_sample;
12359 int64_t next_ts;
12360 unsigned int i;
12361
12362 // Here we consider timestamp to be PTS, hence try to offset it so that we
12363 // can search over the DTS timeline.
12364 timestamp -= (sc->min_corrected_pts + sc->dts_shift);
12365
12366 ret = mov_seek_fragment(s, st, timestamp);
12367 if (ret < 0)
12368 return ret;
12369
12370 for (;;) {
12371 sample = av_index_search_timestamp(st, timestamp, flags);
12372 av_log(s, AV_LOG_TRACE, "stream %d, timestamp %"PRId64", sample %d\n", st->index, timestamp, sample);
12373 if (sample < 0 && sti->nb_index_entries && timestamp < sti->index_entries[0].timestamp)
12374 sample = 0;
12375 if (sample < 0) /* not sure what to do */
12376 return AVERROR_INVALIDDATA;
12377
12378 if (!sample || can_seek_to_key_sample(st, sample, timestamp))
12379 break;
12380
12381 next_ts = timestamp - FFMAX(sc->min_sample_duration, 1);
12382 requested_sample = av_index_search_timestamp(st, next_ts, flags);
12383 if (requested_sample < 0)
12384 return AVERROR_INVALIDDATA;
12385
12386 // If we've reached a different sample trying to find a good pts to
12387 // seek to, give up searching because we'll end up seeking back to
12388 // sample 0 on every seek.
12389 if (sample != requested_sample && !can_seek_to_key_sample(st, requested_sample, next_ts))
12390 break;
12391
12392 timestamp = next_ts;
12393 }
12394
12396 av_log(s, AV_LOG_TRACE, "stream %d, found sample %d\n", st->index, sc->current_sample);
12397 /* adjust time to sample index */
12398 if (sc->tts_data) {
12399 time_sample = 0;
12400 for (i = 0; i < sc->tts_count; i++) {
12401 int next = time_sample + sc->tts_data[i].count;
12402 if (next > sc->current_sample) {
12403 sc->tts_index = i;
12404 sc->tts_sample = sc->current_sample - time_sample;
12405 break;
12406 }
12407 time_sample = next;
12408 }
12409 }
12410
12411 /* adjust stsd index */
12412 if (sc->chunk_count) {
12413 time_sample = 0;
12414 for (i = 0; i < sc->stsc_count; i++) {
12415 int64_t next = time_sample + mov_get_stsc_samples(sc, i);
12416 if (next > sc->current_sample) {
12417 sc->stsc_index = i;
12418 sc->stsc_sample = sc->current_sample - time_sample;
12419 break;
12420 }
12421 av_assert0(next == (int)next);
12422 time_sample = next;
12423 }
12424 }
12425
12426 return sample;
12427}
12428
12430{
12431 FFStream *const sti = ffstream(st);
12432 int64_t first_ts = sti->index_entries[0].timestamp;
12434 int64_t off;
12435
12437 return 0;
12438
12439 /* compute skip samples according to stream initial_padding, seek ts and first ts */
12440 off = av_rescale_q(ts - first_ts, st->time_base,
12441 (AVRational){1, st->codecpar->sample_rate});
12442 return FFMAX(st->codecpar->initial_padding - off, 0);
12443}
12444
12445static int mov_read_seek(AVFormatContext *s, int stream_index, int64_t sample_time, int flags)
12446{
12447 MOVContext *mc = s->priv_data;
12448 AVStream *st;
12449 FFStream *sti;
12450 int sample;
12451 int i;
12452
12453 if (stream_index >= s->nb_streams)
12454 return AVERROR_INVALIDDATA;
12455
12456 st = s->streams[stream_index];
12457 sti = ffstream(st);
12458 sample = mov_seek_stream(s, st, sample_time, flags);
12459 if (sample < 0)
12460 return sample;
12461
12462 if (mc->seek_individually) {
12463 /* adjust seek timestamp to found sample timestamp */
12464 int64_t seek_timestamp = sti->index_entries[sample].timestamp;
12466
12467 for (i = 0; i < s->nb_streams; i++) {
12468 AVStream *const st = s->streams[i];
12469 FFStream *const sti = ffstream(st);
12470 int64_t timestamp;
12471
12472 if (stream_index == i)
12473 continue;
12474
12475 timestamp = av_rescale_q(seek_timestamp, s->streams[stream_index]->time_base, st->time_base);
12476 sample = mov_seek_stream(s, st, timestamp, flags);
12477 if (sample >= 0)
12479 }
12480 } else {
12481 for (i = 0; i < s->nb_streams; i++) {
12482 MOVStreamContext *sc;
12483 st = s->streams[i];
12484 sc = st->priv_data;
12486 }
12487 while (1) {
12488 MOVStreamContext *sc;
12490 if (!entry)
12491 return AVERROR_INVALIDDATA;
12492 sc = st->priv_data;
12493 if (sc->ffindex == stream_index && sc->current_sample == sample)
12494 break;
12496 }
12497 }
12498 return 0;
12499}
12500
12501#define OFFSET(x) offsetof(MOVContext, x)
12502#define FLAGS AV_OPT_FLAG_VIDEO_PARAM | AV_OPT_FLAG_DECODING_PARAM
12503static const AVOption mov_options[] = {
12504 {"use_absolute_path",
12505 "allow using absolute path when opening alias, this is a possible security issue",
12506 OFFSET(use_absolute_path), AV_OPT_TYPE_BOOL, {.i64 = 0},
12507 0, 1, FLAGS},
12508 {"seek_streams_individually",
12509 "Seek each stream individually to the closest point",
12510 OFFSET(seek_individually), AV_OPT_TYPE_BOOL, { .i64 = 1 },
12511 0, 1, FLAGS},
12512 {"ignore_editlist", "Ignore the edit list atom.", OFFSET(ignore_editlist), AV_OPT_TYPE_BOOL, {.i64 = 0},
12513 0, 1, FLAGS},
12514 {"advanced_editlist",
12515 "Modify the AVIndex according to the editlists. Use this option to decode in the order specified by the edits.",
12516 OFFSET(advanced_editlist), AV_OPT_TYPE_BOOL, {.i64 = 1},
12517 0, 1, FLAGS},
12518 {"ignore_chapters", "", OFFSET(ignore_chapters), AV_OPT_TYPE_BOOL, {.i64 = 0},
12519 0, 1, FLAGS},
12520 {"use_mfra_for",
12521 "use mfra for fragment timestamps",
12522 OFFSET(use_mfra_for), AV_OPT_TYPE_INT, {.i64 = FF_MOV_FLAG_MFRA_AUTO},
12524 .unit = "use_mfra_for"},
12525 {"auto", "auto", 0, AV_OPT_TYPE_CONST, {.i64 = FF_MOV_FLAG_MFRA_AUTO}, 0, 0,
12526 FLAGS, .unit = "use_mfra_for" },
12527 {"dts", "dts", 0, AV_OPT_TYPE_CONST, {.i64 = FF_MOV_FLAG_MFRA_DTS}, 0, 0,
12528 FLAGS, .unit = "use_mfra_for" },
12529 {"pts", "pts", 0, AV_OPT_TYPE_CONST, {.i64 = FF_MOV_FLAG_MFRA_PTS}, 0, 0,
12530 FLAGS, .unit = "use_mfra_for" },
12531 {"use_tfdt", "use tfdt for fragment timestamps", OFFSET(use_tfdt), AV_OPT_TYPE_BOOL, {.i64 = 1},
12532 0, 1, FLAGS},
12533 { "export_all", "Export unrecognized metadata entries", OFFSET(export_all),
12534 AV_OPT_TYPE_BOOL, { .i64 = 0 }, 0, 1, .flags = FLAGS },
12535 { "export_xmp", "Export full XMP metadata", OFFSET(export_xmp),
12536 AV_OPT_TYPE_BOOL, { .i64 = 0 }, 0, 1, .flags = FLAGS },
12537 { "activation_bytes", "Secret bytes for Audible AAX files", OFFSET(activation_bytes),
12539 { "audible_key", "AES-128 Key for Audible AAXC files", OFFSET(audible_key),
12541 { "audible_iv", "AES-128 IV for Audible AAXC files", OFFSET(audible_iv),
12543 { "audible_fixed_key", // extracted from libAAX_SDK.so and AAXSDKWin.dll files!
12544 "Fixed key used for handling Audible AAX files", OFFSET(audible_fixed_key),
12545 AV_OPT_TYPE_BINARY, {.str="77214d4b196a87cd520045fd20a51d67"},
12546 .flags = AV_OPT_FLAG_DECODING_PARAM },
12547 { "decryption_key", "The default media decryption key (hex)", OFFSET(decryption_default_key), AV_OPT_TYPE_BINARY, .flags = AV_OPT_FLAG_DECODING_PARAM },
12548 { "decryption_keys", "The media decryption keys by KID (hex)", OFFSET(decryption_keys), AV_OPT_TYPE_DICT, .flags = AV_OPT_FLAG_DECODING_PARAM },
12549 { "enable_drefs", "Enable external track support.", OFFSET(enable_drefs), AV_OPT_TYPE_BOOL,
12550 {.i64 = 0}, 0, 1, FLAGS },
12551 { "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 },
12552 { "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 },
12553
12554 { NULL },
12555};
12556
12557static const AVClass mov_class = {
12558 .class_name = "mov,mp4,m4a,3gp,3g2,mj2",
12559 .item_name = av_default_item_name,
12560 .option = mov_options,
12561 .version = LIBAVUTIL_VERSION_INT,
12562};
12563
12565 .p.name = "mov,mp4,m4a,3gp,3g2,mj2",
12566 .p.long_name = NULL_IF_CONFIG_SMALL("QuickTime / MOV"),
12567 .p.priv_class = &mov_class,
12568 .p.extensions = "mov,mp4,m4a,3gp,3g2,mj2,psp,m4v,m4b,ism,ismv,isma,f4v,avif,heic,heif",
12570 .priv_data_size = sizeof(MOVContext),
12571 .flags_internal = FF_INFMT_FLAG_INIT_CLEANUP,
12577};
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:12564
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:399
static int loop
Definition ffplay.c:407
static int64_t start_time
Definition ffplay.c:398
static unsigned int nb_streams
Definition ffprobe.c:353
static int read_header(FFV1Context *f, RangeCoder *c)
Definition ffv1dec.c:578
FLAC (Free Lossless Audio Codec) common stuff.
@ FLAC_METADATA_TYPE_STREAMINFO
Definition flac.h:46
static av_always_inline void flac_parse_block_header(const uint8_t *block_header, int *last, int *type, int *size)
Parse the metadata block parameters from the header.
Definition flac.h:63
#define FLAC_STREAMINFO_SIZE
Definition flac.h:32
#define sample
static av_cold void cleanup(FlashSV2Context *s)
bitstream reader API header.
static unsigned int get_bits_long(GetBitContext *s, int n)
Read 0-32 bits.
Definition get_bits.h:424
static void skip_bits_long(GetBitContext *s, int n)
Skips the specified number of bits.
Definition get_bits.h:280
static void skip_bits(GetBitContext *s, int n)
Definition get_bits.h:383
static unsigned int get_bits(GetBitContext *s, int n)
Read 1-25 bits.
Definition get_bits.h:337
static int init_get_bits(GetBitContext *s, const uint8_t *buffer, int bit_size)
Initialize GetBitContext.
Definition get_bits.h:517
#define fail
Definition test.h:479
#define AV_OPT_FLAG_DECODING_PARAM
A generic parameter which can be set by the user for demuxing or decoding.
Definition opt.h:355
@ AV_OPT_TYPE_CONST
Special option type for declaring named constants.
Definition opt.h:298
@ AV_OPT_TYPE_BINARY
Underlying C type is a uint8_t* that is either NULL or points to an array allocated with the av_mallo...
Definition opt.h:285
@ AV_OPT_TYPE_INT
Underlying C type is int.
Definition opt.h:258
@ AV_OPT_TYPE_DICT
Underlying C type is AVDictionary*.
Definition opt.h:289
@ AV_OPT_TYPE_BOOL
Underlying C type is int.
Definition opt.h:326
#define AV_CH_SIDE_LEFT
#define AV_CH_SIDE_SURROUND_RIGHT
#define AV_CH_WIDE_LEFT
#define AV_CH_WIDE_RIGHT
#define AV_CH_TOP_FRONT_LEFT
#define AV_CH_FRONT_RIGHT
#define AV_CH_SIDE_SURROUND_LEFT
#define AV_CH_TOP_BACK_CENTER
#define AV_CH_FRONT_RIGHT_OF_CENTER
#define AV_CH_BACK_CENTER
#define AV_CH_TOP_FRONT_CENTER
#define AV_CH_FRONT_LEFT_OF_CENTER
#define AV_CH_LOW_FREQUENCY_2
#define AV_CH_BACK_RIGHT
#define AV_CH_TOP_SIDE_RIGHT
#define AV_CH_FRONT_CENTER
#define AV_CH_TOP_BACK_RIGHT
#define AV_CH_TOP_CENTER
#define AV_CH_SIDE_RIGHT
#define AV_CH_BACK_LEFT
#define AV_CH_TOP_SIDE_LEFT
#define AV_CH_TOP_BACK_LEFT
#define AV_CH_LOW_FREQUENCY
#define AV_CH_TOP_FRONT_RIGHT
#define AV_CH_FRONT_LEFT
int av_get_bits_per_sample(enum AVCodecID codec_id)
Return codec bits per sample.
Definition utils.c: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:140
AVBufferRef * av_buffer_alloc(size_t size)
Allocate an AVBuffer of the given size using av_malloc().
Definition buffer.c:78
void av_dict_free(AVDictionary **pm)
Free all the memory allocated for an AVDictionary struct and all keys and values.
Definition dict.c:233
AVDictionaryEntry * av_dict_get(const AVDictionary *m, const char *key, const AVDictionaryEntry *prev, int flags)
Get a dictionary entry with matching key.
Definition dict.c:60
int av_dict_copy(AVDictionary **dst, const AVDictionary *src, int flags)
Copy entries from one AVDictionary struct into another.
Definition dict.c:247
#define AV_DICT_APPEND
If the entry already exists, append to it.
Definition dict.h:82
#define AV_DICT_DONT_STRDUP_VAL
Take ownership of a value that's been allocated with av_malloc() or another memory allocation functio...
Definition dict.h:79
int av_dict_set(AVDictionary **pm, const char *key, const char *value, int flags)
Set the given entry in *pm, overwriting an existing entry.
Definition dict.c:86
#define AV_DICT_DONT_OVERWRITE
Don't overwrite existing entries.
Definition dict.h:81
#define AV_DICT_DONT_STRDUP_KEY
Take ownership of a key that's been allocated with av_malloc() or another memory allocation function.
Definition dict.h:77
#define AV_DICT_MATCH_CASE
Only get an entry with exact-case key match.
Definition dict.h:74
int av_dict_set_int(AVDictionary **pm, const char *key, int64_t value, int flags)
Convenience wrapper for av_dict_set() that converts the value to a string and stores it.
Definition dict.c:177
#define AVERROR_PATCHWELCOME
Not yet implemented in FFmpeg, patches welcome.
Definition error.h:64
#define AVERROR_BUG
Internal bug, also see AVERROR_BUG2.
Definition error.h:52
#define AVERROR_INVALIDDATA
Invalid data found when processing input.
Definition error.h:61
#define AVERROR_EOF
End of file.
Definition error.h:57
#define av_err2str(errnum)
Convenience macro, the return value should be used only directly in function arguments but never stan...
Definition error.h:122
#define AVERROR(e)
Definition error.h:45
void av_iamf_audio_element_free(AVIAMFAudioElement **paudio_element)
Free an AVIAMFAudioElement and all its contents.
Definition iamf.c:338
@ AV_IAMF_AUDIO_ELEMENT_TYPE_SCENE
Definition iamf.h:349
void av_iamf_mix_presentation_free(AVIAMFMixPresentation **pmix_presentation)
Free an AVIAMFMixPresentation and all its contents.
Definition iamf.c:536
#define AV_LOG_TRACE
Extremely verbose debugging, useful for libav* development.
Definition log.h:236
#define AV_LOG_DEBUG
Stuff which is only useful for libav* developers.
Definition log.h:231
#define AV_LOG_WARNING
Something somehow does not look correct.
Definition log.h:216
#define AV_LOG_FATAL
Something went wrong and recovery is not possible.
Definition log.h:204
#define AV_LOG_VERBOSE
Detailed information.
Definition log.h:226
#define AV_LOG_INFO
Standard information.
Definition log.h:221
#define AV_LOG_ERROR
Something went wrong and cannot losslessly be recovered.
Definition log.h:210
const char * av_default_item_name(void *ptr)
Return the context name.
Definition log.c:241
AVRational av_add_q(AVRational b, AVRational c)
Add two rationals.
Definition rational.c:93
AVRational av_mul_q(AVRational b, AVRational c)
Multiply two rationals.
Definition rational.c:80
int av_reduce(int *dst_num, int *dst_den, int64_t num, int64_t den, int64_t max)
Reduce a fraction.
Definition rational.c:35
static AVRational av_make_q(int num, int den)
Create an AVRational.
Definition rational.h:71
AVRational av_d2q(double d, int max)
Convert a double precision floating point number to a rational.
Definition rational.c:110
static double av_q2d(AVRational a)
Convert an AVRational to a double.
Definition rational.h:104
static int av_cmp_q(AVRational a, AVRational b)
Compare two rationals.
Definition rational.h:89
AVRational av_sub_q(AVRational b, AVRational c)
Subtract one rational from another.
Definition rational.c:101
int64_t av_rescale(int64_t a, int64_t b, int64_t c)
Rescale a 64-bit integer with rounding to nearest.
int64_t av_rescale_q(int64_t a, AVRational bq, AVRational cq)
Rescale a 64-bit integer by 2 rational numbers.
void * av_dynarray2_add(void **tab_ptr, int *nb_ptr, size_t elem_size, const uint8_t *elem_data)
Add an element of size elem_size to a dynamic array.
Definition mem.c:447
void * av_fast_realloc(void *ptr, unsigned int *size, size_t min_size)
Reallocate the given buffer if it is not large enough, otherwise do nothing.
Definition mem.c:601
void * av_realloc_array(void *ptr, size_t nmemb, size_t size)
Definition mem.c:318
int av_reallocp(void *ptr, size_t size)
Allocate, reallocate, or free a block of memory through a pointer to a pointer.
Definition mem.c:289
int av_reallocp_array(void *ptr, size_t nmemb, size_t size)
Allocate, reallocate an array through a pointer to a pointer.
Definition mem.c:326
const char * av_get_media_type_string(enum AVMediaType media_type)
Return a string describing the media_type enum, NULL if media_type is unknown.
Definition utils.c:28
char * av_fourcc_make_string(char *buf, uint32_t fourcc)
Fill the provided buffer with a string containing a FourCC (four-character code) representation.
Definition utils.c:54
#define av_fourcc2str(fourcc)
Definition avutil.h:323
#define AV_FOURCC_MAX_STRING_SIZE
Definition avutil.h:321
@ AVMEDIA_TYPE_AUDIO
Definition avutil.h:201
@ AVMEDIA_TYPE_SUBTITLE
Definition avutil.h:203
@ AVMEDIA_TYPE_VIDEO
Definition avutil.h:200
@ AVMEDIA_TYPE_DATA
Opaque data information usually continuous.
Definition avutil.h:202
void av_sha_update(struct AVSHA *ctx, const uint8_t *data, size_t len)
Update hash value.
Definition sha.c:315
struct AVSHA * av_sha_alloc(void)
Allocate an AVSHA context.
Definition sha.c:46
void av_sha_final(AVSHA *ctx, uint8_t *digest)
Finish hashing and output digest value.
Definition sha.c:347
av_cold int av_sha_init(AVSHA *ctx, int bits)
Initialize SHA-1 or SHA-2 hashing.
Definition sha.c:274
size_t av_strlcat(char *dst, const char *src, size_t size)
Append the string src to the string dst, but to a total length of no more than size - 1 bytes,...
Definition avstring.c:95
char * av_stristr(const char *s1, const char *s2)
Locate the first case-independent occurrence in the string haystack of the string needle.
Definition avstring.c:58
int av_strstart(const char *str, const char *pfx, const char **ptr)
Return non-zero if pfx is a prefix of str.
Definition avstring.c:36
#define AV_NOPTS_VALUE
Undefined timestamp value.
Definition avutil.h:247
#define AV_TIME_BASE
Internal time base represented as integer.
Definition avutil.h:253
#define LIBAVUTIL_VERSION_INT
Definition version.h:85
void av_display_rotation_set(int32_t matrix[9], double angle)
Initialize a transformation matrix describing a pure clockwise rotation by the specified angle (in de...
Definition display.c:50
void av_display_matrix_flip(int32_t matrix[9], int hflip, int vflip)
Flip the input matrix horizontally and/or vertically.
Definition display.c:65
AVSphericalMapping * av_spherical_alloc(size_t *size)
Allocate a AVSphericalVideo structure and initialize its fields to default values.
Definition spherical.c:26
AVSphericalProjection
Projection of the video surface(s) on a sphere.
Definition spherical.h:47
@ AV_SPHERICAL_RECTILINEAR
Video frame displays on a flat, rectangular 2D surface.
Definition spherical.h:78
@ AV_SPHERICAL_EQUIRECTANGULAR
Video represents a sphere mapped on a flat surface using equirectangular projection.
Definition spherical.h:52
@ AV_SPHERICAL_EQUIRECTANGULAR_TILE
Video represents a portion of a sphere mapped on a flat surface using equirectangular projection.
Definition spherical.h:68
@ AV_SPHERICAL_CUBEMAP
Video frame is split into 6 faces of a cube, and arranged on a 3x2 layout.
Definition spherical.h:61
@ AV_SPHERICAL_HALF_EQUIRECTANGULAR
Video frame displays as a 180 degree equirectangular projection.
Definition spherical.h:73
@ AV_SPHERICAL_PARAMETRIC_IMMERSIVE
Parametric Immersive projection (Apple).
Definition spherical.h:90
@ AV_SPHERICAL_FISHEYE
Fisheye projection (Apple).
Definition spherical.h:84
AVStereo3DType
List of possible 3D Types.
Definition stereo3d.h:48
AVStereo3D * av_stereo3d_alloc_size(size_t *size)
Allocate an AVStereo3D structure and set its fields to default values.
Definition stereo3d.c:39
#define AV_STEREO3D_FLAG_INVERT
Inverted views, Right/Bottom represents the left view.
Definition stereo3d.h:194
AVStereo3DPrimaryEye
List of possible primary eyes.
Definition stereo3d.h:174
AVStereo3DView
List of possible view types.
Definition stereo3d.h:149
@ AV_STEREO3D_2D
Video is not stereoscopic (and metadata has to be there).
Definition stereo3d.h:52
@ AV_STEREO3D_TOPBOTTOM
Views are on top of each other.
Definition stereo3d.h:76
@ AV_STEREO3D_UNSPEC
Video is stereoscopic but the packing is unspecified.
Definition stereo3d.h:143
@ AV_STEREO3D_SIDEBYSIDE
Views are next to each other.
Definition stereo3d.h:64
@ AV_PRIMARY_EYE_NONE
Neither eye.
Definition stereo3d.h:178
@ AV_PRIMARY_EYE_LEFT
Left eye.
Definition stereo3d.h:183
@ AV_PRIMARY_EYE_RIGHT
Right eye.
Definition stereo3d.h:188
@ AV_STEREO3D_VIEW_RIGHT
Frame contains only the right view.
Definition stereo3d.h:163
@ AV_STEREO3D_VIEW_PACKED
Frame contains two packed views.
Definition stereo3d.h:153
@ AV_STEREO3D_VIEW_LEFT
Frame contains only the left view.
Definition stereo3d.h:158
@ AV_STEREO3D_VIEW_UNSPEC
Content is unspecified.
Definition stereo3d.h:168
int index
Definition gxfenc.c:90
int a
int tile_rows
#define MAX_REORDER_DELAY
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:370
Memory handling functions.
static int mlp_samplerate(int in)
Definition mlp_parse.h:87
static uint64_t truehd_layout(int chanmap)
Definition mlp_parse.h:105
static int mov_read_ilst(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition mov.c:5710
static int64_t mov_get_skip_samples(AVStream *st, int sample)
Definition mov.c:12429
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:11957
static int mov_read_iloc(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition mov.c:9428
static int mov_read_pack(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition mov.c:7122
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:12445
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:10592
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:5872
static int mov_read_dops(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition mov.c:9004
static int set_display_matrix_from_item(AVPacketSideData **coded_side_data, int *nb_coded_side_data, const HEIFItem *item)
Definition mov.c:10863
static int mov_compare_presentation_samples(const void *a, const void *b)
Definition mov.c:5280
static int mov_switch_root(AVFormatContext *s, int64_t target, int index)
Definition mov.c:11897
static int mov_read_vexu_proj(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition mov.c:7340
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:8588
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:9422
static int mov_parse_tmcd_streams(AVFormatContext *s)
Definition mov.c:11337
static int mov_read_lhvc(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition mov.c:9139
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:9414
static int mov_seek_stream(AVFormatContext *s, AVStream *st, int64_t timestamp, int flags)
Definition mov.c:12354
static int mov_read_packet(AVFormatContext *s, AVPacket *pkt)
Definition mov.c:12110
static int mov_parse_lcevc_streams(AVFormatContext *s)
Definition mov.c:11460
static int mov_read_hvce(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition mov.c:9112
static int cbcs_scheme_decrypt(MOVContext *c, MOVStreamContext *sc, AVEncryptionInfo *sample, uint8_t *input, int size)
Definition mov.c:8821
static int mov_read_default(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition mov.c:10177
static int mov_finalize_packet(AVFormatContext *s, AVStream *st, AVIndexEntry *sample, int64_t current_index, AVPacket *pkt)
Definition mov.c:12026
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:8230
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:6821
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:7413
static int cenc_scheme_decrypt(MOVContext *c, MOVStreamContext *sc, AVEncryptionInfo *sample, uint8_t *input, int size)
Definition mov.c:8625
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:10979
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:9659
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:9395
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:11625
static int mov_read_dfla(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition mov.c:8548
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:7075
static int mov_read_elst(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition mov.c:6747
static int test_same_origin(const char *src, const char *ref)
Definition mov.c:5378
static int sanity_checks(void *log_obj, MOVStreamContext *sc, int index)
Definition mov.c:5535
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:4896
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:7203
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:8934
static const AVClass mov_class
Definition mov.c:12557
static int mov_read_sample_encryption_info(MOVContext *c, AVIOContext *pb, MOVStreamContext *sc, AVEncryptionInfo **sample, int use_subsamples)
Definition mov.c:7974
static int mov_read_meta(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition mov.c:5931
static int mov_read_smdm(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition mov.c:6893
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:6535
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:4818
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:10507
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:9057
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:8446
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:10748
static int mov_seek_fragment(AVFormatContext *s, AVStream *st, int64_t timestamp)
Definition mov.c:12291
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:11514
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:11048
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:4890
static int mov_read_dvcc_dvvc(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition mov.c:9092
static int should_retry(AVIOContext *pb, int error_code)
Definition mov.c:11890
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:6156
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:7021
static int mov_read_trun(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition mov.c:6195
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:9190
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:8325
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:5957
static int mov_read_iprp(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition mov.c:9898
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:8750
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:10803
#define MIN_DATA_ENTRY_BOX_SIZE
Definition mov.c:653
static int mov_change_extradata(AVStream *st, AVPacket *pkt)
Definition mov.c:11933
static int mov_read_mdcv(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition mov.c:6940
static int mov_read_timecode_track(AVFormatContext *s, AVStream *st)
Definition mov.c:10533
static int mov_read_imir(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition mov.c:9879
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:11408
static const MOVParseTableEntry mov_default_parse_table[]
Definition mov.c:10042
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:9786
static int mov_read_trex(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition mov.c:6130
static int mov_read_saiz(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition mov.c:8146
static int mov_read_hfov(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition mov.c:7657
static int mov_read_free(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition mov.c:7854
static int set_icc_profile_from_item(AVPacketSideData **coded_side_data, int *nb_coded_side_data, const HEIFItem *item)
Definition mov.c:10849
static int mov_read_infe(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition mov.c:9525
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:8684
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:5479
static int mov_read_custom(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition mov.c:5771
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:7923
static int mov_read_close(AVFormatContext *s)
Definition mov.c:10657
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:5407
static MOVFragmentStreamInfo * get_frag_stream_info_from_pkt(MOVFragmentIndex *frag_index, AVPacket *pkt, int id)
Definition mov.c:8909
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:8477
static int mov_read_uuid(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition mov.c:7749
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:4826
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:4959
static void mov_update_sample_durations(MOVContext *mov, AVStream *st)
Definition mov.c:5293
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:7050
static int mov_read_keys(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition mov.c:5719
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:5949
static int can_seek_to_key_sample(AVStream *st, int sample, int64_t requested_pts)
Definition mov.c:12327
static int mov_parse_auxiliary_info(MOVContext *c, MOVStreamContext *sc, AVIOContext *pb, MOVEncryptionIndex *encryption_index)
Definition mov.c:8084
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:6849
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:11132
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:9742
static int cenc_decrypt(MOVContext *c, MOVStreamContext *sc, AVEncryptionInfo *sample, uint8_t *input, int size)
Definition mov.c:8893
static int mov_read_senc(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition mov.c:8028
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:11393
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:5554
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:9369
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:10580
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:11587
#define OFFSET(x)
Definition mov.c:12501
static AVIndexEntry * mov_find_next_sample(AVFormatContext *s, AVStream **st)
Definition mov.c:11860
static int mov_read_chap(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition mov.c:6109
#define MOV_MERGE_CTTS
Definition mov.c:4889
static int is_open_key_sample(const MOVStreamContext *sc, int sample)
Definition mov.c:12310
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:9279
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:6984
static int mov_read_frma(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition mov.c:7876
static int mov_read_ispe(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition mov.c:9831
static int mov_codec_id(AVStream *st, uint32_t format)
Definition mov.c:2885
static void export_orphan_timecode(AVFormatContext *s)
Definition mov.c:10730
static int mov_parse_heif_items(AVFormatContext *s)
Definition mov.c:11258
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:10009
static int mov_read_tfhd(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition mov.c:6062
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:9859
static int read_image_grid(AVFormatContext *s, const HEIFGrid *grid, AVStreamGroupTileGrid *tile_grid)
Definition mov.c:10884
static int mov_probe(const AVProbeData *p)
Definition mov.c:10299
static int parse_timecode_in_framenum_format(AVFormatContext *s, AVStream *st, int64_t value, int flags)
Definition mov.c:10493
static int mov_parse_uuid_spherical(MOVStreamContext *sc, AVIOContext *pb, size_t len)
Definition mov.c:7686
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:6674
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:9602
static int tmcd_is_referenced(AVFormatContext *s, int tmcd_id)
Definition mov.c:10712
static void mov_read_chapters(AVFormatContext *s)
Definition mov.c:10394
static int mov_read_cmov(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition mov.c:6694
static void set_frag_stream(MOVFragmentIndex *frag_index, int id)
Definition mov.c:1733
static const AVOption mov_options[]
Definition mov.c:12503
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:7595
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_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]