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/gain_map.h"
50#include "libavutil/pixdesc.h"
51#include "libavutil/sha.h"
52#include "libavutil/spherical.h"
53#include "libavutil/stereo3d.h"
54#include "libavutil/timecode.h"
55#include "libavutil/uuid.h"
56#include "libavcodec/ac3tab.h"
57#include "libavcodec/exif.h"
58#include "libavcodec/flac.h"
63#include "avformat.h"
64#include "internal.h"
65#include "avio_internal.h"
66#include "demux.h"
67#include "dvdclut.h"
68#include "iamf_parse.h"
69#include "iamf_reader.h"
70#include "dovi_isom.h"
71#include "riff.h"
72#include "isom.h"
73#include "libavcodec/get_bits.h"
74#include "id3v1.h"
75#include "mov_chan.h"
76#include "replaygain.h"
77
78#if CONFIG_ZLIB
79#include <zlib.h>
80#endif
81
82#include "qtpalette.h"
83
84/* those functions parse an atom */
85/* links atom IDs to parse functions */
86typedef struct MOVParseTableEntry {
87 uint32_t type;
88 int (*parse)(MOVContext *ctx, AVIOContext *pb, MOVAtom atom);
90
91static int mov_read_default(MOVContext *c, AVIOContext *pb, MOVAtom atom);
94
96 unsigned len, const char *key)
97{
98 char buf[16];
99
100 short current, total = 0;
101 avio_rb16(pb); // unknown
102 current = avio_rb16(pb);
103 if (len >= 6)
104 total = avio_rb16(pb);
105 if (!total)
106 snprintf(buf, sizeof(buf), "%d", current);
107 else
108 snprintf(buf, sizeof(buf), "%d/%d", current, total);
109 c->fc->event_flags |= AVFMT_EVENT_FLAG_METADATA_UPDATED;
110 av_dict_set(&c->fc->metadata, key, buf, 0);
111
112 return 0;
113}
114
116 unsigned len, const char *key)
117{
118 /* bypass padding bytes */
119 avio_r8(pb);
120 avio_r8(pb);
121 avio_r8(pb);
122
123 c->fc->event_flags |= AVFMT_EVENT_FLAG_METADATA_UPDATED;
124 av_dict_set_int(&c->fc->metadata, key, avio_r8(pb), 0);
125
126 return 0;
127}
128
130 unsigned len, const char *key)
131{
132 c->fc->event_flags |= AVFMT_EVENT_FLAG_METADATA_UPDATED;
133 av_dict_set_int(&c->fc->metadata, key, avio_r8(pb), 0);
134
135 return 0;
136}
137
139 unsigned len, const char *key)
140{
141 short genre;
142
143 avio_r8(pb); // unknown
144
145 genre = avio_r8(pb);
146 if (genre < 1 || genre > ID3v1_GENRE_MAX)
147 return 0;
148 c->fc->event_flags |= AVFMT_EVENT_FLAG_METADATA_UPDATED;
149 av_dict_set(&c->fc->metadata, key, ff_id3v1_genre_str[genre-1], 0);
150
151 return 0;
152}
153
154static const uint32_t mac_to_unicode[128] = {
155 0x00C4,0x00C5,0x00C7,0x00C9,0x00D1,0x00D6,0x00DC,0x00E1,
156 0x00E0,0x00E2,0x00E4,0x00E3,0x00E5,0x00E7,0x00E9,0x00E8,
157 0x00EA,0x00EB,0x00ED,0x00EC,0x00EE,0x00EF,0x00F1,0x00F3,
158 0x00F2,0x00F4,0x00F6,0x00F5,0x00FA,0x00F9,0x00FB,0x00FC,
159 0x2020,0x00B0,0x00A2,0x00A3,0x00A7,0x2022,0x00B6,0x00DF,
160 0x00AE,0x00A9,0x2122,0x00B4,0x00A8,0x2260,0x00C6,0x00D8,
161 0x221E,0x00B1,0x2264,0x2265,0x00A5,0x00B5,0x2202,0x2211,
162 0x220F,0x03C0,0x222B,0x00AA,0x00BA,0x03A9,0x00E6,0x00F8,
163 0x00BF,0x00A1,0x00AC,0x221A,0x0192,0x2248,0x2206,0x00AB,
164 0x00BB,0x2026,0x00A0,0x00C0,0x00C3,0x00D5,0x0152,0x0153,
165 0x2013,0x2014,0x201C,0x201D,0x2018,0x2019,0x00F7,0x25CA,
166 0x00FF,0x0178,0x2044,0x20AC,0x2039,0x203A,0xFB01,0xFB02,
167 0x2021,0x00B7,0x201A,0x201E,0x2030,0x00C2,0x00CA,0x00C1,
168 0x00CB,0x00C8,0x00CD,0x00CE,0x00CF,0x00CC,0x00D3,0x00D4,
169 0xF8FF,0x00D2,0x00DA,0x00DB,0x00D9,0x0131,0x02C6,0x02DC,
170 0x00AF,0x02D8,0x02D9,0x02DA,0x00B8,0x02DD,0x02DB,0x02C7,
171};
172
174 char *dst, int dstlen)
175{
176 char *p = dst;
177 char *end = dst+dstlen-1;
178 int i;
179
180 for (i = 0; i < len; i++) {
181 uint8_t t, c = avio_r8(pb);
182
183 if (p >= end)
184 continue;
185
186 if (c < 0x80)
187 *p++ = c;
188 else if (p < end)
189 PUT_UTF8(mac_to_unicode[c-0x80], t, if (p < end) *p++ = t;);
190 }
191 *p = 0;
192 return p - dst;
193}
194
195/**
196 * Get the requested item.
197 */
198static HEIFItem *get_heif_item(MOVContext *c, unsigned id)
199{
200 HEIFItem *item = NULL;
201
202 for (int i = 0; i < c->nb_heif_item; i++) {
203 if (!c->heif_item[i] || c->heif_item[i]->item_id != id)
204 continue;
205
206 item = c->heif_item[i];
207 break;
208 }
209
210 return item;
211}
212
213/**
214 * Get the current stream in the parsing process. This can either be the
215 * latest stream added to the context, or the stream referenced by an item.
216 */
218{
219 AVStream *st = NULL;
220 HEIFItem *item;
221
222 if (c->fc->nb_streams < 1)
223 return NULL;
224
225 if (c->cur_item_id == -1)
226 return c->fc->streams[c->fc->nb_streams-1];
227
228 item = get_heif_item(c, c->cur_item_id);
229 if (item)
230 st = item->st;
231
232 return st;
233}
234
235static int mov_read_covr(MOVContext *c, AVIOContext *pb, int type, int len)
236{
237 AVStream *st;
239 enum AVCodecID id;
240 int ret;
241
242 switch (type) {
243 case 0xd: id = AV_CODEC_ID_MJPEG; break;
244 case 0xe: id = AV_CODEC_ID_PNG; break;
245 case 0x1b: id = AV_CODEC_ID_BMP; break;
246 default:
247 av_log(c->fc, AV_LOG_WARNING, "Unknown cover type: 0x%x.\n", type);
248 avio_skip(pb, len);
249 return 0;
250 }
251
252 sc = av_mallocz(sizeof(*sc));
253 if (!sc)
254 return AVERROR(ENOMEM);
255 ret = ff_add_attached_pic(c->fc, NULL, pb, NULL, len);
256 if (ret < 0) {
257 av_free(sc);
258 return ret;
259 }
260 st = c->fc->streams[c->fc->nb_streams - 1];
261 st->priv_data = sc;
262 sc->id = st->id;
263 sc->refcount = 1;
264
265 if (st->attached_pic.size >= 8 && id != AV_CODEC_ID_BMP) {
266 if (AV_RB64(st->attached_pic.data) == 0x89504e470d0a1a0a) {
267 id = AV_CODEC_ID_PNG;
268 } else {
270 }
271 }
272 st->codecpar->codec_id = id;
273
274 return 0;
275}
276
277// 3GPP TS 26.244
278static int mov_metadata_loci(MOVContext *c, AVIOContext *pb, unsigned len)
279{
280 char language[4] = { 0 };
281 char buf[200], place[100];
282 uint16_t langcode = 0;
283 double longitude, latitude, altitude;
284 const char *key = "location";
285
286 if (len < 4 + 2 + 1 + 1 + 4 + 4 + 4) {
287 av_log(c->fc, AV_LOG_ERROR, "loci too short\n");
288 return AVERROR_INVALIDDATA;
289 }
290
291 avio_skip(pb, 4); // version+flags
292 langcode = avio_rb16(pb);
293 ff_mov_lang_to_iso639(langcode, language);
294 len -= 6;
295
296 len -= avio_get_str(pb, len, place, sizeof(place));
297 if (len < 1) {
298 av_log(c->fc, AV_LOG_ERROR, "place name too long\n");
299 return AVERROR_INVALIDDATA;
300 }
301 avio_skip(pb, 1); // role
302 len -= 1;
303
304 if (len < 12) {
305 av_log(c->fc, AV_LOG_ERROR,
306 "loci too short (%u bytes left, need at least %d)\n", len, 12);
307 return AVERROR_INVALIDDATA;
308 }
309 longitude = ((int32_t) avio_rb32(pb)) / (float) (1 << 16);
310 latitude = ((int32_t) avio_rb32(pb)) / (float) (1 << 16);
311 altitude = ((int32_t) avio_rb32(pb)) / (float) (1 << 16);
312
313 // Try to output in the same format as the ?xyz field
314 snprintf(buf, sizeof(buf), "%+08.4f%+09.4f", latitude, longitude);
315 if (altitude)
316 av_strlcatf(buf, sizeof(buf), "%+f", altitude);
317 av_strlcatf(buf, sizeof(buf), "/%s", place);
318
319 if (*language && strcmp(language, "und")) {
320 char key2[16];
321 snprintf(key2, sizeof(key2), "%s-%s", key, language);
322 av_dict_set(&c->fc->metadata, key2, buf, 0);
323 }
324 c->fc->event_flags |= AVFMT_EVENT_FLAG_METADATA_UPDATED;
325 return av_dict_set(&c->fc->metadata, key, buf, 0);
326}
327
328static int mov_metadata_hmmt(MOVContext *c, AVIOContext *pb, unsigned len)
329{
330 int i, n_hmmt;
331
332 if (len < 2)
333 return 0;
334 if (c->ignore_chapters)
335 return 0;
336
337 n_hmmt = avio_rb32(pb);
338 if (n_hmmt > len / 4)
339 return AVERROR_INVALIDDATA;
340 for (i = 0; i < n_hmmt && !pb->eof_reached; i++) {
341 int moment_time = avio_rb32(pb);
342 avpriv_new_chapter(c->fc, i, av_make_q(1, 1000), moment_time, AV_NOPTS_VALUE, NULL);
343 }
344 if (avio_feof(pb))
345 return AVERROR_INVALIDDATA;
346 return 0;
347}
348
350{
351 char tmp_key[AV_FOURCC_MAX_STRING_SIZE] = {0};
352 char key2[32], language[4] = {0};
353 char *str = NULL;
354 const char *key = NULL;
355 uint16_t langcode = 0;
356 uint32_t data_type = 0, str_size_alloc;
357 uint64_t str_size;
358 int (*parse)(MOVContext*, AVIOContext*, unsigned, const char*) = NULL;
359 int raw = 0;
360 int num = 0;
362
363 if (c->trak_index >= 0 && c->trak_index < c->fc->nb_streams)
364 metadata = &c->fc->streams[c->trak_index]->metadata;
365 else
366 metadata = &c->fc->metadata;
367
368 switch (atom.type) {
369 case MKTAG( '@','P','R','M'): key = "premiere_version"; raw = 1; break;
370 case MKTAG( '@','P','R','Q'): key = "quicktime_version"; raw = 1; break;
371 case MKTAG( 'X','M','P','_'):
372 if (c->export_xmp) { key = "xmp"; raw = 1; } break;
373 case MKTAG( 'a','A','R','T'): key = "album_artist"; break;
374 case MKTAG( 'a','k','I','D'): key = "account_type";
376 case MKTAG( 'a','p','I','D'): key = "account_id"; break;
377 case MKTAG( 'c','a','t','g'): key = "category"; break;
378 case MKTAG( 'c','p','i','l'): key = "compilation";
380 case MKTAG( 'c','p','r','t'): key = "copyright"; break;
381 case MKTAG( 'd','e','s','c'): key = "description"; break;
382 case MKTAG( 'd','i','s','k'): key = "disc";
384 case MKTAG( 'e','g','i','d'): key = "episode_uid";
386 case MKTAG( 'F','I','R','M'): key = "firmware"; raw = 1; break;
387 case MKTAG( 'g','n','r','e'): key = "genre";
388 parse = mov_metadata_gnre; break;
389 case MKTAG( 'h','d','v','d'): key = "hd_video";
391 case MKTAG( 'H','M','M','T'):
392 return mov_metadata_hmmt(c, pb, atom.size);
393 case MKTAG( 'k','e','y','w'): key = "keywords"; break;
394 case MKTAG( 'l','d','e','s'): key = "synopsis"; break;
395 case MKTAG( 'l','o','c','i'):
396 return mov_metadata_loci(c, pb, atom.size);
397 case MKTAG( 'm','a','n','u'): key = "make"; break;
398 case MKTAG( 'm','o','d','l'): key = "model"; break;
399 case MKTAG( 'n','a','m','e'): key = "name"; break;
400 case MKTAG( 'p','c','s','t'): key = "podcast";
402 case MKTAG( 'p','g','a','p'): key = "gapless_playback";
404 case MKTAG( 'p','u','r','d'): key = "purchase_date"; break;
405 case MKTAG( 'r','t','n','g'): key = "rating";
407 case MKTAG( 's','o','a','a'): key = "sort_album_artist"; break;
408 case MKTAG( 's','o','a','l'): key = "sort_album"; break;
409 case MKTAG( 's','o','a','r'): key = "sort_artist"; break;
410 case MKTAG( 's','o','c','o'): key = "sort_composer"; break;
411 case MKTAG( 's','o','n','m'): key = "sort_name"; break;
412 case MKTAG( 's','o','s','n'): key = "sort_show"; break;
413 case MKTAG( 's','t','i','k'): key = "media_type";
415 case MKTAG( 't','r','k','n'): key = "track";
417 case MKTAG( 't','v','e','n'): key = "episode_id"; break;
418 case MKTAG( 't','v','e','s'): key = "episode_sort";
420 case MKTAG( 't','v','n','n'): key = "network"; break;
421 case MKTAG( 't','v','s','h'): key = "show"; break;
422 case MKTAG( 't','v','s','n'): key = "season_number";
424 case MKTAG(0xa9,'A','R','T'): key = "artist"; break;
425 case MKTAG(0xa9,'P','R','D'): key = "producer"; break;
426 case MKTAG(0xa9,'a','l','b'): key = "album"; break;
427 case MKTAG(0xa9,'a','u','t'): key = "artist"; break;
428 case MKTAG(0xa9,'c','h','p'): key = "chapter"; break;
429 case MKTAG(0xa9,'c','m','t'): key = "comment"; break;
430 case MKTAG(0xa9,'c','o','m'): key = "composer"; break;
431 case MKTAG(0xa9,'c','p','y'): key = "copyright"; break;
432 case MKTAG(0xa9,'d','a','y'): key = "date"; break;
433 case MKTAG(0xa9,'d','i','r'): key = "director"; break;
434 case MKTAG(0xa9,'d','i','s'): key = "disclaimer"; break;
435 case MKTAG(0xa9,'e','d','1'): key = "edit_date"; break;
436 case MKTAG(0xa9,'e','n','c'): key = "encoder"; break;
437 case MKTAG(0xa9,'f','m','t'): key = "original_format"; break;
438 case MKTAG(0xa9,'g','e','n'): key = "genre"; break;
439 case MKTAG(0xa9,'g','r','p'): key = "grouping"; break;
440 case MKTAG(0xa9,'h','s','t'): key = "host_computer"; break;
441 case MKTAG(0xa9,'i','n','f'): key = "comment"; break;
442 case MKTAG(0xa9,'l','y','r'): key = "lyrics"; break;
443 case MKTAG(0xa9,'m','a','k'): key = "make"; break;
444 case MKTAG(0xa9,'m','o','d'): key = "model"; break;
445 case MKTAG(0xa9,'n','a','m'): key = "title"; break;
446 case MKTAG(0xa9,'o','p','e'): key = "original_artist"; break;
447 case MKTAG(0xa9,'p','r','d'): key = "producer"; break;
448 case MKTAG(0xa9,'p','r','f'): key = "performers"; break;
449 case MKTAG(0xa9,'r','e','q'): key = "playback_requirements"; break;
450 case MKTAG(0xa9,'s','r','c'): key = "original_source"; break;
451 case MKTAG(0xa9,'s','t','3'): key = "subtitle"; break;
452 case MKTAG(0xa9,'s','w','r'): key = "encoder"; break;
453 case MKTAG(0xa9,'t','o','o'): key = "encoder"; break;
454 case MKTAG(0xa9,'t','r','k'): key = "track"; break;
455 case MKTAG(0xa9,'u','r','l'): key = "URL"; break;
456 case MKTAG(0xa9,'w','r','n'): key = "warning"; break;
457 case MKTAG(0xa9,'w','r','t'): key = "composer"; break;
458 case MKTAG(0xa9,'x','y','z'): key = "location"; break;
459 }
460retry:
461 if (c->itunes_metadata && atom.size > 8) {
462 int data_size = avio_rb32(pb);
463 int tag = avio_rl32(pb);
464 if (tag == MKTAG('d','a','t','a') && data_size <= atom.size && data_size >= 16) {
465 data_type = avio_rb32(pb); // type
466 avio_rb32(pb); // unknown
467 str_size = data_size - 16;
468 atom.size -= 16;
469
470 if (!key && c->found_hdlr_mdta && c->meta_keys) {
471 uint32_t index = av_bswap32(atom.type); // BE number has been read as LE
472 if (index < c->meta_keys_count && index > 0) {
473 key = c->meta_keys[index];
474 } else if (atom.type != MKTAG('c', 'o', 'v', 'r')) {
476 "The index of 'data' is out of range: %"PRId32" < 1 or >= %d.\n",
477 index, c->meta_keys_count);
478 }
479 }
480 if (atom.type == MKTAG('c', 'o', 'v', 'r') ||
481 (key && !strcmp(key, "com.apple.quicktime.artwork"))) {
482 int ret = mov_read_covr(c, pb, data_type, str_size);
483 if (ret < 0) {
484 av_log(c->fc, AV_LOG_ERROR, "Error parsing cover art.\n");
485 return ret;
486 }
487 atom.size -= str_size;
488 if (atom.size > 8)
489 goto retry;
490 return ret;
491 }
492 } else return 0;
493 } else if (atom.size > 4 && (key || c->export_all) && !c->itunes_metadata && !raw) {
494 str_size = avio_rb16(pb); // string length
495 if (str_size > atom.size) {
496 raw = 1;
497 avio_seek(pb, -2, SEEK_CUR);
498 av_log(c->fc, AV_LOG_WARNING, "UDTA parsing failed retrying raw\n");
499 goto retry;
500 }
501 langcode = avio_rb16(pb);
502 ff_mov_lang_to_iso639(langcode, language);
503 atom.size -= 4;
504 } else
505 str_size = atom.size;
506
507 if (c->export_all && !key) {
508 key = av_fourcc_make_string(tmp_key, atom.type);
509 }
510
511 if (!key)
512 return 0;
513 if (atom.size < 0 || str_size >= INT_MAX/2)
514 return AVERROR_INVALIDDATA;
515
516 // Allocates enough space if data_type is a int32 or float32 number, otherwise
517 // worst-case requirement for output string in case of utf8 coded input
518 num = (data_type >= 21 && data_type <= 23);
519 str_size_alloc = (num ? 512 : (raw ? str_size : str_size * 2)) + 1;
520 str = av_mallocz(str_size_alloc);
521 if (!str)
522 return AVERROR(ENOMEM);
523
524 if (parse)
525 parse(c, pb, str_size, key);
526 else {
527 if (!raw && (data_type == 3 || (data_type == 0 && (langcode < 0x400 || langcode == 0x7fff)))) { // MAC Encoded
528 mov_read_mac_string(c, pb, str_size, str, str_size_alloc);
529 } else if (data_type == 21) { // BE signed integer, variable size
530 int val = 0;
531 if (str_size == 1)
532 val = (int8_t)avio_r8(pb);
533 else if (str_size == 2)
534 val = (int16_t)avio_rb16(pb);
535 else if (str_size == 3)
536 val = ((int32_t)(avio_rb24(pb)<<8))>>8;
537 else if (str_size == 4)
538 val = (int32_t)avio_rb32(pb);
539 if (snprintf(str, str_size_alloc, "%d", val) >= str_size_alloc) {
540 av_log(c->fc, AV_LOG_ERROR,
541 "Failed to store the number (%d) in string.\n", val);
542 av_free(str);
543 return AVERROR_INVALIDDATA;
544 }
545 } else if (data_type == 22) { // BE unsigned integer, variable size
546 unsigned int val = 0;
547 if (str_size == 1)
548 val = avio_r8(pb);
549 else if (str_size == 2)
550 val = avio_rb16(pb);
551 else if (str_size == 3)
552 val = avio_rb24(pb);
553 else if (str_size == 4)
554 val = avio_rb32(pb);
555 if (snprintf(str, str_size_alloc, "%u", val) >= str_size_alloc) {
556 av_log(c->fc, AV_LOG_ERROR,
557 "Failed to store the number (%u) in string.\n", val);
558 av_free(str);
559 return AVERROR_INVALIDDATA;
560 }
561 } else if (data_type == 23 && str_size >= 4) { // BE float32
562 float val = av_int2float(avio_rb32(pb));
563 if (snprintf(str, str_size_alloc, "%f", val) >= str_size_alloc) {
564 av_log(c->fc, AV_LOG_ERROR,
565 "Failed to store the float32 number (%f) in string.\n", val);
566 av_free(str);
567 return AVERROR_INVALIDDATA;
568 }
569 } else if (data_type > 1 && data_type != 4) {
570 // data_type can be 0 if not set at all above. data_type 1 means
571 // UTF8 and 4 means "UTF8 sort". For any other type (UTF16 or e.g.
572 // a picture), don't return it blindly in a string that is supposed
573 // to be UTF8 text.
574 av_log(c->fc, AV_LOG_WARNING, "Skipping unhandled metadata %s of type %"PRIu32"\n", key, data_type);
575 av_free(str);
576 return 0;
577 } else {
578 int ret = ffio_read_size(pb, str, str_size);
579 if (ret < 0) {
580 av_free(str);
581 return ret;
582 }
583 str[str_size] = 0;
584 }
585 c->fc->event_flags |= AVFMT_EVENT_FLAG_METADATA_UPDATED;
586 if (c->itunes_metadata && av_dict_get(*metadata, key, NULL, 0))
588 av_dict_set(metadata, key, str, c->itunes_metadata ? AV_DICT_APPEND : 0);
589 if (*language && strcmp(language, "und")) {
590 snprintf(key2, sizeof(key2), "%s-%s", key, language);
591 av_dict_set(metadata, key2, str, 0);
592 }
593 if (!strcmp(key, "encoder")) {
594 int major, minor, micro;
595 if (sscanf(str, "HandBrake %d.%d.%d", &major, &minor, &micro) == 3) {
596 c->handbrake_version = 1000000*major + 1000*minor + micro;
597 }
598 }
599
600 atom.size -= str_size;
601 av_freep(&str);
602
603 // Read remaining data atoms for multi-valued iTunes tags (e.g. multiple
604 // artists stored as multiple data atoms within one tag atom), consistent
605 // with the existing covr path.
606 // Note: multiple sibling tag atoms with the same key (e.g. three separate
607 // ©ART atoms under ilst) are handled by the AV_DICT_APPEND logic above,
608 // since mov_read_udta_string() is called once per tag atom.
609 if (c->itunes_metadata && atom.size > 8)
610 goto retry;
611 }
612
613 av_freep(&str);
614 return 0;
615}
616
618{
619 int64_t start;
620 int i, nb_chapters, str_len, version;
621 char str[256+1];
622 int ret;
623
624 if (c->ignore_chapters)
625 return 0;
626
627 if ((atom.size -= 5) < 0)
628 return 0;
629
630 version = avio_r8(pb);
631 avio_rb24(pb);
632 if (version)
633 avio_rb32(pb); // ???
634 nb_chapters = avio_r8(pb);
635
636 for (i = 0; i < nb_chapters; i++) {
637 if (atom.size < 9)
638 return 0;
639
640 start = avio_rb64(pb);
641 str_len = avio_r8(pb);
642
643 if ((atom.size -= 9+str_len) < 0)
644 return 0;
645
646 ret = ffio_read_size(pb, str, str_len);
647 if (ret < 0)
648 return ret;
649 str[str_len] = 0;
650 avpriv_new_chapter(c->fc, i, (AVRational){1,10000000}, start, AV_NOPTS_VALUE, str);
651 }
652 return 0;
653}
654
655#define MIN_DATA_ENTRY_BOX_SIZE 12
657{
658 AVStream *st;
660 int entries, i, j;
661
662 if (c->fc->nb_streams < 1)
663 return 0;
664 st = c->fc->streams[c->fc->nb_streams-1];
665 sc = st->priv_data;
666
667 avio_rb32(pb); // version + flags
668 entries = avio_rb32(pb);
669 if (!entries ||
670 entries > (atom.size - 1) / MIN_DATA_ENTRY_BOX_SIZE + 1 ||
671 entries >= UINT_MAX / sizeof(*sc->drefs))
672 return AVERROR_INVALIDDATA;
673
674 for (i = 0; i < sc->drefs_count; i++) {
675 MOVDref *dref = &sc->drefs[i];
676 av_freep(&dref->path);
677 av_freep(&dref->dir);
678 }
679 av_free(sc->drefs);
680 sc->drefs_count = 0;
681 sc->drefs = av_mallocz(entries * sizeof(*sc->drefs));
682 if (!sc->drefs)
683 return AVERROR(ENOMEM);
684 sc->drefs_count = entries;
685
686 for (i = 0; i < entries; i++) {
687 MOVDref *dref = &sc->drefs[i];
688 uint32_t size = avio_rb32(pb);
689 int64_t next = avio_tell(pb);
690
691 if (size < 12 || next < 0 || next > INT64_MAX - size)
692 return AVERROR_INVALIDDATA;
693
694 next += size - 4;
695
696 dref->type = avio_rl32(pb);
697 avio_rb32(pb); // version + flags
698
699 if (dref->type == MKTAG('a','l','i','s') && size > 150) {
700 /* macintosh alias record */
701 uint16_t volume_len, len;
702 int16_t type;
703 int ret;
704
705 avio_skip(pb, 10);
706
707 volume_len = avio_r8(pb);
708 volume_len = FFMIN(volume_len, 27);
709 ret = ffio_read_size(pb, dref->volume, 27);
710 if (ret < 0)
711 return ret;
712 dref->volume[volume_len] = 0;
713 av_log(c->fc, AV_LOG_DEBUG, "volume %s, len %d\n", dref->volume, volume_len);
714
715 avio_skip(pb, 12);
716
717 len = avio_r8(pb);
718 len = FFMIN(len, 63);
719 ret = ffio_read_size(pb, dref->filename, 63);
720 if (ret < 0)
721 return ret;
722 dref->filename[len] = 0;
723 av_log(c->fc, AV_LOG_DEBUG, "filename %s, len %d\n", dref->filename, len);
724
725 avio_skip(pb, 16);
726
727 /* read next level up_from_alias/down_to_target */
728 dref->nlvl_from = avio_rb16(pb);
729 dref->nlvl_to = avio_rb16(pb);
730 av_log(c->fc, AV_LOG_DEBUG, "nlvl from %d, nlvl to %d\n",
731 dref->nlvl_from, dref->nlvl_to);
732
733 avio_skip(pb, 16);
734
735 for (type = 0; type != -1 && avio_tell(pb) < next; ) {
736 if (avio_feof(pb))
737 return AVERROR_EOF;
738 type = avio_rb16(pb);
739 len = avio_rb16(pb);
740 av_log(c->fc, AV_LOG_DEBUG, "type %d, len %d\n", type, len);
741 if (len&1)
742 len += 1;
743 if (type == 2) { // absolute path
744 av_free(dref->path);
745 dref->path = av_mallocz(len+1);
746 if (!dref->path)
747 return AVERROR(ENOMEM);
748
749 ret = ffio_read_size(pb, dref->path, len);
750 if (ret < 0) {
751 av_freep(&dref->path);
752 return ret;
753 }
754 if (len > volume_len && !strncmp(dref->path, dref->volume, volume_len)) {
755 len -= volume_len;
756 memmove(dref->path, dref->path+volume_len, len);
757 dref->path[len] = 0;
758 }
759 // trim string of any ending zeros
760 for (j = len - 1; j >= 0; j--) {
761 if (dref->path[j] == 0)
762 len--;
763 else
764 break;
765 }
766 for (j = 0; j < len; j++)
767 if (dref->path[j] == ':' || dref->path[j] == 0)
768 dref->path[j] = '/';
769 av_log(c->fc, AV_LOG_DEBUG, "path %s\n", dref->path);
770 } else if (type == 0) { // directory name
771 av_free(dref->dir);
772 dref->dir = av_malloc(len+1);
773 if (!dref->dir)
774 return AVERROR(ENOMEM);
775
776 ret = ffio_read_size(pb, dref->dir, len);
777 if (ret < 0) {
778 av_freep(&dref->dir);
779 return ret;
780 }
781 dref->dir[len] = 0;
782 for (j = 0; j < len; j++)
783 if (dref->dir[j] == ':')
784 dref->dir[j] = '/';
785 av_log(c->fc, AV_LOG_DEBUG, "dir %s\n", dref->dir);
786 } else
787 avio_skip(pb, len);
788 }
789 } else {
790 av_log(c->fc, AV_LOG_DEBUG, "Unknown dref type 0x%08"PRIx32" size %"PRIu32"\n",
791 dref->type, size);
792 entries--;
793 i--;
794 }
795 avio_seek(pb, next, SEEK_SET);
796 }
797 return 0;
798}
799
801{
802 AVStream *st;
803 uint32_t type;
804 uint32_t ctype;
805 int64_t title_size;
806 char *title_str;
807 int ret;
808
809 avio_r8(pb); /* version */
810 avio_rb24(pb); /* flags */
811
812 /* component type */
813 ctype = avio_rl32(pb);
814 type = avio_rl32(pb); /* component subtype */
815
816 av_log(c->fc, AV_LOG_TRACE, "ctype=%s\n", av_fourcc2str(ctype));
817 av_log(c->fc, AV_LOG_TRACE, "stype=%s\n", av_fourcc2str(type));
818
819 if (c->trak_index < 0) { // meta not inside a trak
820 if (type == MKTAG('m','d','t','a')) {
821 c->found_hdlr_mdta = 1;
822 }
823 return 0;
824 }
825
826 st = c->fc->streams[c->fc->nb_streams-1];
827
828 if (type == MKTAG('v','i','d','e'))
830 else if (type == MKTAG('s','o','u','n'))
832 else if (type == MKTAG('m','1','a',' '))
834 else if ((type == MKTAG('s','u','b','p')) || (type == MKTAG('c','l','c','p')))
836
837 avio_rb32(pb); /* component manufacture */
838 avio_rb32(pb); /* component flags */
839 avio_rb32(pb); /* component flags mask */
840
841 title_size = atom.size - 24;
842 if (title_size > 0) {
843 if (title_size > FFMIN(INT_MAX, SIZE_MAX-1))
844 return AVERROR_INVALIDDATA;
845 title_str = av_malloc(title_size + 1); /* Add null terminator */
846 if (!title_str)
847 return AVERROR(ENOMEM);
848
849 ret = ffio_read_size(pb, title_str, title_size);
850 if (ret < 0) {
851 av_freep(&title_str);
852 return ret;
853 }
854 title_str[title_size] = 0;
855 if (title_str[0]) {
856 int off = (!c->isom && title_str[0] == title_size - 1);
857 // flag added so as to not set stream handler name if already set from mdia->hdlr
858 av_dict_set(&st->metadata, "handler_name", title_str + off, AV_DICT_DONT_OVERWRITE);
859 }
860 av_freep(&title_str);
861 }
862
863 return 0;
864}
865
867{
868 return ff_mov_read_esds(c->fc, pb);
869}
870
872{
873 AVStream *st;
875 enum AVAudioServiceType *ast;
876 int ac3info, acmod, lfeon, bsmod;
877 uint64_t mask;
878
879 if (c->fc->nb_streams < 1)
880 return 0;
881 st = c->fc->streams[c->fc->nb_streams-1];
882
886 sizeof(*ast), 0);
887 if (!sd)
888 return AVERROR(ENOMEM);
889
890 ast = (enum AVAudioServiceType*)sd->data;
891 ac3info = avio_rb24(pb);
892 bsmod = (ac3info >> 14) & 0x7;
893 acmod = (ac3info >> 11) & 0x7;
894 lfeon = (ac3info >> 10) & 0x1;
895
897 if (lfeon)
901
902 *ast = bsmod;
903 if (st->codecpar->ch_layout.nb_channels > 1 && bsmod == 0x7)
905
906 return 0;
907}
908
909#if CONFIG_IAMFDEC
910static int mov_read_iacb(MOVContext *c, AVIOContext *pb, MOVAtom atom)
911{
912 AVStream *st;
915 AVIOContext *descriptor_pb;
917 IAMFContext *iamf;
919 unsigned descriptors_size;
920 int nb_frames, disposition;
921 int version, ret;
922
923 if (atom.size < 5)
924 return AVERROR_INVALIDDATA;
925
926 if (c->fc->nb_streams < 1)
927 return 0;
928
929 version = avio_r8(pb);
930 if (version != 1) {
931 av_log(c->fc, AV_LOG_ERROR, "%s configurationVersion %d",
932 version < 1 ? "invalid" : "unsupported", version);
933 return AVERROR_INVALIDDATA;
934 }
935
936 descriptors_size = ffio_read_leb(pb);
937 if (!descriptors_size || descriptors_size > INT_MAX)
938 return AVERROR_INVALIDDATA;
939
940 st = c->fc->streams[c->fc->nb_streams - 1];
941 sc = st->priv_data;
942
943 if (st->codecpar->extradata) {
944 av_log(c->fc, AV_LOG_WARNING, "ignoring iacb\n");
945 return 0;
946 }
947
948 sc->iamf = av_mallocz(sizeof(*sc->iamf));
949 if (!sc->iamf)
950 return AVERROR(ENOMEM);
951 iamf = &sc->iamf->iamf;
952
953 ret = ff_alloc_extradata(st->codecpar, descriptors_size);
954 if (ret < 0)
955 return ret;
956
957 ret = avio_read(pb, st->codecpar->extradata, descriptors_size);
958 if (ret != descriptors_size)
959 return ret < 0 ? ret : AVERROR_INVALIDDATA;
960
961 ffio_init_read_context(&b, st->codecpar->extradata, descriptors_size);
962 descriptor_pb = &b.pub;
963
964 ret = ff_iamfdec_read_descriptors(iamf, descriptor_pb, descriptors_size, c->fc);
965 if (ret < 0)
966 return ret;
967
968 metadata = st->metadata;
969 st->metadata = NULL;
971 nb_frames = st->nb_frames;
972 duration = st->duration;
973 disposition = st->disposition;
974
975 for (int i = 0; i < iamf->nb_audio_elements; i++) {
976 IAMFAudioElement *audio_element = iamf->audio_elements[i];
977 const AVIAMFAudioElement *element;
978 AVStreamGroup *stg =
980
981 if (!stg) {
982 ret = AVERROR(ENOMEM);
983 goto fail;
984 }
985
987 stg->id = audio_element->audio_element_id;
988 /* Transfer ownership */
989 element = stg->params.iamf_audio_element = audio_element->element;
990 audio_element->element = NULL;
991
992 for (int j = 0; j < audio_element->nb_substreams; j++) {
993 IAMFSubStream *substream = &audio_element->substreams[j];
994 AVStream *stream;
995
996 if (!i && !j) {
997 if (audio_element->layers[0].substream_count != 1)
998 disposition &= ~AV_DISPOSITION_DEFAULT;
999 stream = st;
1000 } else
1001 stream = avformat_new_stream(c->fc, NULL);
1002 if (!stream) {
1003 ret = AVERROR(ENOMEM);
1004 goto fail;
1005 }
1006
1007 stream->start_time = start_time;
1008 stream->nb_frames = nb_frames;
1009 stream->duration = duration;
1010 stream->disposition = disposition;
1011 if (stream != st) {
1012 stream->priv_data = sc;
1013 sc->refcount++;
1014 }
1015
1018 if (i || j) {
1020 if (audio_element->layers[0].substream_count == 1)
1022 }
1023
1024 ret = avcodec_parameters_copy(stream->codecpar, substream->codecpar);
1025 if (ret < 0)
1026 goto fail;
1027
1028 stream->id = substream->audio_substream_id;
1029
1030 avpriv_set_pts_info(st, 64, 1, sc->time_scale);
1031
1033 if (ret < 0)
1034 goto fail;
1035 }
1036
1037 ret = av_dict_copy(&stg->metadata, metadata, 0);
1038 if (ret < 0)
1039 goto fail;
1040 }
1041
1042 for (int i = 0; i < iamf->nb_mix_presentations; i++) {
1043 IAMFMixPresentation *mix_presentation = iamf->mix_presentations[i];
1044 const AVIAMFMixPresentation *mix = mix_presentation->cmix;
1045 AVStreamGroup *stg =
1047
1048 if (!stg) {
1049 ret = AVERROR(ENOMEM);
1050 goto fail;
1051 }
1052
1054 stg->id = mix_presentation->mix_presentation_id;
1055 /* Transfer ownership */
1056 stg->params.iamf_mix_presentation = mix_presentation->mix;
1057 mix_presentation->mix = NULL;
1058
1059 for (int j = 0; j < mix->nb_submixes; j++) {
1060 const AVIAMFSubmix *submix = mix->submixes[j];
1061
1062 for (int k = 0; k < submix->nb_elements; k++) {
1063 const AVIAMFSubmixElement *submix_element = submix->elements[k];
1064 const AVStreamGroup *audio_element = NULL;
1065
1066 for (int l = 0; l < c->fc->nb_stream_groups; l++)
1067 if (c->fc->stream_groups[l]->type == AV_STREAM_GROUP_PARAMS_IAMF_AUDIO_ELEMENT &&
1068 c->fc->stream_groups[l]->id == submix_element->audio_element_id) {
1069 audio_element = c->fc->stream_groups[l];
1070 break;
1071 }
1072 av_assert0(audio_element);
1073
1074 for (int l = 0; l < audio_element->nb_entries; l++) {
1075 ret = avformat_stream_group_add_stream(stg, audio_element->entries[l]->stream);
1076 if (ret < 0 && ret != AVERROR(EEXIST))
1077 goto fail;
1078 }
1079 }
1080 }
1081
1082 ret = av_dict_copy(&stg->metadata, metadata, 0);
1083 if (ret < 0)
1084 goto fail;
1085 }
1086
1087 ret = 0;
1088fail:
1090
1091 return ret;
1092}
1093#endif
1094
1096{
1097 AVStream *st;
1098 int32_t sample_rate;
1099
1100 if (atom.size < 8 || c->fc->nb_streams < 1)
1101 return 0;
1102
1103 st = c->fc->streams[c->fc->nb_streams-1];
1105 av_log(c->fc, AV_LOG_WARNING, "'srat' within non-audio sample entry, skip\n");
1106 return 0;
1107 }
1108
1109 if (!c->isom) {
1110 av_log(c->fc, AV_LOG_WARNING, "'srat' within non-isom, skip\n");
1111 return 0;
1112 }
1113
1114 avio_skip(pb, 4); // version+flags
1115 sample_rate = avio_rb32(pb);
1116 if (sample_rate > 0) {
1117 av_log(c->fc, AV_LOG_DEBUG,
1118 "overwrite sample rate from %d to %d by 'srat'\n",
1119 st->codecpar->sample_rate, sample_rate);
1120 st->codecpar->sample_rate = sample_rate;
1121 } else {
1122 av_log(c->fc, AV_LOG_WARNING,
1123 "ignore invalid sample rate %d in 'srat'\n", sample_rate);
1124 }
1125
1126 return 0;
1127}
1128
1130{
1131 AVStream *st;
1132 AVPacketSideData *sd;
1133 enum AVAudioServiceType *ast;
1134 int eac3info, acmod, lfeon, bsmod;
1135 uint64_t mask;
1136 int ret;
1137
1138 if (c->fc->nb_streams < 1)
1139 return 0;
1140 st = c->fc->streams[c->fc->nb_streams-1];
1141
1142 /* Preserve the complete EC3SpecificBox payload, including optional
1143 * extensions such as E-AC-3 JOC signaling. */
1144 if (atom.size < 5 || (uint64_t)atom.size > (1 << 30))
1145 return AVERROR_INVALIDDATA;
1146 ret = ff_get_extradata(c->fc, st->codecpar, pb, atom.size);
1147 if (ret < 0)
1148 return ret;
1149
1153 sizeof(*ast), 0);
1154 if (!sd)
1155 return AVERROR(ENOMEM);
1156
1157 ast = (enum AVAudioServiceType*)sd->data;
1158
1159 eac3info = AV_RB24(st->codecpar->extradata + 2);
1160 bsmod = (eac3info >> 12) & 0x1f;
1161 acmod = (eac3info >> 9) & 0x7;
1162 lfeon = (eac3info >> 8) & 0x1;
1163
1165 if (lfeon)
1169
1170 *ast = bsmod;
1171 if (st->codecpar->ch_layout.nb_channels > 1 && bsmod == 0x7)
1173
1174 return 0;
1175}
1176
1177/* Maps the DTS `StreamConstruction` field (ETSI TS 102 114 Table E-2) to the
1178 * coarse FFmpeg DTS profile enum. Extension-substream XLL maps to HD_MA;
1179 * extension-substream XXCH, X96, or XBR maps to HD_HRA; core-substream XCH or
1180 * XXCH maps to ES; core-substream X96 maps to 96/24; a core component alone
1181 * maps to DTS; and extension-substream LBR maps to Express. Value 0 (undefined)
1182 * and values outside 1..21 map to AV_PROFILE_UNKNOWN. */
1184{
1185 static const int profile[22] = {
1186 [ 1] = AV_PROFILE_DTS, /* core Core */
1187 [ 2] = AV_PROFILE_DTS_ES, /* core Core + core XCH */
1188 [ 3] = AV_PROFILE_DTS_ES, /* core Core + core XXCH */
1189 [ 4] = AV_PROFILE_DTS_96_24, /* core Core + core X96 */
1190 [ 5] = AV_PROFILE_DTS_HD_HRA, /* core Core + ext XXCH */
1191 [ 6] = AV_PROFILE_DTS_HD_HRA, /* core Core + ext XBR */
1192 [ 7] = AV_PROFILE_DTS_HD_HRA, /* core Core + core XCH + ext XBR */
1193 [ 8] = AV_PROFILE_DTS_HD_HRA, /* core Core + core XXCH + ext XBR */
1194 [ 9] = AV_PROFILE_DTS_HD_HRA, /* core Core + ext XXCH + ext XBR */
1195 [10] = AV_PROFILE_DTS_HD_HRA, /* core Core + ext X96 */
1196 [11] = AV_PROFILE_DTS_HD_HRA, /* core Core + core XCH + ext X96 */
1197 [12] = AV_PROFILE_DTS_HD_HRA, /* core Core + core XXCH + ext X96 */
1198 [13] = AV_PROFILE_DTS_HD_HRA, /* core Core + ext XXCH + ext X96 */
1199 [14] = AV_PROFILE_DTS_HD_MA, /* core Core + ext XLL */
1200 [15] = AV_PROFILE_DTS_HD_MA, /* core Core + core XCH + ext XLL */
1201 [16] = AV_PROFILE_DTS_HD_MA, /* core Core + core X96 + ext XLL */
1202 [17] = AV_PROFILE_DTS_HD_MA, /* ext XLL */
1203 [18] = AV_PROFILE_DTS_EXPRESS, /* ext LBR */
1204 [19] = AV_PROFILE_DTS, /* ext Core */
1205 [20] = AV_PROFILE_DTS_HD_HRA, /* ext Core + ext XXCH */
1206 [21] = AV_PROFILE_DTS_HD_MA, /* ext Core + ext XLL */
1207 };
1208 if (!sc || sc > 21)
1209 return AV_PROFILE_UNKNOWN;
1210 return profile[sc];
1211}
1212
1213/* Maps the 16-bit DTS `ChannelLayout` bitmask (ETSI TS 102 114 Table E-5) to an
1214 * ffmpeg channel mask. Pair bits follow Table 7-10 / DCA_SPEAKER_PAIR_*;
1215 * LwRw (0x0400) and LssRss (0x0800) must not collapse onto SIDE like LsRs. */
1216static uint64_t mov_dts_channel_layout_to_mask(unsigned int code)
1217{
1218 static const struct { unsigned int dts; uint64_t av; } map[] = {
1219 { 0x0001, AV_CH_FRONT_CENTER },
1220 { 0x0002, AV_CH_FRONT_LEFT | AV_CH_FRONT_RIGHT },
1221 { 0x0004, AV_CH_SIDE_LEFT | AV_CH_SIDE_RIGHT },
1222 { 0x0008, AV_CH_LOW_FREQUENCY },
1223 { 0x0010, AV_CH_BACK_CENTER },
1225 { 0x0040, AV_CH_BACK_LEFT | AV_CH_BACK_RIGHT },
1226 { 0x0080, AV_CH_TOP_FRONT_CENTER },
1227 { 0x0100, AV_CH_TOP_CENTER },
1229 { 0x0400, AV_CH_WIDE_LEFT | AV_CH_WIDE_RIGHT },
1231 { 0x1000, AV_CH_LOW_FREQUENCY_2 },
1233 { 0x4000, AV_CH_TOP_BACK_CENTER },
1235 };
1236 uint64_t mask = 0;
1237 int i;
1238 for (i = 0; i < FF_ARRAY_ELEMS(map); i++)
1239 if (code & map[i].dts)
1240 mask |= map[i].av;
1241 return mask;
1242}
1243
1245{
1246#define DDTS_SIZE 20
1248 AVStream *st = NULL;
1249 uint32_t frame_duration_code = 0;
1250 uint32_t channel_layout_code = 0;
1251 uint64_t channel_layout_mask;
1252 unsigned int stream_construction;
1253 unsigned int representation_type;
1254 GetBitContext gb;
1255 int ret;
1256
1257 if ((ret = ffio_read_size(pb, buf, DDTS_SIZE)) < 0)
1258 return ret;
1259
1260 init_get_bits(&gb, buf, 8 * DDTS_SIZE);
1261
1262 if (c->fc->nb_streams < 1) {
1263 return 0;
1264 }
1265 st = c->fc->streams[c->fc->nb_streams-1];
1266
1267 st->codecpar->sample_rate = get_bits_long(&gb, 32);
1268 if (st->codecpar->sample_rate <= 0) {
1269 av_log(c->fc, AV_LOG_ERROR, "Invalid sample rate %d\n", st->codecpar->sample_rate);
1270 return AVERROR_INVALIDDATA;
1271 }
1272 skip_bits_long(&gb, 32); /* max bitrate */
1273 st->codecpar->bit_rate = get_bits_long(&gb, 32);
1275 frame_duration_code = get_bits(&gb, 2);
1276 stream_construction = get_bits(&gb, 5); /* Table E-2 - profile source */
1277 skip_bits(&gb, 1); /* CoreLFEPresent */
1278 skip_bits(&gb, 6); /* CoreLayout */
1279 skip_bits(&gb, 14); /* CoreSize */
1280 skip_bits(&gb, 1); /* StereoDownmix */
1281 representation_type = get_bits(&gb, 3);
1282 channel_layout_code = get_bits(&gb, 16);
1283
1284 st->codecpar->frame_size =
1285 (frame_duration_code == 0) ? 512 :
1286 (frame_duration_code == 1) ? 1024 :
1287 (frame_duration_code == 2) ? 2048 :
1288 (frame_duration_code == 3) ? 4096 : 0;
1289
1290 /* Publish StreamConstruction as codecpar->profile, including for encrypted
1291 * tracks where frame headers cannot be inspected. */
1292 st->codecpar->profile = mov_dts_stream_construction_to_profile(stream_construction);
1293
1294 channel_layout_mask = mov_dts_channel_layout_to_mask(channel_layout_code);
1295 if (channel_layout_mask) {
1297 av_channel_layout_from_mask(&st->codecpar->ch_layout, channel_layout_mask);
1298 } else if (representation_type == 2 || representation_type == 3) {
1301 }
1302
1303 return 0;
1304}
1305
1307{
1308 AVStream *st;
1309
1310 if (c->fc->nb_streams < 1)
1311 return 0;
1312 st = c->fc->streams[c->fc->nb_streams-1];
1313
1314 if (atom.size < 16)
1315 return 0;
1316
1317 /* skip version and flags */
1318 avio_skip(pb, 4);
1319
1320 ff_mov_read_chan(c->fc, pb, st, atom.size - 4);
1321
1322 return 0;
1323}
1324
1326{
1327 int64_t end = av_sat_add64(avio_tell(pb), atom.size);
1328 int version, flags;
1329 int ret;
1330 AVStream *st;
1331
1332 if (c->fc->nb_streams < 1)
1333 return 0;
1334 st = c->fc->streams[c->fc->nb_streams-1];
1335
1336 version = avio_r8(pb);
1337 flags = avio_rb24(pb);
1338 if (version > 1 || flags != 0) {
1339 av_log(c->fc, AV_LOG_WARNING,
1340 "Unsupported 'chnl' box with version %d, flags: %#x\n",
1341 version, flags);
1342 return 0;
1343 }
1344
1345 ret = ff_mov_read_chnl(c->fc, pb, st, version);
1346 if (ret < 0) {
1347 avio_seek(pb, end, SEEK_SET);
1348 return 0;
1349 }
1350
1351 if (avio_tell(pb) != end) {
1352 av_log(c->fc, AV_LOG_WARNING, "skip %" PRId64 " bytes of unknown data inside chnl\n",
1353 end - avio_tell(pb));
1354 avio_seek(pb, end, SEEK_SET);
1355 }
1356 return ret;
1357}
1358
1360{
1361 AVStream *st;
1362 int ret;
1363
1364 if (c->fc->nb_streams < 1)
1365 return 0;
1366 st = c->fc->streams[c->fc->nb_streams-1];
1367
1368 if ((ret = ff_get_wav_header(c->fc, pb, st->codecpar, atom.size, 0)) < 0)
1369 av_log(c->fc, AV_LOG_WARNING, "get_wav_header failed\n");
1370
1371 return ret;
1372}
1373
1375{
1376 AVStream *st;
1377 HEIFItem *item;
1378 AVPacketSideData *sd;
1379 int width, height, err = 0;
1380 AVRational aperture_width, aperture_height, horiz_off, vert_off;
1381 AVRational pc_x, pc_y;
1382 int64_t top, bottom, left, right;
1383
1384 item = get_heif_item(c, c->cur_item_id);
1385 st = get_curr_st(c);
1386 if (!st)
1387 return 0;
1388
1389 width = st->codecpar->width;
1390 height = st->codecpar->height;
1391 if ((!width || !height) && item) {
1392 width = item->width;
1393 height = item->height;
1394 }
1395 if (!width || !height) {
1396 err = AVERROR_INVALIDDATA;
1397 goto fail;
1398 }
1399
1400 aperture_width.num = avio_rb32(pb);
1401 aperture_width.den = avio_rb32(pb);
1402 aperture_height.num = avio_rb32(pb);
1403 aperture_height.den = avio_rb32(pb);
1404
1405 horiz_off.num = avio_rb32(pb);
1406 horiz_off.den = avio_rb32(pb);
1407 vert_off.num = avio_rb32(pb);
1408 vert_off.den = avio_rb32(pb);
1409
1410 if (aperture_width.num < 0 || aperture_width.den <= 0 ||
1411 aperture_height.num < 0 || aperture_height.den <= 0 ||
1412 horiz_off.den <= 0 || vert_off.den <= 0) {
1413 err = AVERROR_INVALIDDATA;
1414 goto fail;
1415 }
1416 if ((av_cmp_q((AVRational) { width, 1 }, aperture_width) < 0) ||
1417 (av_cmp_q((AVRational) { height, 1 }, aperture_height) < 0)) {
1418 err = AVERROR_INVALIDDATA;
1419 goto fail;
1420 }
1421 av_log(c->fc, AV_LOG_TRACE, "clap: apertureWidth %d/%d, apertureHeight %d/%d "
1422 "horizOff %d/%d vertOff %d/%d\n",
1423 aperture_width.num, aperture_width.den, aperture_height.num, aperture_height.den,
1424 horiz_off.num, horiz_off.den, vert_off.num, vert_off.den);
1425
1426 pc_x = av_mul_q((AVRational) { width - 1, 1 }, (AVRational) { 1, 2 });
1427 pc_x = av_add_q(pc_x, horiz_off);
1428 pc_y = av_mul_q((AVRational) { height - 1, 1 }, (AVRational) { 1, 2 });
1429 pc_y = av_add_q(pc_y, vert_off);
1430
1431 aperture_width = av_sub_q(aperture_width, (AVRational) { 1, 1 });
1432 aperture_width = av_mul_q(aperture_width, (AVRational) { 1, 2 });
1433 aperture_height = av_sub_q(aperture_height, (AVRational) { 1, 1 });
1434 aperture_height = av_mul_q(aperture_height, (AVRational) { 1, 2 });
1435
1436 left = av_q2d(av_sub_q(pc_x, aperture_width));
1437 right = av_q2d(av_add_q(pc_x, aperture_width));
1438 top = av_q2d(av_sub_q(pc_y, aperture_height));
1439 bottom = av_q2d(av_add_q(pc_y, aperture_height));
1440
1441 if (top < 0 || bottom < 0 || bottom > (height - 1) ||
1442 left < 0 || right < 0 || right > (width - 1)) {
1443 err = AVERROR_INVALIDDATA;
1444 goto fail;
1445 }
1446
1447 bottom = height - 1 - bottom;
1448 right = width - 1 - right;
1449
1450 if (!(left | right | top | bottom))
1451 return 0;
1452
1453 if ((left + right) >= width ||
1454 (top + bottom) >= height) {
1455 err = AVERROR_INVALIDDATA;
1456 goto fail;
1457 }
1458
1462 sizeof(uint32_t) * 4, 0);
1463 if (!sd)
1464 return AVERROR(ENOMEM);
1465
1466 AV_WL32A(sd->data, top);
1467 AV_WL32A(sd->data + 4, bottom);
1468 AV_WL32A(sd->data + 8, left);
1469 AV_WL32A(sd->data + 12, right);
1470
1471fail:
1472 if (err < 0) {
1473 int explode = !!(c->fc->error_recognition & AV_EF_EXPLODE);
1474 av_log(c->fc, explode ? AV_LOG_ERROR : AV_LOG_WARNING, "Invalid clap box\n");
1475 if (!explode)
1476 err = 0;
1477 }
1478
1479 return err;
1480}
1481
1482/* This atom overrides any previously set aspect ratio */
1484{
1485 const int num = avio_rb32(pb);
1486 const int den = avio_rb32(pb);
1487 AVStream *st;
1488 MOVStreamContext *sc;
1489
1490 if (c->fc->nb_streams < 1)
1491 return 0;
1492 st = c->fc->streams[c->fc->nb_streams-1];
1493 sc = st->priv_data;
1494
1495 av_log(c->fc, AV_LOG_TRACE, "pasp: hSpacing %d, vSpacing %d\n", num, den);
1496
1497 if (den != 0) {
1498 sc->h_spacing = num;
1499 sc->v_spacing = den;
1500 }
1501 return 0;
1502}
1503
1504/* this atom contains actual media data */
1506{
1507 if (atom.size == 0) /* wrong one (MP4) */
1508 return 0;
1509 c->found_mdat=1;
1510 return 0; /* now go for moov */
1511}
1512
1513#define DRM_BLOB_SIZE 56
1514
1516{
1517 uint8_t intermediate_key[20];
1518 uint8_t intermediate_iv[20];
1519 uint8_t input[64];
1520 uint8_t output[64];
1521 uint8_t file_checksum[20];
1522 uint8_t calculated_checksum[20];
1523 char checksum_string[2 * sizeof(file_checksum) + 1];
1524 struct AVSHA *sha;
1525 int i;
1526 int ret = 0;
1527 uint8_t *activation_bytes = c->activation_bytes;
1528 uint8_t *fixed_key = c->audible_fixed_key;
1529
1530 c->aax_mode = 1;
1531
1532 sha = av_sha_alloc();
1533 if (!sha)
1534 return AVERROR(ENOMEM);
1535 av_free(c->aes_decrypt);
1536 c->aes_decrypt = av_aes_alloc();
1537 if (!c->aes_decrypt) {
1538 ret = AVERROR(ENOMEM);
1539 goto fail;
1540 }
1541
1542 /* drm blob processing */
1543 avio_read(pb, output, 8); // go to offset 8, absolute position 0x251
1544 avio_read(pb, input, DRM_BLOB_SIZE);
1545 avio_read(pb, output, 4); // go to offset 4, absolute position 0x28d
1546 ret = ffio_read_size(pb, file_checksum, 20);
1547 if (ret < 0)
1548 goto fail;
1549
1550 // required by external tools
1551 ff_data_to_hex(checksum_string, file_checksum, sizeof(file_checksum), 1);
1552 av_log(c->fc, AV_LOG_INFO, "[aax] file checksum == %s\n", checksum_string);
1553
1554 /* verify activation data */
1555 if (!activation_bytes) {
1556 av_log(c->fc, AV_LOG_WARNING, "[aax] activation_bytes option is missing!\n");
1557 ret = 0; /* allow ffprobe to continue working on .aax files */
1558 goto fail;
1559 }
1560 if (c->activation_bytes_size != 4) {
1561 av_log(c->fc, AV_LOG_FATAL, "[aax] activation_bytes value needs to be 4 bytes!\n");
1562 ret = AVERROR(EINVAL);
1563 goto fail;
1564 }
1565
1566 /* verify fixed key */
1567 if (c->audible_fixed_key_size != 16) {
1568 av_log(c->fc, AV_LOG_FATAL, "[aax] audible_fixed_key value needs to be 16 bytes!\n");
1569 ret = AVERROR(EINVAL);
1570 goto fail;
1571 }
1572
1573 /* AAX (and AAX+) key derivation */
1574 av_sha_init(sha, 160);
1575 av_sha_update(sha, fixed_key, 16);
1576 av_sha_update(sha, activation_bytes, 4);
1577 av_sha_final(sha, intermediate_key);
1578 av_sha_init(sha, 160);
1579 av_sha_update(sha, fixed_key, 16);
1580 av_sha_update(sha, intermediate_key, 20);
1581 av_sha_update(sha, activation_bytes, 4);
1582 av_sha_final(sha, intermediate_iv);
1583 av_sha_init(sha, 160);
1584 av_sha_update(sha, intermediate_key, 16);
1585 av_sha_update(sha, intermediate_iv, 16);
1586 av_sha_final(sha, calculated_checksum);
1587 if (memcmp(calculated_checksum, file_checksum, 20)) { // critical error
1588 av_log(c->fc, AV_LOG_ERROR, "[aax] mismatch in checksums!\n");
1590 goto fail;
1591 }
1592 av_aes_init(c->aes_decrypt, intermediate_key, 128, 1);
1593 av_aes_crypt(c->aes_decrypt, output, input, DRM_BLOB_SIZE >> 4, intermediate_iv, 1);
1594 for (i = 0; i < 4; i++) {
1595 // file data (in output) is stored in big-endian mode
1596 if (activation_bytes[i] != output[3 - i]) { // critical error
1597 av_log(c->fc, AV_LOG_ERROR, "[aax] error in drm blob decryption!\n");
1599 goto fail;
1600 }
1601 }
1602 memcpy(c->file_key, output + 8, 16);
1603 memcpy(input, output + 26, 16);
1604 av_sha_init(sha, 160);
1605 av_sha_update(sha, input, 16);
1606 av_sha_update(sha, c->file_key, 16);
1607 av_sha_update(sha, fixed_key, 16);
1608 av_sha_final(sha, c->file_iv);
1609
1610fail:
1611 av_free(sha);
1612
1613 return ret;
1614}
1615
1617{
1618 if (c->audible_key_size != 16) {
1619 av_log(c->fc, AV_LOG_FATAL, "[aaxc] audible_key value needs to be 16 bytes!\n");
1620 return AVERROR(EINVAL);
1621 }
1622
1623 if (c->audible_iv_size != 16) {
1624 av_log(c->fc, AV_LOG_FATAL, "[aaxc] audible_iv value needs to be 16 bytes!\n");
1625 return AVERROR(EINVAL);
1626 }
1627
1628 c->aes_decrypt = av_aes_alloc();
1629 if (!c->aes_decrypt) {
1630 return AVERROR(ENOMEM);
1631 }
1632
1633 memcpy(c->file_key, c->audible_key, 16);
1634 memcpy(c->file_iv, c->audible_iv, 16);
1635 c->aax_mode = 1;
1636
1637 return 0;
1638}
1639
1640// Audible AAX (and AAX+) bytestream decryption
1641static int aax_filter(uint8_t *input, int size, MOVContext *c)
1642{
1643 int blocks = 0;
1644 unsigned char iv[16];
1645
1646 memcpy(iv, c->file_iv, 16); // iv is overwritten
1647 blocks = size >> 4; // trailing bytes are not encrypted!
1648 av_aes_init(c->aes_decrypt, c->file_key, 128, 1);
1649 av_aes_crypt(c->aes_decrypt, input, input, blocks, iv, 1);
1650
1651 return 0;
1652}
1653
1654/* read major brand, minor version and compatible brands and store them as metadata */
1656{
1657 uint32_t minor_ver;
1658 int comp_brand_size;
1659 char* comp_brands_str;
1660 uint8_t type[5] = {0};
1661 int ret = ffio_read_size(pb, type, 4);
1662 if (ret < 0)
1663 return ret;
1664 if (c->fc->nb_streams) {
1665 if (c->fc->strict_std_compliance >= FF_COMPLIANCE_STRICT)
1666 return AVERROR_INVALIDDATA;
1667 av_log(c->fc, AV_LOG_DEBUG, "Ignoring duplicate FTYP\n");
1668 return 0;
1669 }
1670
1671 if (strcmp(type, "qt "))
1672 c->isom = 1;
1673 av_log(c->fc, AV_LOG_DEBUG, "ISO: File Type Major Brand: %.4s\n",(char *)&type);
1674 av_dict_set(&c->fc->metadata, "major_brand", type, 0);
1675 minor_ver = avio_rb32(pb); /* minor version */
1676 av_dict_set_int(&c->fc->metadata, "minor_version", minor_ver, 0);
1677
1678 comp_brand_size = atom.size - 8;
1679 if (comp_brand_size < 0 || comp_brand_size == INT_MAX)
1680 return AVERROR_INVALIDDATA;
1681 comp_brands_str = av_malloc(comp_brand_size + 1); /* Add null terminator */
1682 if (!comp_brands_str)
1683 return AVERROR(ENOMEM);
1684
1685 ret = ffio_read_size(pb, comp_brands_str, comp_brand_size);
1686 if (ret < 0) {
1687 av_freep(&comp_brands_str);
1688 return ret;
1689 }
1690 comp_brands_str[comp_brand_size] = 0;
1691 av_dict_set(&c->fc->metadata, "compatible_brands",
1692 comp_brands_str, AV_DICT_DONT_STRDUP_VAL);
1693
1694 // Logic for handling Audible's .aaxc files
1695 if (!strcmp(type, "aaxc")) {
1697 }
1698
1699 return 0;
1700}
1701
1702/* this atom should contain all header atoms */
1704{
1705 int ret;
1706
1707 if (c->found_moov) {
1708 av_log(c->fc, AV_LOG_WARNING, "Found duplicated MOOV Atom. Skipped it\n");
1709 avio_skip(pb, atom.size);
1710 return 0;
1711 }
1712
1713 if ((ret = mov_read_default(c, pb, atom)) < 0)
1714 return ret;
1715 /* we parsed the 'moov' atom, we can terminate the parsing as soon as we find the 'mdat' */
1716 /* so we don't parse the whole file if over a network */
1717 c->found_moov=1;
1718 return 0; /* now go for mdat */
1719}
1720
1722 MOVFragmentIndex *frag_index,
1723 int index,
1724 int id)
1725{
1726 int i;
1727 MOVFragmentIndexItem * item;
1728
1729 if (index < 0 || index >= frag_index->nb_items)
1730 return NULL;
1731 item = &frag_index->item[index];
1732 for (i = 0; i < item->nb_stream_info; i++)
1733 if (item->stream_info[i].id == id)
1734 return &item->stream_info[i];
1735
1736 // This shouldn't happen
1737 return NULL;
1738}
1739
1740static void set_frag_stream(MOVFragmentIndex *frag_index, int id)
1741{
1742 int i;
1743 MOVFragmentIndexItem * item;
1744
1745 if (frag_index->current < 0 ||
1746 frag_index->current >= frag_index->nb_items)
1747 return;
1748
1749 item = &frag_index->item[frag_index->current];
1750 for (i = 0; i < item->nb_stream_info; i++)
1751 if (item->stream_info[i].id == id) {
1752 item->current = i;
1753 return;
1754 }
1755
1756 // id not found. This shouldn't happen.
1757 item->current = -1;
1758}
1759
1761 MOVFragmentIndex *frag_index)
1762{
1764 if (frag_index->current < 0 ||
1765 frag_index->current >= frag_index->nb_items)
1766 return NULL;
1767
1768 item = &frag_index->item[frag_index->current];
1769 if (item->current >= 0 && item->current < item->nb_stream_info)
1770 return &item->stream_info[item->current];
1771
1772 // This shouldn't happen
1773 return NULL;
1774}
1775
1777{
1778 int a, b, m;
1779 int64_t moof_offset;
1780
1781 // Optimize for appending new entries
1782 if (!frag_index->nb_items ||
1783 frag_index->item[frag_index->nb_items - 1].moof_offset < offset)
1784 return frag_index->nb_items;
1785
1786 a = -1;
1787 b = frag_index->nb_items;
1788
1789 while (b - a > 1) {
1790 m = (a + b) >> 1;
1791 moof_offset = frag_index->item[m].moof_offset;
1792 if (moof_offset >= offset)
1793 b = m;
1794 if (moof_offset <= offset)
1795 a = m;
1796 }
1797 return b;
1798}
1799
1801{
1802 av_assert0(frag_stream_info);
1803 if (frag_stream_info->sidx_pts != AV_NOPTS_VALUE)
1804 return frag_stream_info->sidx_pts;
1805 if (frag_stream_info->first_tfra_pts != AV_NOPTS_VALUE)
1806 return frag_stream_info->first_tfra_pts;
1807 return frag_stream_info->tfdt_dts;
1808}
1809
1811 MOVFragmentIndex *frag_index, int index)
1812{
1813 MOVFragmentStreamInfo * frag_stream_info;
1814 MOVStreamContext *sc = dst_st->priv_data;
1815 int64_t timestamp;
1816 int i, j;
1817
1818 // If the stream is referenced by any sidx, limit the search
1819 // to fragments that referenced this stream in the sidx
1820 if (sc->has_sidx) {
1821 frag_stream_info = get_frag_stream_info(frag_index, index, sc->id);
1822 if (!frag_stream_info)
1823 return AV_NOPTS_VALUE;
1824 if (frag_stream_info->sidx_pts != AV_NOPTS_VALUE)
1825 return frag_stream_info->sidx_pts;
1826 if (frag_stream_info->first_tfra_pts != AV_NOPTS_VALUE)
1827 return frag_stream_info->first_tfra_pts;
1828 return frag_stream_info->sidx_pts;
1829 }
1830
1831 for (i = 0; i < frag_index->item[index].nb_stream_info; i++) {
1832 if (dst_st->id != frag_index->item[index].stream_info[i].id)
1833 continue;
1834 AVStream *frag_stream = NULL;
1835 frag_stream_info = &frag_index->item[index].stream_info[i];
1836 for (j = 0; j < s->nb_streams; j++) {
1837 MOVStreamContext *sc2 = s->streams[j]->priv_data;
1838 if (sc2->id == frag_stream_info->id)
1839 frag_stream = s->streams[j];
1840 }
1841 if (!frag_stream) {
1842 av_log(s, AV_LOG_WARNING, "No stream matching sidx ID found.\n");
1843 continue;
1844 }
1845 timestamp = get_stream_info_time(frag_stream_info);
1846 if (timestamp != AV_NOPTS_VALUE)
1847 return av_rescale_q(timestamp, frag_stream->time_base, dst_st->time_base);
1848 }
1849 return AV_NOPTS_VALUE;
1850}
1851
1853 AVStream *st, int64_t timestamp)
1854{
1855 int a, b, m, m0;
1856 int64_t frag_time;
1857
1858 a = -1;
1859 b = frag_index->nb_items;
1860
1861 while (b - a > 1) {
1862 m0 = m = (a + b) >> 1;
1863
1864 while (m < b &&
1865 (frag_time = get_frag_time(s, st, frag_index, m)) == AV_NOPTS_VALUE)
1866 m++;
1867
1868 if (m < b && frag_time <= timestamp)
1869 a = m;
1870 else
1871 b = m0;
1872 }
1873
1874 return a;
1875}
1876
1878{
1879 int index, i;
1880 MOVFragmentIndexItem * item;
1881 MOVFragmentStreamInfo * frag_stream_info;
1882
1883 // If moof_offset already exists in frag_index, return index to it
1884 index = search_frag_moof_offset(&c->frag_index, offset);
1885 if (index < c->frag_index.nb_items &&
1886 c->frag_index.item[index].moof_offset == offset)
1887 return index;
1888
1889 // offset is not yet in frag index.
1890 // Insert new item at index (sorted by moof offset)
1891 item = av_fast_realloc(c->frag_index.item,
1892 &c->frag_index.allocated_size,
1893 (c->frag_index.nb_items + 1) *
1894 sizeof(*c->frag_index.item));
1895 if (!item)
1896 return -1;
1897 c->frag_index.item = item;
1898
1899 frag_stream_info = av_realloc_array(NULL, c->fc->nb_streams,
1900 sizeof(*item->stream_info));
1901 if (!frag_stream_info)
1902 return -1;
1903
1904 for (i = 0; i < c->fc->nb_streams; i++) {
1905 // Avoid building frag index if streams lack track id.
1906 MOVStreamContext *sc = c->fc->streams[i]->priv_data;
1907 if (sc->id < 0) {
1908 av_free(frag_stream_info);
1909 return AVERROR_INVALIDDATA;
1910 }
1911
1912 frag_stream_info[i].id = sc->id;
1913 frag_stream_info[i].sidx_pts = AV_NOPTS_VALUE;
1914 frag_stream_info[i].tfdt_dts = AV_NOPTS_VALUE;
1915 frag_stream_info[i].next_trun_dts = AV_NOPTS_VALUE;
1916 frag_stream_info[i].first_tfra_pts = AV_NOPTS_VALUE;
1917 frag_stream_info[i].index_base = -1;
1918 frag_stream_info[i].index_entry = -1;
1919 frag_stream_info[i].encryption_index = NULL;
1920 frag_stream_info[i].stsd_id = -1;
1921 }
1922
1923 if (index < c->frag_index.nb_items)
1924 memmove(c->frag_index.item + index + 1, c->frag_index.item + index,
1925 (c->frag_index.nb_items - index) * sizeof(*c->frag_index.item));
1926 if (index <= c->frag_index.current)
1927 c->frag_index.current++;
1928
1929 item = &c->frag_index.item[index];
1930 item->headers_read = 0;
1931 item->current = 0;
1932 item->nb_stream_info = c->fc->nb_streams;
1933 item->moof_offset = offset;
1934 item->stream_info = frag_stream_info;
1935 c->frag_index.nb_items++;
1936
1937 return index;
1938}
1939
1940static void fix_frag_index_entries(MOVFragmentIndex *frag_index, int index,
1941 int id, int entries)
1942{
1943 int i;
1944 MOVFragmentStreamInfo * frag_stream_info;
1945
1946 if (index < 0)
1947 return;
1948 for (i = index; i < frag_index->nb_items; i++) {
1949 frag_stream_info = get_frag_stream_info(frag_index, i, id);
1950 if (frag_stream_info && frag_stream_info->index_entry >= 0)
1951 frag_stream_info->index_entry += entries;
1952 }
1953}
1954
1956{
1957 // Set by mov_read_tfhd(). mov_read_trun() will reject files missing tfhd.
1958 c->fragment.found_tfhd = 0;
1959
1960 if (!c->has_looked_for_mfra && c->use_mfra_for > 0) {
1961 c->has_looked_for_mfra = 1;
1962 if (pb->seekable & AVIO_SEEKABLE_NORMAL) {
1963 int ret;
1964 av_log(c->fc, AV_LOG_VERBOSE, "stream has moof boxes, will look "
1965 "for a mfra\n");
1966 if ((ret = mov_read_mfra(c, pb)) < 0) {
1967 av_log(c->fc, AV_LOG_VERBOSE, "found a moof box but failed to "
1968 "read the mfra (may be a live ismv)\n");
1969 }
1970 } else {
1971 av_log(c->fc, AV_LOG_VERBOSE, "found a moof box but stream is not "
1972 "seekable, can not look for mfra\n");
1973 }
1974 }
1975 c->fragment.moof_offset = c->fragment.implicit_offset = avio_tell(pb) - 8;
1976 av_log(c->fc, AV_LOG_TRACE, "moof offset %"PRIx64"\n", c->fragment.moof_offset);
1977 c->frag_index.current = update_frag_index(c, c->fragment.moof_offset);
1978 return mov_read_default(c, pb, atom);
1979}
1980
1982{
1983 int64_t time;
1984 if (version == 1) {
1985 time = avio_rb64(pb);
1986 avio_rb64(pb);
1987 if (time < 0) {
1988 av_log(c->fc, AV_LOG_DEBUG, "creation_time is negative\n");
1989 return;
1990 }
1991 } else {
1992 time = avio_rb32(pb);
1993 avio_rb32(pb); /* modification time */
1994 if (time > 0 && time < 2082844800) {
1995 av_log(c->fc, AV_LOG_WARNING, "Detected creation time before 1970, parsing as unix timestamp.\n");
1996 time += 2082844800;
1997 }
1998 }
1999 if (time) {
2000 time -= 2082844800; /* seconds between 1904-01-01 and Epoch */
2001
2002 if ((int64_t)(time * 1000000ULL) / 1000000 != time) {
2003 av_log(c->fc, AV_LOG_DEBUG, "creation_time is not representable\n");
2004 return;
2005 }
2006
2007 ff_dict_set_timestamp(metadata, "creation_time", time * 1000000);
2008 }
2009}
2010
2012{
2013 AVStream *st;
2014 MOVStreamContext *sc;
2015 int version;
2016 char language[4] = {0};
2017 unsigned lang;
2018
2019 if (c->fc->nb_streams < 1)
2020 return 0;
2021 st = c->fc->streams[c->fc->nb_streams-1];
2022 sc = st->priv_data;
2023
2024 if (sc->time_scale) {
2025 av_log(c->fc, AV_LOG_ERROR, "Multiple mdhd?\n");
2026 return AVERROR_INVALIDDATA;
2027 }
2028
2029 version = avio_r8(pb);
2030 if (version > 1) {
2031 avpriv_request_sample(c->fc, "Version %d", version);
2032 return AVERROR_PATCHWELCOME;
2033 }
2034 avio_rb24(pb); /* flags */
2036
2037 sc->time_scale = avio_rb32(pb);
2038 if (sc->time_scale <= 0) {
2039 av_log(c->fc, AV_LOG_ERROR, "Invalid mdhd time scale %d, defaulting to 1\n", sc->time_scale);
2040 sc->time_scale = 1;
2041 }
2042 st->duration = (version == 1) ? avio_rb64(pb) : avio_rb32(pb); /* duration */
2043
2044 if ((version == 1 && st->duration == UINT64_MAX) ||
2045 (version != 1 && st->duration == UINT32_MAX)) {
2046 st->duration = 0;
2047 }
2048
2049 lang = avio_rb16(pb); /* language */
2050 if (ff_mov_lang_to_iso639(lang, language))
2051 av_dict_set(&st->metadata, "language", language, 0);
2052 avio_rb16(pb); /* quality */
2053
2054 return 0;
2055}
2056
2058{
2059 int i;
2060 int version = avio_r8(pb); /* version */
2061 avio_rb24(pb); /* flags */
2062
2063 mov_metadata_creation_time(c, pb, &c->fc->metadata, version);
2064 c->time_scale = avio_rb32(pb); /* time scale */
2065 if (c->time_scale <= 0) {
2066 av_log(c->fc, AV_LOG_ERROR, "Invalid mvhd time scale %d, defaulting to 1\n", c->time_scale);
2067 c->time_scale = 1;
2068 }
2069 av_log(c->fc, AV_LOG_TRACE, "time scale = %i\n", c->time_scale);
2070
2071 c->duration = (version == 1) ? avio_rb64(pb) : avio_rb32(pb); /* duration */
2072 avio_rb32(pb); /* preferred scale */
2073
2074 avio_rb16(pb); /* preferred volume */
2075
2076 avio_skip(pb, 10); /* reserved */
2077
2078 /* movie display matrix, store it in main context and use it later on */
2079 for (i = 0; i < 3; i++) {
2080 c->movie_display_matrix[i][0] = avio_rb32(pb); // 16.16 fixed point
2081 c->movie_display_matrix[i][1] = avio_rb32(pb); // 16.16 fixed point
2082 c->movie_display_matrix[i][2] = avio_rb32(pb); // 2.30 fixed point
2083 }
2084
2085 avio_rb32(pb); /* preview time */
2086 avio_rb32(pb); /* preview duration */
2087 avio_rb32(pb); /* poster time */
2088 avio_rb32(pb); /* selection time */
2089 avio_rb32(pb); /* selection duration */
2090 avio_rb32(pb); /* current time */
2091 avio_rb32(pb); /* next track ID */
2092
2093 return 0;
2094}
2095
2097{
2098 AVStream *st;
2099
2100 if (fc->nb_streams < 1)
2101 return;
2102 st = fc->streams[fc->nb_streams-1];
2103
2104 switch (st->codecpar->codec_id) {
2107 break;
2110 break;
2113 break;
2116 break;
2119 break;
2120 default:
2121 break;
2122 }
2123}
2124
2126{
2127 int little_endian = avio_rb16(pb) & 0xFF;
2128 av_log(c->fc, AV_LOG_TRACE, "enda %d\n", little_endian);
2129 if (little_endian == 1)
2131 return 0;
2132}
2133
2135{
2136 int format_flags;
2137 int version, flags;
2138 int pcm_sample_size;
2139 AVFormatContext *fc = c->fc;
2140 AVStream *st;
2141 MOVStreamContext *sc;
2142
2143 if (atom.size < 6) {
2144 av_log(c->fc, AV_LOG_ERROR, "Empty pcmC box\n");
2145 return AVERROR_INVALIDDATA;
2146 }
2147
2148 version = avio_r8(pb);
2149 flags = avio_rb24(pb);
2150
2151 if (version != 0 || flags != 0) {
2152 av_log(c->fc, AV_LOG_ERROR,
2153 "Unsupported 'pcmC' box with version %d, flags: %x",
2154 version, flags);
2155 return AVERROR_INVALIDDATA;
2156 }
2157
2158 format_flags = avio_r8(pb);
2159 pcm_sample_size = avio_r8(pb);
2160
2161 if (fc->nb_streams < 1)
2162 return AVERROR_INVALIDDATA;
2163
2164 st = fc->streams[fc->nb_streams - 1];
2165 sc = st->priv_data;
2166
2167 if (sc->format == MOV_MP4_FPCM_TAG) {
2168 switch (pcm_sample_size) {
2169 case 32:
2171 break;
2172 case 64:
2174 break;
2175 default:
2176 av_log(fc, AV_LOG_ERROR, "invalid pcm_sample_size %d for %s\n",
2177 pcm_sample_size,
2178 av_fourcc2str(sc->format));
2179 return AVERROR_INVALIDDATA;
2180 }
2181 } else if (sc->format == MOV_MP4_IPCM_TAG) {
2182 switch (pcm_sample_size) {
2183 case 16:
2185 break;
2186 case 24:
2188 break;
2189 case 32:
2191 break;
2192 default:
2193 av_log(fc, AV_LOG_ERROR, "invalid pcm_sample_size %d for %s\n",
2194 pcm_sample_size,
2195 av_fourcc2str(sc->format));
2196 return AVERROR_INVALIDDATA;
2197 }
2198 } else {
2199 av_log(fc, AV_LOG_ERROR, "'pcmC' with invalid sample entry '%s'\n",
2200 av_fourcc2str(sc->format));
2201 return AVERROR_INVALIDDATA;
2202 }
2203
2204 if (format_flags & 1) // indicates little-endian format. If not present, big-endian format is used
2207
2208 return 0;
2209}
2210
2212{
2213 AVStream *st;
2214 HEIFItem *item = NULL;
2215 char color_parameter_type[5] = { 0 };
2216 uint16_t color_primaries, color_trc, color_matrix;
2217 int ret;
2218
2219 st = get_curr_st(c);
2220 if (!st) {
2221 item = get_heif_item(c, c->cur_item_id);
2222 if (!item)
2223 return 0;
2224 }
2225
2226 ret = ffio_read_size(pb, color_parameter_type, 4);
2227 if (ret < 0)
2228 return ret;
2229 if (strncmp(color_parameter_type, "nclx", 4) &&
2230 strncmp(color_parameter_type, "nclc", 4) &&
2231 strncmp(color_parameter_type, "prof", 4)) {
2232 av_log(c->fc, AV_LOG_WARNING, "unsupported color_parameter_type %s\n",
2233 color_parameter_type);
2234 return 0;
2235 }
2236
2237 if (!strncmp(color_parameter_type, "prof", 4)) {
2238 AVPacketSideData *sd;
2239 uint8_t *icc_profile;
2240 if (st) {
2244 atom.size - 4, 0);
2245 if (!sd)
2246 return AVERROR(ENOMEM);
2247 icc_profile = sd->data;
2248 } else {
2249 if (c->heif_icc_profile_items >= c->fc->max_streams) {
2250 av_log(c->fc, AV_LOG_WARNING,
2251 "HEIF ICC profile copies exceed cap %d; ignoring further items\n",
2252 c->fc->max_streams);
2253 return 0;
2254 }
2255 av_freep(&item->icc_profile);
2256 icc_profile = item->icc_profile = av_malloc(atom.size - 4);
2257 if (!icc_profile) {
2258 item->icc_profile_size = 0;
2259 return AVERROR(ENOMEM);
2260 }
2261 item->icc_profile_size = atom.size - 4;
2262 c->heif_icc_profile_items++;
2263 }
2264 ret = ffio_read_size(pb, icc_profile, atom.size - 4);
2265 if (ret < 0)
2266 return ret;
2267 } else if (st) {
2269 color_trc = avio_rb16(pb);
2270 color_matrix = avio_rb16(pb);
2271
2272 av_log(c->fc, AV_LOG_TRACE,
2273 "%s: pri %d trc %d matrix %d",
2274 color_parameter_type, color_primaries, color_trc, color_matrix);
2275
2276 if (!strncmp(color_parameter_type, "nclx", 4)) {
2277 uint8_t color_range = avio_r8(pb) >> 7;
2278 av_log(c->fc, AV_LOG_TRACE, " full %"PRIu8"", color_range);
2279 if (color_range)
2281 else
2283 }
2284
2287 if (!av_color_transfer_name(color_trc))
2288 color_trc = AVCOL_TRC_UNSPECIFIED;
2289 if (!av_color_space_name(color_matrix))
2290 color_matrix = AVCOL_SPC_UNSPECIFIED;
2291
2293 st->codecpar->color_trc = color_trc;
2294 st->codecpar->color_space = color_matrix;
2295 av_log(c->fc, AV_LOG_TRACE, "\n");
2296 }
2297 return 0;
2298}
2299
2301{
2302 AVStream *st;
2303 unsigned mov_field_order;
2304 enum AVFieldOrder decoded_field_order = AV_FIELD_UNKNOWN;
2305
2306 if (c->fc->nb_streams < 1) // will happen with jp2 files
2307 return 0;
2308 st = c->fc->streams[c->fc->nb_streams-1];
2309 if (atom.size < 2)
2310 return AVERROR_INVALIDDATA;
2311 mov_field_order = avio_rb16(pb);
2312 if ((mov_field_order & 0xFF00) == 0x0100)
2313 decoded_field_order = AV_FIELD_PROGRESSIVE;
2314 else if ((mov_field_order & 0xFF00) == 0x0200) {
2315 switch (mov_field_order & 0xFF) {
2316 case 0x01: decoded_field_order = AV_FIELD_TT;
2317 break;
2318 case 0x06: decoded_field_order = AV_FIELD_BB;
2319 break;
2320 case 0x09: decoded_field_order = AV_FIELD_TB;
2321 break;
2322 case 0x0E: decoded_field_order = AV_FIELD_BT;
2323 break;
2324 }
2325 }
2326 if (decoded_field_order == AV_FIELD_UNKNOWN && mov_field_order) {
2327 av_log(c->fc, AV_LOG_ERROR, "Unknown MOV field order 0x%04x\n", mov_field_order);
2328 }
2329 st->codecpar->field_order = decoded_field_order;
2330
2331 return 0;
2332}
2333
2335{
2336 int err = 0;
2337 uint64_t size = (uint64_t)par->extradata_size + atom.size + 8 + AV_INPUT_BUFFER_PADDING_SIZE;
2338 if (size > INT_MAX || (uint64_t)atom.size > INT_MAX)
2339 return AVERROR_INVALIDDATA;
2340 if ((err = av_reallocp(&par->extradata, size)) < 0) {
2341 par->extradata_size = 0;
2342 return err;
2343 }
2345 return 0;
2346}
2347
2348/* Read a whole atom into the extradata return the size of the atom read, possibly truncated if != atom.size */
2350 AVCodecParameters *par, uint8_t *buf)
2351{
2352 int64_t result = atom.size;
2353 int err;
2354
2355 AV_WB32(buf , atom.size + 8);
2356 AV_WL32(buf + 4, atom.type);
2357 err = ffio_read_size(pb, buf + 8, atom.size);
2358 if (err < 0) {
2359 par->extradata_size -= atom.size;
2360 return err;
2361 } else if (err < atom.size) {
2362 av_log(c->fc, AV_LOG_WARNING, "truncated extradata\n");
2363 par->extradata_size -= atom.size - err;
2364 result = err;
2365 }
2366 memset(buf + 8 + err, 0, AV_INPUT_BUFFER_PADDING_SIZE);
2367 return result;
2368}
2369
2370/* FIXME modify QDM2/SVQ3/H.264 decoders to take full atom as extradata */
2372 enum AVCodecID codec_id)
2373{
2374 AVStream *st;
2375 uint64_t original_size;
2376 int err;
2377
2378 if (c->fc->nb_streams < 1) // will happen with jp2 files
2379 return 0;
2380 st = c->fc->streams[c->fc->nb_streams-1];
2381
2382 if (st->codecpar->codec_id != codec_id)
2383 return 0; /* unexpected codec_id - don't mess with extradata */
2384
2385 original_size = st->codecpar->extradata_size;
2386 err = mov_realloc_extradata(st->codecpar, atom);
2387 if (err)
2388 return err;
2389
2390 err = mov_read_atom_into_extradata(c, pb, atom, st->codecpar, st->codecpar->extradata + original_size);
2391 if (err < 0)
2392 return err;
2393 return 0; // Note: this is the original behavior to ignore truncation.
2394}
2395
2396/* wrapper functions for reading ALAC/AVS/MJPEG/MJPEG2000 extradata atoms only for those codecs */
2398{
2399 return mov_read_extradata(c, pb, atom, AV_CODEC_ID_ALAC);
2400}
2401
2403{
2404 return mov_read_extradata(c, pb, atom, AV_CODEC_ID_CAVS);
2405}
2406
2408{
2409 return mov_read_extradata(c, pb, atom, AV_CODEC_ID_JPEG2000);
2410}
2411
2413{
2414 return mov_read_extradata(c, pb, atom, AV_CODEC_ID_R10K);
2415}
2416
2418{
2419 int ret = mov_read_extradata(c, pb, atom, AV_CODEC_ID_AVUI);
2420 if (!ret)
2422 return ret;
2423}
2424
2426{
2428
2429 if (!ret && c->fc->nb_streams >= 1) {
2430 AVCodecParameters *par = c->fc->streams[c->fc->nb_streams-1]->codecpar;
2431 if (par->extradata_size >= 40) {
2432 par->height = AV_RB16(&par->extradata[36]);
2433 par->width = AV_RB16(&par->extradata[38]);
2434 }
2435 }
2436 return ret;
2437}
2438
2440{
2441 if (c->fc->nb_streams >= 1) {
2442 AVStream *const st = c->fc->streams[c->fc->nb_streams - 1];
2443 FFStream *const sti = ffstream(st);
2444 AVCodecParameters *par = st->codecpar;
2445
2446 if (par->codec_tag == MKTAG('A', 'V', 'i', 'n') &&
2447 par->codec_id == AV_CODEC_ID_H264 &&
2448 atom.size > 11) {
2449 int cid;
2450 avio_skip(pb, 10);
2451 cid = avio_rb16(pb);
2452 /* For AVID AVCI50, force width of 1440 to be able to select the correct SPS and PPS */
2453 if (cid == 0xd4d || cid == 0xd4e)
2454 par->width = 1440;
2455 return 0;
2456 } else if ((par->codec_tag == MKTAG('A', 'V', 'd', '1') ||
2457 par->codec_tag == MKTAG('A', 'V', 'j', '2') ||
2458 par->codec_tag == MKTAG('A', 'V', 'd', 'n')) &&
2459 atom.size >= 24) {
2460 int num, den;
2461 avio_skip(pb, 12);
2462 num = avio_rb32(pb);
2463 den = avio_rb32(pb);
2464 if (num <= 0 || den <= 0)
2465 return 0;
2466 switch (avio_rb32(pb)) {
2467 case 2:
2468 if (den >= INT_MAX / 2)
2469 return 0;
2470 den *= 2;
2472 case 1:
2473 sti->display_aspect_ratio = (AVRational){ num, den };
2475 default:
2476 return 0;
2477 }
2478 }
2479 }
2480
2481 return mov_read_avid(c, pb, atom);
2482}
2483
2485{
2486 int ret = 0;
2487 int length = 0;
2488 uint64_t original_size;
2489 if (c->fc->nb_streams >= 1) {
2490 AVCodecParameters *par = c->fc->streams[c->fc->nb_streams-1]->codecpar;
2491 if (par->codec_id == AV_CODEC_ID_H264)
2492 return 0;
2493 if (atom.size == 16) {
2494 original_size = par->extradata_size;
2495 ret = mov_realloc_extradata(par, atom);
2496 if (!ret) {
2497 length = mov_read_atom_into_extradata(c, pb, atom, par, par->extradata + original_size);
2498 if (length == atom.size) {
2499 const uint8_t range_value = par->extradata[original_size + 19];
2500 switch (range_value) {
2501 case 1:
2503 break;
2504 case 2:
2506 break;
2507 default:
2508 av_log(c->fc, AV_LOG_WARNING, "ignored unknown aclr value (%d)\n", range_value);
2509 break;
2510 }
2511 ff_dlog(c->fc, "color_range: %d\n", par->color_range);
2512 } else {
2513 /* For some reason the whole atom was not added to the extradata */
2514 av_log(c->fc, AV_LOG_ERROR, "aclr not decoded - incomplete atom\n");
2515 }
2516 } else {
2517 av_log(c->fc, AV_LOG_ERROR, "aclr not decoded - unable to add atom to extradata\n");
2518 }
2519 } else {
2520 av_log(c->fc, AV_LOG_WARNING, "aclr not decoded - unexpected size %"PRId64"\n", atom.size);
2521 }
2522 }
2523
2524 return ret;
2525}
2526
2528{
2529 return mov_read_extradata(c, pb, atom, AV_CODEC_ID_SVQ3);
2530}
2531
2533{
2534 AVStream *st;
2535 int ret;
2536
2537 if (c->fc->nb_streams < 1)
2538 return 0;
2539 st = c->fc->streams[c->fc->nb_streams-1];
2540
2541 if ((uint64_t)atom.size > (1<<30))
2542 return AVERROR_INVALIDDATA;
2543
2544 if (st->codecpar->codec_id == AV_CODEC_ID_QDM2 ||
2547 // pass all frma atom to codec, needed at least for QDMC and QDM2
2548 ret = ff_get_extradata(c->fc, st->codecpar, pb, atom.size);
2549 if (ret < 0)
2550 return ret;
2551 } else if (atom.size > 8) { /* to read frma, esds atoms */
2552 if (st->codecpar->codec_id == AV_CODEC_ID_ALAC && atom.size >= 24) {
2553 uint64_t buffer;
2554 ret = ffio_ensure_seekback(pb, 8);
2555 if (ret < 0)
2556 return ret;
2557 buffer = avio_rb64(pb);
2558 atom.size -= 8;
2559 if ( (buffer & 0xFFFFFFFF) == MKBETAG('f','r','m','a')
2560 && buffer >> 32 <= atom.size
2561 && buffer >> 32 >= 8) {
2562 avio_skip(pb, -8);
2563 atom.size += 8;
2564 } else if (!st->codecpar->extradata_size) {
2565#define ALAC_EXTRADATA_SIZE 36
2567 if (!st->codecpar->extradata)
2568 return AVERROR(ENOMEM);
2571 AV_WB32(st->codecpar->extradata + 4, MKTAG('a','l','a','c'));
2572 AV_WB64(st->codecpar->extradata + 12, buffer);
2573 avio_read(pb, st->codecpar->extradata + 20, 16);
2574 avio_skip(pb, atom.size - 24);
2575 return 0;
2576 }
2577 }
2578 if ((ret = mov_read_default(c, pb, atom)) < 0)
2579 return ret;
2580 } else
2581 avio_skip(pb, atom.size);
2582 return 0;
2583}
2584
2585/**
2586 * This function reads atom content and puts data in extradata without tag
2587 * nor size unlike mov_read_extradata.
2588 */
2590{
2591 AVStream *st;
2592 int ret;
2593
2594 st = get_curr_st(c);
2595 if (!st)
2596 return 0;
2597
2598 if ((uint64_t)atom.size > (1<<30))
2599 return AVERROR_INVALIDDATA;
2600
2601 if (atom.type == MKTAG('v','v','c','C')) {
2602 avio_skip(pb, 4);
2603 atom.size -= 4;
2604 }
2605
2606 if (atom.size >= 10) {
2607 // Broken files created by legacy versions of libavformat will
2608 // wrap a whole fiel atom inside of a glbl atom.
2609 unsigned size = avio_rb32(pb);
2610 unsigned type = avio_rl32(pb);
2611 if (avio_feof(pb))
2612 return AVERROR_INVALIDDATA;
2613 avio_seek(pb, -8, SEEK_CUR);
2614 if (type == MKTAG('f','i','e','l') && size == atom.size)
2615 return mov_read_default(c, pb, atom);
2616 }
2617 if (st->codecpar->extradata_size > 1 && st->codecpar->extradata) {
2618 av_log(c->fc, AV_LOG_WARNING, "ignoring multiple glbl\n");
2619 return 0;
2620 }
2621 ret = ff_get_extradata(c->fc, st->codecpar, pb, atom.size);
2622 if (ret < 0)
2623 return ret;
2624 if (atom.type == MKTAG('h','v','c','C') && st->codecpar->codec_tag == MKTAG('d','v','h','1'))
2625 /* HEVC-based Dolby Vision derived from hvc1.
2626 Happens to match with an identifier
2627 previously utilized for DV. Thus, if we have
2628 the hvcC extradata box available as specified,
2629 set codec to HEVC */
2631
2632 return 0;
2633}
2634
2636{
2637 AVStream *st;
2638 uint8_t profile_level;
2639 int ret;
2640
2641 if (c->fc->nb_streams < 1)
2642 return 0;
2643 st = c->fc->streams[c->fc->nb_streams-1];
2644
2645 if (atom.size >= (1<<28) || atom.size < 7)
2646 return AVERROR_INVALIDDATA;
2647
2648 profile_level = avio_r8(pb);
2649 if ((profile_level & 0xf0) != 0xc0)
2650 return 0;
2651
2652 avio_seek(pb, 6, SEEK_CUR);
2653 ret = ff_get_extradata(c->fc, st->codecpar, pb, atom.size - 7);
2654 if (ret < 0)
2655 return ret;
2656
2657 return 0;
2658}
2659
2660static int mov_find_tref_id(const MovTref *tag, uint32_t id)
2661{
2662 for (int i = 0; i < tag->nb_id; i++) {
2663 if (tag->id[i] == id)
2664 return 1;
2665 }
2666 return 0;
2667}
2668
2669static int mov_add_tref_id(MovTref *tag, uint32_t id)
2670{
2671 int ret = mov_find_tref_id(tag, id);
2672
2673 if (!ret) {
2674 uint32_t *tmp = av_realloc_array(tag->id, tag->nb_id + 1, sizeof(*tag->id));
2675 if (!tmp)
2676 return AVERROR(ENOMEM);
2677 tag->id = tmp;
2678 tag->id[tag->nb_id++] = id;
2679 }
2680
2681 return 0;
2682}
2683
2685{
2686 for (int i = 0; i < sc->nb_tref_tags; i++) {
2687 MovTref *entry = &sc->tref_tags[i];
2688
2689 if (entry->name == name)
2690 return entry;
2691 }
2692 return NULL;
2693}
2694
2696{
2698
2699 if (!tag) {
2701 sizeof(*sc->tref_tags));
2702 if (!tmp)
2703 return NULL;
2704 sc->tref_tags = tmp;
2705 tag = &sc->tref_tags[sc->nb_tref_tags++];
2706 *tag = (MovTref){ .name = name };
2707 }
2708
2709 return tag;
2710}
2711
2713{
2714 AVStream* st;
2715 MOVStreamContext* sc;
2716
2717 if (c->fc->nb_streams < 1)
2718 return 0;
2719
2720 if (atom.size > 4) {
2721 av_log(c->fc, AV_LOG_ERROR, "Only a single tref of type cdsc/rndr is supported\n");
2722 return AVERROR_PATCHWELCOME;
2723 }
2724 if (atom.size < 4)
2725 return AVERROR_INVALIDDATA;
2726
2727 st = get_curr_st(c);
2728 if (!st)
2729 return AVERROR_INVALIDDATA;
2730 sc = st->priv_data;
2731
2732 MovTref *tag = mov_add_tref_tag(sc, atom.type);
2733 if (!tag)
2734 return AVERROR(ENOMEM);
2735
2736 int ret = mov_add_tref_id(tag, avio_rb32(pb));
2737 if (ret < 0)
2738 return ret;
2739
2740 return 0;
2741}
2742
2744{
2745 AVStream* st;
2746 MOVStreamContext* sc;
2747
2748 if (c->fc->nb_streams < 1)
2749 return 0;
2750
2751 /* For SBAS this should be fine - though beware if someone implements a
2752 * tref atom processor that doesn't drop down to default then this may
2753 * be lost. */
2754 if (atom.size > 4) {
2755 av_log(c->fc, AV_LOG_ERROR, "Only a single tref of type sbas is supported\n");
2756 return AVERROR_PATCHWELCOME;
2757 }
2758 if (atom.size < 4)
2759 return AVERROR_INVALIDDATA;
2760
2761 st = c->fc->streams[c->fc->nb_streams - 1];
2762 sc = st->priv_data;
2763
2764 MovTref *tag = mov_add_tref_tag(sc, atom.type);
2765 if (!tag)
2766 return AVERROR(ENOMEM);
2767
2768 int ret = mov_add_tref_id(tag, avio_rb32(pb));
2769 if (ret < 0)
2770 return ret;
2771
2772 return 0;
2773}
2774
2776{
2777 AVStream* st;
2778 MOVStreamContext* sc;
2779
2780 if (c->fc->nb_streams < 1)
2781 return 0;
2782
2783 if (atom.size > 4)
2784 av_log(c->fc, AV_LOG_WARNING, "More than one vdep reference is not supported.\n");
2785 if (atom.size < 4)
2786 return AVERROR_INVALIDDATA;
2787
2788 st = c->fc->streams[c->fc->nb_streams - 1];
2789 sc = st->priv_data;
2790
2791 MovTref *tag = mov_add_tref_tag(sc, atom.type);
2792 if (!tag)
2793 return AVERROR(ENOMEM);
2794
2795 int ret = mov_add_tref_id(tag, avio_rb32(pb));
2796 if (ret < 0)
2797 return ret;
2798
2799 return 0;
2800}
2801
2802/**
2803 * An strf atom is a BITMAPINFOHEADER struct. This struct is 40 bytes itself,
2804 * but can have extradata appended at the end after the 40 bytes belonging
2805 * to the struct.
2806 */
2808{
2809 AVStream *st;
2810 int ret;
2811
2812 if (c->fc->nb_streams < 1)
2813 return 0;
2814 if (atom.size <= 40)
2815 return 0;
2816 st = c->fc->streams[c->fc->nb_streams-1];
2817
2818 if ((uint64_t)atom.size > (1<<30))
2819 return AVERROR_INVALIDDATA;
2820
2821 avio_skip(pb, 40);
2822 ret = ff_get_extradata(c->fc, st->codecpar, pb, atom.size - 40);
2823 if (ret < 0)
2824 return ret;
2825
2826 return 0;
2827}
2828
2830{
2831 AVStream *st;
2832 MOVStreamContext *sc;
2833 unsigned int i, entries;
2834
2835 if (c->trak_index < 0) {
2836 av_log(c->fc, AV_LOG_WARNING, "STCO outside TRAK\n");
2837 return 0;
2838 }
2839 if (c->fc->nb_streams < 1)
2840 return 0;
2841 st = c->fc->streams[c->fc->nb_streams-1];
2842 sc = st->priv_data;
2843
2844 avio_r8(pb); /* version */
2845 avio_rb24(pb); /* flags */
2846
2847 // Clamp allocation size for `chunk_offsets` -- don't throw an error for an
2848 // invalid count since the EOF path doesn't throw either.
2849 entries = avio_rb32(pb);
2850 entries =
2851 FFMIN(entries,
2852 FFMAX(0, (atom.size - 8) /
2853 (atom.type == MKTAG('s', 't', 'c', 'o') ? 4 : 8)));
2854
2855 if (!entries)
2856 return 0;
2857
2858 if (sc->chunk_offsets) {
2859 av_log(c->fc, AV_LOG_WARNING, "Ignoring duplicated STCO atom\n");
2860 return 0;
2861 }
2862
2864 sc->chunk_count = 0;
2865 sc->chunk_offsets = av_malloc_array(entries, sizeof(*sc->chunk_offsets));
2866 if (!sc->chunk_offsets)
2867 return AVERROR(ENOMEM);
2868 sc->chunk_count = entries;
2869
2870 if (atom.type == MKTAG('s','t','c','o'))
2871 for (i = 0; i < entries && !pb->eof_reached; i++)
2872 sc->chunk_offsets[i] = avio_rb32(pb);
2873 else if (atom.type == MKTAG('c','o','6','4'))
2874 for (i = 0; i < entries && !pb->eof_reached; i++) {
2875 sc->chunk_offsets[i] = avio_rb64(pb);
2876 if (sc->chunk_offsets[i] < 0) {
2877 av_log(c->fc, AV_LOG_WARNING, "Impossible chunk_offset\n");
2878 sc->chunk_offsets[i] = 0;
2879 }
2880 }
2881 else
2882 return AVERROR_INVALIDDATA;
2883
2884 sc->chunk_count = i;
2885
2886 if (pb->eof_reached) {
2887 av_log(c->fc, AV_LOG_WARNING, "reached eof, corrupted STCO atom\n");
2888 return AVERROR_EOF;
2889 }
2890
2891 return 0;
2892}
2893
2894static int mov_codec_id(AVStream *st, uint32_t format)
2895{
2897
2898 if (id <= 0 &&
2899 ((format & 0xFFFF) == 'm' + ('s' << 8) ||
2900 (format & 0xFFFF) == 'T' + ('S' << 8)))
2902
2903 if (st->codecpar->codec_type != AVMEDIA_TYPE_VIDEO && id > 0) {
2905 } else if (st->codecpar->codec_type != AVMEDIA_TYPE_AUDIO &&
2906 /* skip old ASF MPEG-4 tag */
2907 format && format != MKTAG('m','p','4','s')) {
2909 if (id <= 0)
2911 if (id > 0)
2913 else if (st->codecpar->codec_type == AVMEDIA_TYPE_DATA ||
2917 if (id <= 0) {
2920 }
2921
2922 if (id > 0)
2924 else
2926 }
2927 }
2928
2929 st->codecpar->codec_tag = format;
2930
2931 return id;
2932}
2933
2935 AVStream *st, MOVStreamContext *sc)
2936{
2937 uint8_t codec_name[32] = { 0 };
2938 int64_t stsd_start;
2939 unsigned int len;
2940 uint32_t id = 0;
2941
2942 /* The first 16 bytes of the video sample description are already
2943 * read in ff_mov_read_stsd_entries() */
2944 stsd_start = avio_tell(pb) - 16;
2945
2946 if (c->isom) {
2947 avio_skip(pb, 2); /* pre_defined */
2948 avio_skip(pb, 2); /* reserved */
2949 avio_skip(pb, 12); /* pre_defined */
2950 } else {
2951 avio_rb16(pb); /* version */
2952 avio_rb16(pb); /* revision level */
2953 id = avio_rl32(pb); /* vendor */
2954 av_dict_set(&st->metadata, "vendor_id", av_fourcc2str(id), 0);
2955 avio_rb32(pb); /* temporal quality */
2956 avio_rb32(pb); /* spatial quality */
2957 }
2958
2959 st->codecpar->width = avio_rb16(pb); /* width */
2960 st->codecpar->height = avio_rb16(pb); /* height */
2961
2962 avio_rb32(pb); /* horiz resolution */
2963 avio_rb32(pb); /* vert resolution */
2964 avio_rb32(pb); /* data size, always 0 */
2965 avio_rb16(pb); /* frames per samples */
2966
2967 len = avio_r8(pb); /* codec name, pascal string */
2968 if (len > 31)
2969 len = 31;
2970 mov_read_mac_string(c, pb, len, codec_name, sizeof(codec_name));
2971 if (len < 31)
2972 avio_skip(pb, 31 - len);
2973
2974 if (codec_name[0])
2975 av_dict_set(&st->metadata, "encoder", codec_name, 0);
2976
2977 /* codec_tag YV12 triggers an UV swap in rawdec.c */
2978 if (!strncmp(codec_name, "Planar Y'CbCr 8-bit 4:2:0", 25)) {
2979 st->codecpar->codec_tag = MKTAG('I', '4', '2', '0');
2980 st->codecpar->width &= ~1;
2981 st->codecpar->height &= ~1;
2982 }
2983 /* Flash Media Server uses tag H.263 with Sorenson Spark */
2984 if (st->codecpar->codec_tag == MKTAG('H','2','6','3') &&
2985 !strncmp(codec_name, "Sorenson H263", 13))
2987
2988 st->codecpar->bits_per_coded_sample = avio_rb16(pb); /* depth */
2989
2990 avio_seek(pb, stsd_start, SEEK_SET);
2991
2992 if (ff_get_qtpalette(st->codecpar->codec_id, pb, sc->palette)) {
2993 st->codecpar->bits_per_coded_sample &= 0x1F;
2994 sc->has_palette = 1;
2995 }
2996}
2997
2999 AVStream *st, MOVStreamContext *sc)
3000{
3001 int bits_per_sample, flags;
3002 uint16_t version = avio_rb16(pb);
3003 uint32_t id = 0;
3004 AVDictionaryEntry *compatible_brands = av_dict_get(c->fc->metadata, "compatible_brands", NULL, AV_DICT_MATCH_CASE);
3005 int channel_count;
3006
3007 if (c->isom)
3008 avio_skip(pb, 6); /* reserved */
3009 else {
3010 avio_rb16(pb); /* revision level */
3011 id = avio_rl32(pb); /* vendor */
3012 av_dict_set(&st->metadata, "vendor_id", av_fourcc2str(id), 0);
3013 }
3014
3015 channel_count = avio_rb16(pb);
3016
3018 st->codecpar->ch_layout.nb_channels = channel_count;
3019 st->codecpar->bits_per_coded_sample = avio_rb16(pb); /* sample size */
3020 av_log(c->fc, AV_LOG_TRACE, "audio channels %d\n", channel_count);
3021
3022 sc->audio_cid = avio_rb16(pb);
3023 avio_rb16(pb); /* packet size = 0 */
3024
3025 st->codecpar->sample_rate = ((avio_rb32(pb) >> 16));
3026
3027 // Read QT version 1 fields. In version 0 these do not exist.
3028 av_log(c->fc, AV_LOG_TRACE, "version =%d, isom =%d\n", version, c->isom);
3029 if (!c->isom ||
3030 (compatible_brands && strstr(compatible_brands->value, "qt ")) ||
3031 (sc->stsd_version == 0 && version > 0)) {
3032 if (version == 1) {
3033 sc->samples_per_frame = avio_rb32(pb);
3034 avio_rb32(pb); /* bytes per packet */
3035 sc->bytes_per_frame = avio_rb32(pb);
3036 avio_rb32(pb); /* bytes per sample */
3037 } else if (version == 2) {
3038 double sample_rate;
3039
3040 avio_rb32(pb); /* sizeof struct only */
3041 sample_rate = av_int2double(avio_rb64(pb));
3042
3043 if (sample_rate < 0 || sample_rate > INT_MAX ||
3044 isnan(sample_rate)) {
3045 av_log(c->fc, AV_LOG_ERROR, "Invalid sample rate %g\n",
3046 sample_rate);
3047 return AVERROR_INVALIDDATA;
3048 }
3049 st->codecpar->sample_rate = sample_rate;
3050 channel_count = avio_rb32(pb);
3052 st->codecpar->ch_layout.nb_channels = channel_count;
3053 avio_rb32(pb); /* always 0x7F000000 */
3055
3056 flags = avio_rb32(pb); /* lpcm format specific flag */
3057 sc->bytes_per_frame = avio_rb32(pb);
3058 sc->samples_per_frame = avio_rb32(pb);
3059 if (st->codecpar->codec_tag == MKTAG('l','p','c','m'))
3060 st->codecpar->codec_id =
3062 flags);
3063 }
3064 if (version == 0 || (version == 1 && sc->audio_cid != -2)) {
3065 /* can't correctly handle variable sized packet as audio unit */
3066 switch (st->codecpar->codec_id) {
3067 case AV_CODEC_ID_MP2:
3068 case AV_CODEC_ID_MP3:
3070 break;
3071 }
3072 }
3073 }
3074
3075 if (sc->format == 0) {
3076 if (st->codecpar->bits_per_coded_sample == 8)
3077 st->codecpar->codec_id = mov_codec_id(st, MKTAG('r','a','w',' '));
3078 else if (st->codecpar->bits_per_coded_sample == 16)
3079 st->codecpar->codec_id = mov_codec_id(st, MKTAG('t','w','o','s'));
3080 }
3081
3082 switch (st->codecpar->codec_id) {
3083 case AV_CODEC_ID_PCM_S8:
3084 case AV_CODEC_ID_PCM_U8:
3085 if (st->codecpar->bits_per_coded_sample == 16)
3087 break;
3090 if (st->codecpar->bits_per_coded_sample == 8)
3092 else if (st->codecpar->bits_per_coded_sample == 24)
3093 st->codecpar->codec_id =
3096 else if (st->codecpar->bits_per_coded_sample == 32)
3097 st->codecpar->codec_id =
3100 break;
3101 /* set values for old format before stsd version 1 appeared */
3102 case AV_CODEC_ID_MACE3:
3103 sc->samples_per_frame = 6;
3105 break;
3106 case AV_CODEC_ID_MACE6:
3107 sc->samples_per_frame = 6;
3109 break;
3111 sc->samples_per_frame = 64;
3113 break;
3114 case AV_CODEC_ID_GSM:
3115 sc->samples_per_frame = 160;
3116 sc->bytes_per_frame = 33;
3117 break;
3118 default:
3119 break;
3120 }
3121
3122 bits_per_sample = av_get_bits_per_sample(st->codecpar->codec_id);
3123 if (bits_per_sample && (bits_per_sample >> 3) * (uint64_t)st->codecpar->ch_layout.nb_channels <= INT_MAX) {
3124 st->codecpar->bits_per_coded_sample = bits_per_sample;
3125 sc->sample_size = (bits_per_sample >> 3) * st->codecpar->ch_layout.nb_channels;
3126 }
3127
3128 return 0;
3129}
3130
3132 AVStream *st, MOVStreamContext *sc,
3133 int64_t size)
3134{
3135 // ttxt stsd contains display flags, justification, background
3136 // color, fonts, and default styles, so fake an atom to read it
3137 MOVAtom fake_atom = { .size = size };
3138 // mp4s contains a regular esds atom, dfxp ISMV TTML has no content
3139 // in extradata unlike stpp MP4 TTML.
3140 if (st->codecpar->codec_tag != AV_RL32("mp4s") &&
3142 mov_read_glbl(c, pb, fake_atom);
3143 st->codecpar->width = sc->width;
3144 st->codecpar->height = sc->height;
3145}
3146
3148 AVStream *st, MOVStreamContext *sc,
3149 int64_t size)
3150{
3151 int ret;
3152
3153 if (st->codecpar->codec_tag == MKTAG('t','m','c','d')) {
3154 if ((int)size != size)
3155 return AVERROR(ENOMEM);
3156
3157 ret = ff_get_extradata(c->fc, st->codecpar, pb, size);
3158 if (ret < 0)
3159 return ret;
3160 if (size > 16) {
3161 MOVStreamContext *tmcd_ctx = st->priv_data;
3162 int val;
3163 val = AV_RB32(st->codecpar->extradata + 4);
3164 tmcd_ctx->tmcd_flags = val;
3165 st->avg_frame_rate.num = AV_RB32(st->codecpar->extradata + 8); /* timescale */
3166 st->avg_frame_rate.den = AV_RB32(st->codecpar->extradata + 12); /* frameDuration */
3167 tmcd_ctx->tmcd_nb_frames = st->codecpar->extradata[16]; /* number of frames */
3168 if (size > 30) {
3169 uint32_t len = AV_RB32(st->codecpar->extradata + 18); /* name atom length */
3170 uint32_t format = AV_RB32(st->codecpar->extradata + 22);
3171 if (format == AV_RB32("name") && (int64_t)size >= (int64_t)len + 18) {
3172 uint16_t str_size = AV_RB16(st->codecpar->extradata + 26); /* string length */
3173 if (str_size > 0 && size >= (int)str_size + 30 &&
3174 st->codecpar->extradata[30] /* Don't add empty string */) {
3175 char *reel_name = av_malloc(str_size + 1);
3176 if (!reel_name)
3177 return AVERROR(ENOMEM);
3178 memcpy(reel_name, st->codecpar->extradata + 30, str_size);
3179 reel_name[str_size] = 0; /* Add null terminator */
3180 av_dict_set(&st->metadata, "reel_name", reel_name,
3182 }
3183 }
3184 }
3185 }
3186 } else if (st->codecpar->codec_id == AV_CODEC_ID_ITUT_T35) {
3187 int t35_identifier_length = avio_r8(pb);
3188
3189 if (t35_identifier_length <= 0 || t35_identifier_length >= size)
3190 return AVERROR_INVALIDDATA;
3191
3192 ret = ff_get_extradata(c->fc, st->codecpar, pb, t35_identifier_length);
3193 if (ret < 0)
3194 return ret;
3195
3196 int hrsd_len = size - t35_identifier_length - 1;
3197 if (hrsd_len > 0) {
3198 uint8_t *hrsd_str = av_malloc(hrsd_len + 1);
3199 if (!hrsd_str)
3200 return AVERROR(ENOMEM);
3201
3202 ret = ffio_read_size(pb, hrsd_str, hrsd_len);
3203 if (ret < 0) {
3204 av_free(hrsd_str);
3205 return ret;
3206 }
3207 if (hrsd_str[0]) {
3208 hrsd_str[hrsd_len] = 0;
3209 ret = av_dict_set(&st->metadata, "description", hrsd_str, AV_DICT_DONT_OVERWRITE);
3210 }
3211 av_free(hrsd_str);
3212 }
3213 } else {
3214 /* other codec type, just skip (rtp, mp4s ...) */
3215 avio_skip(pb, size);
3216 }
3217 return 0;
3218}
3219
3221 AVStream *st, MOVStreamContext *sc)
3222{
3223 FFStream *const sti = ffstream(st);
3224
3226 !st->codecpar->sample_rate && sc->time_scale > 1)
3227 st->codecpar->sample_rate = sc->time_scale;
3228
3229 /* special codec parameters handling */
3230 switch (st->codecpar->codec_id) {
3231#if CONFIG_DV_DEMUXER
3233 if (c->dv_fctx) {
3234 avpriv_request_sample(c->fc, "multiple DV audio streams");
3235 return AVERROR(ENOSYS);
3236 }
3237
3238 c->dv_fctx = avformat_alloc_context();
3239 if (!c->dv_fctx) {
3240 av_log(c->fc, AV_LOG_ERROR, "dv demux context alloc error\n");
3241 return AVERROR(ENOMEM);
3242 }
3243 c->dv_demux = avpriv_dv_init_demux(c->dv_fctx);
3244 if (!c->dv_demux) {
3245 av_log(c->fc, AV_LOG_ERROR, "dv demux context init error\n");
3246 return AVERROR(ENOMEM);
3247 }
3248 sc->dv_audio_container = 1;
3250 break;
3251#endif
3252 /* no ifdef since parameters are always those */
3253 case AV_CODEC_ID_QCELP:
3256 // force sample rate for qcelp when not stored in mov
3257 if (st->codecpar->codec_tag != MKTAG('Q','c','l','p'))
3258 st->codecpar->sample_rate = 8000;
3259 // FIXME: Why is the following needed for some files?
3260 sc->samples_per_frame = 160;
3261 if (!sc->bytes_per_frame)
3262 sc->bytes_per_frame = 35;
3263 break;
3264 case AV_CODEC_ID_AMR_NB:
3267 /* force sample rate for amr, stsd in 3gp does not store sample rate */
3268 st->codecpar->sample_rate = 8000;
3269 break;
3270 case AV_CODEC_ID_AMR_WB:
3273 st->codecpar->sample_rate = 16000;
3274 break;
3275 case AV_CODEC_ID_MP2:
3276 case AV_CODEC_ID_MP3:
3277 /* force type after stsd for m1a hdlr */
3279 break;
3280 case AV_CODEC_ID_GSM:
3283 case AV_CODEC_ID_ILBC:
3284 case AV_CODEC_ID_MACE3:
3285 case AV_CODEC_ID_MACE6:
3286 case AV_CODEC_ID_QDM2:
3288 break;
3289 case AV_CODEC_ID_ALAC:
3290 if (st->codecpar->extradata_size == 36) {
3291 int channel_count = AV_RB8(st->codecpar->extradata + 21);
3292 if (st->codecpar->ch_layout.nb_channels != channel_count) {
3295 st->codecpar->ch_layout.nb_channels = channel_count;
3296 }
3297 st->codecpar->sample_rate = AV_RB32(st->codecpar->extradata + 32);
3298 }
3299 break;
3300 case AV_CODEC_ID_AC3:
3301 case AV_CODEC_ID_EAC3:
3303 case AV_CODEC_ID_VC1:
3304 case AV_CODEC_ID_VP8:
3305 case AV_CODEC_ID_VP9:
3307 break;
3309 case AV_CODEC_ID_PRORES:
3310 case AV_CODEC_ID_APV:
3311 case AV_CODEC_ID_EVC:
3312 case AV_CODEC_ID_LCEVC:
3313 case AV_CODEC_ID_AV1:
3314 /* field_order detection of H264 requires parsing */
3315 case AV_CODEC_ID_H264:
3317 break;
3318 default:
3319 break;
3320 }
3321 return 0;
3322}
3323
3325 int codec_tag, int format,
3326 int64_t size)
3327{
3328 if (codec_tag &&
3329 (codec_tag != format &&
3330 // AVID 1:1 samples with differing data format and codec tag exist
3331 (codec_tag != AV_RL32("AV1x") || format != AV_RL32("AVup")) &&
3332 // prores is allowed to have differing data format and codec tag
3333 codec_tag != AV_RL32("apcn") && codec_tag != AV_RL32("apch") &&
3334 // so is dv (sigh)
3335 codec_tag != AV_RL32("dvpp") && codec_tag != AV_RL32("dvcp") &&
3336 (c->fc->video_codec_id ? ff_codec_get_id(ff_codec_movvideo_tags, format) != c->fc->video_codec_id
3337 : codec_tag != MKTAG('j','p','e','g')))) {
3338 /* Multiple fourcc, we skip JPEG. This is not correct, we should
3339 * export it as a separate AVStream but this needs a few changes
3340 * in the MOV demuxer, patch welcome. */
3341
3342 av_log(c->fc, AV_LOG_WARNING, "multiple fourcc not supported\n");
3343 avio_skip(pb, size);
3344 return 1;
3345 }
3346
3347 return 0;
3348}
3349
3351{
3352 int ret;
3353
3354 /* special codec parameters handling */
3355 switch (st->codecpar->codec_id) {
3356 case AV_CODEC_ID_H264:
3357 // done for ai5q, ai52, ai55, ai1q, ai12 and ai15.
3360 if (ret < 0)
3361 return ret;
3362 }
3363 break;
3364 default:
3365 break;
3366 }
3367
3368 return 0;
3369}
3370
3372{
3373 AVStream *st;
3374 MOVStreamContext *sc;
3375 int pseudo_stream_id;
3376
3377 av_assert0 (c->fc->nb_streams >= 1);
3378 st = c->fc->streams[c->fc->nb_streams-1];
3379 sc = st->priv_data;
3380
3381 for (pseudo_stream_id = 0;
3382 pseudo_stream_id < entries && !pb->eof_reached;
3383 pseudo_stream_id++) {
3384 //Parsing Sample description table
3385 enum AVCodecID id;
3386 int ret, dref_id = 1;
3387 MOVAtom a = { AV_RL32("stsd") };
3388 int64_t start_pos = avio_tell(pb);
3389 int64_t size = avio_rb32(pb); /* size */
3390 uint32_t format = avio_rl32(pb); /* data format */
3391
3392 if (size >= 16) {
3393 avio_rb32(pb); /* reserved */
3394 avio_rb16(pb); /* reserved */
3395 dref_id = avio_rb16(pb);
3396 } else if (size <= 7) {
3397 av_log(c->fc, AV_LOG_ERROR,
3398 "invalid size %"PRId64" in stsd\n", size);
3399 return AVERROR_INVALIDDATA;
3400 }
3401
3403 size - (avio_tell(pb) - start_pos))) {
3404 sc->stsd_count++;
3405 continue;
3406 }
3407
3408 sc->pseudo_stream_id = st->codecpar->codec_tag ? -1 : pseudo_stream_id;
3409 sc->dref_id= dref_id;
3410 sc->format = format;
3411
3412 id = mov_codec_id(st, format);
3413
3414 av_log(c->fc, AV_LOG_TRACE,
3415 "size=%"PRId64" 4CC=%s codec_type=%d\n", size,
3417
3418 st->codecpar->codec_id = id;
3420 mov_parse_stsd_video(c, pb, st, sc);
3421 } else if (st->codecpar->codec_type==AVMEDIA_TYPE_AUDIO) {
3422 ret = mov_parse_stsd_audio(c, pb, st, sc);
3423 if (ret < 0)
3424 return ret;
3425 if (st->codecpar->sample_rate < 0) {
3426 av_log(c->fc, AV_LOG_ERROR, "Invalid sample rate %d\n", st->codecpar->sample_rate);
3427 return AVERROR_INVALIDDATA;
3428 }
3429 if (st->codecpar->ch_layout.nb_channels < 0) {
3430 av_log(c->fc, AV_LOG_ERROR, "Invalid channels %d\n", st->codecpar->ch_layout.nb_channels);
3431 return AVERROR_INVALIDDATA;
3432 }
3433 } else if (st->codecpar->codec_type==AVMEDIA_TYPE_SUBTITLE){
3434 mov_parse_stsd_subtitle(c, pb, st, sc,
3435 size - (avio_tell(pb) - start_pos));
3436 } else {
3437 ret = mov_parse_stsd_data(c, pb, st, sc,
3438 size - (avio_tell(pb) - start_pos));
3439 if (ret < 0)
3440 return ret;
3441 }
3442 /* this will read extra atoms at the end (wave, alac, damr, avcC, hvcC, SMI ...) */
3443 a.size = size - (avio_tell(pb) - start_pos);
3444 if (a.size > 8) {
3445 if ((ret = mov_read_default(c, pb, a)) < 0)
3446 return ret;
3447 } else if (a.size > 0)
3448 avio_skip(pb, a.size);
3449
3451 if (ret < 0)
3452 return ret;
3453
3454 if (sc->extradata && st->codecpar->extradata) {
3455 int extra_size = st->codecpar->extradata_size;
3456
3457 /* Move the current stream extradata to the stream context one. */
3458 sc->extradata_size[pseudo_stream_id] = extra_size;
3459 sc->extradata[pseudo_stream_id] = st->codecpar->extradata;
3460 st->codecpar->extradata = NULL;
3461 st->codecpar->extradata_size = 0;
3462 }
3463 sc->stsd_count++;
3464 }
3465
3466 if (pb->eof_reached) {
3467 av_log(c->fc, AV_LOG_WARNING, "reached eof, corrupted STSD atom\n");
3468 return AVERROR_EOF;
3469 }
3470
3471 return 0;
3472}
3473
3475{
3476 AVStream *st;
3477 MOVStreamContext *sc;
3478 int ret, entries;
3479
3480 if (c->fc->nb_streams < 1)
3481 return 0;
3482 st = c->fc->streams[c->fc->nb_streams - 1];
3483 sc = st->priv_data;
3484
3485 if (sc->extradata) {
3486 av_log(c->fc, AV_LOG_ERROR,
3487 "Duplicate stsd found in this track.\n");
3488 return AVERROR_INVALIDDATA;
3489 }
3490
3491 sc->stsd_version = avio_r8(pb);
3492 avio_rb24(pb); /* flags */
3493 entries = avio_rb32(pb);
3494
3495 /* Each entry contains a size (4 bytes) and format (4 bytes). */
3496 if (entries <= 0 || entries > atom.size / 8 || entries > 1024) {
3497 av_log(c->fc, AV_LOG_ERROR, "invalid STSD entries %d\n", entries);
3498 return AVERROR_INVALIDDATA;
3499 }
3500
3501 /* Prepare space for hosting multiple extradata. */
3502 sc->extradata = av_calloc(entries, sizeof(*sc->extradata));
3503 if (!sc->extradata)
3504 return AVERROR(ENOMEM);
3505
3506 sc->extradata_size = av_calloc(entries, sizeof(*sc->extradata_size));
3507 if (!sc->extradata_size) {
3508 ret = AVERROR(ENOMEM);
3509 goto fail;
3510 }
3511
3512 ret = ff_mov_read_stsd_entries(c, pb, entries);
3513 if (ret < 0)
3514 goto fail;
3515
3516 /* Restore back the primary extradata. */
3519 if (sc->extradata_size[0]) {
3521 if (!st->codecpar->extradata)
3522 return AVERROR(ENOMEM);
3523 memcpy(st->codecpar->extradata, sc->extradata[0], sc->extradata_size[0]);
3524 }
3525
3526 return mov_finalize_stsd_codec(c, pb, st, sc);
3527fail:
3528 if (sc->extradata) {
3529 int j;
3530 for (j = 0; j < sc->stsd_count; j++)
3531 av_freep(&sc->extradata[j]);
3532 }
3533
3534 sc->stsd_count = 0;
3535 av_freep(&sc->extradata);
3537 return ret;
3538}
3539
3541{
3542 AVStream *st;
3543 MOVStreamContext *sc;
3544 unsigned int i, entries;
3545
3546 if (c->trak_index < 0) {
3547 av_log(c->fc, AV_LOG_WARNING, "STSC outside TRAK\n");
3548 return 0;
3549 }
3550
3551 if (c->fc->nb_streams < 1)
3552 return 0;
3553 st = c->fc->streams[c->fc->nb_streams-1];
3554 sc = st->priv_data;
3555
3556 avio_r8(pb); /* version */
3557 avio_rb24(pb); /* flags */
3558
3559 entries = avio_rb32(pb);
3560 if ((uint64_t)entries * 12 + 4 > atom.size)
3561 return AVERROR_INVALIDDATA;
3562
3563 av_log(c->fc, AV_LOG_TRACE, "track[%u].stsc.entries = %u\n", c->fc->nb_streams - 1, entries);
3564
3565 if (!entries)
3566 return 0;
3567 if (sc->stsc_data) {
3568 av_log(c->fc, AV_LOG_WARNING, "Ignoring duplicated STSC atom\n");
3569 return 0;
3570 }
3571 av_free(sc->stsc_data);
3572 sc->stsc_count = 0;
3573 sc->stsc_data = av_malloc_array(entries, sizeof(*sc->stsc_data));
3574 if (!sc->stsc_data)
3575 return AVERROR(ENOMEM);
3576
3577 for (i = 0; i < entries && !pb->eof_reached; i++) {
3578 sc->stsc_data[i].first = avio_rb32(pb);
3579 sc->stsc_data[i].count = avio_rb32(pb);
3580 sc->stsc_data[i].id = avio_rb32(pb);
3581 }
3582
3583 sc->stsc_count = i;
3584 for (i = sc->stsc_count - 1; i < UINT_MAX; i--) {
3585 int64_t first_min = i + 1;
3586 if ((i+1 < sc->stsc_count && sc->stsc_data[i].first >= sc->stsc_data[i+1].first) ||
3587 (i > 0 && sc->stsc_data[i].first <= sc->stsc_data[i-1].first) ||
3588 sc->stsc_data[i].first < first_min ||
3589 sc->stsc_data[i].count < 1 ||
3590 sc->stsc_data[i].id < 1) {
3591 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);
3592 if (i+1 >= sc->stsc_count) {
3593 if (sc->stsc_data[i].count == 0 && i > 0) {
3594 sc->stsc_count --;
3595 continue;
3596 }
3597 sc->stsc_data[i].first = FFMAX(sc->stsc_data[i].first, first_min);
3598 if (i > 0 && sc->stsc_data[i].first <= sc->stsc_data[i-1].first)
3599 sc->stsc_data[i].first = FFMIN(sc->stsc_data[i-1].first + 1LL, INT_MAX);
3600 sc->stsc_data[i].count = FFMAX(sc->stsc_data[i].count, 1);
3601 sc->stsc_data[i].id = FFMAX(sc->stsc_data[i].id, 1);
3602 continue;
3603 }
3604 av_assert0(sc->stsc_data[i+1].first >= 2);
3605 // We replace this entry by the next valid
3606 sc->stsc_data[i].first = sc->stsc_data[i+1].first - 1;
3607 sc->stsc_data[i].count = sc->stsc_data[i+1].count;
3608 sc->stsc_data[i].id = sc->stsc_data[i+1].id;
3609 }
3610 }
3611
3612 if (pb->eof_reached) {
3613 av_log(c->fc, AV_LOG_WARNING, "reached eof, corrupted STSC atom\n");
3614 return AVERROR_EOF;
3615 }
3616
3617 return 0;
3618}
3619
3620static inline int mov_stsc_index_valid(unsigned int index, unsigned int count)
3621{
3622 return index < count - 1;
3623}
3624
3625/* Compute the samples value for the stsc entry at the given index. */
3626static inline int64_t mov_get_stsc_samples(MOVStreamContext *sc, unsigned int index)
3627{
3628 int chunk_count;
3629
3631 chunk_count = sc->stsc_data[index + 1].first - sc->stsc_data[index].first;
3632 else {
3633 // Validation for stsc / stco happens earlier in mov_read_stsc + mov_read_trak.
3635 chunk_count = sc->chunk_count - (sc->stsc_data[index].first - 1);
3636 }
3637
3638 return sc->stsc_data[index].count * (int64_t)chunk_count;
3639}
3640
3642{
3643 AVStream *st;
3644 MOVStreamContext *sc;
3645 unsigned i, entries;
3646
3647 if (c->trak_index < 0) {
3648 av_log(c->fc, AV_LOG_WARNING, "STPS outside TRAK\n");
3649 return 0;
3650 }
3651
3652 if (c->fc->nb_streams < 1)
3653 return 0;
3654 st = c->fc->streams[c->fc->nb_streams-1];
3655 sc = st->priv_data;
3656
3657 avio_rb32(pb); // version + flags
3658
3659 entries = avio_rb32(pb);
3660 if (sc->stps_data)
3661 av_log(c->fc, AV_LOG_WARNING, "Duplicated STPS atom\n");
3662 av_free(sc->stps_data);
3663 sc->stps_count = 0;
3664 sc->stps_data = av_malloc_array(entries, sizeof(*sc->stps_data));
3665 if (!sc->stps_data)
3666 return AVERROR(ENOMEM);
3667
3668 for (i = 0; i < entries && !pb->eof_reached; i++) {
3669 sc->stps_data[i] = avio_rb32(pb);
3670 }
3671
3672 sc->stps_count = i;
3673
3674 if (pb->eof_reached) {
3675 av_log(c->fc, AV_LOG_WARNING, "reached eof, corrupted STPS atom\n");
3676 return AVERROR_EOF;
3677 }
3678
3679 return 0;
3680}
3681
3683{
3684 AVStream *st;
3685 FFStream *sti;
3686 MOVStreamContext *sc;
3687 unsigned int i, entries;
3688
3689 if (c->trak_index < 0) {
3690 av_log(c->fc, AV_LOG_WARNING, "STSS outside TRAK\n");
3691 return 0;
3692 }
3693
3694 if (c->fc->nb_streams < 1)
3695 return 0;
3696 st = c->fc->streams[c->fc->nb_streams-1];
3697 sti = ffstream(st);
3698 sc = st->priv_data;
3699
3700 avio_r8(pb); /* version */
3701 avio_rb24(pb); /* flags */
3702
3703 entries = avio_rb32(pb);
3704
3705 av_log(c->fc, AV_LOG_TRACE, "keyframe_count = %u\n", entries);
3706
3707 if (!entries) {
3708 sc->keyframe_absent = 1;
3711 return 0;
3712 }
3713 if (sc->keyframes)
3714 av_log(c->fc, AV_LOG_WARNING, "Duplicated STSS atom\n");
3715 if (entries >= UINT_MAX / sizeof(int))
3716 return AVERROR_INVALIDDATA;
3717 av_freep(&sc->keyframes);
3718 sc->keyframe_count = 0;
3719 sc->keyframes = av_malloc_array(entries, sizeof(*sc->keyframes));
3720 if (!sc->keyframes)
3721 return AVERROR(ENOMEM);
3722
3723 for (i = 0; i < entries && !pb->eof_reached; i++) {
3724 sc->keyframes[i] = avio_rb32(pb);
3725 }
3726
3727 sc->keyframe_count = i;
3728
3729 if (pb->eof_reached) {
3730 av_log(c->fc, AV_LOG_WARNING, "reached eof, corrupted STSS atom\n");
3731 return AVERROR_EOF;
3732 }
3733
3734 return 0;
3735}
3736
3738{
3739 AVStream *st;
3740 MOVStreamContext *sc;
3741 unsigned int i, entries, sample_size, field_size, num_bytes;
3742 GetBitContext gb;
3743 unsigned char* buf;
3744 int ret;
3745
3746 if (c->trak_index < 0) {
3747 av_log(c->fc, AV_LOG_WARNING, "STSZ outside TRAK\n");
3748 return 0;
3749 }
3750
3751 if (c->fc->nb_streams < 1)
3752 return 0;
3753 st = c->fc->streams[c->fc->nb_streams-1];
3754 sc = st->priv_data;
3755
3756 avio_r8(pb); /* version */
3757 avio_rb24(pb); /* flags */
3758
3759 if (atom.type == MKTAG('s','t','s','z')) {
3760 sample_size = avio_rb32(pb);
3761 if (!sc->sample_size) /* do not overwrite value computed in stsd */
3762 sc->sample_size = sample_size;
3763 sc->stsz_sample_size = sample_size;
3764 field_size = 32;
3765 } else {
3766 sample_size = 0;
3767 avio_rb24(pb); /* reserved */
3768 field_size = avio_r8(pb);
3769 }
3770 entries = avio_rb32(pb);
3771
3772 av_log(c->fc, AV_LOG_TRACE, "sample_size = %u sample_count = %u\n", sc->sample_size, entries);
3773
3774 sc->sample_count = entries;
3775 if (sample_size)
3776 return 0;
3777
3778 if (field_size != 4 && field_size != 8 && field_size != 16 && field_size != 32) {
3779 av_log(c->fc, AV_LOG_ERROR, "Invalid sample field size %u\n", field_size);
3780 return AVERROR_INVALIDDATA;
3781 }
3782
3783 if (!entries)
3784 return 0;
3785 if (entries >= (INT_MAX - 4 - 8 * AV_INPUT_BUFFER_PADDING_SIZE) / field_size)
3786 return AVERROR_INVALIDDATA;
3787 if (sc->sample_sizes)
3788 av_log(c->fc, AV_LOG_WARNING, "Duplicated STSZ atom\n");
3789 av_free(sc->sample_sizes);
3790 sc->sample_count = 0;
3791 sc->sample_sizes = av_malloc_array(entries, sizeof(*sc->sample_sizes));
3792 if (!sc->sample_sizes)
3793 return AVERROR(ENOMEM);
3794
3795 num_bytes = (entries*field_size+4)>>3;
3796
3797 buf = av_malloc(num_bytes+AV_INPUT_BUFFER_PADDING_SIZE);
3798 if (!buf) {
3799 av_freep(&sc->sample_sizes);
3800 return AVERROR(ENOMEM);
3801 }
3802
3803 ret = ffio_read_size(pb, buf, num_bytes);
3804 if (ret < 0) {
3805 av_freep(&sc->sample_sizes);
3806 av_free(buf);
3807 av_log(c->fc, AV_LOG_WARNING, "STSZ atom truncated\n");
3808 return 0;
3809 }
3810
3811 init_get_bits(&gb, buf, 8*num_bytes);
3812
3813 for (i = 0; i < entries; i++) {
3814 sc->sample_sizes[i] = get_bits_long(&gb, field_size);
3815 if (sc->sample_sizes[i] > INT64_MAX - sc->data_size) {
3816 av_free(buf);
3817 av_log(c->fc, AV_LOG_ERROR, "Sample size overflow in STSZ\n");
3818 return AVERROR_INVALIDDATA;
3819 }
3820 sc->data_size += sc->sample_sizes[i];
3821 }
3822
3823 sc->sample_count = i;
3824
3825 av_free(buf);
3826
3827 return 0;
3828}
3829
3831{
3832 AVStream *st;
3833 MOVStreamContext *sc;
3834 unsigned int i, entries;
3835 int64_t duration = 0;
3836 int64_t total_sample_count = 0;
3837 int64_t current_dts = 0;
3838 int64_t corrected_dts = 0;
3839
3840 if (c->trak_index < 0) {
3841 av_log(c->fc, AV_LOG_WARNING, "STTS outside TRAK\n");
3842 return 0;
3843 }
3844
3845 if (c->fc->nb_streams < 1)
3846 return 0;
3847 st = c->fc->streams[c->fc->nb_streams-1];
3848 sc = st->priv_data;
3849
3850 avio_r8(pb); /* version */
3851 avio_rb24(pb); /* flags */
3852 entries = avio_rb32(pb);
3853
3854 av_log(c->fc, AV_LOG_TRACE, "track[%u].stts.entries = %u\n",
3855 c->fc->nb_streams-1, entries);
3856
3857 if (sc->stts_data)
3858 av_log(c->fc, AV_LOG_WARNING, "Duplicated STTS atom\n");
3859 av_freep(&sc->stts_data);
3860 sc->stts_count = 0;
3861 if (entries >= INT_MAX / sizeof(*sc->stts_data))
3862 return AVERROR(ENOMEM);
3863
3864 for (i = 0; i < entries && !pb->eof_reached; i++) {
3865 unsigned int sample_duration;
3866 unsigned int sample_count;
3867 unsigned int min_entries = FFMIN(FFMAX(i + 1, 1024 * 1024), entries);
3869 min_entries * sizeof(*sc->stts_data));
3870 if (!stts_data) {
3871 av_freep(&sc->stts_data);
3872 sc->stts_count = 0;
3873 return AVERROR(ENOMEM);
3874 }
3875 sc->stts_count = min_entries;
3876 sc->stts_data = stts_data;
3877
3878 sample_count = avio_rb32(pb);
3879 sample_duration = avio_rb32(pb);
3880
3881 sc->stts_data[i].count= sample_count;
3882 sc->stts_data[i].duration= sample_duration;
3883
3884 av_log(c->fc, AV_LOG_TRACE, "sample_count=%u, sample_duration=%u\n",
3885 sample_count, sample_duration);
3886
3887 /* STTS sample offsets are uint32 but some files store it as int32
3888 * with negative values used to correct DTS delays.
3889 There may be abnormally large values as well. */
3890 if (sample_duration > c->max_stts_delta) {
3891 // assume high delta is a correction if negative when cast as int32
3892 int32_t delta_magnitude = (int32_t)sample_duration;
3893 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",
3894 sample_duration, i, sample_count, st->index);
3895 sc->stts_data[i].duration = 1;
3896 corrected_dts = av_sat_add64(corrected_dts, (delta_magnitude < 0 ? (int64_t)delta_magnitude : 1) * sample_count);
3897 } else {
3898 corrected_dts += sample_duration * (uint64_t)sample_count;
3899 }
3900
3901 current_dts += sc->stts_data[i].duration * (uint64_t)sample_count;
3902
3903 if (current_dts > corrected_dts) {
3904 int64_t drift = av_sat_sub64(current_dts, corrected_dts) / FFMAX(sample_count, 1);
3905 uint32_t correction = (sc->stts_data[i].duration > drift) ? drift : sc->stts_data[i].duration - 1;
3906 current_dts -= correction * (uint64_t)sample_count;
3907 sc->stts_data[i].duration -= correction;
3908 }
3909
3910 duration+=(int64_t)sc->stts_data[i].duration*(uint64_t)sc->stts_data[i].count;
3911 total_sample_count+=sc->stts_data[i].count;
3912 }
3913
3914 sc->stts_count = i;
3915
3916 if (duration > 0 &&
3917 duration <= INT64_MAX - sc->duration_for_fps &&
3918 total_sample_count <= INT_MAX - sc->nb_frames_for_fps) {
3920 sc->nb_frames_for_fps += total_sample_count;
3921 }
3922
3923 if (pb->eof_reached) {
3924 av_log(c->fc, AV_LOG_WARNING, "reached eof, corrupted STTS atom\n");
3925 return AVERROR_EOF;
3926 }
3927
3928 st->nb_frames= total_sample_count;
3929 if (duration)
3930 st->duration= FFMIN(st->duration, duration);
3931
3932 // All samples have zero duration. They have higher chance be chose by
3933 // mov_find_next_sample, which leads to seek again and again.
3934 //
3935 // It's AVERROR_INVALIDDATA actually, but such files exist in the wild.
3936 // So only mark data stream as discarded for safety.
3937 if (!duration && sc->stts_count &&
3939 av_log(c->fc, AV_LOG_WARNING,
3940 "All samples in data stream index:id [%d:%d] have zero "
3941 "duration, stream set to be discarded by default. Override "
3942 "using AVStream->discard or -discard for ffmpeg command.\n",
3943 st->index, sc->id);
3944 st->discard = AVDISCARD_ALL;
3945 }
3946 sc->track_end = duration;
3947 return 0;
3948}
3949
3951{
3952 AVStream *st;
3953 MOVStreamContext *sc;
3954 unsigned int i;
3955 int64_t entries;
3956
3957 if (c->fc->nb_streams < 1)
3958 return 0;
3959 st = c->fc->streams[c->fc->nb_streams - 1];
3960 sc = st->priv_data;
3961
3962 avio_r8(pb); /* version */
3963 avio_rb24(pb); /* flags */
3964 entries = atom.size - 4;
3965
3966 av_log(c->fc, AV_LOG_TRACE, "track[%u].sdtp.entries = %" PRId64 "\n",
3967 c->fc->nb_streams - 1, entries);
3968
3969 if (sc->sdtp_data)
3970 av_log(c->fc, AV_LOG_WARNING, "Duplicated SDTP atom\n");
3971 av_freep(&sc->sdtp_data);
3972 sc->sdtp_count = 0;
3973
3974 if (entries < 0 || entries > UINT_MAX)
3975 return AVERROR(ERANGE);
3976
3977 sc->sdtp_data = av_malloc(entries);
3978 if (!sc->sdtp_data)
3979 return AVERROR(ENOMEM);
3980
3981 for (i = 0; i < entries && !pb->eof_reached; i++)
3982 sc->sdtp_data[i] = avio_r8(pb);
3983 sc->sdtp_count = i;
3984
3985 return 0;
3986}
3987
3988static void mov_update_dts_shift(MOVStreamContext *sc, int duration, void *logctx)
3989{
3990 if (duration < 0) {
3991 if (duration == INT_MIN) {
3992 av_log(logctx, AV_LOG_WARNING, "mov_update_dts_shift(): dts_shift set to %d\n", INT_MAX);
3993 duration++;
3994 }
3995 sc->dts_shift = FFMAX(sc->dts_shift, -duration);
3996 }
3997}
3998
4000{
4001 AVStream *st;
4002 MOVStreamContext *sc;
4003 unsigned int i, entries, ctts_count = 0;
4004
4005 if (c->trak_index < 0) {
4006 av_log(c->fc, AV_LOG_WARNING, "CTTS outside TRAK\n");
4007 return 0;
4008 }
4009
4010 if (c->fc->nb_streams < 1)
4011 return 0;
4012 st = c->fc->streams[c->fc->nb_streams-1];
4013 sc = st->priv_data;
4014
4015 avio_r8(pb); /* version */
4016 avio_rb24(pb); /* flags */
4017 entries = avio_rb32(pb);
4018
4019 av_log(c->fc, AV_LOG_TRACE, "track[%u].ctts.entries = %u\n", c->fc->nb_streams - 1, entries);
4020
4021 if (!entries)
4022 return 0;
4023 if (entries >= UINT_MAX / sizeof(*sc->ctts_data))
4024 return AVERROR_INVALIDDATA;
4025 av_freep(&sc->ctts_data);
4026 sc->ctts_data = av_fast_realloc(NULL, &sc->ctts_allocated_size, entries * sizeof(*sc->ctts_data));
4027 if (!sc->ctts_data)
4028 return AVERROR(ENOMEM);
4029
4030 for (i = 0; i < entries && !pb->eof_reached; i++) {
4031 MOVCtts *ctts_data;
4032 const size_t min_size_needed = (ctts_count + 1) * sizeof(MOVCtts);
4033 const size_t requested_size =
4034 min_size_needed > sc->ctts_allocated_size ?
4035 FFMAX(min_size_needed, 2 * sc->ctts_allocated_size) :
4036 min_size_needed;
4037 int count = avio_rb32(pb);
4038 int duration = avio_rb32(pb);
4039
4040 if (count <= 0) {
4041 av_log(c->fc, AV_LOG_TRACE,
4042 "ignoring CTTS entry with count=%d duration=%d\n",
4043 count, duration);
4044 continue;
4045 }
4046
4047 if (ctts_count >= UINT_MAX / sizeof(MOVCtts) - 1)
4048 return AVERROR(ENOMEM);
4049
4050 ctts_data = av_fast_realloc(sc->ctts_data, &sc->ctts_allocated_size, requested_size);
4051
4052 if (!ctts_data)
4053 return AVERROR(ENOMEM);
4054
4055 sc->ctts_data = ctts_data;
4056
4057 ctts_data[ctts_count].count = count;
4058 ctts_data[ctts_count].offset = duration;
4059 ctts_count++;
4060
4061 av_log(c->fc, AV_LOG_TRACE, "count=%d, duration=%d\n",
4062 count, duration);
4063
4064 if (i+2<entries)
4066 }
4067
4068 sc->ctts_count = ctts_count;
4069
4070 if (pb->eof_reached) {
4071 av_log(c->fc, AV_LOG_WARNING, "reached eof, corrupted CTTS atom\n");
4072 return AVERROR_EOF;
4073 }
4074
4075 av_log(c->fc, AV_LOG_TRACE, "dts shift %d\n", sc->dts_shift);
4076
4077 return 0;
4078}
4079
4081{
4082 AVStream *st;
4083 MOVStreamContext *sc;
4084 uint8_t version;
4085 uint32_t grouping_type;
4086 uint32_t default_length;
4087 av_unused uint32_t default_group_description_index;
4088 uint32_t entry_count;
4089
4090 if (c->fc->nb_streams < 1)
4091 return 0;
4092 st = c->fc->streams[c->fc->nb_streams - 1];
4093 sc = st->priv_data;
4094
4095 version = avio_r8(pb); /* version */
4096 avio_rb24(pb); /* flags */
4097 grouping_type = avio_rl32(pb);
4098
4099 /*
4100 * This function only supports "sync" boxes, but the code is able to parse
4101 * other boxes (such as "tscl", "tsas" and "stsa")
4102 */
4103 if (grouping_type != MKTAG('s','y','n','c'))
4104 return 0;
4105
4106 default_length = version >= 1 ? avio_rb32(pb) : 0;
4107 default_group_description_index = version >= 2 ? avio_rb32(pb) : 0;
4108 entry_count = avio_rb32(pb);
4109
4110 if (entry_count > atom.size)
4111 return AVERROR_INVALIDDATA;
4112
4113 av_freep(&sc->sgpd_sync);
4114 sc->sgpd_sync_count = entry_count;
4115 sc->sgpd_sync = av_calloc(entry_count, sizeof(*sc->sgpd_sync));
4116 if (!sc->sgpd_sync)
4117 return AVERROR(ENOMEM);
4118
4119 for (uint32_t i = 0; i < entry_count && !pb->eof_reached; i++) {
4120 uint32_t description_length = default_length;
4121 if (version >= 1 && default_length == 0)
4122 description_length = avio_rb32(pb);
4123 if (grouping_type == MKTAG('s','y','n','c')) {
4124 const uint8_t nal_unit_type = avio_r8(pb) & 0x3f;
4125 sc->sgpd_sync[i] = nal_unit_type;
4126 description_length -= 1;
4127 }
4128 avio_skip(pb, description_length);
4129 }
4130
4131 if (pb->eof_reached) {
4132 av_log(c->fc, AV_LOG_WARNING, "reached eof, corrupted SGPD atom\n");
4133 return AVERROR_EOF;
4134 }
4135
4136 return 0;
4137}
4138
4140{
4141 AVStream *st;
4142 MOVStreamContext *sc;
4143 unsigned int i, entries;
4144 uint8_t version;
4145 uint32_t grouping_type;
4146 MOVSbgp *table, **tablep;
4147 int *table_count;
4148
4149 if (c->fc->nb_streams < 1)
4150 return 0;
4151 st = c->fc->streams[c->fc->nb_streams-1];
4152 sc = st->priv_data;
4153
4154 version = avio_r8(pb); /* version */
4155 avio_rb24(pb); /* flags */
4156 grouping_type = avio_rl32(pb);
4157
4158 if (grouping_type == MKTAG('r','a','p',' ')) {
4159 tablep = &sc->rap_group;
4160 table_count = &sc->rap_group_count;
4161 } else if (grouping_type == MKTAG('s','y','n','c')) {
4162 tablep = &sc->sync_group;
4163 table_count = &sc->sync_group_count;
4164 } else {
4165 return 0;
4166 }
4167
4168 if (version == 1)
4169 avio_rb32(pb); /* grouping_type_parameter */
4170
4171 entries = avio_rb32(pb);
4172 if (!entries)
4173 return 0;
4174 if (*tablep)
4175 av_log(c->fc, AV_LOG_WARNING, "Duplicated SBGP %s atom\n", av_fourcc2str(grouping_type));
4176 av_freep(tablep);
4177 table = av_malloc_array(entries, sizeof(*table));
4178 if (!table)
4179 return AVERROR(ENOMEM);
4180 *tablep = table;
4181
4182 for (i = 0; i < entries && !pb->eof_reached; i++) {
4183 table[i].count = avio_rb32(pb); /* sample_count */
4184 table[i].index = avio_rb32(pb); /* group_description_index */
4185 }
4186
4187 *table_count = i;
4188
4189 if (pb->eof_reached) {
4190 av_log(c->fc, AV_LOG_WARNING, "reached eof, corrupted SBGP atom\n");
4191 return AVERROR_EOF;
4192 }
4193
4194 return 0;
4195}
4196
4197/**
4198 * Get ith edit list entry (media time, duration).
4199 */
4201 const MOVStreamContext *msc,
4202 unsigned int edit_list_index,
4203 int64_t *edit_list_media_time,
4204 int64_t *edit_list_duration,
4205 int64_t global_timescale)
4206{
4207 if (edit_list_index == msc->elst_count) {
4208 return 0;
4209 }
4210 *edit_list_media_time = msc->elst_data[edit_list_index].time;
4211 *edit_list_duration = msc->elst_data[edit_list_index].duration;
4212
4213 /* duration is in global timescale units;convert to msc timescale */
4214 if (global_timescale == 0) {
4215 avpriv_request_sample(mov->fc, "Support for mvhd.timescale = 0 with editlists");
4216 return 0;
4217 }
4218 *edit_list_duration = av_rescale(*edit_list_duration, msc->time_scale,
4219 global_timescale);
4220
4221 if (*edit_list_duration < 0 ||
4222 *edit_list_media_time > INT64_MAX - *edit_list_duration)
4223 *edit_list_duration = 0;
4224
4225 return 1;
4226}
4227
4228/**
4229 * Find the closest previous frame to the timestamp_pts, in e_old index
4230 * entries. Searching for just any frame / just key frames can be controlled by
4231 * last argument 'flag'.
4232 * Note that if ctts_data is not NULL, we will always search for a key frame
4233 * irrespective of the value of 'flag'. If we don't find any keyframe, we will
4234 * return the first frame of the video.
4235 *
4236 * Here the timestamp_pts is considered to be a presentation timestamp and
4237 * the timestamp of index entries are considered to be decoding timestamps.
4238 *
4239 * Returns 0 if successful in finding a frame, else returns -1.
4240 * Places the found index corresponding output arg.
4241 *
4242 * If ctts_old is not NULL, then refines the searched entry by searching
4243 * backwards from the found timestamp, to find the frame with correct PTS.
4244 *
4245 * Places the found ctts_index and ctts_sample in corresponding output args.
4246 */
4248 AVIndexEntry *e_old,
4249 int nb_old,
4250 MOVTimeToSample *tts_data,
4251 int64_t tts_count,
4252 int64_t timestamp_pts,
4253 int flag,
4254 int64_t* index,
4255 int64_t* tts_index,
4256 int64_t* tts_sample)
4257{
4258 MOVStreamContext *msc = st->priv_data;
4259 FFStream *const sti = ffstream(st);
4260 AVIndexEntry *e_keep = sti->index_entries;
4261 int nb_keep = sti->nb_index_entries;
4262 int64_t i = 0;
4263
4265
4266 // If dts_shift > 0, then all the index timestamps will have to be offset by
4267 // at least dts_shift amount to obtain PTS.
4268 // Hence we decrement the searched timestamp_pts by dts_shift to find the closest index element.
4269 if (msc->dts_shift > 0) {
4270 timestamp_pts -= msc->dts_shift;
4271 }
4272
4273 sti->index_entries = e_old;
4274 sti->nb_index_entries = nb_old;
4276
4277 // Keep going backwards in the index entries until the timestamp is the same.
4278 if (*index >= 0) {
4279 for (i = *index; i > 0 && e_old[i].timestamp == e_old[i - 1].timestamp;
4280 i--) {
4281 if ((flag & AVSEEK_FLAG_ANY) ||
4282 (e_old[i - 1].flags & AVINDEX_KEYFRAME)) {
4283 *index = i - 1;
4284 }
4285 }
4286 }
4287
4288 // If we have CTTS then refine the search, by searching backwards over PTS
4289 // computed by adding corresponding CTTS durations to index timestamps.
4290 if (msc->ctts_count && *index >= 0) {
4291 av_assert0(tts_index);
4292 av_assert0(tts_sample);
4293 // Find out the ctts_index for the found frame.
4294 *tts_index = FFMIN(*index, tts_count);
4295 *tts_sample = 0;
4296
4297 while (*index >= 0 && (*tts_index) >= 0 && (*tts_index) < tts_count) {
4298 // Find a "key frame" with PTS <= timestamp_pts (So that we can decode B-frames correctly).
4299 // No need to add dts_shift to the timestamp here because timestamp_pts has already been
4300 // compensated by dts_shift above.
4301 if ((e_old[*index].timestamp + tts_data[*tts_index].offset) <= timestamp_pts &&
4302 (e_old[*index].flags & AVINDEX_KEYFRAME)) {
4303 break;
4304 }
4305
4306 (*index)--;
4307 if (*tts_sample == 0) {
4308 (*tts_index)--;
4309 if (*tts_index >= 0)
4310 *tts_sample = tts_data[*tts_index].count - 1;
4311 } else {
4312 (*tts_sample)--;
4313 }
4314 }
4315 }
4316
4317 /* restore AVStream state*/
4318 sti->index_entries = e_keep;
4319 sti->nb_index_entries = nb_keep;
4320 return *index >= 0 ? 0 : -1;
4321}
4322
4323/**
4324 * Add index entry with the given values, to the end of ffstream(st)->index_entries.
4325 * Returns the new size ffstream(st)->index_entries if successful, else returns -1.
4326 *
4327 * This function is similar to ff_add_index_entry in libavformat/utils.c
4328 * except that here we are always unconditionally adding an index entry to
4329 * the end, instead of searching the entries list and skipping the add if
4330 * there is an existing entry with the same timestamp.
4331 * This is needed because the mov_fix_index calls this func with the same
4332 * unincremented timestamp for successive discarded frames.
4333 */
4335 int size, int distance, int flags)
4336{
4337 FFStream *const sti = ffstream(st);
4338 AVIndexEntry *entries, *ie;
4339 int64_t index = -1;
4340 const size_t min_size_needed = (sti->nb_index_entries + 1) * sizeof(AVIndexEntry);
4341
4342 // Double the allocation each time, to lower memory fragmentation.
4343 // Another difference from ff_add_index_entry function.
4344 const size_t requested_size =
4345 min_size_needed > sti->index_entries_allocated_size ?
4346 FFMAX(min_size_needed, 2 * sti->index_entries_allocated_size) :
4347 min_size_needed;
4348
4349 if (sti->nb_index_entries + 1U >= UINT_MAX / sizeof(AVIndexEntry))
4350 return -1;
4351
4352 entries = av_fast_realloc(sti->index_entries,
4354 requested_size);
4355 if (!entries)
4356 return -1;
4357
4358 sti->index_entries = entries;
4359
4360 index = sti->nb_index_entries++;
4361 ie= &entries[index];
4362
4363 ie->pos = pos;
4364 ie->timestamp = timestamp;
4366 ie->size= size;
4367 ie->flags = flags;
4368 return index;
4369}
4370
4371/**
4372 * Rewrite timestamps of index entries in the range [end_index - frame_duration_buffer_size, end_index)
4373 * by subtracting end_ts successively by the amounts given in frame_duration_buffer.
4374 */
4375static void fix_index_entry_timestamps(AVStream* st, int end_index, int64_t end_ts,
4376 int64_t* frame_duration_buffer,
4377 int frame_duration_buffer_size) {
4378 FFStream *const sti = ffstream(st);
4379 int i = 0;
4380 av_assert0(end_index >= 0 && end_index <= sti->nb_index_entries);
4381 for (i = 0; i < frame_duration_buffer_size; i++) {
4382 end_ts -= frame_duration_buffer[frame_duration_buffer_size - 1 - i];
4383 sti->index_entries[end_index - 1 - i].timestamp = end_ts;
4384 }
4385}
4386
4387static int add_tts_entry(MOVTimeToSample **tts_data, unsigned int *tts_count, unsigned int *allocated_size,
4388 int count, int offset, unsigned int duration)
4389{
4390 MOVTimeToSample *tts_buf_new;
4391 const size_t min_size_needed = (*tts_count + 1) * sizeof(MOVTimeToSample);
4392 const size_t requested_size =
4393 min_size_needed > *allocated_size ?
4394 FFMAX(min_size_needed, 2 * (*allocated_size)) :
4395 min_size_needed;
4396
4397 if ((unsigned)(*tts_count) >= UINT_MAX / sizeof(MOVTimeToSample) - 1)
4398 return -1;
4399
4400 tts_buf_new = av_fast_realloc(*tts_data, allocated_size, requested_size);
4401
4402 if (!tts_buf_new)
4403 return -1;
4404
4405 *tts_data = tts_buf_new;
4406
4407 tts_buf_new[*tts_count].count = count;
4408 tts_buf_new[*tts_count].offset = offset;
4409 tts_buf_new[*tts_count].duration = duration;
4410
4411 *tts_count = (*tts_count) + 1;
4412 return 0;
4413}
4414
4415#define MAX_REORDER_DELAY 16
4417{
4418 MOVStreamContext *msc = st->priv_data;
4419 FFStream *const sti = ffstream(st);
4420 int ctts_ind = 0;
4421 int ctts_sample = 0;
4422 int64_t pts_buf[MAX_REORDER_DELAY + 1]; // Circular buffer to sort pts.
4423 int buf_start = 0;
4424 int j, r, num_swaps;
4425
4426 for (j = 0; j < MAX_REORDER_DELAY + 1; j++)
4427 pts_buf[j] = INT64_MIN;
4428
4429 if (st->codecpar->video_delay <= 0 && msc->ctts_count &&
4431 st->codecpar->video_delay = 0;
4432 for (int ind = 0; ind < sti->nb_index_entries && ctts_ind < msc->tts_count; ++ind) {
4433 // Point j to the last elem of the buffer and insert the current pts there.
4434 j = buf_start;
4435 buf_start = (buf_start + 1);
4436 if (buf_start == MAX_REORDER_DELAY + 1)
4437 buf_start = 0;
4438
4439 pts_buf[j] = sti->index_entries[ind].timestamp + msc->tts_data[ctts_ind].offset;
4440
4441 // The timestamps that are already in the sorted buffer, and are greater than the
4442 // current pts, are exactly the timestamps that need to be buffered to output PTS
4443 // in correct sorted order.
4444 // Hence the video delay (which is the buffer size used to sort DTS and output PTS),
4445 // can be computed as the maximum no. of swaps any particular timestamp needs to
4446 // go through, to keep this buffer in sorted order.
4447 num_swaps = 0;
4448 while (j != buf_start) {
4449 r = j - 1;
4450 if (r < 0) r = MAX_REORDER_DELAY;
4451 if (pts_buf[j] < pts_buf[r]) {
4452 FFSWAP(int64_t, pts_buf[j], pts_buf[r]);
4453 ++num_swaps;
4454 } else {
4455 break;
4456 }
4457 j = r;
4458 }
4459 st->codecpar->video_delay = FFMAX(st->codecpar->video_delay, num_swaps);
4460
4461 ctts_sample++;
4462 if (ctts_sample == msc->tts_data[ctts_ind].count) {
4463 ctts_ind++;
4464 ctts_sample = 0;
4465 }
4466 }
4467 av_log(c->fc, AV_LOG_DEBUG, "Setting codecpar->delay to %d for stream st: %d\n",
4468 st->codecpar->video_delay, st->index);
4469 }
4470}
4471
4473{
4474 sc->current_sample++;
4475 sc->current_index++;
4476 if (sc->index_ranges &&
4478 sc->current_index_range->end) {
4479 sc->current_index_range++;
4481 }
4482}
4483
4485{
4486 sc->current_sample--;
4487 sc->current_index--;
4488 if (sc->index_ranges &&
4491 sc->current_index_range--;
4492 sc->current_index = sc->current_index_range->end - 1;
4493 }
4494}
4495
4496static void mov_current_sample_set(MOVStreamContext *sc, int current_sample)
4497{
4498 int64_t range_size;
4499
4500 sc->current_sample = current_sample;
4501 sc->current_index = current_sample;
4502 if (!sc->index_ranges) {
4503 return;
4504 }
4505
4506 for (sc->current_index_range = sc->index_ranges;
4508 sc->current_index_range++) {
4509 range_size = sc->current_index_range->end - sc->current_index_range->start;
4510 if (range_size > current_sample) {
4511 sc->current_index = sc->current_index_range->start + current_sample;
4512 break;
4513 }
4514 current_sample -= range_size;
4515 }
4516}
4517
4518/**
4519 * Fix ffstream(st)->index_entries, so that it contains only the entries (and the entries
4520 * which are needed to decode them) that fall in the edit list time ranges.
4521 * Also fixes the timestamps of the index entries to match the timeline
4522 * specified the edit lists.
4523 */
4524static void mov_fix_index(MOVContext *mov, AVStream *st)
4525{
4526 MOVStreamContext *msc = st->priv_data;
4527 FFStream *const sti = ffstream(st);
4528 AVIndexEntry *e_old = sti->index_entries;
4529 int nb_old = sti->nb_index_entries;
4530 const AVIndexEntry *e_old_end = e_old + nb_old;
4531 const AVIndexEntry *current = NULL;
4532 MOVTimeToSample *tts_data_old = msc->tts_data;
4533 int64_t tts_index_old = 0;
4534 int64_t tts_sample_old = 0;
4535 int64_t tts_count_old = msc->tts_count;
4536 int64_t edit_list_media_time = 0;
4537 int64_t edit_list_duration = 0;
4538 int64_t frame_duration = 0;
4539 int64_t edit_list_dts_counter = 0;
4540 int64_t edit_list_dts_entry_end = 0;
4541 int64_t edit_list_start_tts_sample = 0;
4542 int64_t curr_cts;
4543 int64_t curr_ctts = 0;
4544 int64_t empty_edits_sum_duration = 0;
4545 int64_t edit_list_index = 0;
4546 int64_t index;
4547 int flags;
4548 int64_t start_dts = 0;
4549 int64_t edit_list_start_encountered = 0;
4550 int64_t search_timestamp = 0;
4551 int64_t* frame_duration_buffer = NULL;
4552 int num_discarded_begin = 0;
4553 int first_non_zero_audio_edit = -1;
4554 int packet_skip_samples = 0;
4555 MOVIndexRange *current_index_range = NULL;
4556 int found_keyframe_after_edit = 0;
4557 int found_non_empty_edit = 0;
4558
4559 if (!msc->elst_data || msc->elst_count <= 0 || nb_old <= 0) {
4560 return;
4561 }
4562
4563 int64_t max_entries = nb_old * 16LL + (1 << 16);
4564
4565 // allocate the index ranges array
4566 msc->index_ranges = av_malloc_array(msc->elst_count + 1,
4567 sizeof(msc->index_ranges[0]));
4568 if (!msc->index_ranges) {
4569 av_log(mov->fc, AV_LOG_ERROR, "Cannot allocate index ranges buffer\n");
4570 return;
4571 }
4573
4574 // Clean AVStream from traces of old index
4575 sti->index_entries = NULL;
4577 sti->nb_index_entries = 0;
4578
4579 // Clean time to sample fields of MOVStreamContext
4580 msc->tts_data = NULL;
4581 msc->tts_count = 0;
4582 msc->tts_index = 0;
4583 msc->tts_sample = 0;
4584 msc->tts_allocated_size = 0;
4585
4586 // Reinitialize min_corrected_pts so that it can be computed again.
4587 msc->min_corrected_pts = -1;
4588
4589 // If the dts_shift is positive (in case of negative ctts values in mov),
4590 // then negate the DTS by dts_shift
4591 if (msc->dts_shift > 0) {
4592 edit_list_dts_entry_end -= msc->dts_shift;
4593 av_log(mov->fc, AV_LOG_DEBUG, "Shifting DTS by %d because of negative CTTS.\n", msc->dts_shift);
4594 }
4595
4596 start_dts = edit_list_dts_entry_end;
4597
4598 while (get_edit_list_entry(mov, msc, edit_list_index, &edit_list_media_time,
4599 &edit_list_duration, mov->time_scale)) {
4600 av_log(mov->fc, AV_LOG_DEBUG, "Processing st: %d, edit list %"PRId64" - media time: %"PRId64", duration: %"PRId64"\n",
4601 st->index, edit_list_index, edit_list_media_time, edit_list_duration);
4602 edit_list_index++;
4603 edit_list_dts_counter = edit_list_dts_entry_end;
4604 edit_list_dts_entry_end = av_sat_add64(edit_list_dts_entry_end, edit_list_duration);
4605 if (edit_list_dts_entry_end == INT64_MAX) {
4606 av_log(mov->fc, AV_LOG_ERROR, "Cannot calculate dts entry length with duration %"PRId64"\n",
4607 edit_list_duration);
4608 break;
4609 }
4610 num_discarded_begin = 0;
4611 if (edit_list_media_time == -1) {
4612 if (!found_non_empty_edit)
4613 empty_edits_sum_duration += edit_list_duration;
4614 continue;
4615 }
4616 found_non_empty_edit = 1;
4617
4618 // If we encounter a non-negative edit list reset the skip_samples/initial_padding fields and set them
4619 // according to the edit list below.
4621 if (first_non_zero_audio_edit < 0) {
4622 first_non_zero_audio_edit = 1;
4623 } else {
4624 first_non_zero_audio_edit = 0;
4625 }
4626
4627 if (first_non_zero_audio_edit > 0)
4628 sti->skip_samples = st->codecpar->initial_padding = 0;
4629 }
4630
4631 // While reordering frame index according to edit list we must handle properly
4632 // the scenario when edit list entry starts from none key frame.
4633 // We find closest previous key frame and preserve it and consequent frames in index.
4634 // All frames which are outside edit list entry time boundaries will be dropped after decoding.
4635 search_timestamp = edit_list_media_time;
4637 // Audio decoders like AAC need need a decoder delay samples previous to the current sample,
4638 // to correctly decode this frame. Hence for audio we seek to a frame 1 sec. before the
4639 // edit_list_media_time to cover the decoder delay.
4640 search_timestamp = FFMAX(av_sat_sub64(search_timestamp, msc->time_scale), e_old[0].timestamp);
4641 }
4642
4643 if (find_prev_closest_index(st, e_old, nb_old, tts_data_old, tts_count_old, search_timestamp, 0,
4644 &index, &tts_index_old, &tts_sample_old) < 0) {
4645 av_log(mov->fc, AV_LOG_WARNING,
4646 "st: %d edit list: %"PRId64" Missing key frame while searching for timestamp: %"PRId64"\n",
4647 st->index, edit_list_index, search_timestamp);
4648 if (find_prev_closest_index(st, e_old, nb_old, tts_data_old, tts_count_old, search_timestamp, AVSEEK_FLAG_ANY,
4649 &index, &tts_index_old, &tts_sample_old) < 0) {
4650 av_log(mov->fc, AV_LOG_WARNING,
4651 "st: %d edit list %"PRId64" Cannot find an index entry before timestamp: %"PRId64".\n",
4652 st->index, edit_list_index, search_timestamp);
4653 index = 0;
4654 tts_index_old = 0;
4655 tts_sample_old = 0;
4656 }
4657 }
4658 current = e_old + index;
4659 edit_list_start_tts_sample = tts_sample_old;
4660
4661 // Iterate over index and arrange it according to edit list
4662 edit_list_start_encountered = 0;
4663 found_keyframe_after_edit = 0;
4664 for (; current < e_old_end; current++, index++) {
4665 if (sti->nb_index_entries >= max_entries) {
4666 av_log(mov->fc, AV_LOG_ERROR, "Edit list expands the sample index beyond %"PRId64" entries\n",
4667 max_entries);
4668 goto truncated;
4669 }
4670 // check if frame outside edit list mark it for discard
4671 frame_duration = (current + 1 < e_old_end) ?
4672 ((current + 1)->timestamp - current->timestamp) : edit_list_duration;
4673
4674 flags = current->flags;
4675
4676 // frames (pts) before or after edit list
4677 curr_cts = current->timestamp + msc->dts_shift;
4678 curr_ctts = 0;
4679
4680 if (tts_data_old && tts_index_old < tts_count_old) {
4681 curr_ctts = tts_data_old[tts_index_old].offset;
4682 av_log(mov->fc, AV_LOG_TRACE, "stts: %"PRId64" ctts: %"PRId64", tts_index: %"PRId64", tts_count: %"PRId64"\n",
4683 curr_cts, curr_ctts, tts_index_old, tts_count_old);
4684 curr_cts += curr_ctts;
4685 tts_sample_old++;
4686 if (tts_sample_old == tts_data_old[tts_index_old].count) {
4687 if (add_tts_entry(&msc->tts_data, &msc->tts_count,
4688 &msc->tts_allocated_size,
4689 tts_data_old[tts_index_old].count - edit_list_start_tts_sample,
4690 tts_data_old[tts_index_old].offset, tts_data_old[tts_index_old].duration) == -1) {
4691 av_log(mov->fc, AV_LOG_ERROR, "Cannot add Time To Sample entry %"PRId64" - {%"PRId64", %d}\n",
4692 tts_index_old,
4693 tts_data_old[tts_index_old].count - edit_list_start_tts_sample,
4694 tts_data_old[tts_index_old].offset);
4695 break;
4696 }
4697 tts_index_old++;
4698 tts_sample_old = 0;
4699 edit_list_start_tts_sample = 0;
4700 }
4701 }
4702
4703 if (curr_cts < edit_list_media_time || curr_cts >= (edit_list_duration + edit_list_media_time)) {
4705 curr_cts < edit_list_media_time && curr_cts + frame_duration > edit_list_media_time &&
4706 first_non_zero_audio_edit > 0) {
4707 packet_skip_samples = edit_list_media_time - curr_cts;
4708 sti->skip_samples += packet_skip_samples;
4709
4710 // Shift the index entry timestamp by packet_skip_samples to be correct.
4711 edit_list_dts_counter -= packet_skip_samples;
4712 if (edit_list_start_encountered == 0) {
4713 edit_list_start_encountered = 1;
4714 // Make timestamps strictly monotonically increasing for audio, by rewriting timestamps for
4715 // discarded packets.
4716 if (frame_duration_buffer) {
4717 fix_index_entry_timestamps(st, sti->nb_index_entries, edit_list_dts_counter,
4718 frame_duration_buffer, num_discarded_begin);
4719 av_freep(&frame_duration_buffer);
4720 }
4721 }
4722
4723 av_log(mov->fc, AV_LOG_DEBUG, "skip %d audio samples from curr_cts: %"PRId64"\n", packet_skip_samples, curr_cts);
4724 } else {
4726 av_log(mov->fc, AV_LOG_DEBUG, "drop a frame at curr_cts: %"PRId64" @ %"PRId64"\n", curr_cts, index);
4727
4728 if (edit_list_start_encountered == 0) {
4729 num_discarded_begin++;
4730 if (av_reallocp_array(&frame_duration_buffer, num_discarded_begin,
4731 sizeof(*frame_duration_buffer)) < 0) {
4732 av_log(mov->fc, AV_LOG_ERROR, "Cannot reallocate frame duration buffer\n");
4733 break;
4734 }
4735 frame_duration_buffer[num_discarded_begin - 1] = frame_duration;
4736
4737 // Increment skip_samples for the first non-zero audio edit list
4739 first_non_zero_audio_edit > 0 && st->codecpar->codec_id != AV_CODEC_ID_VORBIS) {
4740 sti->skip_samples += frame_duration;
4741 }
4742 }
4743 }
4744 } else {
4745 if (msc->min_corrected_pts < 0) {
4746 msc->min_corrected_pts = edit_list_dts_counter + curr_ctts + msc->dts_shift;
4747 } else {
4748 msc->min_corrected_pts = FFMIN(msc->min_corrected_pts, edit_list_dts_counter + curr_ctts + msc->dts_shift);
4749 }
4750 if (edit_list_start_encountered == 0) {
4751 edit_list_start_encountered = 1;
4752 // Make timestamps strictly monotonically increasing by rewriting timestamps for
4753 // discarded packets.
4754 if (frame_duration_buffer) {
4755 fix_index_entry_timestamps(st, sti->nb_index_entries, edit_list_dts_counter,
4756 frame_duration_buffer, num_discarded_begin);
4757 av_freep(&frame_duration_buffer);
4758 }
4759 }
4760 }
4761
4762 if (add_index_entry(st, current->pos, edit_list_dts_counter, current->size,
4763 current->min_distance, flags) == -1) {
4764 av_log(mov->fc, AV_LOG_ERROR, "Cannot add index entry\n");
4765 break;
4766 }
4767
4768 // Update the index ranges array
4769 if (!current_index_range || index != current_index_range->end) {
4770 current_index_range = current_index_range ? current_index_range + 1
4771 : msc->index_ranges;
4772 current_index_range->start = index;
4773 }
4774 current_index_range->end = index + 1;
4775
4776 // Only start incrementing DTS in frame_duration amounts, when we encounter a frame in edit list.
4777 if (edit_list_start_encountered > 0) {
4778 edit_list_dts_counter = edit_list_dts_counter + frame_duration;
4779 }
4780
4781 // Break when found first key frame after edit entry completion
4782 if ((curr_cts + frame_duration >= (edit_list_duration + edit_list_media_time)) &&
4784 if (msc->ctts_count) {
4785 // If we have CTTS and this is the first keyframe after edit elist,
4786 // wait for one more, because there might be trailing B-frames after this I-frame
4787 // that do belong to the edit.
4788 if (st->codecpar->codec_type != AVMEDIA_TYPE_AUDIO && found_keyframe_after_edit == 0) {
4789 found_keyframe_after_edit = 1;
4790 continue;
4791 }
4792 if (tts_sample_old != 0) {
4793 if (add_tts_entry(&msc->tts_data, &msc->tts_count,
4794 &msc->tts_allocated_size,
4795 tts_sample_old - edit_list_start_tts_sample,
4796 tts_data_old[tts_index_old].offset, tts_data_old[tts_index_old].duration) == -1) {
4797 av_log(mov->fc, AV_LOG_ERROR, "Cannot add Time To Sample entry %"PRId64" - {%"PRId64", %d}\n",
4798 tts_index_old, tts_sample_old - edit_list_start_tts_sample,
4799 tts_data_old[tts_index_old].offset);
4800 break;
4801 }
4802 }
4803 }
4804 break;
4805 }
4806 }
4807 }
4808truncated:
4809 // If there are empty edits, then msc->min_corrected_pts might be positive
4810 // intentionally. So we subtract the sum duration of empty edits here.
4811 msc->min_corrected_pts -= empty_edits_sum_duration;
4812
4813 // If the minimum pts turns out to be greater than zero after fixing the index, then we subtract the
4814 // dts by that amount to make the first pts zero.
4816 if (msc->min_corrected_pts > 0) {
4817 av_log(mov->fc, AV_LOG_DEBUG, "Offset DTS by %"PRId64" to make first pts zero.\n", msc->min_corrected_pts);
4818 for (int i = 0; i < sti->nb_index_entries; ++i)
4820 }
4821 }
4822 // Start time should be equal to zero or the duration of any empty edits.
4823 st->start_time = empty_edits_sum_duration;
4824
4825 // Update av stream length, if it ends up shorter than the track's media duration
4826 st->duration = FFMIN(st->duration, edit_list_dts_entry_end - start_dts);
4828
4829 // Free the old index and the old CTTS structures
4830 av_free(e_old);
4831 av_free(tts_data_old);
4832 av_freep(&frame_duration_buffer);
4833
4834 // Null terminate the index ranges array
4835 current_index_range = current_index_range ? current_index_range + 1
4836 : msc->index_ranges;
4837 current_index_range->start = 0;
4838 current_index_range->end = 0;
4839 msc->current_index = msc->index_ranges[0].start;
4840}
4841
4842static uint32_t get_sgpd_sync_index(const MOVStreamContext *sc, int nal_unit_type)
4843{
4844 for (uint32_t i = 0; i < sc->sgpd_sync_count; i++)
4845 if (sc->sgpd_sync[i] == nal_unit_type)
4846 return i + 1;
4847 return 0;
4848}
4849
4851{
4852 int k;
4853 int sample_id = 0;
4854 uint32_t cra_index;
4855 MOVStreamContext *sc = st->priv_data;
4856
4858 return 0;
4859
4860 /* Build an unrolled index of the samples */
4861 sc->sample_offsets_count = 0;
4862 for (uint32_t i = 0; i < sc->ctts_count; i++) {
4863 if (sc->ctts_data[i].count > INT_MAX - sc->sample_offsets_count)
4864 return AVERROR(ENOMEM);
4866 }
4869 if (!sc->sample_offsets)
4870 return AVERROR(ENOMEM);
4871 k = 0;
4872 for (uint32_t i = 0; i < sc->ctts_count; i++)
4873 for (int j = 0; j < sc->ctts_data[i].count; j++)
4874 sc->sample_offsets[k++] = sc->ctts_data[i].offset;
4875
4876 /* The following HEVC NAL type reveal the use of open GOP sync points
4877 * (TODO: BLA types may also be concerned) */
4878 cra_index = get_sgpd_sync_index(sc, HEVC_NAL_CRA_NUT); /* Clean Random Access */
4879 if (!cra_index)
4880 return 0;
4881
4882 /* Build a list of open-GOP key samples */
4883 sc->open_key_samples_count = 0;
4884 for (uint32_t i = 0; i < sc->sync_group_count; i++)
4885 if (sc->sync_group[i].index == cra_index) {
4886 if (sc->sync_group[i].count > INT_MAX - sc->open_key_samples_count)
4887 return AVERROR(ENOMEM);
4889 }
4892 if (!sc->open_key_samples)
4893 return AVERROR(ENOMEM);
4894 k = 0;
4895 for (uint32_t i = 0; i < sc->sync_group_count; i++) {
4896 const MOVSbgp *sg = &sc->sync_group[i];
4897 if (sg->index == cra_index)
4898 for (uint32_t j = 0; j < sg->count; j++)
4899 sc->open_key_samples[k++] = sample_id;
4900 if (sg->count > INT_MAX - sample_id)
4901 return AVERROR_PATCHWELCOME;
4902 sample_id += sg->count;
4903 }
4904
4905 /* Identify the minimal time step between samples */
4906 sc->min_sample_duration = UINT_MAX;
4907 for (uint32_t i = 0; i < sc->stts_count; i++)
4909
4910 return 0;
4911}
4912
4913#define MOV_MERGE_CTTS 1
4914#define MOV_MERGE_STTS 2
4915/*
4916 * Merge stts and ctts arrays into a new combined array.
4917 * stts_count and ctts_count may be left untouched as they will be
4918 * used to check for the presence of either of them.
4919 */
4921{
4922 MOVStreamContext *sc = st->priv_data;
4923 int ctts = sc->ctts_data && (flags & MOV_MERGE_CTTS);
4924 int stts = sc->stts_data && (flags & MOV_MERGE_STTS);
4925 int idx = 0;
4926
4927 if (!sc->ctts_data && !sc->stts_data)
4928 return 0;
4929 // Expand time to sample entries such that we have a 1-1 mapping with samples
4930 if (!sc->sample_count || sc->sample_count >= UINT_MAX / sizeof(*sc->tts_data))
4931 return -1;
4932
4933 if (ctts) {
4935 sc->sample_count * sizeof(*sc->tts_data));
4936 if (!sc->tts_data)
4937 return -1;
4938
4939 memset(sc->tts_data, 0, sc->tts_allocated_size);
4940
4941 for (int i = 0; i < sc->ctts_count &&
4942 idx < sc->sample_count; i++)
4943 for (int j = 0; j < sc->ctts_data[i].count &&
4944 idx < sc->sample_count; j++) {
4945 sc->tts_data[idx].offset = sc->ctts_data[i].offset;
4946 sc->tts_data[idx++].count = 1;
4947 }
4948
4949 sc->tts_count = idx;
4950 } else
4951 sc->ctts_count = 0;
4952 av_freep(&sc->ctts_data);
4953 sc->ctts_allocated_size = 0;
4954
4955 idx = 0;
4956 if (stts) {
4958 sc->sample_count * sizeof(*sc->tts_data));
4959 if (!tts_data)
4960 return -1;
4961
4962 if (!sc->tts_data)
4963 memset(tts_data, 0, sc->tts_allocated_size);
4964 sc->tts_data = tts_data;
4965
4966 for (int i = 0; i < sc->stts_count &&
4967 idx < sc->sample_count; i++)
4968 for (int j = 0; j < sc->stts_data[i].count &&
4969 idx < sc->sample_count; j++) {
4970 sc->tts_data[idx].duration = sc->stts_data[i].duration;
4971 sc->tts_data[idx++].count = 1;
4972 }
4973
4974 sc->tts_count = FFMAX(sc->tts_count, idx);
4975 } else
4976 sc->stts_count = 0;
4977 av_freep(&sc->stts_data);
4978 sc->stts_allocated_size = 0;
4979
4980 return 0;
4981}
4982
4984{
4985 MOVStreamContext *sc = st->priv_data;
4986 FFStream *const sti = ffstream(st);
4987 int64_t current_offset;
4988 int64_t current_dts = 0;
4989 unsigned int stts_index = 0;
4990 unsigned int stsc_index = 0;
4991 unsigned int stss_index = 0;
4992 unsigned int stps_index = 0;
4993 unsigned int i, j;
4994 uint64_t stream_size = 0;
4995
4997 if (ret < 0)
4998 return;
4999
5000 if (sc->elst_count) {
5001 int i, edit_start_index = 0, multiple_edits = 0;
5002 int64_t empty_duration = 0; // empty duration of the first edit list entry
5003 int64_t start_time = 0; // start time of the media
5004
5005 for (i = 0; i < sc->elst_count; i++) {
5006 const MOVElst *e = &sc->elst_data[i];
5007 if (i == 0 && e->time == -1) {
5008 /* if empty, the first entry is the start time of the stream
5009 * relative to the presentation itself */
5010 empty_duration = e->duration;
5011 edit_start_index = 1;
5012 } else if (i == edit_start_index && e->time >= 0) {
5013 start_time = e->time;
5014 } else {
5015 multiple_edits = 1;
5016 }
5017 }
5018
5019 if (multiple_edits && !mov->advanced_editlist) {
5021 av_log(mov->fc, AV_LOG_WARNING, "multiple edit list entries, "
5022 "not supported in fragmented MP4 files\n");
5023 else
5024 av_log(mov->fc, AV_LOG_WARNING, "multiple edit list entries, "
5025 "Use -advanced_editlist to correctly decode otherwise "
5026 "a/v desync might occur\n");
5027 }
5028
5029 /* adjust first dts according to edit list */
5030 if ((empty_duration || start_time) && mov->time_scale > 0) {
5031 if (empty_duration)
5032 empty_duration = av_rescale(empty_duration, sc->time_scale, mov->time_scale);
5033
5034 if (av_sat_sub64(start_time, empty_duration) != start_time - (uint64_t)empty_duration)
5035 av_log(mov->fc, AV_LOG_WARNING, "start_time - empty_duration is not representable\n");
5036
5037 sc->time_offset = start_time - (uint64_t)empty_duration;
5039 if (!mov->advanced_editlist)
5040 current_dts = -av_clip64(sc->time_offset, -INT64_MAX, INT64_MAX);
5041 }
5042
5043 if (!multiple_edits && !mov->advanced_editlist &&
5046 (AVRational){1, st->codecpar->sample_rate});
5047 }
5048
5049 /* only use old uncompressed audio chunk demuxing when stts specifies it */
5050 if (!(st->codecpar->codec_type == AVMEDIA_TYPE_AUDIO &&
5051 sc->stts_count == 1 && sc->stts_data && sc->stts_data[0].duration == 1)) {
5052 unsigned int current_sample = 0;
5053 unsigned int stts_sample = 0;
5054 unsigned int sample_size;
5055 unsigned int distance = 0;
5056 unsigned int rap_group_index = 0;
5057 unsigned int rap_group_sample = 0;
5058 int rap_group_present = sc->rap_group_count && sc->rap_group;
5059 int key_off = (sc->keyframe_count && sc->keyframes[0] > 0) || (sc->stps_count && sc->stps_data[0] > 0);
5060
5061 av_assert0(sc->dts_shift >= 0);
5062 if (current_dts < INT64_MIN + sc->dts_shift)
5063 return;
5064 current_dts -= sc->dts_shift;
5065 if (!sc->sample_count || sti->nb_index_entries || sc->tts_count)
5066 return;
5067 if (sc->sample_count >= UINT_MAX / sizeof(*sti->index_entries) - sti->nb_index_entries)
5068 return;
5070 sti->nb_index_entries + sc->sample_count,
5071 sizeof(*sti->index_entries)) < 0) {
5072 sti->nb_index_entries = 0;
5073 return;
5074 }
5075 sti->index_entries_allocated_size = (sti->nb_index_entries + sc->sample_count) * sizeof(*sti->index_entries);
5076
5078 if (ret < 0)
5079 return;
5080
5081 for (i = 0; i < sc->chunk_count; i++) {
5082 int64_t next_offset = i+1 < sc->chunk_count ? sc->chunk_offsets[i+1] : INT64_MAX;
5083 current_offset = sc->chunk_offsets[i];
5084 while (mov_stsc_index_valid(stsc_index, sc->stsc_count) &&
5085 i + 1 == sc->stsc_data[stsc_index + 1].first)
5086 stsc_index++;
5087
5088 if (next_offset > current_offset && sc->sample_size>0 && sc->sample_size < sc->stsz_sample_size &&
5089 sc->stsc_data[stsc_index].count * (int64_t)sc->stsz_sample_size > next_offset - current_offset) {
5090 av_log(mov->fc, AV_LOG_WARNING, "STSZ sample size %d invalid (too large), ignoring\n", sc->stsz_sample_size);
5091 sc->stsz_sample_size = sc->sample_size;
5092 }
5093 if (sc->stsz_sample_size>0 && sc->stsz_sample_size < sc->sample_size) {
5094 av_log(mov->fc, AV_LOG_WARNING, "STSZ sample size %d invalid (too small), ignoring\n", sc->stsz_sample_size);
5095 sc->stsz_sample_size = sc->sample_size;
5096 }
5097
5098 for (j = 0; j < sc->stsc_data[stsc_index].count; j++) {
5099 int keyframe = 0;
5100 if (current_sample >= sc->sample_count) {
5101 av_log(mov->fc, AV_LOG_ERROR, "wrong sample count\n");
5102 return;
5103 }
5104
5105 if (!sc->keyframe_absent && (!sc->keyframe_count || current_sample+key_off == sc->keyframes[stss_index])) {
5106 keyframe = 1;
5107 if (stss_index + 1 < sc->keyframe_count)
5108 stss_index++;
5109 } else if (sc->stps_count && current_sample+key_off == sc->stps_data[stps_index]) {
5110 keyframe = 1;
5111 if (stps_index + 1 < sc->stps_count)
5112 stps_index++;
5113 }
5114 if (rap_group_present && rap_group_index < sc->rap_group_count) {
5115 if (sc->rap_group[rap_group_index].index > 0)
5116 keyframe = 1;
5117 if (++rap_group_sample == sc->rap_group[rap_group_index].count) {
5118 rap_group_sample = 0;
5119 rap_group_index++;
5120 }
5121 }
5122 if (sc->keyframe_absent
5123 && !sc->stps_count
5124 && !rap_group_present
5125 && (st->codecpar->codec_type == AVMEDIA_TYPE_AUDIO || (i==0 && j==0)))
5126 keyframe = 1;
5127 if (keyframe)
5128 distance = 0;
5129 sample_size = sc->stsz_sample_size > 0 ? sc->stsz_sample_size : sc->sample_sizes[current_sample];
5130 if (current_offset > INT64_MAX - sample_size) {
5131 av_log(mov->fc, AV_LOG_ERROR, "Current offset %"PRId64" or sample size %u is too large\n",
5132 current_offset,
5133 sample_size);
5134 return;
5135 }
5136
5137 if (sc->pseudo_stream_id == -1 ||
5138 sc->stsc_data[stsc_index].id - 1 == sc->pseudo_stream_id) {
5139 AVIndexEntry *e;
5140 if (sample_size > 0x3FFFFFFF) {
5141 av_log(mov->fc, AV_LOG_ERROR, "Sample size %u is too large\n", sample_size);
5142 return;
5143 }
5144 e = &sti->index_entries[sti->nb_index_entries++];
5145 e->pos = current_offset;
5146 e->timestamp = current_dts;
5147 e->size = sample_size;
5149 e->flags = keyframe ? AVINDEX_KEYFRAME : 0;
5150 av_log(mov->fc, AV_LOG_TRACE, "AVIndex stream %d, sample %u, offset %"PRIx64", dts %"PRId64", "
5151 "size %u, distance %u, keyframe %d\n", st->index, current_sample,
5152 current_offset, current_dts, sample_size, distance, keyframe);
5153 if (st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO && sti->nb_index_entries < 100)
5154 ff_rfps_add_frame(mov->fc, st, current_dts);
5155 }
5156
5157 current_offset += sample_size;
5158 stream_size += sample_size;
5159
5160 if (current_dts > INT64_MAX - sc->tts_data[stts_index].duration)
5161 return;
5162 current_dts += sc->tts_data[stts_index].duration;
5163
5164 distance++;
5165 stts_sample++;
5166 current_sample++;
5167 if (stts_index + 1 < sc->tts_count && stts_sample == sc->tts_data[stts_index].count) {
5168 stts_sample = 0;
5169 stts_index++;
5170 }
5171 }
5172 }
5173 if (st->duration > 0)
5174 st->codecpar->bit_rate = stream_size*8*sc->time_scale/st->duration;
5175 } else {
5176 unsigned chunk_samples, total = 0;
5177
5178 if (!sc->chunk_count || sc->tts_count)
5179 return;
5180
5181 // compute total chunk count
5182 for (i = 0; i < sc->stsc_count; i++) {
5183 unsigned count, chunk_count;
5184
5185 chunk_samples = sc->stsc_data[i].count;
5186 if (i != sc->stsc_count - 1 &&
5187 sc->samples_per_frame && chunk_samples % sc->samples_per_frame) {
5188 av_log(mov->fc, AV_LOG_ERROR, "error unaligned chunk\n");
5189 return;
5190 }
5191
5192 if (sc->samples_per_frame >= 160) { // gsm
5193 count = chunk_samples / sc->samples_per_frame;
5194 } else if (sc->samples_per_frame > 1) {
5195 unsigned samples = (1024/sc->samples_per_frame)*sc->samples_per_frame;
5196 count = (chunk_samples+samples-1) / samples;
5197 } else {
5198 count = (chunk_samples+1023) / 1024;
5199 }
5200
5202 chunk_count = sc->stsc_data[i+1].first - sc->stsc_data[i].first;
5203 else
5204 chunk_count = sc->chunk_count - (sc->stsc_data[i].first - 1);
5205 total += chunk_count * count;
5206 }
5207
5208 av_log(mov->fc, AV_LOG_TRACE, "chunk count %u\n", total);
5209 if (total >= UINT_MAX / sizeof(*sti->index_entries) - sti->nb_index_entries)
5210 return;
5212 sti->nb_index_entries + total,
5213 sizeof(*sti->index_entries)) < 0) {
5214 sti->nb_index_entries = 0;
5215 return;
5216 }
5217 sti->index_entries_allocated_size = (sti->nb_index_entries + total) * sizeof(*sti->index_entries);
5218
5219 // populate index
5220 for (i = 0; i < sc->chunk_count; i++) {
5221 current_offset = sc->chunk_offsets[i];
5222 if (mov_stsc_index_valid(stsc_index, sc->stsc_count) &&
5223 i + 1 == sc->stsc_data[stsc_index + 1].first)
5224 stsc_index++;
5225 chunk_samples = sc->stsc_data[stsc_index].count;
5226
5227 while (chunk_samples > 0) {
5228 AVIndexEntry *e;
5229 unsigned size, samples;
5230
5231 if (sc->samples_per_frame > 1 && !sc->bytes_per_frame) {
5233 "Zero bytes per frame, but %d samples per frame",
5234 sc->samples_per_frame);
5235 return;
5236 }
5237
5238 if (sc->samples_per_frame >= 160) { // gsm
5239 samples = sc->samples_per_frame;
5240 size = sc->bytes_per_frame;
5241 } else {
5242 if (sc->samples_per_frame > 1) {
5243 samples = FFMIN((1024 / sc->samples_per_frame)*
5244 sc->samples_per_frame, chunk_samples);
5245 size = (samples / sc->samples_per_frame) * sc->bytes_per_frame;
5246 } else {
5247 samples = FFMIN(1024, chunk_samples);
5248 size = samples * sc->sample_size;
5249 }
5250 }
5251
5252 if (sti->nb_index_entries >= total) {
5253 av_log(mov->fc, AV_LOG_ERROR, "wrong chunk count %u\n", total);
5254 return;
5255 }
5256 if (size > 0x3FFFFFFF) {
5257 av_log(mov->fc, AV_LOG_ERROR, "Sample size %u is too large\n", size);
5258 return;
5259 }
5260 e = &sti->index_entries[sti->nb_index_entries++];
5261 e->pos = current_offset;
5262 e->timestamp = current_dts;
5263 e->size = size;
5264 e->min_distance = 0;
5266 av_log(mov->fc, AV_LOG_TRACE, "AVIndex stream %d, chunk %u, offset %"PRIx64", dts %"PRId64", "
5267 "size %u, duration %u\n", st->index, i, current_offset, current_dts,
5268 size, samples);
5269
5270 current_offset += size;
5271 if (current_dts > INT64_MAX - samples)
5272 return;
5273 current_dts += samples;
5274 chunk_samples -= samples;
5275 }
5276 }
5277
5279 if (ret < 0)
5280 return;
5281 }
5282
5283 if (!mov->ignore_editlist && mov->advanced_editlist) {
5284 // Fix index according to edit lists.
5285 mov_fix_index(mov, st);
5286 }
5287
5288 // Update start time of the stream.
5291 if (sc->tts_data) {
5293 }
5294 }
5295
5296 mov_estimate_video_delay(mov, st);
5297}
5298
5303
5304static int mov_compare_presentation_samples(const void *a, const void *b)
5305{
5306 const MOVPresentationSample *sa = a;
5307 const MOVPresentationSample *sb = b;
5308
5309 if (sa->pts != sb->pts)
5310 return (sa->pts > sb->pts) - (sa->pts < sb->pts);
5311 return (sa->index > sb->index) - (sa->index < sb->index);
5312}
5313
5314/*
5315 * Set sample durations from adjacent presentation timestamps.
5316 */
5318{
5319 MOVStreamContext *sc = st->priv_data;
5320 FFStream *const sti = ffstream(st);
5321 MOVPresentationSample *samples = NULL;
5322 MOVTimeToSample *tts_data = NULL;
5323 unsigned int tts_index = 0, tts_sample = 0;
5324 int count = sti->nb_index_entries;
5325
5326 /* A single STTS entry describes a fixed sample delta. */
5328 !sc->ctts_count || sc->stts_count < 2 ||
5329 !sc->tts_data || count < 2 ||
5330 count >= UINT_MAX / sizeof(*tts_data))
5331 return;
5332
5333 samples = av_malloc_array(count, sizeof(*samples));
5334 tts_data = av_malloc_array(count, sizeof(*tts_data));
5335 if (!samples || !tts_data)
5336 goto fail;
5337
5338 for (int i = 0; i < count; i++) {
5339 int64_t dts, offset;
5340
5341 if (tts_index >= sc->tts_count || !sc->tts_data[tts_index].count)
5342 goto fail;
5343
5344 tts_data[i] = sc->tts_data[tts_index];
5345 tts_data[i].count = 1;
5346
5347 dts = sti->index_entries[i].timestamp;
5348 offset = (int64_t)sc->dts_shift + tts_data[i].offset;
5349 if (dts == AV_NOPTS_VALUE ||
5350 (offset > 0 && dts > INT64_MAX - offset) ||
5351 (offset < 0 && dts < INT64_MIN - offset))
5352 goto fail;
5353
5354 samples[i].index = i;
5355 samples[i].pts = dts + offset;
5356
5357 if (++tts_sample == sc->tts_data[tts_index].count) {
5358 tts_index++;
5359 tts_sample = 0;
5360 }
5361 }
5362 if (tts_index != sc->tts_count || tts_sample)
5363 goto fail;
5364
5365 qsort(samples, count, sizeof(*samples), mov_compare_presentation_samples);
5366
5367 for (int i = 0; i + 1 < count; i++) {
5368 uint64_t duration;
5369
5370 if (samples[i].pts >= samples[i + 1].pts)
5371 goto fail;
5372
5373 /*
5374 * In VFR streams with reordered frames, STTS deltas follow decode
5375 * order while AVPacket.duration follows presentation order. CTTS
5376 * may produce presentation intervals that cannot be obtained by
5377 * merely permuting the STTS deltas, so derive each known duration
5378 * from adjacent PTS.
5379 */
5380 duration = (uint64_t)samples[i + 1].pts - samples[i].pts;
5381 if (!duration || duration > UINT_MAX)
5382 goto fail;
5383
5384 tts_data[samples[i].index].duration = (unsigned int)duration;
5385 }
5386
5387 av_log(mov->fc, AV_LOG_DEBUG,
5388 "Updated sample durations in presentation order for stream %d\n",
5389 st->index);
5390
5391 av_freep(&sc->tts_data);
5392 sc->tts_data = tts_data;
5393 sc->tts_count = count;
5394 sc->tts_allocated_size = count * sizeof(*tts_data);
5395 tts_data = NULL;
5396
5397fail:
5398 av_free(samples);
5399 av_free(tts_data);
5400}
5401
5402static int test_same_origin(const char *src, const char *ref) {
5403 char src_proto[64];
5404 char ref_proto[64];
5405 char src_auth[256];
5406 char ref_auth[256];
5407 char src_host[256];
5408 char ref_host[256];
5409 int src_port=-1;
5410 int ref_port=-1;
5411
5412 av_url_split(src_proto, sizeof(src_proto), src_auth, sizeof(src_auth), src_host, sizeof(src_host), &src_port, NULL, 0, src);
5413 av_url_split(ref_proto, sizeof(ref_proto), ref_auth, sizeof(ref_auth), ref_host, sizeof(ref_host), &ref_port, NULL, 0, ref);
5414
5415 if (strlen(src) == 0) {
5416 return -1;
5417 } else if (strlen(src_auth) + 1 >= sizeof(src_auth) ||
5418 strlen(ref_auth) + 1 >= sizeof(ref_auth) ||
5419 strlen(src_host) + 1 >= sizeof(src_host) ||
5420 strlen(ref_host) + 1 >= sizeof(ref_host)) {
5421 return 0;
5422 } else if (strcmp(src_proto, ref_proto) ||
5423 strcmp(src_auth, ref_auth) ||
5424 strcmp(src_host, ref_host) ||
5425 src_port != ref_port) {
5426 return 0;
5427 } else
5428 return 1;
5429}
5430
5431static int mov_open_dref(MOVContext *c, AVIOContext **pb, const char *src, MOVDref *ref)
5432{
5433 /* try relative path, we do not try the absolute because it can leak information about our
5434 system to an attacker */
5435 if (ref->nlvl_to > 0 && ref->nlvl_from > 0) {
5436 char filename[1025];
5437 const char *src_path;
5438 int i, l;
5439
5440 /* find a source dir */
5441 src_path = strrchr(src, '/');
5442 if (src_path)
5443 src_path++;
5444 else
5445 src_path = src;
5446
5447 /* find a next level down to target */
5448 for (i = 0, l = strlen(ref->path) - 1; l >= 0; l--)
5449 if (ref->path[l] == '/') {
5450 if (i == ref->nlvl_to - 1)
5451 break;
5452 else
5453 i++;
5454 }
5455
5456 /* compose filename if next level down to target was found */
5457 if (i == ref->nlvl_to - 1 && src_path - src < sizeof(filename)) {
5458 memcpy(filename, src, src_path - src);
5459 filename[src_path - src] = 0;
5460
5461 for (i = 1; i < ref->nlvl_from; i++)
5462 av_strlcat(filename, "../", sizeof(filename));
5463
5464 av_strlcat(filename, ref->path + l + 1, sizeof(filename));
5465 if (!c->use_absolute_path) {
5466 int same_origin = test_same_origin(src, filename);
5467
5468 if (!same_origin) {
5469 av_log(c->fc, AV_LOG_ERROR,
5470 "Reference with mismatching origin, %s not tried for security reasons, "
5471 "set demuxer option use_absolute_path to allow it anyway\n",
5472 ref->path);
5473 return AVERROR(ENOENT);
5474 }
5475
5476 if (strstr(ref->path + l + 1, "..") ||
5477 strstr(ref->path + l + 1, ":") ||
5478 (ref->nlvl_from > 1 && same_origin < 0) ||
5479 (filename[0] == '/' && src_path == src))
5480 return AVERROR(ENOENT);
5481 }
5482
5483 if (strlen(filename) + 1 == sizeof(filename))
5484 return AVERROR(ENOENT);
5485 if (!c->fc->io_open(c->fc, pb, filename, AVIO_FLAG_READ, NULL))
5486 return 0;
5487 }
5488 } else if (c->use_absolute_path) {
5489 av_log(c->fc, AV_LOG_WARNING, "Using absolute path on user request, "
5490 "this is a possible security issue\n");
5491 if (!c->fc->io_open(c->fc, pb, ref->path, AVIO_FLAG_READ, NULL))
5492 return 0;
5493 } else {
5494 av_log(c->fc, AV_LOG_ERROR,
5495 "Absolute path %s not tried for security reasons, "
5496 "set demuxer option use_absolute_path to allow absolute paths\n",
5497 ref->path);
5498 }
5499
5500 return AVERROR(ENOENT);
5501}
5502
5504{
5505 if (sc->time_scale <= 0) {
5506 av_log(c->fc, AV_LOG_WARNING, "stream %d, timescale not set\n", sc->ffindex);
5507 sc->time_scale = c->time_scale;
5508 if (sc->time_scale <= 0)
5509 sc->time_scale = 1;
5510 }
5511}
5512
5513#if CONFIG_IAMFDEC
5514static int mov_update_iamf_streams(MOVContext *c, const AVStream *st)
5515{
5516 const MOVStreamContext *sc = st->priv_data;
5517 const IAMFContext *iamf = &sc->iamf->iamf;
5518
5519 for (int i = 0; i < iamf->nb_audio_elements; i++) {
5520 const AVStreamGroup *stg = NULL;
5521
5522 for (int j = 0; j < c->fc->nb_stream_groups; j++)
5523 if (c->fc->stream_groups[j]->type == AV_STREAM_GROUP_PARAMS_IAMF_AUDIO_ELEMENT &&
5524 c->fc->stream_groups[j]->id == iamf->audio_elements[i]->audio_element_id)
5525 stg = c->fc->stream_groups[j];
5526 av_assert0(stg);
5527
5528 for (int j = 0; j < stg->nb_entries; j++) {
5529 const FFStream *sti = cffstream(st);
5530 AVStream *out = stg->entries[j]->stream;
5531 FFStream *out_sti = ffstream(stg->entries[j]->stream);
5532
5533 out->codecpar->bit_rate = 0;
5534
5535 if (out == st)
5536 continue;
5537
5538 out->time_base = st->time_base;
5539 out->start_time = st->start_time;
5540 out->duration = st->duration;
5541 out->nb_frames = st->nb_frames;
5542 out->discard = st->discard;
5543
5544 av_assert0(!out_sti->index_entries);
5546 if (!out_sti->index_entries)
5547 return AVERROR(ENOMEM);
5548
5550 out_sti->nb_index_entries = sti->nb_index_entries;
5551 out_sti->skip_samples = sti->skip_samples;
5552 memcpy(out_sti->index_entries, sti->index_entries, sti->index_entries_allocated_size);
5553 }
5554 }
5555
5556 return 0;
5557}
5558#endif
5559
5560static int sanity_checks(void *log_obj, MOVStreamContext *sc, int index)
5561{
5562 if ((sc->chunk_count && (!sc->stts_count || !sc->stsc_count ||
5563 (!sc->sample_size && !sc->sample_count))) ||
5564 (sc->sample_count && (!sc->chunk_count ||
5565 (!sc->sample_size && !sc->sample_sizes)))) {
5566 av_log(log_obj, AV_LOG_ERROR, "stream %d, missing mandatory atoms, broken header\n",
5567 index);
5568 return 1;
5569 }
5570
5571 if (sc->stsc_count && sc->stsc_data[ sc->stsc_count - 1 ].first > sc->chunk_count) {
5572 av_log(log_obj, AV_LOG_ERROR, "stream %d, contradictionary STSC and STCO\n",
5573 index);
5574 return 2;
5575 }
5576 return 0;
5577}
5578
5580{
5581 AVStream *st;
5582 MOVStreamContext *sc;
5583 int ret;
5584
5585 st = avformat_new_stream(c->fc, NULL);
5586 if (!st) return AVERROR(ENOMEM);
5587 st->id = -1;
5588 sc = av_mallocz(sizeof(MOVStreamContext));
5589 if (!sc) return AVERROR(ENOMEM);
5590
5591 st->priv_data = sc;
5593 sc->ffindex = st->index;
5594 c->trak_index = st->index;
5595 sc->refcount = 1;
5596
5597 if ((ret = mov_read_default(c, pb, atom)) < 0)
5598 return ret;
5599
5600 c->trak_index = -1;
5601
5602 // Here stsc refers to a chunk not described in stco. This is technically invalid,
5603 // but we can overlook it (clearing stsc) whenever stts_count == 0 (indicating no samples).
5604 if (!sc->chunk_count && !sc->stts_count && sc->stsc_count) {
5605 sc->stsc_count = 0;
5606 av_freep(&sc->stsc_data);
5607 }
5608
5609 ret = sanity_checks(c->fc, sc, st->index);
5610 if (ret)
5611 return ret > 1 ? AVERROR_INVALIDDATA : 0;
5612
5613 fix_timescale(c, sc);
5614
5615 avpriv_set_pts_info(st, 64, 1, sc->time_scale);
5616
5617 /*
5618 * Advanced edit list support does not work with fragemented MP4s, which
5619 * have stsc, stsz, stco, and stts with zero entries in the moov atom.
5620 * In these files, trun atoms may be streamed in.
5621 */
5622 if (!sc->stts_count && c->advanced_editlist) {
5623
5624 av_log(c->fc, AV_LOG_VERBOSE, "advanced_editlist does not work with fragmented "
5625 "MP4. disabling.\n");
5626 c->advanced_editlist = 0;
5627 c->advanced_editlist_autodisabled = 1;
5628 }
5629
5630 mov_build_index(c, st);
5631 /*
5632 * Fragment samples are appended later by mov_read_trun() and are not
5633 * covered by this non-fragmented track update.
5634 */
5636
5637#if CONFIG_IAMFDEC
5638 if (sc->iamf) {
5639 ret = mov_update_iamf_streams(c, st);
5640 if (ret < 0)
5641 return ret;
5642 }
5643#endif
5644
5645 if (sc->dref_id-1 < sc->drefs_count && sc->drefs[sc->dref_id-1].path) {
5646 MOVDref *dref = &sc->drefs[sc->dref_id - 1];
5647 if (c->enable_drefs) {
5648 if (mov_open_dref(c, &sc->pb, c->fc->url, dref) < 0)
5649 av_log(c->fc, AV_LOG_ERROR,
5650 "stream %d, error opening alias: path='%s', dir='%s', "
5651 "filename='%s', volume='%s', nlvl_from=%d, nlvl_to=%d\n",
5652 st->index, dref->path, dref->dir, dref->filename,
5653 dref->volume, dref->nlvl_from, dref->nlvl_to);
5654 } else {
5655 av_log(c->fc, AV_LOG_WARNING,
5656 "Skipped opening external track: "
5657 "stream %d, alias: path='%s', dir='%s', "
5658 "filename='%s', volume='%s', nlvl_from=%d, nlvl_to=%d."
5659 "Set enable_drefs to allow this.\n",
5660 st->index, dref->path, dref->dir, dref->filename,
5661 dref->volume, dref->nlvl_from, dref->nlvl_to);
5662 }
5663 } else {
5664 sc->pb = c->fc->pb;
5665 sc->pb_is_copied = 1;
5666 }
5667
5669 int stts_constant = sc->stts_count && sc->tts_count;
5670 if (sc->h_spacing && sc->v_spacing)
5672 sc->h_spacing, sc->v_spacing, INT_MAX);
5673 if (!st->sample_aspect_ratio.num && st->codecpar->width && st->codecpar->height &&
5674 sc->height && sc->width &&
5675 (st->codecpar->width != sc->width || st->codecpar->height != sc->height)) {
5677 (int64_t)st->codecpar->height * sc->width,
5678 (int64_t)st->codecpar->width * sc->height, INT_MAX);
5679 }
5680
5681#if FF_API_R_FRAME_RATE
5682 for (unsigned int i = 1; sc->stts_count && i + 1 < sc->tts_count; i++) {
5683 if (sc->tts_data[i].duration == sc->tts_data[0].duration)
5684 continue;
5685 stts_constant = 0;
5686 }
5687 if (stts_constant)
5689 sc->time_scale, sc->tts_data[0].duration, INT_MAX);
5690#endif
5691 }
5692
5693#if CONFIG_H261_DECODER || CONFIG_H263_DECODER || CONFIG_MPEG4_DECODER
5694 switch (st->codecpar->codec_id) {
5695#if CONFIG_H261_DECODER
5696 case AV_CODEC_ID_H261:
5697#endif
5698#if CONFIG_H263_DECODER
5699 case AV_CODEC_ID_H263:
5700#endif
5701#if CONFIG_MPEG4_DECODER
5702 case AV_CODEC_ID_MPEG4:
5703#endif
5704 st->codecpar->width = 0; /* let decoder init width/height */
5705 st->codecpar->height= 0;
5706 break;
5707 }
5708#endif
5709
5710 // If the duration of the mp3 packets is not constant, then they could need a parser
5712 && sc->time_scale == st->codecpar->sample_rate) {
5713 int stts_constant = 1;
5714 for (int i = 1; sc->stts_count && i < sc->tts_count; i++) {
5715 if (sc->tts_data[i].duration == sc->tts_data[0].duration)
5716 continue;
5717 stts_constant = 0;
5718 }
5719 if (!stts_constant)
5721 }
5722 /* Do not need those anymore. */
5723 av_freep(&sc->chunk_offsets);
5724 av_freep(&sc->sample_sizes);
5725 av_freep(&sc->keyframes);
5726 av_freep(&sc->stps_data);
5727 av_freep(&sc->elst_data);
5728 av_freep(&sc->rap_group);
5729 av_freep(&sc->sync_group);
5730 av_freep(&sc->sgpd_sync);
5731
5732 return 0;
5733}
5734
5736{
5737 int ret;
5738 c->itunes_metadata = 1;
5739 ret = mov_read_default(c, pb, atom);
5740 c->itunes_metadata = 0;
5741 return ret;
5742}
5743
5745{
5746 uint32_t count;
5747 uint32_t i;
5748
5749 if (atom.size < 8)
5750 return 0;
5751
5752 avio_skip(pb, 4);
5753 count = avio_rb32(pb);
5754 atom.size -= 8;
5755 if (count > atom.size / 8 || count >= UINT_MAX / sizeof(*c->meta_keys)) {
5756 av_log(c->fc, AV_LOG_ERROR,
5757 "The 'keys' atom with the invalid key count: %"PRIu32"\n", count);
5758 return AVERROR_INVALIDDATA;
5759 }
5760
5761 c->meta_keys = av_malloc_array(count + 1, sizeof(*c->meta_keys));
5762 if (!c->meta_keys)
5763 return AVERROR(ENOMEM);
5764
5765 c->meta_keys[0] = NULL;
5766 c->meta_keys_count = 1;
5767 for (i = 1; i <= count; ++i) {
5768 uint32_t key_size = avio_rb32(pb);
5769 uint32_t type = avio_rl32(pb);
5770 c->meta_keys[i] = NULL;
5771 c->meta_keys_count = i + 1;
5772 if (key_size < 8 || key_size > atom.size) {
5773 av_log(c->fc, AV_LOG_ERROR,
5774 "The key# %"PRIu32" in meta has invalid size:"
5775 "%"PRIu32"\n", i, key_size);
5776 return AVERROR_INVALIDDATA;
5777 }
5778 atom.size -= key_size;
5779 key_size -= 8;
5780 if (type != MKTAG('m','d','t','a')) {
5781 avio_skip(pb, key_size);
5782 continue;
5783 }
5784 c->meta_keys[i] = av_malloc(key_size + 1);
5785 if (!c->meta_keys[i])
5786 return AVERROR(ENOMEM);
5787 int ret = ffio_read_size(pb, c->meta_keys[i], key_size);
5788 if (ret < 0)
5789 return ret;
5790 c->meta_keys[i][key_size] = 0;
5791 }
5792
5793 return 0;
5794}
5795
5797{
5798 int64_t end = av_sat_add64(avio_tell(pb), atom.size);
5799 uint8_t *key = NULL, *val = NULL, *mean = NULL;
5800 int i;
5801 int ret = 0;
5802 AVStream *st;
5803
5804 if (c->fc->nb_streams < 1)
5805 return 0;
5806 st = c->fc->streams[c->fc->nb_streams-1];
5807
5808 for (i = 0; i < 3; i++) {
5809 uint8_t **p;
5810 uint32_t len, tag;
5811
5812 if (end - avio_tell(pb) <= 12)
5813 break;
5814
5815 len = avio_rb32(pb);
5816 tag = avio_rl32(pb);
5817 avio_skip(pb, 4); // flags
5818
5819 if (len < 12 || len - 12 > end - avio_tell(pb))
5820 break;
5821 len -= 12;
5822
5823 if (tag == MKTAG('m', 'e', 'a', 'n'))
5824 p = &mean;
5825 else if (tag == MKTAG('n', 'a', 'm', 'e'))
5826 p = &key;
5827 else if (tag == MKTAG('d', 'a', 't', 'a') && len > 4) {
5828 avio_skip(pb, 4);
5829 len -= 4;
5830 p = &val;
5831 } else
5832 break;
5833
5834 if (*p)
5835 break;
5836
5837 *p = av_malloc(len + 1);
5838 if (!*p) {
5839 ret = AVERROR(ENOMEM);
5840 break;
5841 }
5842 ret = ffio_read_size(pb, *p, len);
5843 if (ret < 0) {
5844 av_freep(p);
5845 break;
5846 }
5847 (*p)[len] = 0;
5848 }
5849
5850 if (mean && key && val) {
5851 if (strcmp(key, "iTunSMPB") == 0) {
5852 int64_t priming, remainder, samples;
5853 if (ff_itunes_parse_smpb(val, &priming, &remainder, &samples) >= 0) {
5854 if(priming>0 && priming<16384)
5855 st->codecpar->initial_padding = priming = av_rescale_q(priming, st->time_base,
5856 (AVRational){ 1, st->codecpar->sample_rate });
5857 if (remainder > 0) {
5859 (AVRational){ 1, st->codecpar->sample_rate });
5860 remainder = av_rescale_q(remainder, st->time_base,
5861 (AVRational){ 1, st->codecpar->sample_rate });
5862 samples = av_rescale_q(samples, st->time_base,
5863 (AVRational){ 1, st->codecpar->sample_rate });
5864 if (duration > remainder && duration > samples) {
5865 ffstream(st)->first_discard_sample = duration - remainder;
5867 }
5868 }
5869 av_log(c->fc, AV_LOG_DEBUG, "Parsed iTunSMPB: priming %"PRId64", "
5870 "remainder %"PRId64" samples %"PRId64"\n",
5871 priming, remainder, samples);
5872 }
5873 }
5874 if (strcmp(mean, "com.apple.iTunes") == 0 &&
5875 strcmp(key, "DISCSUBTITLE") == 0) {
5876 av_dict_set(&c->fc->metadata, "disc_subtitle", val,
5878 val = NULL;
5879 }
5880 if (strcmp(key, "cdec") != 0) {
5881 av_dict_set(&c->fc->metadata, key, val,
5883 key = val = NULL;
5884 }
5885 } else {
5886 av_log(c->fc, AV_LOG_VERBOSE,
5887 "Unhandled or malformed custom metadata of size %"PRId64"\n", atom.size);
5888 }
5889
5890 avio_seek(pb, end, SEEK_SET);
5891 av_freep(&key);
5892 av_freep(&val);
5893 av_freep(&mean);
5894 return ret;
5895}
5896
5898{
5899 MOVStreamContext *sc;
5900 AVStream *st;
5901
5902 st = avformat_new_stream(c->fc, NULL);
5903 if (!st)
5904 return AVERROR(ENOMEM);
5905 sc = av_mallocz(sizeof(MOVStreamContext));
5906 if (!sc)
5907 goto fail;
5908
5909 item->st = st;
5910 st->id = item->item_id;
5911 st->priv_data = sc;
5913 st->codecpar->codec_id = mov_codec_id(st, item->type);
5914 sc->id = st->id;
5915 sc->ffindex = st->index;
5916 st->avg_frame_rate.num = st->avg_frame_rate.den = 1;
5917 st->time_base.num = st->time_base.den = 1;
5918 st->nb_frames = 1;
5919 sc->time_scale = 1;
5920 sc->pb = c->fc->pb;
5921 sc->pb_is_copied = 1;
5922 sc->refcount = 1;
5923
5924 if (item->name)
5925 av_dict_set(&st->metadata, "title", item->name, 0);
5926
5927 // Populate the necessary fields used by mov_build_index.
5928 sc->stsc_data = av_malloc_array(1, sizeof(*sc->stsc_data));
5929 if (!sc->stsc_data)
5930 goto fail;
5931 sc->stsc_count = 1;
5932 sc->stsc_data[0].first = 1;
5933 sc->stsc_data[0].count = 1;
5934 sc->stsc_data[0].id = 1;
5935 sc->chunk_offsets = av_malloc_array(1, sizeof(*sc->chunk_offsets));
5936 if (!sc->chunk_offsets)
5937 goto fail;
5938 sc->chunk_count = 1;
5939 sc->stts_data = av_malloc_array(1, sizeof(*sc->stts_data));
5940 if (!sc->stts_data)
5941 goto fail;
5942 sc->stts_count = 1;
5943 sc->stts_data[0].count = 1;
5944 // Not used for still images. But needed by mov_build_index.
5945 sc->stts_data[0].duration = 0;
5946
5947 return 0;
5948fail:
5949 mov_free_stream_context(c->fc, st);
5950 ff_remove_stream(c->fc, st);
5951 item->st = NULL;
5952
5953 return AVERROR(ENOMEM);
5954}
5955
5957{
5958 while (atom.size > 8) {
5959 uint32_t tag;
5960 if (avio_feof(pb))
5961 return AVERROR_EOF;
5962 tag = avio_rl32(pb);
5963 atom.size -= 4;
5964 if (tag == MKTAG('h','d','l','r')) {
5965 avio_seek(pb, -8, SEEK_CUR);
5966 atom.size += 8;
5967 return mov_read_default(c, pb, atom);
5968 }
5969 }
5970 return 0;
5971}
5972
5973// return 1 when matrix is identity, 0 otherwise
5974#define IS_MATRIX_IDENT(matrix) \
5975 ( (matrix)[0][0] == (1 << 16) && \
5976 (matrix)[1][1] == (1 << 16) && \
5977 (matrix)[2][2] == (1 << 30) && \
5978 !(matrix)[0][1] && !(matrix)[0][2] && \
5979 !(matrix)[1][0] && !(matrix)[1][2] && \
5980 !(matrix)[2][0] && !(matrix)[2][1])
5981
5983{
5984 int i, j, e;
5985 int width;
5986 int height;
5987 int display_matrix[3][3];
5988 int res_display_matrix[3][3] = { { 0 } };
5989 AVStream *st;
5990 MOVStreamContext *sc;
5991 int version;
5992 int flags;
5993
5994 if (c->fc->nb_streams < 1)
5995 return 0;
5996 st = c->fc->streams[c->fc->nb_streams-1];
5997 sc = st->priv_data;
5998
5999 // Each stream (trak) should have exactly 1 tkhd. This catches bad files and
6000 // avoids corrupting AVStreams mapped to an earlier tkhd.
6001 if (st->id != -1)
6002 return AVERROR_INVALIDDATA;
6003
6004 version = avio_r8(pb);
6005 flags = avio_rb24(pb);
6007
6008 if (version == 1) {
6009 avio_rb64(pb);
6010 avio_rb64(pb);
6011 } else {
6012 avio_rb32(pb); /* creation time */
6013 avio_rb32(pb); /* modification time */
6014 }
6015 st->id = (int)avio_rb32(pb); /* track id (NOT 0 !)*/
6016 sc->id = st->id;
6017 avio_rb32(pb); /* reserved */
6018
6019 /* highlevel (considering edits) duration in movie timebase */
6020 (version == 1) ? avio_rb64(pb) : avio_rb32(pb);
6021 avio_rb32(pb); /* reserved */
6022 avio_rb32(pb); /* reserved */
6023
6024 avio_rb16(pb); /* layer */
6025 avio_rb16(pb); /* alternate group */
6026 avio_rb16(pb); /* volume */
6027 avio_rb16(pb); /* reserved */
6028
6029 //read in the display matrix (outlined in ISO 14496-12, Section 6.2.2)
6030 // they're kept in fixed point format through all calculations
6031 // save u,v,z to store the whole matrix in the AV_PKT_DATA_DISPLAYMATRIX
6032 // side data, but the scale factor is not needed to calculate aspect ratio
6033 for (i = 0; i < 3; i++) {
6034 display_matrix[i][0] = avio_rb32(pb); // 16.16 fixed point
6035 display_matrix[i][1] = avio_rb32(pb); // 16.16 fixed point
6036 display_matrix[i][2] = avio_rb32(pb); // 2.30 fixed point
6037 }
6038
6039 width = avio_rb32(pb); // 16.16 fixed point track width
6040 height = avio_rb32(pb); // 16.16 fixed point track height
6041 sc->width = width >> 16;
6042 sc->height = height >> 16;
6043
6044 // apply the moov display matrix (after the tkhd one)
6045 for (i = 0; i < 3; i++) {
6046 const int sh[3] = { 16, 16, 30 };
6047 for (j = 0; j < 3; j++) {
6048 for (e = 0; e < 3; e++) {
6049 res_display_matrix[i][j] +=
6050 ((int64_t) display_matrix[i][e] *
6051 c->movie_display_matrix[e][j]) >> sh[e];
6052 }
6053 }
6054 }
6055
6056 // save the matrix when it is not the default identity
6057 if (!IS_MATRIX_IDENT(res_display_matrix)) {
6059 sc->display_matrix = av_malloc(sizeof(int32_t) * 9);
6060 if (!sc->display_matrix)
6061 return AVERROR(ENOMEM);
6062
6063 for (i = 0; i < 3; i++)
6064 for (j = 0; j < 3; j++)
6065 sc->display_matrix[i * 3 + j] = res_display_matrix[i][j];
6066 }
6067
6068 // transform the display width/height according to the matrix
6069 // to keep the same scale, use [width height 1<<16]
6070 if (width && height && sc->display_matrix) {
6071 double disp_transform[2];
6072
6073 for (i = 0; i < 2; i++)
6074 disp_transform[i] = hypot(sc->display_matrix[0 + i],
6075 sc->display_matrix[3 + i]);
6076
6077 if (disp_transform[0] > 1 && disp_transform[1] > 1 &&
6078 disp_transform[0] < (1<<24) && disp_transform[1] < (1<<24) &&
6079 fabs((disp_transform[0] / disp_transform[1]) - 1.0) > 0.01)
6081 disp_transform[0] / disp_transform[1],
6082 INT_MAX);
6083 }
6084 return 0;
6085}
6086
6088{
6089 MOVFragment *frag = &c->fragment;
6090 MOVTrackExt *trex = NULL;
6091 int flags, track_id, i;
6092 MOVFragmentStreamInfo * frag_stream_info;
6093
6094 avio_r8(pb); /* version */
6095 flags = avio_rb24(pb);
6096
6097 track_id = avio_rb32(pb);
6098 if (!track_id)
6099 return AVERROR_INVALIDDATA;
6100 for (i = 0; i < c->trex_count; i++)
6101 if (c->trex_data[i].track_id == track_id) {
6102 trex = &c->trex_data[i];
6103 break;
6104 }
6105 if (!trex) {
6106 av_log(c->fc, AV_LOG_WARNING, "could not find corresponding trex (id %u)\n", track_id);
6107 return 0;
6108 }
6109 c->fragment.found_tfhd = 1;
6110 frag->track_id = track_id;
6111 set_frag_stream(&c->frag_index, track_id);
6112
6115 frag->moof_offset : frag->implicit_offset;
6116 frag->stsd_id = flags & MOV_TFHD_STSD_ID ? avio_rb32(pb) : trex->stsd_id;
6117
6119 avio_rb32(pb) : trex->duration;
6120 frag->size = flags & MOV_TFHD_DEFAULT_SIZE ?
6121 avio_rb32(pb) : trex->size;
6123 avio_rb32(pb) : trex->flags;
6124 av_log(c->fc, AV_LOG_TRACE, "frag flags 0x%x\n", frag->flags);
6125
6126 frag_stream_info = get_current_frag_stream_info(&c->frag_index);
6127 if (frag_stream_info) {
6128 frag_stream_info->next_trun_dts = AV_NOPTS_VALUE;
6129 frag_stream_info->stsd_id = frag->stsd_id;
6130 }
6131 return 0;
6132}
6133
6135{
6136 unsigned i, num;
6137 void *new_tracks;
6138
6139 num = atom.size / 4;
6140 if (!(new_tracks = av_malloc_array(num, sizeof(int))))
6141 return AVERROR(ENOMEM);
6142
6143 av_free(c->chapter_tracks);
6144 c->chapter_tracks = new_tracks;
6145 c->nb_chapter_tracks = num;
6146
6147 for (i = 0; i < num && !pb->eof_reached; i++)
6148 c->chapter_tracks[i] = avio_rb32(pb);
6149
6150 c->nb_chapter_tracks = i;
6151
6152 return 0;
6153}
6154
6156{
6157 MOVTrackExt *trex;
6158 int err;
6159
6160 if ((uint64_t)c->trex_count+1 >= UINT_MAX / sizeof(*c->trex_data))
6161 return AVERROR_INVALIDDATA;
6162 if ((err = av_reallocp_array(&c->trex_data, c->trex_count + 1,
6163 sizeof(*c->trex_data))) < 0) {
6164 c->trex_count = 0;
6165 return err;
6166 }
6167
6168 c->fc->duration = AV_NOPTS_VALUE; // the duration from mvhd is not representing the whole file when fragments are used.
6169
6170 trex = &c->trex_data[c->trex_count++];
6171 avio_r8(pb); /* version */
6172 avio_rb24(pb); /* flags */
6173 trex->track_id = avio_rb32(pb);
6174 trex->stsd_id = avio_rb32(pb);
6175 trex->duration = avio_rb32(pb);
6176 trex->size = avio_rb32(pb);
6177 trex->flags = avio_rb32(pb);
6178 return 0;
6179}
6180
6182{
6183 MOVFragment *frag = &c->fragment;
6184 AVStream *st = NULL;
6185 MOVStreamContext *sc;
6186 int version, i;
6187 MOVFragmentStreamInfo * frag_stream_info;
6188 int64_t base_media_decode_time;
6189
6190 for (i = 0; i < c->fc->nb_streams; i++) {
6191 sc = c->fc->streams[i]->priv_data;
6192 if (sc->id == frag->track_id) {
6193 st = c->fc->streams[i];
6194 break;
6195 }
6196 }
6197 if (!st) {
6198 av_log(c->fc, AV_LOG_WARNING, "could not find corresponding track id %u\n", frag->track_id);
6199 return 0;
6200 }
6201 sc = st->priv_data;
6202 if (sc->pseudo_stream_id + 1 != frag->stsd_id && sc->pseudo_stream_id != -1)
6203 return 0;
6204 version = avio_r8(pb);
6205 avio_rb24(pb); /* flags */
6206 if (version) {
6207 base_media_decode_time = avio_rb64(pb);
6208 } else {
6209 base_media_decode_time = avio_rb32(pb);
6210 }
6211
6212 frag_stream_info = get_current_frag_stream_info(&c->frag_index);
6213 if (frag_stream_info)
6214 frag_stream_info->tfdt_dts = base_media_decode_time;
6215 sc->track_end = base_media_decode_time;
6216
6217 return 0;
6218}
6219
6221{
6222 MOVFragment *frag = &c->fragment;
6223 AVStream *st = NULL;
6224 FFStream *sti = NULL;
6225 MOVStreamContext *sc;
6226 MOVTimeToSample *tts_data;
6227 uint64_t offset;
6228 int64_t dts, pts = AV_NOPTS_VALUE;
6229 int data_offset = 0;
6230 unsigned entries, first_sample_flags = frag->flags;
6231 int flags, distance, i;
6232 int64_t prev_dts = AV_NOPTS_VALUE;
6233 int next_frag_index = -1, index_entry_pos;
6234 size_t requested_size;
6235 AVIndexEntry *new_entries;
6236 MOVFragmentStreamInfo * frag_stream_info;
6237
6238 if (!frag->found_tfhd) {
6239 av_log(c->fc, AV_LOG_ERROR, "trun track id unknown, no tfhd was found\n");
6240 return AVERROR_INVALIDDATA;
6241 }
6242
6243 for (i = 0; i < c->fc->nb_streams; i++) {
6244 sc = c->fc->streams[i]->priv_data;
6245 if (sc->id == frag->track_id) {
6246 st = c->fc->streams[i];
6247 sti = ffstream(st);
6248 break;
6249 }
6250 }
6251 if (!st) {
6252 av_log(c->fc, AV_LOG_WARNING, "could not find corresponding track id %u\n", frag->track_id);
6253 return 0;
6254 }
6255 sc = st->priv_data;
6256 if (sc->pseudo_stream_id+1 != frag->stsd_id && sc->pseudo_stream_id != -1)
6257 return 0;
6258
6259 // Find the next frag_index index that has a valid index_entry for
6260 // the current track_id.
6261 //
6262 // A valid index_entry means the trun for the fragment was read
6263 // and it's samples are in index_entries at the given position.
6264 // New index entries will be inserted before the index_entry found.
6265 index_entry_pos = sti->nb_index_entries;
6266 for (i = c->frag_index.current + 1; i < c->frag_index.nb_items; i++) {
6267 frag_stream_info = get_frag_stream_info(&c->frag_index, i, frag->track_id);
6268 if (frag_stream_info && frag_stream_info->index_entry >= 0) {
6269 next_frag_index = i;
6270 index_entry_pos = frag_stream_info->index_entry;
6271 break;
6272 }
6273 }
6274 av_assert0(index_entry_pos <= sti->nb_index_entries);
6275
6276 avio_r8(pb); /* version */
6277 flags = avio_rb24(pb);
6278 entries = avio_rb32(pb);
6279 av_log(c->fc, AV_LOG_TRACE, "flags 0x%x entries %u\n", flags, entries);
6280
6281 /* Explicit zero sizes are bounded by the trun payload. Reject a zero
6282 * default size before allocating or updating the sample index. */
6283 if (entries && !frag->size && !(flags & MOV_TRUN_SAMPLE_SIZE))
6284 return AVERROR_INVALIDDATA;
6285
6286 if ((uint64_t)entries+sc->tts_count >= UINT_MAX/sizeof(*sc->tts_data))
6287 return AVERROR_INVALIDDATA;
6288 if (flags & MOV_TRUN_DATA_OFFSET) data_offset = avio_rb32(pb);
6289 if (flags & MOV_TRUN_FIRST_SAMPLE_FLAGS) first_sample_flags = avio_rb32(pb);
6290
6291 int entry_size = !!(flags & MOV_TRUN_SAMPLE_DURATION) * 4
6292 + !!(flags & MOV_TRUN_SAMPLE_SIZE) * 4
6293 + !!(flags & MOV_TRUN_SAMPLE_FLAGS) * 4
6294 + !!(flags & MOV_TRUN_SAMPLE_CTS) * 4;
6295 int64_t sample_data_size = avio_size(sc->pb);
6296 int64_t max_entries = INT64_MAX;
6297
6298 if (sample_data_size > 0)
6299 max_entries = sample_data_size - sti->nb_index_entries;
6300 if (entry_size) {
6301 int64_t size = sc->pb == pb ? sample_data_size : avio_size(pb);
6302 int64_t pos = avio_tell(pb);
6303 int64_t left = atom.size - 8 - !!(flags & MOV_TRUN_DATA_OFFSET) * 4
6305
6306 if (pos >= 0 && size >= pos)
6307 left = FFMIN(left, size - pos);
6308 max_entries = FFMIN(max_entries, left / entry_size);
6309 }
6310 if (entries > max_entries) {
6311 av_log(c->fc, AV_LOG_ERROR, "trun sample count %u exceeds the %"PRId64" "
6312 "samples the input can hold\n", entries, max_entries);
6313 return AVERROR_INVALIDDATA;
6314 }
6315
6316 frag_stream_info = get_current_frag_stream_info(&c->frag_index);
6317 if (frag_stream_info) {
6318 if (frag_stream_info->next_trun_dts != AV_NOPTS_VALUE) {
6319 dts = av_sat_sub64(frag_stream_info->next_trun_dts, sc->time_offset);
6320 } else if (frag_stream_info->first_tfra_pts != AV_NOPTS_VALUE &&
6321 c->use_mfra_for == FF_MOV_FLAG_MFRA_PTS) {
6322 pts = frag_stream_info->first_tfra_pts;
6323 av_log(c->fc, AV_LOG_DEBUG, "found mfra time %"PRId64
6324 ", using it for pts\n", pts);
6325 } else if (frag_stream_info->first_tfra_pts != AV_NOPTS_VALUE &&
6326 c->use_mfra_for == FF_MOV_FLAG_MFRA_DTS) {
6327 dts = frag_stream_info->first_tfra_pts;
6328 av_log(c->fc, AV_LOG_DEBUG, "found mfra time %"PRId64
6329 ", using it for dts\n", pts);
6330 } else {
6331 int has_tfdt = frag_stream_info->tfdt_dts != AV_NOPTS_VALUE;
6332 int has_sidx = frag_stream_info->sidx_pts != AV_NOPTS_VALUE;
6333 int fallback_tfdt = !c->use_tfdt && !has_sidx && has_tfdt;
6334 int fallback_sidx = c->use_tfdt && !has_tfdt && has_sidx;
6335
6336 if (fallback_sidx) {
6337 av_log(c->fc, AV_LOG_DEBUG, "use_tfdt set but no tfdt found, using sidx instead\n");
6338 }
6339 if (fallback_tfdt) {
6340 av_log(c->fc, AV_LOG_DEBUG, "use_tfdt not set but no sidx found, using tfdt instead\n");
6341 }
6342
6343 if (has_tfdt && c->use_tfdt || fallback_tfdt) {
6344 dts = av_sat_sub64(frag_stream_info->tfdt_dts, sc->time_offset);
6345 av_log(c->fc, AV_LOG_DEBUG, "found tfdt time %"PRId64
6346 ", using it for dts\n", dts);
6347 } else if (has_sidx && !c->use_tfdt || fallback_sidx) {
6348 // FIXME: sidx earliest_presentation_time is *PTS*, s.b.
6349 // pts = frag_stream_info->sidx_pts;
6350 dts = frag_stream_info->sidx_pts;
6351 av_log(c->fc, AV_LOG_DEBUG, "found sidx time %"PRId64
6352 ", using it for dts\n", frag_stream_info->sidx_pts);
6353 } else {
6354 dts = av_sat_sub64(sc->track_end, sc->time_offset);
6355 av_log(c->fc, AV_LOG_DEBUG, "found track end time %"PRId64
6356 ", using it for dts\n", dts);
6357 }
6358 }
6359 } else {
6360 dts = av_sat_sub64(sc->track_end, sc->time_offset);
6361 av_log(c->fc, AV_LOG_DEBUG, "found track end time %"PRId64
6362 ", using it for dts\n", dts);
6363 }
6364 offset = frag->base_data_offset + data_offset;
6365 distance = 0;
6366 av_log(c->fc, AV_LOG_TRACE, "first sample flags 0x%x\n", first_sample_flags);
6367
6368 // realloc space for new index entries
6369 if ((uint64_t)sti->nb_index_entries + entries >= UINT_MAX / sizeof(AVIndexEntry)) {
6370 entries = UINT_MAX / sizeof(AVIndexEntry) - sti->nb_index_entries;
6371 av_log(c->fc, AV_LOG_ERROR, "Failed to add index entry\n");
6372 }
6373 if (entries == 0)
6374 return 0;
6375
6376 requested_size = (sti->nb_index_entries + entries) * sizeof(AVIndexEntry);
6377 new_entries = av_fast_realloc(sti->index_entries,
6379 requested_size);
6380 if (!new_entries)
6381 return AVERROR(ENOMEM);
6382 sti->index_entries= new_entries;
6383
6384 requested_size = (sti->nb_index_entries + entries) * sizeof(*sc->tts_data);
6385 tts_data = av_fast_realloc(sc->tts_data, &sc->tts_allocated_size,
6386 requested_size);
6387 if (!tts_data)
6388 return AVERROR(ENOMEM);
6389 sc->tts_data = tts_data;
6390
6391 // In case there were samples without time to sample entries, ensure they get
6392 // zero valued entries. This ensures clips which mix boxes with and
6393 // without time to sample entries don't pickup uninitialized data.
6394 if (sc->tts_count < sti->nb_index_entries)
6395 memset(sc->tts_data + sc->tts_count, 0,
6396 sizeof(*sc->tts_data) * (sti->nb_index_entries - sc->tts_count));
6397
6398 if (index_entry_pos < sti->nb_index_entries) {
6399 // Make hole in index_entries and tts_data for new samples
6400 memmove(sti->index_entries + index_entry_pos + entries,
6401 sti->index_entries + index_entry_pos,
6402 sizeof(*sti->index_entries) *
6403 (sti->nb_index_entries - index_entry_pos));
6404 memmove(sc->tts_data + index_entry_pos + entries,
6405 sc->tts_data + index_entry_pos,
6406 sizeof(*sc->tts_data) * (sti->nb_index_entries - index_entry_pos));
6407 if (index_entry_pos < sc->current_sample) {
6408 sc->current_sample += entries;
6409 }
6410 }
6411
6412 sti->nb_index_entries += entries;
6413 sc->tts_count = sti->nb_index_entries;
6414 sc->stts_count = sti->nb_index_entries;
6416 sc->ctts_count = sti->nb_index_entries;
6417
6418 // Record the index_entry position in frag_index of this fragment
6419 if (frag_stream_info) {
6420 frag_stream_info->index_entry = index_entry_pos;
6421 if (frag_stream_info->index_base < 0)
6422 frag_stream_info->index_base = index_entry_pos;
6423 }
6424
6425 if (index_entry_pos > 0)
6426 prev_dts = sti->index_entries[index_entry_pos-1].timestamp;
6427
6428 for (i = 0; i < entries && !pb->eof_reached; i++) {
6429 unsigned sample_size = frag->size;
6430 int sample_flags = i ? frag->flags : first_sample_flags;
6431 unsigned sample_duration = frag->duration;
6432 unsigned ctts_duration = 0;
6433 int keyframe = 0;
6434 int index_entry_flags = 0;
6435
6436 if (flags & MOV_TRUN_SAMPLE_DURATION) sample_duration = avio_rb32(pb);
6437 if (flags & MOV_TRUN_SAMPLE_SIZE) sample_size = avio_rb32(pb);
6438 if (flags & MOV_TRUN_SAMPLE_FLAGS) sample_flags = avio_rb32(pb);
6439 if (flags & MOV_TRUN_SAMPLE_CTS) ctts_duration = avio_rb32(pb);
6440
6441 if (sample_duration > c->max_stts_delta) {
6442 av_log(c->fc, AV_LOG_WARNING,
6443 "Too large sample duration %u in trun entry %u in st:%d. Clipping to 1.\n",
6444 sample_duration, i, st->index);
6445 sample_duration = 1;
6446 }
6447
6448 mov_update_dts_shift(sc, ctts_duration, c->fc);
6449 if (pts != AV_NOPTS_VALUE) {
6450 dts = av_sat_sub64(pts, sc->dts_shift);
6451 if (flags & MOV_TRUN_SAMPLE_CTS) {
6452 dts = av_sat_sub64(dts, ctts_duration);
6453 } else {
6454 dts = av_sat_sub64(dts, sc->time_offset);
6455 }
6456 av_log(c->fc, AV_LOG_DEBUG,
6457 "pts %"PRId64" calculated dts %"PRId64
6458 " sc->dts_shift %d ctts.duration %d"
6459 " sc->time_offset %"PRId64
6460 " flags & MOV_TRUN_SAMPLE_CTS %d\n",
6461 pts, dts,
6462 sc->dts_shift, ctts_duration,
6465 }
6466
6467 keyframe =
6468 !(sample_flags & (MOV_FRAG_SAMPLE_FLAG_IS_NON_SYNC |
6470 if (keyframe) {
6471 distance = 0;
6472 index_entry_flags |= AVINDEX_KEYFRAME;
6473 }
6474 // Fragments can overlap in time. Discard overlapping frames after
6475 // decoding.
6476 if (prev_dts >= dts)
6477 index_entry_flags |= AVINDEX_DISCARD_FRAME;
6478
6479 sti->index_entries[index_entry_pos].pos = offset;
6480 sti->index_entries[index_entry_pos].timestamp = dts;
6481 sti->index_entries[index_entry_pos].size = sample_size;
6482 sti->index_entries[index_entry_pos].min_distance = distance;
6483 sti->index_entries[index_entry_pos].flags = index_entry_flags;
6484
6485 sc->tts_data[index_entry_pos].count = 1;
6486 sc->tts_data[index_entry_pos].offset = ctts_duration;
6487 sc->tts_data[index_entry_pos].duration = sample_duration;
6488 index_entry_pos++;
6489
6490 av_log(c->fc, AV_LOG_TRACE, "AVIndex stream %d, sample %d, offset %"PRIx64", dts %"PRId64", "
6491 "size %u, distance %d, keyframe %d\n", st->index,
6492 index_entry_pos, offset, dts, sample_size, distance, keyframe);
6493 distance++;
6494 if (av_sat_add64(dts, sample_duration) != dts + (uint64_t)sample_duration)
6495 return AVERROR_INVALIDDATA;
6496 dts += sample_duration;
6497 offset += sample_size;
6498 sc->data_size += sample_size;
6499
6500 if (sample_duration <= INT64_MAX - sc->duration_for_fps &&
6501 1 <= INT_MAX - sc->nb_frames_for_fps
6502 ) {
6503 sc->duration_for_fps += sample_duration;
6504 sc->nb_frames_for_fps ++;
6505 }
6506 }
6507 if (frag_stream_info)
6508 frag_stream_info->next_trun_dts = av_sat_add64(dts, sc->time_offset);
6509 if (i < entries) {
6510 // EOF found before reading all entries. Fix the hole this would
6511 // leave in index_entries and tts_data
6512 int gap = entries - i;
6513 memmove(sti->index_entries + index_entry_pos,
6514 sti->index_entries + index_entry_pos + gap,
6515 sizeof(*sti->index_entries) *
6516 (sti->nb_index_entries - (index_entry_pos + gap)));
6517 memmove(sc->tts_data + index_entry_pos,
6518 sc->tts_data + index_entry_pos + gap,
6519 sizeof(*sc->tts_data) *
6520 (sc->tts_count - (index_entry_pos + gap)));
6521
6522 sti->nb_index_entries -= gap;
6523 sc->tts_count -= gap;
6524 if (index_entry_pos < sc->current_sample) {
6525 sc->current_sample -= gap;
6526 }
6527 entries = i;
6528 }
6529
6530 // The end of this new fragment may overlap in time with the start
6531 // of the next fragment in index_entries. Mark the samples in the next
6532 // fragment that overlap with AVINDEX_DISCARD_FRAME
6533 prev_dts = AV_NOPTS_VALUE;
6534 if (index_entry_pos > 0)
6535 prev_dts = sti->index_entries[index_entry_pos-1].timestamp;
6536 for (int i = index_entry_pos; i < sti->nb_index_entries; i++) {
6537 if (prev_dts < sti->index_entries[i].timestamp)
6538 break;
6540 }
6541
6542 // If a hole was created to insert the new index_entries into,
6543 // the index_entry recorded for all subsequent moof must
6544 // be incremented by the number of entries inserted.
6545 fix_frag_index_entries(&c->frag_index, next_frag_index,
6546 frag->track_id, entries);
6547
6548 if (pb->eof_reached) {
6549 av_log(c->fc, AV_LOG_WARNING, "reached eof, corrupted TRUN atom\n");
6550 return AVERROR_EOF;
6551 }
6552
6553 frag->implicit_offset = offset;
6554
6555 sc->track_end = av_sat_add64(dts, sc->time_offset);
6556 if (st->duration < sc->track_end)
6557 st->duration = sc->track_end;
6558
6559 return 0;
6560}
6561
6563{
6564 int64_t stream_size = avio_size(pb);
6565 int64_t offset = av_sat_add64(avio_tell(pb), atom.size), pts, timestamp;
6566 uint8_t version, is_complete;
6567 int64_t offadd;
6568 unsigned i, j, track_id, item_count;
6569 AVStream *st = NULL;
6570 AVStream *ref_st = NULL;
6571 MOVStreamContext *sc, *ref_sc = NULL;
6572 AVRational timescale;
6573
6574 version = avio_r8(pb);
6575 if (version > 1) {
6576 avpriv_request_sample(c->fc, "sidx version %u", version);
6577 return 0;
6578 }
6579
6580 avio_rb24(pb); // flags
6581
6582 track_id = avio_rb32(pb); // Reference ID
6583 for (i = 0; i < c->fc->nb_streams; i++) {
6584 sc = c->fc->streams[i]->priv_data;
6585 if (sc->id == track_id) {
6586 st = c->fc->streams[i];
6587 break;
6588 }
6589 }
6590 if (!st) {
6591 av_log(c->fc, AV_LOG_WARNING, "could not find corresponding track id %d\n", track_id);
6592 return 0;
6593 }
6594
6595 sc = st->priv_data;
6596
6597 timescale = av_make_q(1, avio_rb32(pb));
6598
6599 if (timescale.den <= 0) {
6600 av_log(c->fc, AV_LOG_ERROR, "Invalid sidx timescale 1/%d\n", timescale.den);
6601 return AVERROR_INVALIDDATA;
6602 }
6603
6604 if (version == 0) {
6605 pts = avio_rb32(pb);
6606 offadd= avio_rb32(pb);
6607 } else {
6608 pts = avio_rb64(pb);
6609 offadd= avio_rb64(pb);
6610 }
6611 if (av_sat_add64(offset, offadd) != offset + (uint64_t)offadd)
6612 return AVERROR_INVALIDDATA;
6613
6614 offset += (uint64_t)offadd;
6615
6616 avio_rb16(pb); // reserved
6617
6618 item_count = avio_rb16(pb);
6619 if (item_count == 0)
6620 return AVERROR_INVALIDDATA;
6621
6622 for (i = 0; i < item_count; i++) {
6623 int index;
6624 MOVFragmentStreamInfo * frag_stream_info;
6625 uint32_t size = avio_rb32(pb);
6626 uint32_t duration = avio_rb32(pb);
6627 if (size & 0x80000000) {
6628 avpriv_request_sample(c->fc, "sidx reference_type 1");
6629 return AVERROR_PATCHWELCOME;
6630 }
6631 avio_rb32(pb); // sap_flags
6632 timestamp = av_rescale_q(pts, timescale, st->time_base);
6633
6635 frag_stream_info = get_frag_stream_info(&c->frag_index, index, track_id);
6636 if (frag_stream_info)
6637 frag_stream_info->sidx_pts = timestamp;
6638
6639 if (av_sat_add64(offset, size) != offset + (uint64_t)size ||
6640 av_sat_add64(pts, duration) != pts + (uint64_t)duration
6641 )
6642 return AVERROR_INVALIDDATA;
6643 offset += size;
6644 pts += duration;
6645 }
6646
6647 st->duration = sc->track_end = pts;
6648
6649 sc->has_sidx = 1;
6650
6651 // See if the remaining bytes are just an mfra which we can ignore.
6652 is_complete = offset == stream_size;
6653 if (!is_complete && (pb->seekable & AVIO_SEEKABLE_NORMAL) && stream_size > 0 ) {
6654 int64_t ret;
6655 int64_t original_pos = avio_tell(pb);
6656 if (!c->have_read_mfra_size) {
6657 if ((ret = avio_seek(pb, stream_size - 4, SEEK_SET)) < 0)
6658 return ret;
6659 c->mfra_size = avio_rb32(pb);
6660 c->have_read_mfra_size = 1;
6661 if ((ret = avio_seek(pb, original_pos, SEEK_SET)) < 0)
6662 return ret;
6663 }
6664 if (offset == stream_size - c->mfra_size)
6665 is_complete = 1;
6666 }
6667
6668 if (is_complete) {
6669 // Find first entry in fragment index that came from an sidx.
6670 // This will pretty much always be the first entry.
6671 for (i = 0; i < c->frag_index.nb_items; i++) {
6672 MOVFragmentIndexItem * item = &c->frag_index.item[i];
6673 for (j = 0; ref_st == NULL && j < item->nb_stream_info; j++) {
6675 si = &item->stream_info[j];
6676 if (si->sidx_pts != AV_NOPTS_VALUE) {
6677 ref_st = c->fc->streams[j];
6678 ref_sc = ref_st->priv_data;
6679 break;
6680 }
6681 }
6682 }
6683 if (ref_st) for (i = 0; i < c->fc->nb_streams; i++) {
6684 st = c->fc->streams[i];
6685 sc = st->priv_data;
6686 if (!sc->has_sidx) {
6687 st->duration = sc->track_end = av_rescale(ref_st->duration, sc->time_scale, ref_sc->time_scale);
6688 }
6689 }
6690
6691 if (offadd == 0)
6692 c->frag_index.complete = 1;
6693 }
6694
6695 return 0;
6696}
6697
6698/* this atom should be null (from specs), but some buggy files put the 'moov' atom inside it... */
6699/* like the files created with Adobe Premiere 5.0, for samples see */
6700/* http://graphics.tudelft.nl/~wouter/publications/soundtests/ */
6702{
6703 int err;
6704
6705 if (atom.size < 8)
6706 return 0; /* continue */
6707 if (avio_rb32(pb) != 0) { /* 0 sized mdat atom... use the 'wide' atom size */
6708 avio_skip(pb, atom.size - 4);
6709 return 0;
6710 }
6711 atom.type = avio_rl32(pb);
6712 atom.size -= 8;
6713 if (atom.type != MKTAG('m','d','a','t')) {
6714 avio_skip(pb, atom.size);
6715 return 0;
6716 }
6717 err = mov_read_mdat(c, pb, atom);
6718 return err;
6719}
6720
6722{
6723#if CONFIG_ZLIB
6725 uint8_t *cmov_data;
6726 uint8_t *moov_data; /* uncompressed data */
6727 long cmov_len, moov_len;
6728 int ret = -1;
6729
6730 avio_rb32(pb); /* dcom atom */
6731 if (avio_rl32(pb) != MKTAG('d','c','o','m'))
6732 return AVERROR_INVALIDDATA;
6733 if (avio_rl32(pb) != MKTAG('z','l','i','b')) {
6734 av_log(c->fc, AV_LOG_ERROR, "unknown compression for cmov atom !\n");
6735 return AVERROR_INVALIDDATA;
6736 }
6737 avio_rb32(pb); /* cmvd atom */
6738 if (avio_rl32(pb) != MKTAG('c','m','v','d'))
6739 return AVERROR_INVALIDDATA;
6740 moov_len = avio_rb32(pb); /* uncompressed size */
6741 cmov_len = atom.size - 6 * 4;
6742
6743 cmov_data = av_malloc(cmov_len);
6744 if (!cmov_data)
6745 return AVERROR(ENOMEM);
6746 moov_data = av_malloc(moov_len);
6747 if (!moov_data) {
6748 av_free(cmov_data);
6749 return AVERROR(ENOMEM);
6750 }
6751 ret = ffio_read_size(pb, cmov_data, cmov_len);
6752 if (ret < 0)
6753 goto free_and_return;
6754
6756 if (uncompress (moov_data, (uLongf *) &moov_len, (const Bytef *)cmov_data, cmov_len) != Z_OK)
6757 goto free_and_return;
6758 ffio_init_read_context(&ctx, moov_data, moov_len);
6759 ctx.pub.seekable = AVIO_SEEKABLE_NORMAL;
6760 atom.type = MKTAG('m','o','o','v');
6761 atom.size = moov_len;
6762 ret = mov_read_default(c, &ctx.pub, atom);
6763free_and_return:
6764 av_free(moov_data);
6765 av_free(cmov_data);
6766 return ret;
6767#else
6768 av_log(c->fc, AV_LOG_ERROR, "this file requires zlib support compiled in\n");
6769 return AVERROR(ENOSYS);
6770#endif
6771}
6772
6773/* edit list atom */
6775{
6776 MOVStreamContext *sc;
6777 int i, edit_count, version;
6778 int64_t elst_entry_size;
6779
6780 if (c->fc->nb_streams < 1 || c->ignore_editlist)
6781 return 0;
6782 sc = c->fc->streams[c->fc->nb_streams-1]->priv_data;
6783
6784 version = avio_r8(pb); /* version */
6785 avio_rb24(pb); /* flags */
6786 edit_count = avio_rb32(pb); /* entries */
6787 atom.size -= 8;
6788
6789 elst_entry_size = version == 1 ? 20 : 12;
6790 if (atom.size != edit_count * elst_entry_size) {
6791 if (c->fc->strict_std_compliance >= FF_COMPLIANCE_STRICT) {
6792 av_log(c->fc, AV_LOG_ERROR, "Invalid edit list entry_count: %d for elst atom of size: %"PRId64" bytes.\n",
6793 edit_count, atom.size + 8);
6794 return AVERROR_INVALIDDATA;
6795 } else {
6796 edit_count = atom.size / elst_entry_size;
6797 if (edit_count * elst_entry_size != atom.size) {
6798 av_log(c->fc, AV_LOG_WARNING, "ELST atom of %"PRId64" bytes, bigger than %d entries.\n", atom.size, edit_count);
6799 }
6800 }
6801 }
6802
6803 if (!edit_count)
6804 return 0;
6805 if (sc->elst_data)
6806 av_log(c->fc, AV_LOG_WARNING, "Duplicated ELST atom\n");
6807 av_free(sc->elst_data);
6808 sc->elst_count = 0;
6809 sc->elst_data = av_malloc_array(edit_count, sizeof(*sc->elst_data));
6810 if (!sc->elst_data)
6811 return AVERROR(ENOMEM);
6812
6813 av_log(c->fc, AV_LOG_TRACE, "track[%u].edit_count = %i\n", c->fc->nb_streams - 1, edit_count);
6814 for (i = 0; i < edit_count && atom.size > 0 && !pb->eof_reached; i++) {
6815 MOVElst *e = &sc->elst_data[i];
6816
6817 if (version == 1) {
6818 e->duration = avio_rb64(pb);
6819 e->time = avio_rb64(pb);
6820 atom.size -= 16;
6821 } else {
6822 e->duration = avio_rb32(pb); /* segment duration */
6823 e->time = (int32_t)avio_rb32(pb); /* media time */
6824 atom.size -= 8;
6825 }
6826 e->rate = avio_rb32(pb) / 65536.0;
6827 atom.size -= 4;
6828 av_log(c->fc, AV_LOG_TRACE, "duration=%"PRId64" time=%"PRId64" rate=%f\n",
6829 e->duration, e->time, e->rate);
6830
6831 if (e->time < 0 && e->time != -1 &&
6832 c->fc->strict_std_compliance >= FF_COMPLIANCE_STRICT) {
6833 av_log(c->fc, AV_LOG_ERROR, "Track %d, edit %d: Invalid edit list media time=%"PRId64"\n",
6834 c->fc->nb_streams-1, i, e->time);
6835 return AVERROR_INVALIDDATA;
6836 }
6837 if (e->duration < 0) {
6838 av_log(c->fc, AV_LOG_ERROR, "Track %d, edit %d: Invalid edit list duration=%"PRId64"\n",
6839 c->fc->nb_streams-1, i, e->duration);
6840 return AVERROR_INVALIDDATA;
6841 }
6842 }
6843 sc->elst_count = i;
6844
6845 return 0;
6846}
6847
6849{
6850 MOVStreamContext *sc;
6851 int err;
6852
6853 if (c->fc->nb_streams < 1)
6854 return AVERROR_INVALIDDATA;
6855 sc = c->fc->streams[c->fc->nb_streams - 1]->priv_data;
6856
6857 if (atom.size % sizeof(uint32_t))
6858 return AVERROR_INVALIDDATA;
6859
6860 MovTref *tag = mov_add_tref_tag(sc, atom.type);
6861 if (!tag)
6862 return AVERROR(ENOMEM);
6863
6864 int nb_timecode_track = atom.size >> 2;
6865 for (int i = 0; i < nb_timecode_track; i++) {
6866 if (avio_feof(pb))
6867 return AVERROR_INVALIDDATA;
6868 err = mov_add_tref_id(tag, avio_rb32(pb));
6869 if (err < 0)
6870 return err;
6871 }
6872
6873 return 0;
6874}
6875
6877{
6878 AVStream *st;
6879 int version, color_range, color_primaries, color_trc, color_space;
6880
6881 if (c->fc->nb_streams < 1)
6882 return 0;
6883 st = c->fc->streams[c->fc->nb_streams - 1];
6884
6885 if (atom.size < 5) {
6886 av_log(c->fc, AV_LOG_ERROR, "Empty VP Codec Configuration box\n");
6887 return AVERROR_INVALIDDATA;
6888 }
6889
6890 version = avio_r8(pb);
6891 if (version != 1) {
6892 av_log(c->fc, AV_LOG_WARNING, "Unsupported VP Codec Configuration box version %d\n", version);
6893 return 0;
6894 }
6895 avio_skip(pb, 3); /* flags */
6896
6897 avio_skip(pb, 2); /* profile + level */
6898 color_range = avio_r8(pb); /* bitDepth, chromaSubsampling, videoFullRangeFlag */
6900 color_trc = avio_r8(pb);
6901 color_space = avio_r8(pb);
6902 if (avio_rb16(pb)) /* codecIntializationDataSize */
6903 return AVERROR_INVALIDDATA;
6904
6907 if (!av_color_transfer_name(color_trc))
6908 color_trc = AVCOL_TRC_UNSPECIFIED;
6909 if (!av_color_space_name(color_space))
6910 color_space = AVCOL_SPC_UNSPECIFIED;
6911
6914 st->codecpar->color_trc = color_trc;
6915 st->codecpar->color_space = color_space;
6916
6917 return 0;
6918}
6919
6921{
6922 MOVStreamContext *sc;
6923 int i, version;
6924
6925 if (c->fc->nb_streams < 1)
6926 return AVERROR_INVALIDDATA;
6927
6928 sc = c->fc->streams[c->fc->nb_streams - 1]->priv_data;
6929
6930 if (atom.size < 5) {
6931 av_log(c->fc, AV_LOG_ERROR, "Empty Mastering Display Metadata box\n");
6932 return AVERROR_INVALIDDATA;
6933 }
6934
6935 version = avio_r8(pb);
6936 if (version) {
6937 av_log(c->fc, AV_LOG_WARNING, "Unsupported Mastering Display Metadata box version %d\n", version);
6938 return 0;
6939 }
6940 if (sc->mastering) {
6941 av_log(c->fc, AV_LOG_WARNING, "Ignoring duplicate Mastering Display Metadata\n");
6942 return 0;
6943 }
6944
6945 avio_skip(pb, 3); /* flags */
6946
6948 if (!sc->mastering)
6949 return AVERROR(ENOMEM);
6950
6951 for (i = 0; i < 3; i++) {
6952 sc->mastering->display_primaries[i][0] = av_make_q(avio_rb16(pb), 1 << 16);
6953 sc->mastering->display_primaries[i][1] = av_make_q(avio_rb16(pb), 1 << 16);
6954 }
6955 sc->mastering->white_point[0] = av_make_q(avio_rb16(pb), 1 << 16);
6956 sc->mastering->white_point[1] = av_make_q(avio_rb16(pb), 1 << 16);
6957
6958 sc->mastering->max_luminance = av_make_q(avio_rb32(pb), 1 << 8);
6959 sc->mastering->min_luminance = av_make_q(avio_rb32(pb), 1 << 14);
6960
6961 sc->mastering->has_primaries = 1;
6962 sc->mastering->has_luminance = 1;
6963
6964 return 0;
6965}
6966
6968{
6969 MOVStreamContext *sc;
6970 const int mapping[3] = {1, 2, 0};
6971 const int chroma_den = 50000;
6972 const int luma_den = 10000;
6973 int i;
6974
6975 if (c->fc->nb_streams < 1)
6976 return AVERROR_INVALIDDATA;
6977
6978 sc = c->fc->streams[c->fc->nb_streams - 1]->priv_data;
6979
6980 if (atom.size < 24) {
6981 av_log(c->fc, AV_LOG_ERROR, "Invalid Mastering Display Color Volume box\n");
6982 return AVERROR_INVALIDDATA;
6983 }
6984
6985 if (sc->mastering) {
6986 av_log(c->fc, AV_LOG_WARNING, "Ignoring duplicate Mastering Display Color Volume\n");
6987 return 0;
6988 }
6989
6991 if (!sc->mastering)
6992 return AVERROR(ENOMEM);
6993
6994 for (i = 0; i < 3; i++) {
6995 const int j = mapping[i];
6996 sc->mastering->display_primaries[j][0] = av_make_q(avio_rb16(pb), chroma_den);
6997 sc->mastering->display_primaries[j][1] = av_make_q(avio_rb16(pb), chroma_den);
6998 }
6999 sc->mastering->white_point[0] = av_make_q(avio_rb16(pb), chroma_den);
7000 sc->mastering->white_point[1] = av_make_q(avio_rb16(pb), chroma_den);
7001
7002 sc->mastering->max_luminance = av_make_q(avio_rb32(pb), luma_den);
7003 sc->mastering->min_luminance = av_make_q(avio_rb32(pb), luma_den);
7004
7005 sc->mastering->has_luminance = 1;
7006 sc->mastering->has_primaries = 1;
7007
7008 return 0;
7009}
7010
7012{
7013 MOVStreamContext *sc;
7014 int version;
7015
7016 if (c->fc->nb_streams < 1)
7017 return AVERROR_INVALIDDATA;
7018
7019 sc = c->fc->streams[c->fc->nb_streams - 1]->priv_data;
7020
7021 if (atom.size < 5) {
7022 av_log(c->fc, AV_LOG_ERROR, "Empty Content Light Level box\n");
7023 return AVERROR_INVALIDDATA;
7024 }
7025
7026 version = avio_r8(pb);
7027 if (version) {
7028 av_log(c->fc, AV_LOG_WARNING, "Unsupported Content Light Level box version %d\n", version);
7029 return 0;
7030 }
7031 avio_skip(pb, 3); /* flags */
7032
7033 if (sc->coll){
7034 av_log(c->fc, AV_LOG_WARNING, "Ignoring duplicate COLL\n");
7035 return 0;
7036 }
7037
7039 if (!sc->coll)
7040 return AVERROR(ENOMEM);
7041
7042 sc->coll->MaxCLL = avio_rb16(pb);
7043 sc->coll->MaxFALL = avio_rb16(pb);
7044
7045 return 0;
7046}
7047
7049{
7050 MOVStreamContext *sc;
7051
7052 if (c->fc->nb_streams < 1)
7053 return AVERROR_INVALIDDATA;
7054
7055 sc = c->fc->streams[c->fc->nb_streams - 1]->priv_data;
7056
7057 if (atom.size < 4) {
7058 av_log(c->fc, AV_LOG_ERROR, "Empty Content Light Level Info box\n");
7059 return AVERROR_INVALIDDATA;
7060 }
7061
7062 if (sc->coll){
7063 av_log(c->fc, AV_LOG_WARNING, "Ignoring duplicate CLLI/COLL\n");
7064 return 0;
7065 }
7066
7068 if (!sc->coll)
7069 return AVERROR(ENOMEM);
7070
7071 sc->coll->MaxCLL = avio_rb16(pb);
7072 sc->coll->MaxFALL = avio_rb16(pb);
7073
7074 return 0;
7075}
7076
7078{
7079 MOVStreamContext *sc;
7080 const int illuminance_den = 10000;
7081 const int ambient_den = 50000;
7082 if (c->fc->nb_streams < 1)
7083 return AVERROR_INVALIDDATA;
7084 sc = c->fc->streams[c->fc->nb_streams - 1]->priv_data;
7085 if (atom.size < 6) {
7086 av_log(c->fc, AV_LOG_ERROR, "Empty Ambient Viewing Environment Info box\n");
7087 return AVERROR_INVALIDDATA;
7088 }
7089 if (sc->ambient){
7090 av_log(c->fc, AV_LOG_WARNING, "Ignoring duplicate AMVE\n");
7091 return 0;
7092 }
7094 if (!sc->ambient)
7095 return AVERROR(ENOMEM);
7096 sc->ambient->ambient_illuminance = av_make_q(avio_rb32(pb), illuminance_den);
7097 sc->ambient->ambient_light_x = av_make_q(avio_rb16(pb), ambient_den);
7098 sc->ambient->ambient_light_y = av_make_q(avio_rb16(pb), ambient_den);
7099 return 0;
7100}
7101
7103{
7104 AVStream *st;
7105 MOVStreamContext *sc;
7106 enum AVStereo3DType type;
7107 int mode;
7108
7109 if (c->fc->nb_streams < 1)
7110 return 0;
7111
7112 st = c->fc->streams[c->fc->nb_streams - 1];
7113 sc = st->priv_data;
7114
7115 if (atom.size < 5) {
7116 av_log(c->fc, AV_LOG_ERROR, "Empty stereoscopic video box\n");
7117 return AVERROR_INVALIDDATA;
7118 }
7119
7120 if (sc->stereo3d)
7121 return AVERROR_INVALIDDATA;
7122
7123 avio_skip(pb, 4); /* version + flags */
7124
7125 mode = avio_r8(pb);
7126 switch (mode) {
7127 case 0:
7129 break;
7130 case 1:
7132 break;
7133 case 2:
7135 break;
7136 default:
7137 av_log(c->fc, AV_LOG_WARNING, "Unknown st3d mode value %d\n", mode);
7138 return 0;
7139 }
7140
7142 if (!sc->stereo3d)
7143 return AVERROR(ENOMEM);
7144
7145 sc->stereo3d->type = type;
7146 return 0;
7147}
7148
7150{
7151 AVStream *st;
7152 MOVStreamContext *sc;
7153 int size = 0;
7154 int64_t remaining;
7155 uint32_t tag = 0;
7157
7158 if (c->fc->nb_streams < 1)
7159 return 0;
7160
7161 st = c->fc->streams[c->fc->nb_streams - 1];
7162 sc = st->priv_data;
7163
7164 remaining = atom.size;
7165 while (remaining > 0) {
7166 size = avio_rb32(pb);
7167 if (size < 8 || size > remaining ) {
7168 av_log(c->fc, AV_LOG_ERROR, "Invalid child size in pack box\n");
7169 return AVERROR_INVALIDDATA;
7170 }
7171
7172 tag = avio_rl32(pb);
7173 switch (tag) {
7174 case MKTAG('p','k','i','n'): {
7175 if (size != 16) {
7176 av_log(c->fc, AV_LOG_ERROR, "Invalid size of pkin box: %d\n", size);
7177 return AVERROR_INVALIDDATA;
7178 }
7179 avio_skip(pb, 1); // version
7180 avio_skip(pb, 3); // flags
7181
7182 tag = avio_rl32(pb);
7183 switch (tag) {
7184 case MKTAG('s','i','d','e'):
7186 break;
7187 case MKTAG('o','v','e','r'):
7189 break;
7190 case 0:
7191 // This means value will be set in another layer
7192 break;
7193 default:
7194 av_log(c->fc, AV_LOG_WARNING, "Unknown tag in pkin: %s\n",
7196 avio_skip(pb, size - 8);
7197 break;
7198 }
7199
7200 break;
7201 }
7202 default:
7203 av_log(c->fc, AV_LOG_WARNING, "Unknown tag in pack: %s\n",
7205 avio_skip(pb, size - 8);
7206 break;
7207 }
7208 remaining -= size;
7209 }
7210
7211 if (remaining != 0) {
7212 av_log(c->fc, AV_LOG_ERROR, "Broken pack box\n");
7213 return AVERROR_INVALIDDATA;
7214 }
7215
7216 if (type == AV_STEREO3D_2D)
7217 return 0;
7218
7219 if (!sc->stereo3d) {
7221 if (!sc->stereo3d)
7222 return AVERROR(ENOMEM);
7223 }
7224
7225 sc->stereo3d->type = type;
7226
7227 return 0;
7228}
7229
7231{
7232 AVStream *st;
7233 MOVStreamContext *sc;
7234 int size, version, layout;
7235 int32_t yaw, pitch, roll;
7236 uint32_t l = 0, t = 0, r = 0, b = 0;
7237 uint32_t tag, padding = 0;
7238 enum AVSphericalProjection projection;
7239
7240 if (c->fc->nb_streams < 1)
7241 return 0;
7242
7243 st = c->fc->streams[c->fc->nb_streams - 1];
7244 sc = st->priv_data;
7245
7246 if (atom.size < 8) {
7247 av_log(c->fc, AV_LOG_ERROR, "Empty spherical video box\n");
7248 return AVERROR_INVALIDDATA;
7249 }
7250
7251 size = avio_rb32(pb);
7252 if (size <= 12 || size > atom.size)
7253 return AVERROR_INVALIDDATA;
7254
7255 tag = avio_rl32(pb);
7256 if (tag != MKTAG('s','v','h','d')) {
7257 av_log(c->fc, AV_LOG_ERROR, "Missing spherical video header\n");
7258 return 0;
7259 }
7260 version = avio_r8(pb);
7261 if (version != 0) {
7262 av_log(c->fc, AV_LOG_WARNING, "Unknown spherical version %d\n",
7263 version);
7264 return 0;
7265 }
7266 avio_skip(pb, 3); /* flags */
7267 avio_skip(pb, size - 12); /* metadata_source */
7268
7269 size = avio_rb32(pb);
7270 if (size > atom.size)
7271 return AVERROR_INVALIDDATA;
7272
7273 tag = avio_rl32(pb);
7274 if (tag != MKTAG('p','r','o','j')) {
7275 av_log(c->fc, AV_LOG_ERROR, "Missing projection box\n");
7276 return 0;
7277 }
7278
7279 size = avio_rb32(pb);
7280 if (size > atom.size)
7281 return AVERROR_INVALIDDATA;
7282
7283 tag = avio_rl32(pb);
7284 if (tag != MKTAG('p','r','h','d')) {
7285 av_log(c->fc, AV_LOG_ERROR, "Missing projection header box\n");
7286 return 0;
7287 }
7288 version = avio_r8(pb);
7289 if (version != 0) {
7290 av_log(c->fc, AV_LOG_WARNING, "Unknown spherical version %d\n",
7291 version);
7292 return 0;
7293 }
7294 avio_skip(pb, 3); /* flags */
7295
7296 /* 16.16 fixed point */
7297 yaw = avio_rb32(pb);
7298 pitch = avio_rb32(pb);
7299 roll = avio_rb32(pb);
7300
7301 size = avio_rb32(pb);
7302 if (size > atom.size)
7303 return AVERROR_INVALIDDATA;
7304
7305 tag = avio_rl32(pb);
7306 version = avio_r8(pb);
7307 if (version != 0) {
7308 av_log(c->fc, AV_LOG_WARNING, "Unknown spherical version %d\n",
7309 version);
7310 return 0;
7311 }
7312 avio_skip(pb, 3); /* flags */
7313 switch (tag) {
7314 case MKTAG('c','b','m','p'):
7315 layout = avio_rb32(pb);
7316 if (layout) {
7317 av_log(c->fc, AV_LOG_WARNING,
7318 "Unsupported cubemap layout %d\n", layout);
7319 return 0;
7320 }
7321 projection = AV_SPHERICAL_CUBEMAP;
7322 padding = avio_rb32(pb);
7323 break;
7324 case MKTAG('e','q','u','i'):
7325 t = avio_rb32(pb);
7326 b = avio_rb32(pb);
7327 l = avio_rb32(pb);
7328 r = avio_rb32(pb);
7329
7330 if (b >= UINT_MAX - t || r >= UINT_MAX - l) {
7331 av_log(c->fc, AV_LOG_ERROR,
7332 "Invalid bounding rectangle coordinates "
7333 "%"PRIu32",%"PRIu32",%"PRIu32",%"PRIu32"\n", l, t, r, b);
7334 return AVERROR_INVALIDDATA;
7335 }
7336
7337 if (l || t || r || b)
7339 else
7340 projection = AV_SPHERICAL_EQUIRECTANGULAR;
7341 break;
7342 default:
7343 av_log(c->fc, AV_LOG_ERROR, "Unknown projection type: %s\n", av_fourcc2str(tag));
7344 return 0;
7345 }
7346
7348 if (!sc->spherical)
7349 return AVERROR(ENOMEM);
7350
7351 sc->spherical->projection = projection;
7352
7353 sc->spherical->yaw = yaw;
7354 sc->spherical->pitch = pitch;
7355 sc->spherical->roll = roll;
7356
7357 sc->spherical->padding = padding;
7358
7359 sc->spherical->bound_left = l;
7360 sc->spherical->bound_top = t;
7361 sc->spherical->bound_right = r;
7362 sc->spherical->bound_bottom = b;
7363
7364 return 0;
7365}
7366
7368{
7369 AVStream *st;
7370 MOVStreamContext *sc;
7371 int size;
7372 uint32_t tag;
7373 enum AVSphericalProjection projection;
7374
7375 if (c->fc->nb_streams < 1)
7376 return 0;
7377
7378 st = c->fc->streams[c->fc->nb_streams - 1];
7379 sc = st->priv_data;
7380
7381 if (atom.size < 16) {
7382 av_log(c->fc, AV_LOG_ERROR, "Invalid size for proj box: %"PRIu64"\n", atom.size);
7383 return AVERROR_INVALIDDATA;
7384 }
7385
7386 size = avio_rb32(pb);
7387 if (size < 16) {
7388 av_log(c->fc, AV_LOG_ERROR, "Invalid size for prji box: %d\n", size);
7389 return AVERROR_INVALIDDATA;
7390 } else if (size > 16) {
7391 av_log(c->fc, AV_LOG_WARNING, "Box has more bytes (%d) than prji box required (16) \n", size);
7392 }
7393
7394 tag = avio_rl32(pb);
7395 if (tag != MKTAG('p','r','j','i')) {
7396 av_log(c->fc, AV_LOG_ERROR, "Invalid child box of proj box: %s\n",
7398 return AVERROR_INVALIDDATA;
7399 }
7400
7401 // version and flags, only support (0, 0)
7402 unsigned n = avio_rl32(pb);
7403 if (n != 0) {
7404 av_log(c->fc, AV_LOG_ERROR, "prji version %u, flag %u are not supported\n",
7405 n & 0xFF, n >> 8);
7406 return AVERROR_PATCHWELCOME;
7407 }
7408
7409 tag = avio_rl32(pb);
7410 switch (tag) {
7411 case MKTAG('r','e','c','t'):
7412 projection = AV_SPHERICAL_RECTILINEAR;
7413 break;
7414 case MKTAG('e','q','u','i'):
7415 projection = AV_SPHERICAL_EQUIRECTANGULAR;
7416 break;
7417 case MKTAG('h','e','q','u'):
7419 break;
7420 case MKTAG('f','i','s','h'):
7421 projection = AV_SPHERICAL_FISHEYE;
7422 break;
7423 case MKTAG('p','r','i','m'):
7425 break;
7426 default:
7427 av_log(c->fc, AV_LOG_ERROR, "Invalid projection type in prji box: %s\n", av_fourcc2str(tag));
7428 return AVERROR_INVALIDDATA;
7429 }
7430
7432 if (!sc->spherical)
7433 return AVERROR(ENOMEM);
7434
7435 sc->spherical->projection = projection;
7436
7437 return 0;
7438}
7439
7441{
7442 AVStream *st;
7443 MOVStreamContext *sc;
7444 int size, flags = 0;
7445 int64_t remaining;
7446 uint32_t tag, baseline = 0;
7449 enum AVStereo3DPrimaryEye primary_eye = AV_PRIMARY_EYE_NONE;
7450 AVRational horizontal_disparity_adjustment = { 0, 1 };
7451
7452 if (c->fc->nb_streams < 1)
7453 return 0;
7454
7455 st = c->fc->streams[c->fc->nb_streams - 1];
7456 sc = st->priv_data;
7457
7458 remaining = atom.size;
7459 while (remaining > 0) {
7460 size = avio_rb32(pb);
7461 if (size < 8 || size > remaining ) {
7462 av_log(c->fc, AV_LOG_ERROR, "Invalid child size in eyes box\n");
7463 return AVERROR_INVALIDDATA;
7464 }
7465
7466 tag = avio_rl32(pb);
7467 switch (tag) {
7468 case MKTAG('s','t','r','i'): {
7469 int has_right, has_left;
7470 uint8_t tmp;
7471 if (size != 13) {
7472 av_log(c->fc, AV_LOG_ERROR, "Invalid size of stri box: %d\n", size);
7473 return AVERROR_INVALIDDATA;
7474 }
7475 avio_skip(pb, 1); // version
7476 avio_skip(pb, 3); // flags
7477
7478 tmp = avio_r8(pb);
7479
7480 // eye_views_reversed
7481 if (tmp & 8) {
7483 }
7484 // has_additional_views
7485 if (tmp & 4) {
7486 // skip...
7487 }
7488
7489 has_right = tmp & 2; // has_right_eye_view
7490 has_left = tmp & 1; // has_left_eye_view
7491
7492 if (has_left && has_right)
7494 else if (has_left)
7495 view = AV_STEREO3D_VIEW_LEFT;
7496 else if (has_right)
7498 if (has_left || has_right)
7500
7501 break;
7502 }
7503 case MKTAG('h','e','r','o'): {
7504 int tmp;
7505 if (size != 13) {
7506 av_log(c->fc, AV_LOG_ERROR, "Invalid size of hero box: %d\n", size);
7507 return AVERROR_INVALIDDATA;
7508 }
7509 avio_skip(pb, 1); // version
7510 avio_skip(pb, 3); // flags
7511
7512 tmp = avio_r8(pb);
7513 if (tmp == 0)
7514 primary_eye = AV_PRIMARY_EYE_NONE;
7515 else if (tmp == 1)
7516 primary_eye = AV_PRIMARY_EYE_LEFT;
7517 else if (tmp == 2)
7518 primary_eye = AV_PRIMARY_EYE_RIGHT;
7519 else
7520 av_log(c->fc, AV_LOG_WARNING, "Unknown hero eye type: %d\n", tmp);
7521
7522 break;
7523 }
7524 case MKTAG('c','a','m','s'): {
7525 uint32_t subtag;
7526 int subsize;
7527 if (size != 24) {
7528 av_log(c->fc, AV_LOG_ERROR, "Invalid size of cams box: %d\n", size);
7529 return AVERROR_INVALIDDATA;
7530 }
7531
7532 subsize = avio_rb32(pb);
7533 if (subsize != 16) {
7534 av_log(c->fc, AV_LOG_ERROR, "Invalid size of blin box: %d\n", size);
7535 return AVERROR_INVALIDDATA;
7536 }
7537
7538 subtag = avio_rl32(pb);
7539 if (subtag != MKTAG('b','l','i','n')) {
7540 av_log(c->fc, AV_LOG_ERROR, "Expected blin box, got %s\n",
7541 av_fourcc2str(subtag));
7542 return AVERROR_INVALIDDATA;
7543 }
7544
7545 avio_skip(pb, 1); // version
7546 avio_skip(pb, 3); // flags
7547
7548 baseline = avio_rb32(pb);
7549
7550 break;
7551 }
7552 case MKTAG('c','m','f','y'): {
7553 uint32_t subtag;
7554 int subsize;
7555 int32_t adjustment;
7556 if (size != 24) {
7557 av_log(c->fc, AV_LOG_ERROR, "Invalid size of cmfy box: %d\n", size);
7558 return AVERROR_INVALIDDATA;
7559 }
7560
7561 subsize = avio_rb32(pb);
7562 if (subsize != 16) {
7563 av_log(c->fc, AV_LOG_ERROR, "Invalid size of dadj box: %d\n", size);
7564 return AVERROR_INVALIDDATA;
7565 }
7566
7567 subtag = avio_rl32(pb);
7568 if (subtag != MKTAG('d','a','d','j')) {
7569 av_log(c->fc, AV_LOG_ERROR, "Expected dadj box, got %s\n",
7570 av_fourcc2str(subtag));
7571 return AVERROR_INVALIDDATA;
7572 }
7573
7574 avio_skip(pb, 1); // version
7575 avio_skip(pb, 3); // flags
7576
7577 adjustment = (int32_t) avio_rb32(pb);
7578
7579 horizontal_disparity_adjustment.num = (int) adjustment;
7580 horizontal_disparity_adjustment.den = 10000;
7581
7582 break;
7583 }
7584 default:
7585 av_log(c->fc, AV_LOG_WARNING, "Unknown tag in eyes: %s\n",
7587 avio_skip(pb, size - 8);
7588 break;
7589 }
7590 remaining -= size;
7591 }
7592
7593 if (remaining != 0) {
7594 av_log(c->fc, AV_LOG_ERROR, "Broken eyes box\n");
7595 return AVERROR_INVALIDDATA;
7596 }
7597
7598 if (type == AV_STEREO3D_2D)
7599 return 0;
7600
7601 if (!sc->stereo3d) {
7603 if (!sc->stereo3d)
7604 return AVERROR(ENOMEM);
7605 }
7606
7607 sc->stereo3d->flags = flags;
7608 /* eyes/stri only records packed vs single-eye, not SBS/TB. Keep a more
7609 * specific type already set by st3d. */
7610 if (type != AV_STEREO3D_UNSPEC)
7611 sc->stereo3d->type = type;
7612 else if (sc->stereo3d->type == AV_STEREO3D_2D)
7613 sc->stereo3d->type = type;
7614 sc->stereo3d->view = view;
7615 sc->stereo3d->primary_eye = primary_eye;
7616 sc->stereo3d->baseline = baseline;
7617 sc->stereo3d->horizontal_disparity_adjustment = horizontal_disparity_adjustment;
7618
7619 return 0;
7620}
7621
7623{
7624 int size;
7625 int64_t remaining;
7626 uint32_t tag;
7627
7628 if (c->fc->nb_streams < 1)
7629 return 0;
7630
7631 if (atom.size < 8) {
7632 av_log(c->fc, AV_LOG_ERROR, "Empty video extension usage box\n");
7633 return AVERROR_INVALIDDATA;
7634 }
7635
7636 remaining = atom.size;
7637 while (remaining > 0) {
7638 size = avio_rb32(pb);
7639 if (size < 8 || size > remaining ) {
7640 av_log(c->fc, AV_LOG_ERROR, "Invalid child size in vexu box\n");
7641 return AVERROR_INVALIDDATA;
7642 }
7643
7644 tag = avio_rl32(pb);
7645 switch (tag) {
7646 case MKTAG('p','r','o','j'): {
7647 MOVAtom proj = { tag, size - 8 };
7648 int ret = mov_read_vexu_proj(c, pb, proj);
7649 if (ret < 0)
7650 return ret;
7651 break;
7652 }
7653 case MKTAG('e','y','e','s'): {
7654 MOVAtom eyes = { tag, size - 8 };
7655 int ret = mov_read_eyes(c, pb, eyes);
7656 if (ret < 0)
7657 return ret;
7658 break;
7659 }
7660 case MKTAG('p','a','c','k'): {
7661 MOVAtom pack = { tag, size - 8 };
7662 int ret = mov_read_pack(c, pb, pack);
7663 if (ret < 0)
7664 return ret;
7665 break;
7666 }
7667 default:
7668 av_log(c->fc, AV_LOG_WARNING, "Unknown tag in vexu: %s\n",
7670 avio_skip(pb, size - 8);
7671 break;
7672 }
7673 remaining -= size;
7674 }
7675
7676 if (remaining != 0) {
7677 av_log(c->fc, AV_LOG_ERROR, "Broken vexu box\n");
7678 return AVERROR_INVALIDDATA;
7679 }
7680
7681 return 0;
7682}
7683
7685{
7686 AVStream *st;
7687 MOVStreamContext *sc;
7688
7689 if (c->fc->nb_streams < 1)
7690 return 0;
7691
7692 st = c->fc->streams[c->fc->nb_streams - 1];
7693 sc = st->priv_data;
7694
7695 if (atom.size != 4) {
7696 av_log(c->fc, AV_LOG_ERROR, "Invalid size of hfov box: %"PRIu64"\n", atom.size);
7697 return AVERROR_INVALIDDATA;
7698 }
7699
7700
7701 if (!sc->stereo3d) {
7703 if (!sc->stereo3d)
7704 return AVERROR(ENOMEM);
7705 }
7706
7708 sc->stereo3d->horizontal_field_of_view.den = 1000; // thousands of a degree
7709
7710 return 0;
7711}
7712
7714{
7715 int ret = 0;
7716 uint8_t *buffer = av_malloc(len + 1);
7717 const char *val;
7718
7719 if (!buffer)
7720 return AVERROR(ENOMEM);
7721 buffer[len] = '\0';
7722
7723 ret = ffio_read_size(pb, buffer, len);
7724 if (ret < 0)
7725 goto out;
7726
7727 /* Check for mandatory keys and values, try to support XML as best-effort */
7728 if (!sc->spherical &&
7729 av_stristr(buffer, "<GSpherical:StitchingSoftware>") &&
7730 (val = av_stristr(buffer, "<GSpherical:Spherical>")) &&
7731 av_stristr(val, "true") &&
7732 (val = av_stristr(buffer, "<GSpherical:Stitched>")) &&
7733 av_stristr(val, "true") &&
7734 (val = av_stristr(buffer, "<GSpherical:ProjectionType>")) &&
7735 av_stristr(val, "equirectangular")) {
7737 if (!sc->spherical)
7738 goto out;
7739
7741
7742 if (av_stristr(buffer, "<GSpherical:StereoMode>") && !sc->stereo3d) {
7743 enum AVStereo3DType mode;
7744
7745 if (av_stristr(buffer, "left-right"))
7747 else if (av_stristr(buffer, "top-bottom"))
7749 else
7751
7753 if (!sc->stereo3d)
7754 goto out;
7755
7756 sc->stereo3d->type = mode;
7757 }
7758
7759 /* orientation */
7760 val = av_stristr(buffer, "<GSpherical:InitialViewHeadingDegrees>");
7761 if (val)
7762 sc->spherical->yaw = strtol(val, NULL, 10) * (1 << 16);
7763 val = av_stristr(buffer, "<GSpherical:InitialViewPitchDegrees>");
7764 if (val)
7765 sc->spherical->pitch = strtol(val, NULL, 10) * (1 << 16);
7766 val = av_stristr(buffer, "<GSpherical:InitialViewRollDegrees>");
7767 if (val)
7768 sc->spherical->roll = strtol(val, NULL, 10) * (1 << 16);
7769 }
7770
7771out:
7772 av_free(buffer);
7773 return ret;
7774}
7775
7777{
7778 AVStream *st;
7779 MOVStreamContext *sc;
7780 int64_t ret;
7781 AVUUID uuid;
7782 static const AVUUID uuid_isml_manifest = {
7783 0xa5, 0xd4, 0x0b, 0x30, 0xe8, 0x14, 0x11, 0xdd,
7784 0xba, 0x2f, 0x08, 0x00, 0x20, 0x0c, 0x9a, 0x66
7785 };
7786 static const AVUUID uuid_xmp = {
7787 0xbe, 0x7a, 0xcf, 0xcb, 0x97, 0xa9, 0x42, 0xe8,
7788 0x9c, 0x71, 0x99, 0x94, 0x91, 0xe3, 0xaf, 0xac
7789 };
7790 static const AVUUID uuid_spherical = {
7791 0xff, 0xcc, 0x82, 0x63, 0xf8, 0x55, 0x4a, 0x93,
7792 0x88, 0x14, 0x58, 0x7a, 0x02, 0x52, 0x1f, 0xdd,
7793 };
7794
7795 if (atom.size < AV_UUID_LEN || atom.size >= FFMIN(INT_MAX, SIZE_MAX))
7796 return AVERROR_INVALIDDATA;
7797
7798 if (c->fc->nb_streams < 1)
7799 return 0;
7800 st = c->fc->streams[c->fc->nb_streams - 1];
7801 sc = st->priv_data;
7802
7803 ret = ffio_read_size(pb, uuid, AV_UUID_LEN);
7804 if (ret < 0)
7805 return ret;
7806 if (av_uuid_equal(uuid, uuid_isml_manifest)) {
7807 uint8_t *buffer, *ptr;
7808 char *endptr;
7809 size_t len = atom.size - AV_UUID_LEN;
7810
7811 if (len < 4) {
7812 return AVERROR_INVALIDDATA;
7813 }
7814 ret = avio_skip(pb, 4); // zeroes
7815 len -= 4;
7816
7817 buffer = av_mallocz(len + 1);
7818 if (!buffer) {
7819 return AVERROR(ENOMEM);
7820 }
7821 ret = ffio_read_size(pb, buffer, len);
7822 if (ret < 0) {
7823 av_free(buffer);
7824 return ret;
7825 }
7826
7827 ptr = buffer;
7828 while ((ptr = av_stristr(ptr, "systemBitrate=\""))) {
7829 ptr += sizeof("systemBitrate=\"") - 1;
7830 c->bitrates_count++;
7831 c->bitrates = av_realloc_f(c->bitrates, c->bitrates_count, sizeof(*c->bitrates));
7832 if (!c->bitrates) {
7833 c->bitrates_count = 0;
7834 av_free(buffer);
7835 return AVERROR(ENOMEM);
7836 }
7837 errno = 0;
7838 ret = strtol(ptr, &endptr, 10);
7839 if (ret < 0 || errno || *endptr != '"') {
7840 c->bitrates[c->bitrates_count - 1] = 0;
7841 } else {
7842 c->bitrates[c->bitrates_count - 1] = ret;
7843 }
7844 }
7845
7846 av_free(buffer);
7847 } else if (av_uuid_equal(uuid, uuid_xmp)) {
7848 uint8_t *buffer;
7849 size_t len = atom.size - AV_UUID_LEN;
7850 if (c->export_xmp) {
7851 buffer = av_mallocz(len + 1);
7852 if (!buffer) {
7853 return AVERROR(ENOMEM);
7854 }
7855 ret = ffio_read_size(pb, buffer, len);
7856 if (ret < 0) {
7857 av_free(buffer);
7858 return ret;
7859 }
7860 buffer[len] = '\0';
7861 av_dict_set(&c->fc->metadata, "xmp",
7863 } else {
7864 // skip all uuid atom, which makes it fast for long uuid-xmp file
7865 ret = avio_skip(pb, len);
7866 if (ret < 0)
7867 return ret;
7868 }
7869 } else if (av_uuid_equal(uuid, uuid_spherical)) {
7870 size_t len = atom.size - AV_UUID_LEN;
7871 ret = mov_parse_uuid_spherical(sc, pb, len);
7872 if (ret < 0)
7873 return ret;
7874 if (!sc->spherical)
7875 av_log(c->fc, AV_LOG_WARNING, "Invalid spherical metadata found\n");
7876 }
7877
7878 return 0;
7879}
7880
7882{
7883 int ret;
7884 uint8_t content[16];
7885
7886 if (atom.size < 8)
7887 return 0;
7888
7889 ret = ffio_read_size(pb, content, FFMIN(sizeof(content), atom.size));
7890 if (ret < 0)
7891 return ret;
7892
7893 if ( !c->found_moov
7894 && !c->found_mdat
7895 && !memcmp(content, "Anevia\x1A\x1A", 8)
7896 && c->use_mfra_for == FF_MOV_FLAG_MFRA_AUTO) {
7897 c->use_mfra_for = FF_MOV_FLAG_MFRA_PTS;
7898 }
7899
7900 return 0;
7901}
7902
7904{
7905 uint32_t format = avio_rl32(pb);
7906 MOVStreamContext *sc;
7907 enum AVCodecID id;
7908 AVStream *st;
7909
7910 if (c->fc->nb_streams < 1)
7911 return 0;
7912 st = c->fc->streams[c->fc->nb_streams - 1];
7913 sc = st->priv_data;
7914
7915 switch (sc->format)
7916 {
7917 case MKTAG('e','n','c','v'): // encrypted video
7918 case MKTAG('e','n','c','a'): // encrypted audio
7919 id = mov_codec_id(st, format);
7920 if (st->codecpar->codec_id != AV_CODEC_ID_NONE &&
7921 st->codecpar->codec_id != id) {
7922 av_log(c->fc, AV_LOG_WARNING,
7923 "ignoring 'frma' atom of '%.4s', stream has codec id %d\n",
7924 (char*)&format, st->codecpar->codec_id);
7925 break;
7926 }
7927
7928 st->codecpar->codec_id = id;
7929 sc->format = format;
7930 break;
7931
7932 default:
7933 if (format != sc->format) {
7934 av_log(c->fc, AV_LOG_WARNING,
7935 "ignoring 'frma' atom of '%.4s', stream format is '%.4s'\n",
7936 (char*)&format, (char*)&sc->format);
7937 }
7938 break;
7939 }
7940
7941 return 0;
7942}
7943
7944/**
7945 * Gets the current encryption info and associated current stream context. If
7946 * we are parsing a track fragment, this will return the specific encryption
7947 * info for this fragment; otherwise this will return the global encryption
7948 * info for the current stream.
7949 */
7951{
7952 MOVFragmentStreamInfo *frag_stream_info;
7953 AVStream *st;
7954 int i;
7955
7956 frag_stream_info = get_current_frag_stream_info(&c->frag_index);
7957 if (frag_stream_info) {
7958 for (i = 0; i < c->fc->nb_streams; i++) {
7959 *sc = c->fc->streams[i]->priv_data;
7960 if ((*sc)->id == frag_stream_info->id) {
7961 st = c->fc->streams[i];
7962 break;
7963 }
7964 }
7965 if (i == c->fc->nb_streams)
7966 return 0;
7967 *sc = st->priv_data;
7968
7969 if (!frag_stream_info->encryption_index) {
7970 // If this stream isn't encrypted, don't create the index.
7971 if (!(*sc)->cenc.default_encrypted_sample)
7972 return 0;
7973 frag_stream_info->encryption_index = av_mallocz(sizeof(*frag_stream_info->encryption_index));
7974 if (!frag_stream_info->encryption_index)
7975 return AVERROR(ENOMEM);
7976 }
7977 *encryption_index = frag_stream_info->encryption_index;
7978 return 1;
7979 } else {
7980 // No current track fragment, using stream level encryption info.
7981
7982 if (c->fc->nb_streams < 1)
7983 return 0;
7984 st = c->fc->streams[c->fc->nb_streams - 1];
7985 *sc = st->priv_data;
7986
7987 if (!(*sc)->cenc.encryption_index) {
7988 // If this stream isn't encrypted, don't create the index.
7989 if (!(*sc)->cenc.default_encrypted_sample)
7990 return 0;
7991 (*sc)->cenc.encryption_index = av_mallocz(sizeof(*frag_stream_info->encryption_index));
7992 if (!(*sc)->cenc.encryption_index)
7993 return AVERROR(ENOMEM);
7994 }
7995
7996 *encryption_index = (*sc)->cenc.encryption_index;
7997 return 1;
7998 }
7999}
8000
8002{
8003 int i, ret;
8004 unsigned int subsample_count;
8005 AVSubsampleEncryptionInfo *subsamples;
8006
8007 if (!sc->cenc.default_encrypted_sample) {
8008 av_log(c->fc, AV_LOG_ERROR, "Missing schm or tenc\n");
8009 return AVERROR_INVALIDDATA;
8010 }
8011
8012 if (sc->cenc.per_sample_iv_size || use_subsamples) {
8014 if (!*sample)
8015 return AVERROR(ENOMEM);
8016 } else
8017 *sample = NULL;
8018
8019 if (sc->cenc.per_sample_iv_size != 0) {
8020 if ((ret = ffio_read_size(pb, (*sample)->iv, sc->cenc.per_sample_iv_size)) < 0) {
8021 av_log(c->fc, AV_LOG_ERROR, "failed to read the initialization vector\n");
8023 *sample = NULL;
8024 return ret;
8025 }
8026 }
8027
8028 if (use_subsamples) {
8029 subsample_count = avio_rb16(pb);
8030 av_free((*sample)->subsamples);
8031 (*sample)->subsamples = av_calloc(subsample_count, sizeof(*subsamples));
8032 if (!(*sample)->subsamples) {
8034 *sample = NULL;
8035 return AVERROR(ENOMEM);
8036 }
8037
8038 for (i = 0; i < subsample_count && !pb->eof_reached; i++) {
8039 (*sample)->subsamples[i].bytes_of_clear_data = avio_rb16(pb);
8040 (*sample)->subsamples[i].bytes_of_protected_data = avio_rb32(pb);
8041 }
8042
8043 if (pb->eof_reached) {
8044 av_log(c->fc, AV_LOG_ERROR, "hit EOF while reading sub-sample encryption info\n");
8046 *sample = NULL;
8047 return AVERROR_INVALIDDATA;
8048 }
8049 (*sample)->subsample_count = subsample_count;
8050 }
8051
8052 return 0;
8053}
8054
8056{
8057 AVEncryptionInfo **encrypted_samples;
8058 MOVEncryptionIndex *encryption_index;
8059 MOVStreamContext *sc;
8060 int use_subsamples, ret;
8061 unsigned int sample_count, i, alloc_size = 0;
8062
8063 ret = get_current_encryption_info(c, &encryption_index, &sc);
8064 if (ret != 1)
8065 return ret;
8066
8067 if (encryption_index->nb_encrypted_samples) {
8068 // This can happen if we have both saio/saiz and senc atoms.
8069 av_log(c->fc, AV_LOG_DEBUG, "Ignoring duplicate encryption info in senc\n");
8070 return 0;
8071 }
8072
8073 avio_r8(pb); /* version */
8074 use_subsamples = avio_rb24(pb) & 0x02; /* flags */
8075
8076 sample_count = avio_rb32(pb);
8077 if (sample_count >= INT_MAX / sizeof(*encrypted_samples))
8078 return AVERROR(ENOMEM);
8079
8080 for (i = 0; i < sample_count; i++) {
8081 unsigned int min_samples = FFMIN(FFMAX(i + 1, 1024 * 1024), sample_count);
8082 encrypted_samples = av_fast_realloc(encryption_index->encrypted_samples, &alloc_size,
8083 min_samples * sizeof(*encrypted_samples));
8084 if (encrypted_samples) {
8085 encryption_index->encrypted_samples = encrypted_samples;
8086
8088 c, pb, sc, &encryption_index->encrypted_samples[i], use_subsamples);
8089 } else {
8090 ret = AVERROR(ENOMEM);
8091 }
8092 if (pb->eof_reached) {
8093 av_log(c->fc, AV_LOG_ERROR, "Hit EOF while reading senc\n");
8094 if (ret >= 0)
8095 av_encryption_info_free(encryption_index->encrypted_samples[i]);
8097 }
8098
8099 if (ret < 0) {
8100 for (; i > 0; i--)
8101 av_encryption_info_free(encryption_index->encrypted_samples[i - 1]);
8102 av_freep(&encryption_index->encrypted_samples);
8103 return ret;
8104 }
8105 }
8106 encryption_index->nb_encrypted_samples = sample_count;
8107
8108 return 0;
8109}
8110
8112{
8113 AVEncryptionInfo **sample, **encrypted_samples;
8114 int64_t prev_pos;
8115 size_t sample_count, sample_info_size, i;
8116 int ret = 0;
8117 unsigned int alloc_size = 0;
8118
8119 if (encryption_index->nb_encrypted_samples)
8120 return 0;
8121 sample_count = encryption_index->auxiliary_info_sample_count;
8122 if (encryption_index->auxiliary_offsets_count != 1) {
8123 av_log(c->fc, AV_LOG_ERROR, "Multiple auxiliary info chunks are not supported\n");
8124 return AVERROR_PATCHWELCOME;
8125 }
8126 if (sample_count >= INT_MAX / sizeof(*encrypted_samples))
8127 return AVERROR(ENOMEM);
8128
8129 prev_pos = avio_tell(pb);
8130 if (!(pb->seekable & AVIO_SEEKABLE_NORMAL) ||
8131 avio_seek(pb, encryption_index->auxiliary_offsets[0], SEEK_SET) != encryption_index->auxiliary_offsets[0]) {
8132 av_log(c->fc, AV_LOG_INFO, "Failed to seek for auxiliary info, will only parse senc atoms for encryption info\n");
8133 goto finish;
8134 }
8135
8136 for (i = 0; i < sample_count && !pb->eof_reached; i++) {
8137 unsigned int min_samples = FFMIN(FFMAX(i + 1, 1024 * 1024), sample_count);
8138 encrypted_samples = av_fast_realloc(encryption_index->encrypted_samples, &alloc_size,
8139 min_samples * sizeof(*encrypted_samples));
8140 if (!encrypted_samples) {
8141 ret = AVERROR(ENOMEM);
8142 goto finish;
8143 }
8144 encryption_index->encrypted_samples = encrypted_samples;
8145
8146 sample = &encryption_index->encrypted_samples[i];
8147 sample_info_size = encryption_index->auxiliary_info_default_size
8148 ? encryption_index->auxiliary_info_default_size
8149 : encryption_index->auxiliary_info_sizes[i];
8150
8151 ret = mov_read_sample_encryption_info(c, pb, sc, sample, sample_info_size > sc->cenc.per_sample_iv_size);
8152 if (ret < 0)
8153 goto finish;
8154 }
8155 if (pb->eof_reached) {
8156 av_log(c->fc, AV_LOG_ERROR, "Hit EOF while reading auxiliary info\n");
8158 } else {
8159 encryption_index->nb_encrypted_samples = sample_count;
8160 }
8161
8162finish:
8163 avio_seek(pb, prev_pos, SEEK_SET);
8164 if (ret < 0) {
8165 for (; i > 0; i--) {
8166 av_encryption_info_free(encryption_index->encrypted_samples[i - 1]);
8167 }
8168 av_freep(&encryption_index->encrypted_samples);
8169 }
8170 return ret;
8171}
8172
8174{
8175 MOVEncryptionIndex *encryption_index;
8176 MOVStreamContext *sc;
8177 int ret;
8178 unsigned int sample_count, aux_info_type, aux_info_param;
8179
8180 ret = get_current_encryption_info(c, &encryption_index, &sc);
8181 if (ret != 1)
8182 return ret;
8183
8184 if (encryption_index->nb_encrypted_samples) {
8185 // This can happen if we have both saio/saiz and senc atoms.
8186 av_log(c->fc, AV_LOG_DEBUG, "Ignoring duplicate encryption info in saiz\n");
8187 return 0;
8188 }
8189
8190 if (encryption_index->auxiliary_info_sample_count) {
8191 av_log(c->fc, AV_LOG_ERROR, "Duplicate saiz atom\n");
8192 return AVERROR_INVALIDDATA;
8193 }
8194
8195 avio_r8(pb); /* version */
8196 if (avio_rb24(pb) & 0x01) { /* flags */
8197 aux_info_type = avio_rb32(pb);
8198 aux_info_param = avio_rb32(pb);
8200 if (aux_info_type != sc->cenc.default_encrypted_sample->scheme) {
8201 av_log(c->fc, AV_LOG_DEBUG, "Ignoring saiz box with non-zero aux_info_type\n");
8202 return 0;
8203 }
8204 if (aux_info_param != 0) {
8205 av_log(c->fc, AV_LOG_DEBUG, "Ignoring saiz box with non-zero aux_info_type_parameter\n");
8206 return 0;
8207 }
8208 } else {
8209 // Didn't see 'schm' or 'tenc', so this isn't encrypted.
8210 if ((aux_info_type == MKBETAG('c','e','n','c') ||
8211 aux_info_type == MKBETAG('c','e','n','s') ||
8212 aux_info_type == MKBETAG('c','b','c','1') ||
8213 aux_info_type == MKBETAG('c','b','c','s')) &&
8214 aux_info_param == 0) {
8215 av_log(c->fc, AV_LOG_ERROR, "Saw encrypted saiz without schm/tenc\n");
8216 return AVERROR_INVALIDDATA;
8217 } else {
8218 return 0;
8219 }
8220 }
8221 } else if (!sc->cenc.default_encrypted_sample) {
8222 // Didn't see 'schm' or 'tenc', so this isn't encrypted.
8223 return 0;
8224 }
8225
8226 encryption_index->auxiliary_info_default_size = avio_r8(pb);
8227 sample_count = avio_rb32(pb);
8228
8229 if (encryption_index->auxiliary_info_default_size == 0) {
8230 if (sample_count == 0)
8231 return AVERROR_INVALIDDATA;
8232
8233 encryption_index->auxiliary_info_sizes = av_malloc(sample_count);
8234 if (!encryption_index->auxiliary_info_sizes)
8235 return AVERROR(ENOMEM);
8236
8237 ret = avio_read(pb, encryption_index->auxiliary_info_sizes, sample_count);
8238 if (ret != sample_count) {
8239 av_freep(&encryption_index->auxiliary_info_sizes);
8240
8241 if (ret >= 0)
8243 av_log(c->fc, AV_LOG_ERROR, "Failed to read the auxiliary info, %s\n",
8244 av_err2str(ret));
8245 return ret;
8246 }
8247 }
8248 encryption_index->auxiliary_info_sample_count = sample_count;
8249
8250 if (encryption_index->auxiliary_offsets_count) {
8251 return mov_parse_auxiliary_info(c, sc, pb, encryption_index);
8252 }
8253
8254 return 0;
8255}
8256
8258{
8259 uint64_t *auxiliary_offsets;
8260 MOVEncryptionIndex *encryption_index;
8261 MOVStreamContext *sc;
8262 int i, ret;
8263 unsigned int version, entry_count, aux_info_type, aux_info_param;
8264 unsigned int alloc_size = 0;
8265
8266 ret = get_current_encryption_info(c, &encryption_index, &sc);
8267 if (ret != 1)
8268 return ret;
8269
8270 if (encryption_index->nb_encrypted_samples) {
8271 // This can happen if we have both saio/saiz and senc atoms.
8272 av_log(c->fc, AV_LOG_DEBUG, "Ignoring duplicate encryption info in saio\n");
8273 return 0;
8274 }
8275
8276 if (encryption_index->auxiliary_offsets_count) {
8277 av_log(c->fc, AV_LOG_ERROR, "Duplicate saio atom\n");
8278 return AVERROR_INVALIDDATA;
8279 }
8280
8281 version = avio_r8(pb); /* version */
8282 if (avio_rb24(pb) & 0x01) { /* flags */
8283 aux_info_type = avio_rb32(pb);
8284 aux_info_param = avio_rb32(pb);
8286 if (aux_info_type != sc->cenc.default_encrypted_sample->scheme) {
8287 av_log(c->fc, AV_LOG_DEBUG, "Ignoring saio box with non-zero aux_info_type\n");
8288 return 0;
8289 }
8290 if (aux_info_param != 0) {
8291 av_log(c->fc, AV_LOG_DEBUG, "Ignoring saio box with non-zero aux_info_type_parameter\n");
8292 return 0;
8293 }
8294 } else {
8295 // Didn't see 'schm' or 'tenc', so this isn't encrypted.
8296 if ((aux_info_type == MKBETAG('c','e','n','c') ||
8297 aux_info_type == MKBETAG('c','e','n','s') ||
8298 aux_info_type == MKBETAG('c','b','c','1') ||
8299 aux_info_type == MKBETAG('c','b','c','s')) &&
8300 aux_info_param == 0) {
8301 av_log(c->fc, AV_LOG_ERROR, "Saw encrypted saio without schm/tenc\n");
8302 return AVERROR_INVALIDDATA;
8303 } else {
8304 return 0;
8305 }
8306 }
8307 } else if (!sc->cenc.default_encrypted_sample) {
8308 // Didn't see 'schm' or 'tenc', so this isn't encrypted.
8309 return 0;
8310 }
8311
8312 entry_count = avio_rb32(pb);
8313 if (entry_count >= INT_MAX / sizeof(*auxiliary_offsets))
8314 return AVERROR(ENOMEM);
8315
8316 for (i = 0; i < entry_count && !pb->eof_reached; i++) {
8317 unsigned int min_offsets = FFMIN(FFMAX(i + 1, 1024), entry_count);
8318 auxiliary_offsets = av_fast_realloc(
8319 encryption_index->auxiliary_offsets, &alloc_size,
8320 min_offsets * sizeof(*auxiliary_offsets));
8321 if (!auxiliary_offsets) {
8322 av_freep(&encryption_index->auxiliary_offsets);
8323 return AVERROR(ENOMEM);
8324 }
8325 encryption_index->auxiliary_offsets = auxiliary_offsets;
8326
8327 if (version == 0) {
8328 encryption_index->auxiliary_offsets[i] = avio_rb32(pb);
8329 } else {
8330 encryption_index->auxiliary_offsets[i] = avio_rb64(pb);
8331 }
8332 if (c->frag_index.current >= 0) {
8333 encryption_index->auxiliary_offsets[i] += c->fragment.base_data_offset;
8334 }
8335 }
8336
8337 if (pb->eof_reached) {
8338 av_log(c->fc, AV_LOG_ERROR, "Hit EOF while reading saio\n");
8339 av_freep(&encryption_index->auxiliary_offsets);
8340 return AVERROR_INVALIDDATA;
8341 }
8342
8343 encryption_index->auxiliary_offsets_count = entry_count;
8344
8345 if (encryption_index->auxiliary_info_sample_count) {
8346 return mov_parse_auxiliary_info(c, sc, pb, encryption_index);
8347 }
8348
8349 return 0;
8350}
8351
8353{
8355 uint8_t **key_ids;
8356 AVStream *st;
8357 AVPacketSideData *old_side_data = NULL;
8358 uint8_t *side_data = NULL, *extra_data;
8359 size_t side_data_size = 0;
8360 int ret = 0;
8361 unsigned int version, kid_count, extra_data_size, alloc_size = 0;
8362
8363 if (c->fc->nb_streams < 1)
8364 return 0;
8365 st = c->fc->streams[c->fc->nb_streams-1];
8366
8367 version = avio_r8(pb); /* version */
8368 avio_rb24(pb); /* flags */
8369
8370 info = av_encryption_init_info_alloc(/* system_id_size */ 16, /* num_key_ids */ 0,
8371 /* key_id_size */ 16, /* data_size */ 0);
8372 if (!info)
8373 return AVERROR(ENOMEM);
8374
8375 if ((ret = ffio_read_size(pb, info->system_id, 16)) < 0) {
8376 av_log(c->fc, AV_LOG_ERROR, "Failed to read the system id\n");
8377 goto finish;
8378 }
8379
8380 if (version > 0) {
8381 kid_count = avio_rb32(pb);
8382 if (kid_count >= INT_MAX / sizeof(*key_ids)) {
8383 ret = AVERROR(ENOMEM);
8384 goto finish;
8385 }
8386
8387 for (unsigned int i = 0; i < kid_count && !pb->eof_reached; i++) {
8388 unsigned int min_kid_count = FFMIN(FFMAX(i + 1, 1024), kid_count);
8389 key_ids = av_fast_realloc(info->key_ids, &alloc_size,
8390 min_kid_count * sizeof(*key_ids));
8391 if (!key_ids) {
8392 ret = AVERROR(ENOMEM);
8393 goto finish;
8394 }
8395 info->key_ids = key_ids;
8396
8397 info->key_ids[i] = av_mallocz(16);
8398 if (!info->key_ids[i]) {
8399 ret = AVERROR(ENOMEM);
8400 goto finish;
8401 }
8402 info->num_key_ids = i + 1;
8403
8404 if ((ret = ffio_read_size(pb, info->key_ids[i], 16)) < 0) {
8405 av_log(c->fc, AV_LOG_ERROR, "Failed to read the key id\n");
8406 goto finish;
8407 }
8408 }
8409
8410 if (pb->eof_reached) {
8411 av_log(c->fc, AV_LOG_ERROR, "Hit EOF while reading pssh\n");
8413 goto finish;
8414 }
8415 }
8416
8417 extra_data_size = avio_rb32(pb);
8418 extra_data = av_malloc(extra_data_size);
8419 if (!extra_data) {
8420 ret = AVERROR(ENOMEM);
8421 goto finish;
8422 }
8423 ret = avio_read(pb, extra_data, extra_data_size);
8424 if (ret != extra_data_size) {
8425 av_free(extra_data);
8426
8427 if (ret >= 0)
8429 goto finish;
8430 }
8431
8432 av_freep(&info->data); // malloc(0) may still allocate something.
8433 info->data = extra_data;
8434 info->data_size = extra_data_size;
8435
8436 for (int i = 0; i < st->codecpar->nb_coded_side_data; i++)
8438 old_side_data = &st->codecpar->coded_side_data[i];
8439
8440 // If there is existing initialization data, append the new record to it.
8441 if (old_side_data) {
8442 side_data = old_side_data->data;
8443 side_data_size = old_side_data->size;
8444 }
8445 if (!old_side_data || side_data != c->pssh_side_data)
8446 c->pssh_side_data_allocated = 0;
8447
8448 ret = av_encryption_init_info_append_side_data(&side_data, &side_data_size,
8449 &c->pssh_side_data_allocated, info);
8450 if (ret < 0)
8451 goto finish;
8452
8453 if (old_side_data) {
8454 old_side_data->data = side_data;
8455 old_side_data->size = side_data_size;
8459 side_data, side_data_size, 0)) {
8460 av_free(side_data);
8461 ret = AVERROR(ENOMEM);
8462 goto finish;
8463 }
8464 c->pssh_side_data = side_data;
8465
8466finish:
8468 return ret;
8469}
8470
8472{
8473 AVStream *st;
8474 MOVStreamContext *sc;
8475
8476 if (c->fc->nb_streams < 1)
8477 return 0;
8478 st = c->fc->streams[c->fc->nb_streams-1];
8479 sc = st->priv_data;
8480
8481 if (sc->pseudo_stream_id != 0) {
8482 av_log(c->fc, AV_LOG_ERROR, "schm boxes are only supported in first sample descriptor\n");
8483 return AVERROR_PATCHWELCOME;
8484 }
8485
8486 if (atom.size < 8)
8487 return AVERROR_INVALIDDATA;
8488
8489 avio_rb32(pb); /* version and flags */
8490
8491 if (!sc->cenc.default_encrypted_sample) {
8493 if (!sc->cenc.default_encrypted_sample) {
8494 return AVERROR(ENOMEM);
8495 }
8496 }
8497
8499 return 0;
8500}
8501
8503{
8504 AVStream *st;
8505 MOVStreamContext *sc;
8506 unsigned int version, pattern, is_protected, iv_size;
8507
8508 if (c->fc->nb_streams < 1)
8509 return 0;
8510 st = c->fc->streams[c->fc->nb_streams-1];
8511 sc = st->priv_data;
8512
8513 if (sc->pseudo_stream_id != 0) {
8514 av_log(c->fc, AV_LOG_ERROR, "tenc atom are only supported in first sample descriptor\n");
8515 return AVERROR_PATCHWELCOME;
8516 }
8517
8518 if (!sc->cenc.default_encrypted_sample) {
8520 if (!sc->cenc.default_encrypted_sample) {
8521 return AVERROR(ENOMEM);
8522 }
8523 }
8524
8525 if (atom.size < 20)
8526 return AVERROR_INVALIDDATA;
8527
8528 version = avio_r8(pb); /* version */
8529 avio_rb24(pb); /* flags */
8530
8531 avio_r8(pb); /* reserved */
8532 pattern = avio_r8(pb);
8533
8534 if (version > 0) {
8536 sc->cenc.default_encrypted_sample->skip_byte_block = pattern & 0xf;
8537 }
8538
8539 is_protected = avio_r8(pb);
8540 if (is_protected && !sc->cenc.encryption_index) {
8541 // The whole stream should be by-default encrypted.
8543 if (!sc->cenc.encryption_index)
8544 return AVERROR(ENOMEM);
8545 }
8546 iv_size = avio_r8(pb);
8547 if (iv_size != 0 && iv_size != 8 && iv_size != 16) {
8548 av_log(c->fc, AV_LOG_ERROR, "invalid per-sample IV size value\n");
8549 return AVERROR_INVALIDDATA;
8550 }
8551 sc->cenc.per_sample_iv_size = iv_size;
8552 if (avio_read(pb, sc->cenc.default_encrypted_sample->key_id, 16) != 16) {
8553 av_log(c->fc, AV_LOG_ERROR, "failed to read the default key ID\n");
8554 return AVERROR_INVALIDDATA;
8555 }
8556
8557 if (is_protected && !sc->cenc.per_sample_iv_size) {
8558 iv_size = avio_r8(pb);
8559 if (iv_size != 8 && iv_size != 16) {
8560 av_log(c->fc, AV_LOG_ERROR, "invalid default_constant_IV_size in tenc atom\n");
8561 return AVERROR_INVALIDDATA;
8562 }
8563
8564 if (avio_read(pb, sc->cenc.default_encrypted_sample->iv, iv_size) != iv_size) {
8565 av_log(c->fc, AV_LOG_ERROR, "failed to read the default IV\n");
8566 return AVERROR_INVALIDDATA;
8567 }
8568 }
8569
8570 return 0;
8571}
8572
8574{
8575 AVStream *st;
8576 int last, type, size, ret;
8577 uint8_t buf[4];
8578
8579 if (c->fc->nb_streams < 1)
8580 return 0;
8581 st = c->fc->streams[c->fc->nb_streams-1];
8582
8583 if ((uint64_t)atom.size > (1<<30) || atom.size < 42)
8584 return AVERROR_INVALIDDATA;
8585
8586 /* Check FlacSpecificBox version. */
8587 if (avio_r8(pb) != 0)
8588 return AVERROR_INVALIDDATA;
8589
8590 avio_rb24(pb); /* Flags */
8591
8592 if (avio_read(pb, buf, sizeof(buf)) != sizeof(buf)) {
8593 av_log(c->fc, AV_LOG_ERROR, "failed to read FLAC metadata block header\n");
8594 return pb->error < 0 ? pb->error : AVERROR_INVALIDDATA;
8595 }
8596 flac_parse_block_header(buf, &last, &type, &size);
8597
8599 av_log(c->fc, AV_LOG_ERROR, "STREAMINFO must be first FLACMetadataBlock\n");
8600 return AVERROR_INVALIDDATA;
8601 }
8602
8603 ret = ff_get_extradata(c->fc, st->codecpar, pb, size);
8604 if (ret < 0)
8605 return ret;
8606
8607 if (!last)
8608 av_log(c->fc, AV_LOG_WARNING, "non-STREAMINFO FLACMetadataBlock(s) ignored\n");
8609
8610 return 0;
8611}
8612
8614 AVDictionaryEntry *key_entry_hex;
8615 char kid_hex[16*2+1];
8616
8617 if (c->decryption_default_key && c->decryption_default_key_len != len) {
8618 av_log(c->fc, AV_LOG_ERROR, "invalid default decryption key length: got %d, expected %d\n", c->decryption_default_key_len, len);
8619 return -1;
8620 }
8621
8622 if (!c->decryption_keys) {
8623 av_assert0(c->decryption_default_key);
8624 memcpy(out, c->decryption_default_key, len);
8625 return 0;
8626 }
8627
8628 if (sample->key_id_size != 16) {
8629 av_log(c->fc, AV_LOG_ERROR, "invalid key ID size: got %u, expected 16\n", sample->key_id_size);
8630 return -1;
8631 }
8632
8633 ff_data_to_hex(kid_hex, sample->key_id, 16, 1);
8634 key_entry_hex = av_dict_get(c->decryption_keys, kid_hex, NULL, AV_DICT_DONT_STRDUP_KEY|AV_DICT_DONT_STRDUP_VAL);
8635 if (!key_entry_hex) {
8636 if (!c->decryption_default_key) {
8637 av_log(c->fc, AV_LOG_ERROR, "unable to find KID %s\n", kid_hex);
8638 return -1;
8639 }
8640 memcpy(out, c->decryption_default_key, len);
8641 return 0;
8642 }
8643 if (strlen(key_entry_hex->value) != len*2) {
8644 return -1;
8645 }
8646 ff_hex_to_data(out, key_entry_hex->value);
8647 return 0;
8648}
8649
8651{
8652 int i, ret;
8653 int bytes_of_protected_data;
8654 uint8_t decryption_key[AES_CTR_KEY_SIZE];
8655
8656 if (!sc->cenc.aes_ctr) {
8657 ret = get_key_from_kid(decryption_key, sizeof(decryption_key), c, sample);
8658 if (ret < 0) {
8659 return ret;
8660 }
8661
8662 /* initialize the cipher */
8664 if (!sc->cenc.aes_ctr) {
8665 return AVERROR(ENOMEM);
8666 }
8667
8668 ret = av_aes_ctr_init(sc->cenc.aes_ctr, decryption_key);
8669 if (ret < 0) {
8670 return ret;
8671 }
8672 }
8673
8675
8676 if (!sample->subsample_count) {
8677 /* decrypt the whole packet */
8678 av_aes_ctr_crypt(sc->cenc.aes_ctr, input, input, size);
8679 return 0;
8680 }
8681
8682 for (i = 0; i < sample->subsample_count; i++) {
8683 if (sample->subsamples[i].bytes_of_clear_data + (int64_t)sample->subsamples[i].bytes_of_protected_data > size) {
8684 av_log(c->fc, AV_LOG_ERROR, "subsample size exceeds the packet size left\n");
8685 return AVERROR_INVALIDDATA;
8686 }
8687
8688 /* skip the clear bytes */
8689 input += sample->subsamples[i].bytes_of_clear_data;
8690 size -= sample->subsamples[i].bytes_of_clear_data;
8691
8692 /* decrypt the encrypted bytes */
8693
8694 bytes_of_protected_data = sample->subsamples[i].bytes_of_protected_data;
8695 av_aes_ctr_crypt(sc->cenc.aes_ctr, input, input, bytes_of_protected_data);
8696
8697 input += bytes_of_protected_data;
8698 size -= bytes_of_protected_data;
8699 }
8700
8701 if (size > 0) {
8702 av_log(c->fc, AV_LOG_ERROR, "leftover packet bytes after subsample processing\n");
8703 return AVERROR_INVALIDDATA;
8704 }
8705
8706 return 0;
8707}
8708
8710{
8711 int i, ret;
8712 int num_of_encrypted_blocks;
8713 uint8_t iv[16];
8714 uint8_t decryption_key[16];
8715
8716 if (!sc->cenc.aes_ctx) {
8717 ret = get_key_from_kid(decryption_key, sizeof(decryption_key), c, sample);
8718 if (ret < 0) {
8719 return ret;
8720 }
8721
8722 /* initialize the cipher */
8723 sc->cenc.aes_ctx = av_aes_alloc();
8724 if (!sc->cenc.aes_ctx) {
8725 return AVERROR(ENOMEM);
8726 }
8727
8728 ret = av_aes_init(sc->cenc.aes_ctx, decryption_key, 16 * 8, 1);
8729 if (ret < 0) {
8730 return ret;
8731 }
8732 }
8733
8734 memcpy(iv, sample->iv, 16);
8735
8736 /* whole-block full sample encryption */
8737 if (!sample->subsample_count) {
8738 /* decrypt the whole packet */
8739 av_aes_crypt(sc->cenc.aes_ctx, input, input, size/16, iv, 1);
8740 return 0;
8741 }
8742
8743 for (i = 0; i < sample->subsample_count; i++) {
8744 if (sample->subsamples[i].bytes_of_clear_data + (int64_t)sample->subsamples[i].bytes_of_protected_data > size) {
8745 av_log(c->fc, AV_LOG_ERROR, "subsample size exceeds the packet size left\n");
8746 return AVERROR_INVALIDDATA;
8747 }
8748
8749 if (sample->subsamples[i].bytes_of_protected_data % 16) {
8750 av_log(c->fc, AV_LOG_ERROR, "subsample BytesOfProtectedData is not a multiple of 16\n");
8751 return AVERROR_INVALIDDATA;
8752 }
8753
8754 /* skip the clear bytes */
8755 input += sample->subsamples[i].bytes_of_clear_data;
8756 size -= sample->subsamples[i].bytes_of_clear_data;
8757
8758 /* decrypt the encrypted bytes */
8759 num_of_encrypted_blocks = sample->subsamples[i].bytes_of_protected_data/16;
8760 if (num_of_encrypted_blocks > 0) {
8761 av_aes_crypt(sc->cenc.aes_ctx, input, input, num_of_encrypted_blocks, iv, 1);
8762 }
8763 input += sample->subsamples[i].bytes_of_protected_data;
8764 size -= sample->subsamples[i].bytes_of_protected_data;
8765 }
8766
8767 if (size > 0) {
8768 av_log(c->fc, AV_LOG_ERROR, "leftover packet bytes after subsample processing\n");
8769 return AVERROR_INVALIDDATA;
8770 }
8771
8772 return 0;
8773}
8774
8776{
8777 int i, ret, rem_bytes;
8778 uint8_t *data;
8779 uint8_t decryption_key[AES_CTR_KEY_SIZE];
8780
8781 if (!sc->cenc.aes_ctr) {
8782 ret = get_key_from_kid(decryption_key, sizeof(decryption_key), c, sample);
8783 if (ret < 0) {
8784 return ret;
8785 }
8786
8787 /* initialize the cipher */
8789 if (!sc->cenc.aes_ctr) {
8790 return AVERROR(ENOMEM);
8791 }
8792
8793 ret = av_aes_ctr_init(sc->cenc.aes_ctr, decryption_key);
8794 if (ret < 0) {
8795 return ret;
8796 }
8797 }
8798
8800
8801 /* whole-block full sample encryption */
8802 if (!sample->subsample_count) {
8803 /* decrypt the whole packet */
8804 av_aes_ctr_crypt(sc->cenc.aes_ctr, input, input, size);
8805 return 0;
8806 } else if (!sample->crypt_byte_block && !sample->skip_byte_block) {
8807 av_log(c->fc, AV_LOG_ERROR, "pattern encryption is not present in 'cens' scheme\n");
8808 return AVERROR_INVALIDDATA;
8809 }
8810
8811 for (i = 0; i < sample->subsample_count; i++) {
8812 if (sample->subsamples[i].bytes_of_clear_data + (int64_t)sample->subsamples[i].bytes_of_protected_data > size) {
8813 av_log(c->fc, AV_LOG_ERROR, "subsample size exceeds the packet size left\n");
8814 return AVERROR_INVALIDDATA;
8815 }
8816
8817 /* skip the clear bytes */
8818 input += sample->subsamples[i].bytes_of_clear_data;
8819 size -= sample->subsamples[i].bytes_of_clear_data;
8820
8821 /* decrypt the encrypted bytes */
8822 data = input;
8823 rem_bytes = sample->subsamples[i].bytes_of_protected_data;
8824 while (rem_bytes > 0) {
8825 if (rem_bytes < 16*sample->crypt_byte_block) {
8826 break;
8827 }
8828 av_aes_ctr_crypt(sc->cenc.aes_ctr, data, data, 16*sample->crypt_byte_block);
8829 data += 16*sample->crypt_byte_block;
8830 rem_bytes -= 16*sample->crypt_byte_block;
8831 data += FFMIN(16*sample->skip_byte_block, rem_bytes);
8832 rem_bytes -= FFMIN(16*sample->skip_byte_block, rem_bytes);
8833 }
8834 input += sample->subsamples[i].bytes_of_protected_data;
8835 size -= sample->subsamples[i].bytes_of_protected_data;
8836 }
8837
8838 if (size > 0) {
8839 av_log(c->fc, AV_LOG_ERROR, "leftover packet bytes after subsample processing\n");
8840 return AVERROR_INVALIDDATA;
8841 }
8842
8843 return 0;
8844}
8845
8847{
8848 int i, ret, rem_bytes;
8849 uint8_t iv[16];
8850 uint8_t *data;
8851 uint8_t decryption_key[16];
8852
8853 if (!sc->cenc.aes_ctx) {
8854 ret = get_key_from_kid(decryption_key, sizeof(decryption_key), c, sample);
8855 if (ret < 0) {
8856 return ret;
8857 }
8858
8859 /* initialize the cipher */
8860 sc->cenc.aes_ctx = av_aes_alloc();
8861 if (!sc->cenc.aes_ctx) {
8862 return AVERROR(ENOMEM);
8863 }
8864
8865 ret = av_aes_init(sc->cenc.aes_ctx, decryption_key, 16 * 8, 1);
8866 if (ret < 0) {
8867 return ret;
8868 }
8869 }
8870
8871 /* whole-block full sample encryption */
8872 if (!sample->subsample_count) {
8873 /* decrypt the whole packet */
8874 memcpy(iv, sample->iv, 16);
8875 av_aes_crypt(sc->cenc.aes_ctx, input, input, size/16, iv, 1);
8876 return 0;
8877 } else if (!sample->crypt_byte_block && !sample->skip_byte_block) {
8878 av_log(c->fc, AV_LOG_ERROR, "pattern encryption is not present in 'cbcs' scheme\n");
8879 return AVERROR_INVALIDDATA;
8880 }
8881
8882 for (i = 0; i < sample->subsample_count; i++) {
8883 if (sample->subsamples[i].bytes_of_clear_data + (int64_t)sample->subsamples[i].bytes_of_protected_data > size) {
8884 av_log(c->fc, AV_LOG_ERROR, "subsample size exceeds the packet size left\n");
8885 return AVERROR_INVALIDDATA;
8886 }
8887
8888 /* skip the clear bytes */
8889 input += sample->subsamples[i].bytes_of_clear_data;
8890 size -= sample->subsamples[i].bytes_of_clear_data;
8891
8892 /* decrypt the encrypted bytes */
8893 memcpy(iv, sample->iv, 16);
8894 data = input;
8895 rem_bytes = sample->subsamples[i].bytes_of_protected_data;
8896 while (rem_bytes > 0) {
8897 if (rem_bytes < 16*sample->crypt_byte_block) {
8898 break;
8899 }
8900 av_aes_crypt(sc->cenc.aes_ctx, data, data, sample->crypt_byte_block, iv, 1);
8901 data += 16*sample->crypt_byte_block;
8902 rem_bytes -= 16*sample->crypt_byte_block;
8903 data += FFMIN(16*sample->skip_byte_block, rem_bytes);
8904 rem_bytes -= FFMIN(16*sample->skip_byte_block, rem_bytes);
8905 }
8906 input += sample->subsamples[i].bytes_of_protected_data;
8907 size -= sample->subsamples[i].bytes_of_protected_data;
8908 }
8909
8910 if (size > 0) {
8911 av_log(c->fc, AV_LOG_ERROR, "leftover packet bytes after subsample processing\n");
8912 return AVERROR_INVALIDDATA;
8913 }
8914
8915 return 0;
8916}
8917
8918static int cenc_decrypt(MOVContext *c, MOVStreamContext *sc, AVEncryptionInfo *sample, uint8_t *input, int size)
8919{
8920 if (sample->scheme == MKBETAG('c','e','n','c') && !sample->crypt_byte_block && !sample->skip_byte_block) {
8921 return cenc_scheme_decrypt(c, sc, sample, input, size);
8922 } else if (sample->scheme == MKBETAG('c','b','c','1') && !sample->crypt_byte_block && !sample->skip_byte_block) {
8923 return cbc1_scheme_decrypt(c, sc, sample, input, size);
8924 } else if (sample->scheme == MKBETAG('c','e','n','s')) {
8925 return cens_scheme_decrypt(c, sc, sample, input, size);
8926 } else if (sample->scheme == MKBETAG('c','b','c','s')) {
8927 return cbcs_scheme_decrypt(c, sc, sample, input, size);
8928 } else {
8929 av_log(c->fc, AV_LOG_ERROR, "invalid encryption scheme\n");
8930 return AVERROR_INVALIDDATA;
8931 }
8932}
8933
8935{
8936 int current = frag_index->current;
8937
8938 if (!frag_index->nb_items)
8939 return NULL;
8940
8941 // Check frag_index->current is the right one for pkt. It can out of sync.
8942 if (current >= 0 && current < frag_index->nb_items) {
8943 if (frag_index->item[current].moof_offset < pkt->pos &&
8944 (current + 1 == frag_index->nb_items ||
8945 frag_index->item[current + 1].moof_offset > pkt->pos))
8946 return get_frag_stream_info(frag_index, current, id);
8947 }
8948
8949
8950 for (int i = 0; i < frag_index->nb_items; i++) {
8951 if (frag_index->item[i].moof_offset > pkt->pos)
8952 break;
8953 current = i;
8954 }
8955 frag_index->current = current;
8956 return get_frag_stream_info(frag_index, current, id);
8957}
8958
8959static int cenc_filter(MOVContext *mov, AVStream* st, MOVStreamContext *sc, AVPacket *pkt, int current_index)
8960{
8961 MOVFragmentStreamInfo *frag_stream_info;
8962 MOVEncryptionIndex *encryption_index;
8963 AVEncryptionInfo *encrypted_sample;
8964 int encrypted_index, ret;
8965
8966 frag_stream_info = get_frag_stream_info_from_pkt(&mov->frag_index, pkt, sc->id);
8967 encrypted_index = current_index;
8968 encryption_index = NULL;
8969 if (frag_stream_info) {
8970 // Note this only supports encryption info in the first sample descriptor.
8971 if (frag_stream_info->stsd_id == 1) {
8972 if (frag_stream_info->encryption_index) {
8973 encrypted_index = current_index - frag_stream_info->index_base;
8974 encryption_index = frag_stream_info->encryption_index;
8975 } else {
8976 encryption_index = sc->cenc.encryption_index;
8977 }
8978 }
8979 } else {
8980 encryption_index = sc->cenc.encryption_index;
8981 }
8982
8983 if (encryption_index) {
8984 if (encryption_index->auxiliary_info_sample_count &&
8985 !encryption_index->nb_encrypted_samples) {
8986 av_log(mov->fc, AV_LOG_ERROR, "saiz atom found without saio\n");
8987 return AVERROR_INVALIDDATA;
8988 }
8989 if (encryption_index->auxiliary_offsets_count &&
8990 !encryption_index->nb_encrypted_samples) {
8991 av_log(mov->fc, AV_LOG_ERROR, "saio atom found without saiz\n");
8992 return AVERROR_INVALIDDATA;
8993 }
8994
8995 encrypted_sample = NULL;
8996 if (!encryption_index->nb_encrypted_samples) {
8997 // Full-sample encryption with default settings.
8998 encrypted_sample = sc->cenc.default_encrypted_sample;
8999 } else if (encrypted_index >= 0 && encrypted_index < encryption_index->nb_encrypted_samples) {
9000 // Per-sample setting override.
9001 encrypted_sample = encryption_index->encrypted_samples[encrypted_index];
9002 if (!encrypted_sample) {
9003 encrypted_sample = sc->cenc.default_encrypted_sample;
9004 }
9005 }
9006
9007 if (!encrypted_sample) {
9008 av_log(mov->fc, AV_LOG_ERROR, "Incorrect number of samples in encryption info\n");
9009 return AVERROR_INVALIDDATA;
9010 }
9011
9012 if (mov->decryption_keys || mov->decryption_default_key) {
9013 return cenc_decrypt(mov, sc, encrypted_sample, pkt->data, pkt->size);
9014 } else {
9015 size_t size;
9016 uint8_t *side_data = av_encryption_info_add_side_data(encrypted_sample, &size);
9017 if (!side_data)
9018 return AVERROR(ENOMEM);
9020 if (ret < 0)
9021 av_free(side_data);
9022 return ret;
9023 }
9024 }
9025
9026 return 0;
9027}
9028
9030{
9031 const int OPUS_SEEK_PREROLL_MS = 80;
9032 int ret;
9033 AVStream *st;
9034 size_t size;
9035 uint16_t pre_skip;
9036
9037 if (c->fc->nb_streams < 1)
9038 return 0;
9039 st = c->fc->streams[c->fc->nb_streams-1];
9040
9041 if ((uint64_t)atom.size > (1<<30) || atom.size < 11 || st->codecpar->extradata)
9042 return AVERROR_INVALIDDATA;
9043
9044 /* Check OpusSpecificBox version. */
9045 if (avio_r8(pb) != 0) {
9046 av_log(c->fc, AV_LOG_ERROR, "unsupported OpusSpecificBox version\n");
9047 return AVERROR_INVALIDDATA;
9048 }
9049
9050 /* OpusSpecificBox size plus magic for Ogg OpusHead header. */
9051 size = atom.size + 8;
9052
9053 if ((ret = ff_alloc_extradata(st->codecpar, size)) < 0)
9054 return ret;
9055
9056 AV_WL32A(st->codecpar->extradata, MKTAG('O','p','u','s'));
9057 AV_WL32A(st->codecpar->extradata + 4, MKTAG('H','e','a','d'));
9058 AV_WB8(st->codecpar->extradata + 8, 1); /* OpusHead version */
9059 if ((ret = ffio_read_size(pb, st->codecpar->extradata + 9, size - 9)) < 0) {
9061 st->codecpar->extradata_size = 0;
9062 return ret;
9063 }
9064
9065 /* OpusSpecificBox is stored in big-endian, but OpusHead is
9066 little-endian; aside from the preceding magic and version they're
9067 otherwise currently identical. Data after output gain at offset 16
9068 doesn't need to be bytewapped. */
9069 pre_skip = AV_RB16A(st->codecpar->extradata + 10);
9070 AV_WL16A(st->codecpar->extradata + 10, pre_skip);
9071 AV_WL32A(st->codecpar->extradata + 12, AV_RB32A(st->codecpar->extradata + 12));
9072 AV_WL16A(st->codecpar->extradata + 16, AV_RB16A(st->codecpar->extradata + 16));
9073
9074 st->codecpar->initial_padding = pre_skip;
9076 (AVRational){1, 1000},
9077 (AVRational){1, 48000});
9078
9079 return 0;
9080}
9081
9083{
9084 AVStream *st;
9085 unsigned format_info;
9086 int channel_assignment, channel_assignment1, channel_assignment2;
9087 int ratebits;
9088 uint64_t chmask;
9089
9090 if (c->fc->nb_streams < 1)
9091 return 0;
9092 st = c->fc->streams[c->fc->nb_streams-1];
9093
9094 if (atom.size < 10)
9095 return AVERROR_INVALIDDATA;
9096
9097 format_info = avio_rb32(pb);
9098
9099 ratebits = (format_info >> 28) & 0xF;
9100 channel_assignment1 = (format_info >> 15) & 0x1F;
9101 channel_assignment2 = format_info & 0x1FFF;
9102 if (channel_assignment2)
9103 channel_assignment = channel_assignment2;
9104 else
9105 channel_assignment = channel_assignment1;
9106
9107 st->codecpar->frame_size = 40 << (ratebits & 0x7);
9108 st->codecpar->sample_rate = mlp_samplerate(ratebits);
9109
9111 chmask = truehd_layout(channel_assignment);
9113
9114 return 0;
9115}
9116
9118{
9119 AVStream *st;
9120 uint8_t buf[ISOM_DVCC_DVVC_SIZE];
9121 int ret;
9122 int64_t read_size = atom.size;
9123
9124 if (c->fc->nb_streams < 1)
9125 return 0;
9126 st = c->fc->streams[c->fc->nb_streams-1];
9127
9128 // At most 24 bytes
9129 read_size = FFMIN(read_size, ISOM_DVCC_DVVC_SIZE);
9130
9131 if ((ret = ffio_read_size(pb, buf, read_size)) < 0)
9132 return ret;
9133
9134 return ff_isom_parse_dvcc_dvvc(c->fc, st, buf, read_size);
9135}
9136
9138{
9139 AVStream *st;
9140 AVPacketSideData *sd;
9141 int ret;
9142
9143 if (c->fc->nb_streams < 1)
9144 return 0;
9145 st = c->fc->streams[c->fc->nb_streams - 1];
9146
9147 if (atom.size < 23 || atom.size > INT_MAX - AV_INPUT_BUFFER_PADDING_SIZE)
9148 return AVERROR_INVALIDDATA;
9149
9153 atom.size, 0);
9154 if (!sd)
9155 return AVERROR(ENOMEM);
9156
9157 ret = ffio_read_size(pb, sd->data, atom.size);
9158 if (ret < 0)
9159 return ret;
9160
9161 return 0;
9162}
9163
9165{
9166 AVStream *st;
9167 uint8_t *buf;
9168 int ret, old_size, num_arrays;
9169
9170 if (c->fc->nb_streams < 1)
9171 return 0;
9172 st = c->fc->streams[c->fc->nb_streams-1];
9173
9174 if (!st->codecpar->extradata_size)
9175 // TODO: handle lhvC when present before hvcC
9176 return 0;
9177
9178 if (atom.size < 6 || st->codecpar->extradata_size < 23 ||
9179 atom.size > INT_MAX - AV_INPUT_BUFFER_PADDING_SIZE) {
9180 return AVERROR_INVALIDDATA;
9181 }
9182
9184 if (!buf)
9185 return AVERROR(ENOMEM);
9186 memset(buf + atom.size, 0, AV_INPUT_BUFFER_PADDING_SIZE);
9187
9188 ret = ffio_read_size(pb, buf, atom.size);
9189 if (ret < 0) {
9190 av_free(buf);
9191 av_log(c->fc, AV_LOG_WARNING, "lhvC atom truncated\n");
9192 return 0;
9193 }
9194
9195 num_arrays = buf[5];
9196 old_size = st->codecpar->extradata_size;
9197 atom.size -= 8 /* account for mov_realloc_extradata offsetting */
9198 + 6 /* lhvC bytes before the arrays*/;
9199
9200 ret = mov_realloc_extradata(st->codecpar, atom);
9201 if (ret < 0) {
9202 av_free(buf);
9203 return ret;
9204 }
9205
9206 st->codecpar->extradata[22] += num_arrays;
9207 memcpy(st->codecpar->extradata + old_size, buf + 6, atom.size + 8);
9208
9210
9211 av_free(buf);
9212 return 0;
9213}
9214
9216{
9217 AVFormatContext *ctx = c->fc;
9218 AVStream *st = NULL;
9219 AVBPrint scheme_buf, value_buf;
9220 int64_t scheme_str_len = 0, value_str_len = 0;
9221 int version, flags, ret = AVERROR_BUG;
9222 int64_t size = atom.size;
9223
9224 if (atom.size < 6)
9225 // 4 bytes for version + flags, 2x 1 byte for null
9226 return AVERROR_INVALIDDATA;
9227
9228 if (c->fc->nb_streams < 1)
9229 return 0;
9230 st = c->fc->streams[c->fc->nb_streams-1];
9231
9232 version = avio_r8(pb);
9233 flags = avio_rb24(pb);
9234 size -= 4;
9235
9236 if (version != 0 || flags != 0) {
9238 "Unsupported 'kind' box with version %d, flags: %x",
9239 version, flags);
9240 return AVERROR_INVALIDDATA;
9241 }
9242
9245
9246 if ((scheme_str_len = ff_read_string_to_bprint_overwrite(pb, &scheme_buf,
9247 size)) < 0) {
9248 ret = scheme_str_len;
9249 goto cleanup;
9250 }
9251
9252 if (scheme_str_len + 1 >= size) {
9253 // we need to have another string, even if nullptr.
9254 // we check with + 1 since we expect that if size was not hit,
9255 // an additional null was read.
9257 goto cleanup;
9258 }
9259
9260 size -= scheme_str_len + 1;
9261
9262 if ((value_str_len = ff_read_string_to_bprint_overwrite(pb, &value_buf,
9263 size)) < 0) {
9264 ret = value_str_len;
9265 goto cleanup;
9266 }
9267
9268 if (value_str_len == size) {
9269 // in case of no trailing null, box is not valid.
9271 goto cleanup;
9272 }
9273
9275 "%s stream %d KindBox(scheme: %s, value: %s)\n",
9277 st->index,
9278 scheme_buf.str, value_buf.str);
9279
9280 for (int i = 0; ff_mov_track_kind_table[i].scheme_uri; i++) {
9282 if (!av_strstart(scheme_buf.str, map.scheme_uri, NULL))
9283 continue;
9284
9285 for (int j = 0; map.value_maps[j].disposition; j++) {
9286 const struct MP4TrackKindValueMapping value_map = map.value_maps[j];
9287 if (!av_strstart(value_buf.str, value_map.value, NULL))
9288 continue;
9289
9290 st->disposition |= value_map.disposition;
9291 }
9292 }
9293
9294 ret = 0;
9295
9296cleanup:
9297
9298 av_bprint_finalize(&scheme_buf, NULL);
9299 av_bprint_finalize(&value_buf, NULL);
9300
9301 return ret;
9302}
9303
9305{
9306 AVStream *st;
9307 AVChannelLayout ch_layout = { 0 };
9308 int ret, i, version, type;
9309 int ambisonic_order, channel_order, normalization, channel_count;
9310 int ambi_channels, non_diegetic_channels;
9311
9312 if (c->fc->nb_streams < 1)
9313 return 0;
9314
9315 st = c->fc->streams[c->fc->nb_streams - 1];
9316
9317 if (atom.size < 16) {
9318 av_log(c->fc, AV_LOG_ERROR, "SA3D audio box too small\n");
9319 return AVERROR_INVALIDDATA;
9320 }
9321
9322 version = avio_r8(pb);
9323 if (version) {
9324 av_log(c->fc, AV_LOG_WARNING, "Unsupported SA3D box version %d\n", version);
9325 return 0;
9326 }
9327
9328 type = avio_r8(pb);
9329 if (type & 0x7f) {
9330 av_log(c->fc, AV_LOG_WARNING,
9331 "Unsupported ambisonic type %d\n", type & 0x7f);
9332 return 0;
9333 }
9334 non_diegetic_channels = (type >> 7) * 2; // head_locked_stereo
9335
9336 ambisonic_order = avio_rb32(pb);
9337
9338 channel_order = avio_r8(pb);
9339 if (channel_order) {
9340 av_log(c->fc, AV_LOG_WARNING,
9341 "Unsupported channel_order %d\n", channel_order);
9342 return 0;
9343 }
9344
9345 normalization = avio_r8(pb);
9346 if (normalization) {
9347 av_log(c->fc, AV_LOG_WARNING,
9348 "Unsupported normalization %d\n", normalization);
9349 return 0;
9350 }
9351
9352 channel_count = avio_rb32(pb);
9353 if (ambisonic_order < 0 || ambisonic_order > 31 ||
9354 channel_count != ((ambisonic_order + 1LL) * (ambisonic_order + 1LL) +
9355 non_diegetic_channels)) {
9356 av_log(c->fc, AV_LOG_ERROR,
9357 "Invalid number of channels (%d / %d)\n",
9358 channel_count, ambisonic_order);
9359 return 0;
9360 }
9361 ambi_channels = channel_count - non_diegetic_channels;
9362
9363 ret = av_channel_layout_custom_init(&ch_layout, channel_count);
9364 if (ret < 0)
9365 return 0;
9366
9367 for (i = 0; i < channel_count; i++) {
9368 unsigned channel = avio_rb32(pb);
9369
9370 if (channel >= channel_count) {
9371 av_log(c->fc, AV_LOG_ERROR, "Invalid channel index (%d / %d)\n",
9372 channel, ambisonic_order);
9373 av_channel_layout_uninit(&ch_layout);
9374 return 0;
9375 }
9376 if (channel >= ambi_channels)
9377 ch_layout.u.map[i].id = channel - ambi_channels;
9378 else
9379 ch_layout.u.map[i].id = AV_CHAN_AMBISONIC_BASE + channel;
9380 }
9381
9383 if (ret < 0) {
9384 av_channel_layout_uninit(&ch_layout);
9385 return 0;
9386 }
9387
9389 st->codecpar->ch_layout = ch_layout;
9390
9391 return 0;
9392}
9393
9395{
9396 AVStream *st;
9397 int version;
9398
9399 if (c->fc->nb_streams < 1)
9400 return 0;
9401
9402 st = c->fc->streams[c->fc->nb_streams - 1];
9403
9404 if (atom.size < 5) {
9405 av_log(c->fc, AV_LOG_ERROR, "Empty SAND audio box\n");
9406 return AVERROR_INVALIDDATA;
9407 }
9408
9409 version = avio_r8(pb);
9410 if (version) {
9411 av_log(c->fc, AV_LOG_WARNING, "Unsupported SAND box version %d\n", version);
9412 return 0;
9413 }
9414
9416
9417 return 0;
9418}
9419
9420static int rb_size(AVIOContext *pb, int64_t *value, int size)
9421{
9422 if (size == 0)
9423 *value = 0;
9424 else if (size == 1)
9425 *value = avio_r8(pb);
9426 else if (size == 2)
9427 *value = avio_rb16(pb);
9428 else if (size == 4)
9429 *value = avio_rb32(pb);
9430 else if (size == 8) {
9431 *value = avio_rb64(pb);
9432 if (*value < 0)
9433 return -1;
9434 } else
9435 return -1;
9436 return size;
9437}
9438
9440{
9441 AVBPrint aux_type;
9442 HEIFItem *item;
9443
9444 avio_r8(pb); /* version */
9445 avio_rb24(pb); /* flags */
9446
9448 ff_read_string_to_bprint_overwrite(pb, &aux_type, atom.size - 4);
9449
9450 av_log(c->fc, AV_LOG_TRACE, "auxC: item_id %d, aux_type %s\n",
9451 c->cur_item_id, aux_type.str);
9452
9453 item = get_heif_item(c, c->cur_item_id);
9454 if (item) {
9455 if ((av_stristr(aux_type.str, "hdrgainmap")))
9456 item->is_gainmap = 1;
9457 else if (strstr(aux_type.str, "urn:mpeg:hevc:2015:auxid:1") ||
9458 strstr(aux_type.str, "urn:mpeg:mpegB:cicp:systems:auxiliary:alpha"))
9459 item->is_alpha = 1;
9460 }
9461 return 0;
9462}
9463
9465{
9466 avio_rb32(pb); // version & flags.
9467 c->primary_item_id = avio_rb16(pb);
9468 av_log(c->fc, AV_LOG_TRACE, "pitm: primary_item_id %d\n", c->primary_item_id);
9469 return atom.size;
9470}
9471
9473{
9474 c->idat_offset = avio_tell(pb);
9475 return 0;
9476}
9477
9479{
9480 HEIFItem **heif_item;
9481 int version, offset_size, length_size, base_offset_size, index_size;
9482 int item_count, extent_count;
9483 int64_t base_offset, extent_offset, extent_length;
9484 uint8_t value;
9485
9486 if (c->found_iloc) {
9487 av_log(c->fc, AV_LOG_INFO, "Duplicate iloc box found\n");
9488 return 0;
9489 }
9490
9491 version = avio_r8(pb);
9492 avio_rb24(pb); // flags.
9493
9494 value = avio_r8(pb);
9495 offset_size = (value >> 4) & 0xF;
9496 length_size = value & 0xF;
9497 value = avio_r8(pb);
9498 base_offset_size = (value >> 4) & 0xF;
9499 index_size = !version ? 0 : (value & 0xF);
9500 if (index_size) {
9501 avpriv_report_missing_feature(c->fc, "iloc: index_size != 0");
9502 return AVERROR_PATCHWELCOME;
9503 }
9504 item_count = (version < 2) ? avio_rb16(pb) : avio_rb32(pb);
9505
9506 if (item_count > atom.size)
9507 return AVERROR_INVALIDDATA;
9508
9509 heif_item = av_realloc_array(c->heif_item, FFMAX(item_count, c->nb_heif_item), sizeof(*c->heif_item));
9510 if (!heif_item)
9511 return AVERROR(ENOMEM);
9512 c->heif_item = heif_item;
9513 if (item_count > c->nb_heif_item)
9514 memset(&c->heif_item[c->nb_heif_item], 0,
9515 sizeof(*c->heif_item) * (item_count - c->nb_heif_item));
9516 c->nb_heif_item = FFMAX(c->nb_heif_item, item_count);
9517
9518 av_log(c->fc, AV_LOG_TRACE, "iloc: item_count %d\n", item_count);
9519 for (int i = 0; i < item_count; i++) {
9520 HEIFItem *item = NULL;
9521 int item_id = (version < 2) ? avio_rb16(pb) : avio_rb32(pb);
9522 int offset_type = (version > 0) ? avio_rb16(pb) & 0xf : 0;
9523 int j;
9524
9525 if (avio_feof(pb))
9526 return AVERROR_INVALIDDATA;
9527 if (offset_type > 1) {
9528 avpriv_report_missing_feature(c->fc, "iloc offset type %d", offset_type);
9529 return AVERROR_PATCHWELCOME;
9530 }
9531
9532 avio_rb16(pb); // data_reference_index.
9533 if (rb_size(pb, &base_offset, base_offset_size) < 0)
9534 return AVERROR_INVALIDDATA;
9535 extent_count = avio_rb16(pb);
9536 if (extent_count > 1) {
9537 // For still AVIF images, we only support one extent item.
9538 avpriv_report_missing_feature(c->fc, "iloc: extent_count > 1");
9539 return AVERROR_PATCHWELCOME;
9540 }
9541
9542 if (rb_size(pb, &extent_offset, offset_size) < 0 ||
9543 rb_size(pb, &extent_length, length_size) < 0 ||
9544 base_offset > INT64_MAX - extent_offset)
9545 return AVERROR_INVALIDDATA;
9546
9547 for (j = 0; j < c->nb_heif_item; j++) {
9548 item = c->heif_item[j];
9549 if (!item)
9550 item = c->heif_item[j] = av_mallocz(sizeof(*item));
9551 else if (item->item_id != item_id)
9552 continue;
9553 break;
9554 }
9555 if (!item)
9556 return AVERROR(ENOMEM);
9557 if (j == c->nb_heif_item)
9558 return AVERROR_INVALIDDATA;
9559
9560 item->item_id = item_id;
9561
9562 if (offset_type == 1)
9563 item->is_idat_relative = 1;
9564 item->extent_length = extent_length;
9565 item->extent_offset = base_offset + extent_offset;
9566 av_log(c->fc, AV_LOG_TRACE, "iloc: item_idx %d, item->item_id %d, offset_type %d, "
9567 "extent_offset %"PRId64", extent_length %"PRId64"\n",
9568 i, item->item_id, offset_type, item->extent_offset, item->extent_length);
9569 }
9570
9571 c->found_iloc = 1;
9572 return atom.size;
9573}
9574
9576{
9577 HEIFItem *item = NULL;
9578 AVBPrint item_name;
9579 int64_t size = atom.size;
9580 uint32_t item_type;
9581 int item_id;
9582 int i, version, flags, ret;
9583
9584 version = avio_r8(pb);
9585 flags = avio_rb24(pb);
9586 size -= 4;
9587 if (size < 0)
9588 return AVERROR_INVALIDDATA;
9589
9590 if (version < 2) {
9591 avpriv_report_missing_feature(c->fc, "infe version < 2");
9592 avio_skip(pb, size);
9593 return 1;
9594 }
9595
9596 item_id = version > 2 ? avio_rb32(pb) : avio_rb16(pb);
9597 avio_rb16(pb); // item_protection_index
9598 item_type = avio_rl32(pb);
9599 size -= 8;
9600 if (size < 1)
9601 return AVERROR_INVALIDDATA;
9602
9605 if (ret < 0) {
9607 return ret;
9608 }
9609
9610 av_log(c->fc, AV_LOG_TRACE, "infe: item_id %d, item_type %s, item_name %s\n",
9611 item_id, av_fourcc2str(item_type), item_name.str);
9612
9613 size -= ret + 1;
9614 if (size > 0)
9615 avio_skip(pb, size);
9616
9617 for (i = 0; i < c->nb_heif_item; i++) {
9618 item = c->heif_item[i];
9619 if (!item)
9620 item = c->heif_item[i] = av_mallocz(sizeof(*item));
9621 else if (item->item_id != item_id)
9622 continue;
9623 break;
9624 }
9625 if (!item) {
9627 return AVERROR(ENOMEM);
9628 }
9629 if (i == c->nb_heif_item) {
9631 return AVERROR_INVALIDDATA;
9632 }
9633
9634 av_freep(&item->name);
9636 item->item_id = item_id;
9637 item->type = item_type;
9638 item->flags = flags;
9639
9640 switch (item_type) {
9641 case MKTAG('a','v','0','1'):
9642 case MKTAG('j','p','e','g'):
9643 case MKTAG('h','v','c','1'):
9644 ret = heif_add_stream(c, item);
9645 if (ret < 0)
9646 return ret;
9647 break;
9648 }
9649
9650 return 0;
9651}
9652
9654{
9655 HEIFItem **heif_item;
9656 int entry_count;
9657 int version, got_stream = 0, ret, i;
9658
9659 if (c->found_iinf) {
9660 av_log(c->fc, AV_LOG_WARNING, "Duplicate iinf box found\n");
9661 return 0;
9662 }
9663
9664 version = avio_r8(pb);
9665 avio_rb24(pb); // flags.
9666 entry_count = version ? avio_rb32(pb) : avio_rb16(pb);
9667
9668 if (entry_count > atom.size)
9669 return AVERROR_INVALIDDATA;
9670
9671 /* account for the version/flags/entry_count fields already consumed,
9672 * so the per-entry loop below can bound each infe box by what is
9673 * actually left in this iinf box, the same way mov_read_iprp() bounds
9674 * ipco/ipma entries by the remaining iprp size. */
9675 atom.size -= version ? 8 : 6;
9676 if (atom.size < 0)
9677 return AVERROR_INVALIDDATA;
9678
9679 heif_item = av_realloc_array(c->heif_item, FFMAX(entry_count, c->nb_heif_item), sizeof(*c->heif_item));
9680 if (!heif_item)
9681 return AVERROR(ENOMEM);
9682 c->heif_item = heif_item;
9683 if (entry_count > c->nb_heif_item)
9684 memset(&c->heif_item[c->nb_heif_item], 0,
9685 sizeof(*c->heif_item) * (entry_count - c->nb_heif_item));
9686 c->nb_heif_item = FFMAX(c->nb_heif_item, entry_count);
9687
9688 for (i = 0; i < entry_count; i++) {
9689 MOVAtom infe;
9690
9691 infe.size = avio_rb32(pb);
9692 infe.type = avio_rl32(pb);
9693 if (avio_feof(pb) || infe.size < 8 || infe.size > atom.size ||
9694 infe.type != MKTAG('i','n','f','e')) {
9696 goto fail;
9697 }
9698
9699 atom.size -= infe.size;
9700 infe.size -= 8;
9701
9702 ret = mov_read_infe(c, pb, infe);
9703 if (ret < 0)
9704 goto fail;
9705 if (!ret)
9706 got_stream = 1;
9707 }
9708
9709 c->found_iinf = got_stream;
9710 return 0;
9711fail:
9712 for (; i >= 0; i--) {
9713 HEIFItem *item = c->heif_item[i];
9714
9715 if (!item)
9716 continue;
9717
9718 av_freep(&item->name);
9719 }
9720 return ret;
9721}
9722
9724 HEIFItem *item, int version, int entries)
9725{
9726 HEIFGroup *tmap = av_realloc_array(c->heif_group, c->nb_heif_group + 1U,
9727 sizeof(*c->heif_group));
9728 int ret;
9729
9730 if (!tmap)
9731 return AVERROR(ENOMEM);
9732 c->heif_group = tmap;
9733
9734 if (entries != 2) {
9735 avpriv_report_missing_feature(c->fc, "Derived image item of type %s with an "
9736 "item reference count other than 2",
9737 av_fourcc2str(item->type));
9738 return 0;
9739 }
9740
9741 tmap = &tmap[c->nb_heif_group];
9742
9743 tmap->item_idx_list = NULL; // Not needed
9744 tmap->item_id_list = av_malloc_array(entries, sizeof(*tmap->item_id_list));
9745 tmap->item_list = av_calloc(entries, sizeof(*tmap->item_list));
9746 if (!tmap->item_id_list || !tmap->item_list) {
9747 ret = AVERROR(ENOMEM);
9748 goto fail;
9749 }
9750
9751 /* 'to' item ids */
9752 for (int i = 0; i < entries; i++) {
9753 tmap->item_id_list[i] = version ? avio_rb32(pb) : avio_rb16(pb);
9754
9755 if (avio_feof(pb)) {
9757 goto fail;
9758 }
9759 }
9760
9761 tmap->nb_items = entries;
9762 tmap->item = item;
9763 ++c->nb_heif_group;
9764
9765 return 0;
9766fail:
9767 av_freep(&tmap->item_id_list);
9768 av_freep(&tmap->item_list);
9769
9770 return ret;
9771}
9772
9774 HEIFItem *item, int version, int entries)
9775{
9776 HEIFGroup *grid = av_realloc_array(c->heif_group, c->nb_heif_group + 1U,
9777 sizeof(*c->heif_group));
9778 int ret;
9779
9780 if (!grid)
9781 return AVERROR(ENOMEM);
9782 c->heif_group = grid;
9783 grid = &grid[c->nb_heif_group];
9784
9785 grid->item_id_list = av_malloc_array(entries, sizeof(*grid->item_id_list));
9786 grid->item_idx_list = av_calloc(entries, sizeof(*grid->item_idx_list));
9787 grid->item_list = av_calloc(entries, sizeof(*grid->item_list));
9788 if (!grid->item_id_list || !grid->item_list || !grid->item_idx_list) {
9789 ret = AVERROR(ENOMEM);
9790 goto fail;
9791 }
9792 /* 'to' item ids */
9793 for (int i = 0; i < entries; i++) {
9794 grid->item_id_list[i] = version ? avio_rb32(pb) : avio_rb16(pb);
9795
9796 if (avio_feof(pb)) {
9798 goto fail;
9799 }
9800 }
9801
9802 grid->nb_items = entries;
9803 grid->item = item;
9804 ++c->nb_heif_group;
9805
9806 return 0;
9807fail:
9808 av_freep(&grid->item_id_list);
9809 av_freep(&grid->item_idx_list);
9810 av_freep(&grid->item_list);
9811
9812 return ret;
9813}
9814
9816{
9817 HEIFItem *item = NULL;
9818 int entries;
9819 int from_item_id = version ? avio_rb32(pb) : avio_rb16(pb);
9820 int ret;
9821
9822 for (int i = 0; i < c->nb_heif_group; i++) {
9823 if (c->heif_group[i].item->item_id == from_item_id) {
9824 av_log(c->fc, AV_LOG_ERROR, "More than one 'dimg' box "
9825 "referencing the same Derived Image item\n");
9826 return AVERROR_INVALIDDATA;
9827 }
9828 }
9829 for (int i = 0; i < c->nb_heif_item; i++) {
9830 if (!c->heif_item[i] || c->heif_item[i]->item_id != from_item_id)
9831 continue;
9832 item = c->heif_item[i];
9833
9834 switch (item->type) {
9835 case MKTAG('g','r','i','d'):
9836 case MKTAG('i','o','v','l'):
9837 case MKTAG('t','m','a','p'):
9838 break;
9839 default:
9840 avpriv_report_missing_feature(c->fc, "Derived Image item of type %s",
9841 av_fourcc2str(item->type));
9842 return 0;
9843 }
9844 break;
9845 }
9846 if (!item) {
9847 av_log(c->fc, AV_LOG_ERROR, "Missing derived image information\n");
9848 return AVERROR_INVALIDDATA;
9849 }
9850
9851 entries = avio_rb16(pb);
9852 if (!entries) {
9853 av_log(c->fc, AV_LOG_ERROR,
9854 "Derived image item references no input images\n");
9855 return AVERROR_INVALIDDATA;
9856 }
9857
9858 av_log(c->fc, AV_LOG_TRACE, "dimg: from_item_id %d, entries %d\n",
9859 from_item_id, entries);
9860
9861 switch (item->type) {
9862 case MKTAG('g','r','i','d'):
9863 case MKTAG('i','o','v','l'):
9864 ret = mov_read_iref_dimg_grid(c, pb, item, version, entries);
9865 break;
9866 case MKTAG('t','m','a','p'):
9867 ret = mov_read_iref_dimg_tmap(c, pb, item, version, entries);
9868 break;
9869 default:
9870 av_unreachable("item->type should have been checked above");
9871 }
9872
9873 return ret;
9874}
9875
9877 int version, uint32_t size)
9878{
9879 HEIFItem *from_item = NULL;
9880 int entries;
9881 int item_id_size = version ? 4 : 2;
9882 int from_item_id = version ? avio_rb32(pb) : avio_rb16(pb);
9883 const HEIFItemRef ref = { type, from_item_id };
9884
9885 from_item = get_heif_item(c, from_item_id);
9886 if (!from_item) {
9887 av_log(c->fc, AV_LOG_ERROR, "Missing stream referenced by %s iref\n",
9889 return AVERROR_INVALIDDATA;
9890 }
9891
9892 entries = avio_rb16(pb);
9893 if ((int64_t)entries * item_id_size > (int64_t)size - item_id_size - 2) {
9894 av_log(c->fc, AV_LOG_ERROR, "iref %s entry count %d exceeds the sub-box size\n",
9895 av_fourcc2str(type), entries);
9896 return AVERROR_INVALIDDATA;
9897 }
9898 /* 'to' item ids */
9899 for (int i = 0; i < entries; i++) {
9900 HEIFItem *item = get_heif_item(c, version ? avio_rb32(pb) : avio_rb16(pb));
9901
9902 if (avio_feof(pb))
9903 return AVERROR_INVALIDDATA;
9904
9905 if (!item) {
9906 av_log(c->fc, AV_LOG_WARNING, "Missing stream referenced by %s item\n",
9908 continue;
9909 }
9910
9911 if (!av_dynarray2_add((void **)&item->iref_from_list, &item->nb_iref_from_list,
9912 sizeof(*item->iref_from_list), (const uint8_t *)&ref))
9913 return AVERROR(ENOMEM);
9914 }
9915
9916 av_log(c->fc, AV_LOG_TRACE, "%s: from_item_id %d, entries %d\n",
9917 av_fourcc2str(type), from_item_id, entries);
9918
9919 return 0;
9920}
9921
9923 int version, uint32_t size)
9924{
9925 HEIFItem *from_item = NULL;
9926 int entries;
9927 unsigned from_item_id = version ? avio_rb32(pb) : avio_rb16(pb);
9928
9929 from_item = get_heif_item(c, from_item_id);
9930 if (!from_item) {
9931 av_log(c->fc, AV_LOG_ERROR, "Missing item referenced by %s iref\n",
9933 return AVERROR_INVALIDDATA;
9934 }
9935
9936 entries = avio_rb16(pb);
9937 if (entries != 1) {
9938 avpriv_report_missing_feature(c->fc, "%s iref with an item reference "
9939 "count other than 1",
9941 return 0;
9942 }
9943
9944 /* 'to' item ids */
9945 for (int i = 0; i < entries; i++) {
9946 unsigned to_item_id = version ? avio_rb32(pb) : avio_rb16(pb);
9947 const HEIFItemRef ref = { type, to_item_id };
9948 HEIFItem *item = get_heif_item(c, to_item_id);
9949
9950 if (avio_feof(pb))
9951 return AVERROR_INVALIDDATA;
9952
9953 if (!item) {
9954 av_log(c->fc, AV_LOG_WARNING, "Missing item referenced by %s iref\n",
9956 continue;
9957 }
9958
9959 if (!av_dynarray2_add((void **)&from_item->iref_to_list, &from_item->nb_iref_to_list,
9960 sizeof(*from_item->iref_to_list), (const uint8_t *)&ref))
9961 return AVERROR(ENOMEM);
9962 }
9963
9964 av_log(c->fc, AV_LOG_TRACE, "%s: from_item_id %d, entries %d\n",
9965 av_fourcc2str(type), from_item_id, entries);
9966
9967 return 0;
9968}
9969
9971{
9972 int version = avio_r8(pb);
9973 int ret;
9974
9975 avio_rb24(pb); // flags
9976 atom.size -= 4;
9977
9978 if (version > 1) {
9979 av_log(c->fc, AV_LOG_WARNING, "Unknown iref box version %d\n", version);
9980 return 0;
9981 }
9982
9983 while (atom.size) {
9984 int64_t next = avio_tell(pb);
9985 uint32_t type, size = avio_rb32(pb);
9986
9987 if (size < 14 || size > atom.size || next > INT64_MAX - size)
9988 return AVERROR_INVALIDDATA;
9989
9990 next += size;
9991 type = avio_rl32(pb);
9992 switch (type) {
9993 case MKTAG('d','i','m','g'):
9995 if (ret < 0)
9996 return ret;
9997 break;
9998 case MKTAG('c','d','s','c'):
9999 ret = mov_read_iref_cdsc(c, pb, type, version, size - 8);
10000 if (ret < 0)
10001 return ret;
10002 break;
10003 case MKTAG('a','u','x','l'):
10004 case MKTAG('t','h','m','b'):
10005 ret = mov_read_iref_auxl(c, pb, type, version, size - 8);
10006 if (ret < 0)
10007 return ret;
10008 break;
10009 default:
10010 av_log(c->fc, AV_LOG_DEBUG, "Unknown iref type %s size %"PRIu32"\n",
10012 }
10013
10014 atom.size -= size;
10015 avio_seek(pb, next, SEEK_SET);
10016 }
10017 return 0;
10018}
10019
10021{
10022 HEIFItem *item;
10023 uint32_t width, height;
10024
10025 avio_r8(pb); /* version */
10026 avio_rb24(pb); /* flags */
10027 width = avio_rb32(pb);
10028 height = avio_rb32(pb);
10029
10030 av_log(c->fc, AV_LOG_TRACE, "ispe: item_id %d, width %"PRIu32", height %"PRIu32"\n",
10031 c->cur_item_id, width, height);
10032
10033 if (!width || !height || width > INT_MAX || height > INT_MAX) {
10034 av_log(c->fc, AV_LOG_ERROR, "Invalid ispe dimensions %"PRIu32"x%"PRIu32"\n",
10035 width, height);
10036 return AVERROR_INVALIDDATA;
10037 }
10038
10039 item = get_heif_item(c, c->cur_item_id);
10040 if (item) {
10041 item->width = width;
10042 item->height = height;
10043 }
10044
10045 return 0;
10046}
10047
10049{
10050 HEIFItem *item;
10051 int angle;
10052
10053 angle = avio_r8(pb) & 0x3;
10054
10055 av_log(c->fc, AV_LOG_TRACE, "irot: item_id %d, angle %u\n",
10056 c->cur_item_id, angle);
10057
10058 item = get_heif_item(c, c->cur_item_id);
10059 if (item) {
10060 // angle * 90 specifies the angle (in anti-clockwise direction)
10061 // in units of degrees.
10062 item->rotation = angle * 90;
10063 }
10064
10065 return 0;
10066}
10067
10069{
10070 HEIFItem *item;
10071 int axis;
10072
10073 axis = avio_r8(pb) & 0x1;
10074
10075 av_log(c->fc, AV_LOG_TRACE, "imir: item_id %d, axis %u\n",
10076 c->cur_item_id, axis);
10077
10078 item = get_heif_item(c, c->cur_item_id);
10079 if (item) {
10080 item->hflip = axis;
10081 item->vflip = !axis;
10082 }
10083
10084 return 0;
10085}
10086
10087typedef struct MOVAtomExt {
10088 uint32_t type;
10090 uint8_t *data;
10091} MOVAtomExt;
10092
10094 MOVAtomExt **atoms, int *nb_atoms)
10095{
10096 while (atom.size >= 8) {
10097 MOVAtomExt *ref = av_dynarray2_add((void**)atoms, nb_atoms, sizeof(MOVAtomExt), NULL);
10098 if (!ref)
10099 return AVERROR(ENOMEM);
10100
10101 ref->data = NULL;
10102 ref->size = avio_rb32(pb);
10103 ref->type = avio_rl32(pb);
10104 if (ref->size > atom.size || ref->size < 8)
10105 break;
10106 ref->data = av_malloc(ref->size);
10107 if (!ref->data)
10108 return AVERROR_INVALIDDATA;
10109
10110 av_log(c->fc, AV_LOG_TRACE, "ipco: index %d, box type %s\n", *nb_atoms,
10111 av_fourcc2str(ref->type));
10112 AV_WB32(ref->data, ref->size);
10113 AV_WL32(ref->data + 4, ref->type);
10114 if (avio_read(pb, ref->data + 8, ref->size - 8) != ref->size - 8) {
10115 return AVERROR_INVALIDDATA;
10116 }
10117 atom.size -= ref->size;
10118 }
10119
10120 if (atom.size)
10121 return AVERROR_INVALIDDATA;
10122
10123 return 0;
10124}
10125
10127 MOVAtomExt *atoms, int nb_atoms)
10128{
10129 unsigned count;
10130 int version, flags;
10131 int ret;
10132
10133 version = avio_r8(pb);
10134 flags = avio_rb24(pb);
10135 count = avio_rb32(pb);
10136 atom.size -= 8;
10137
10138 for (int i = 0; i < count; i++) {
10139 int item_id = version ? avio_rb32(pb) : avio_rb16(pb);
10140 int assoc_count = avio_r8(pb);
10141
10142 atom.size -= (version ? 5 : 3) + assoc_count * (1 + (flags & 1));
10143 if (avio_feof(pb) || atom.size < 0)
10144 return AVERROR_INVALIDDATA;
10145
10146 for (int j = 0; j < assoc_count; j++) {
10147 FFIOContext b;
10148 MOVAtomExt *ref;
10149 int index = avio_r8(pb) & 0x7f;
10150 if (flags & 1) {
10151 index <<= 8;
10152 index |= avio_r8(pb);
10153 }
10154 if (!index)
10155 continue;
10156 if (index > nb_atoms) {
10157 return AVERROR_INVALIDDATA;
10158 }
10159 ref = &atoms[--index];
10160
10161 av_log(c->fc, AV_LOG_TRACE, "ipma: property_index %d, item_id %d, item_type %s\n",
10162 index + 1, item_id, av_fourcc2str(ref->type));
10163
10164 c->cur_item_id = item_id;
10165
10166 ffio_init_read_context(&b, ref->data, ref->size);
10167 ret = mov_read_default(c, &b.pub,
10168 (MOVAtom) { .size = ref->size,
10169 .type = MKTAG('i','p','c','o') });
10170 if (ret < 0)
10171 return ret;
10172 }
10173 }
10174
10175 if (atom.size)
10176 return AVERROR_INVALIDDATA;
10177
10178 return 0;
10179}
10180
10182{
10183 MOVAtomExt *atoms = NULL;
10184 MOVAtom a;
10185 int nb_atoms = 0;
10186 int ret;
10187
10188 a.size = avio_rb32(pb);
10189 a.type = avio_rl32(pb);
10190
10191 if (a.size <= 8 || a.size > atom.size || a.type != MKTAG('i','p','c','o'))
10192 return AVERROR_INVALIDDATA;
10193
10194 atom.size -= a.size;
10195 a.size -= 8;
10196
10197 ret = mov_read_ipco(c, pb, a, &atoms, &nb_atoms);
10198 if (ret < 0)
10199 goto fail;
10200
10201 a.size = avio_rb32(pb);
10202 a.type = avio_rl32(pb);
10203
10204 if (a.size <= 8 || a.size > atom.size || a.type != MKTAG('i','p','m','a')) {
10206 goto fail;
10207 }
10208
10209 a.size -= 8;
10210
10211 ret = mov_read_ipma(c, pb, a, atoms, nb_atoms);
10212 if (ret < 0)
10213 goto fail;
10214
10215 ret = 0;
10216fail:
10217 c->cur_item_id = -1;
10218 for (int i = 0; i < nb_atoms; i++)
10219 av_free(atoms[i].data);
10220 av_free(atoms);
10221
10222 return ret;
10223}
10224
10226{
10227 avio_rb32(pb); // version & flags
10228 uint16_t graphics_mode = avio_rb16(pb);
10229 // ignored: opcolor[3]
10230
10231 if (c->fc->nb_streams < 1)
10232 return 0;
10233 AVStream *st = c->fc->streams[c->fc->nb_streams - 1];
10235 return 0;
10236
10237 switch (graphics_mode) {
10241 break;
10244 break;
10247 break;
10248 default:
10250 av_log(c->fc, AV_LOG_WARNING, "Unhandled graphics mode: 0x%x\n",
10251 graphics_mode);
10252 break;
10253 }
10254
10255 return 0;
10256}
10257
10259{
10260 AVFormatContext *ctx = c->fc;
10261 AVStream *st;
10262 int profile_level_indication, reference_ch_layout, config_length;
10263 int ret = 0;
10264
10265 if (ctx->nb_streams < 1)
10266 return 0;
10267
10268 st = ctx->streams[ctx->nb_streams - 1];
10270 return 0;
10271
10272 if (avio_r8(pb) != 1) // ConfigurationVersion
10273 return 0;
10274
10275 profile_level_indication = avio_r8(pb);
10276 st->codecpar->profile = (profile_level_indication - 1) / 5;
10277 st->codecpar->level = ((profile_level_indication - 1) % 5) + 1;
10278
10279 reference_ch_layout = avio_r8(pb);
10280 config_length = avio_rb16(pb);
10281 if (config_length)
10282 ret = ff_get_extradata(ctx, st->codecpar, pb, config_length);
10283
10284 if (!reference_ch_layout ||
10285 reference_ch_layout >= FF_ARRAY_ELEMS(ff_mpa_cicp_channel_layout_masks)) {
10286 av_log(ctx, AV_LOG_WARNING, "Unknown referenceChannelLayout value: %d\n", reference_ch_layout);
10287 return ret;
10288 }
10289
10291 ff_mpa_cicp_channel_layout_masks[reference_ch_layout]);
10292
10293 return ret;
10294}
10295
10297{ MKTAG('A','C','L','R'), mov_read_aclr },
10298{ MKTAG('A','P','R','G'), mov_read_avid },
10299{ MKTAG('A','A','L','P'), mov_read_avid },
10300{ MKTAG('A','R','E','S'), mov_read_ares },
10301{ MKTAG('a','v','s','s'), mov_read_avss },
10302{ MKTAG('a','v','1','C'), mov_read_glbl },
10303{ MKTAG('c','h','p','l'), mov_read_chpl },
10304{ MKTAG('c','o','6','4'), mov_read_stco },
10305{ MKTAG('c','o','l','r'), mov_read_colr },
10306{ MKTAG('c','t','t','s'), mov_read_ctts }, /* composition time to sample */
10307{ MKTAG('d','i','n','f'), mov_read_default },
10308{ MKTAG('D','p','x','E'), mov_read_dpxe },
10309{ MKTAG('d','r','e','f'), mov_read_dref },
10310{ MKTAG('e','d','t','s'), mov_read_default },
10311{ MKTAG('e','l','s','t'), mov_read_elst },
10312{ MKTAG('e','n','d','a'), mov_read_enda },
10313{ MKTAG('f','i','e','l'), mov_read_fiel },
10314{ MKTAG('a','d','r','m'), mov_read_adrm },
10315{ MKTAG('f','t','y','p'), mov_read_ftyp },
10316{ MKTAG('g','l','b','l'), mov_read_glbl },
10317{ MKTAG('h','d','l','r'), mov_read_hdlr },
10318{ MKTAG('i','l','s','t'), mov_read_ilst },
10319{ MKTAG('j','p','2','h'), mov_read_jp2h },
10320{ MKTAG('m','d','a','t'), mov_read_mdat },
10321{ MKTAG('m','d','h','d'), mov_read_mdhd },
10322{ MKTAG('m','d','i','a'), mov_read_default },
10323{ MKTAG('m','e','t','a'), mov_read_meta },
10324{ MKTAG('m','i','n','f'), mov_read_default },
10325{ MKTAG('m','o','o','f'), mov_read_moof },
10326{ MKTAG('m','o','o','v'), mov_read_moov },
10327{ MKTAG('m','v','e','x'), mov_read_default },
10328{ MKTAG('m','v','h','d'), mov_read_mvhd },
10329{ MKTAG('S','M','I',' '), mov_read_svq3 },
10330{ MKTAG('a','l','a','c'), mov_read_alac }, /* alac specific atom */
10331{ MKTAG('a','v','c','C'), mov_read_glbl },
10332{ MKTAG('p','a','s','p'), mov_read_pasp },
10333{ MKTAG('c','l','a','p'), mov_read_clap },
10334{ MKTAG('c','d','s','c'), mov_read_cdsc_rndr },
10335{ MKTAG('r','n','d','r'), mov_read_cdsc_rndr },
10336{ MKTAG('s','b','a','s'), mov_read_sbas },
10337{ MKTAG('v','d','e','p'), mov_read_vdep },
10338{ MKTAG('s','i','d','x'), mov_read_sidx },
10339{ MKTAG('s','t','b','l'), mov_read_default },
10340{ MKTAG('s','t','c','o'), mov_read_stco },
10341{ MKTAG('s','t','p','s'), mov_read_stps },
10342{ MKTAG('s','t','r','f'), mov_read_strf },
10343{ MKTAG('s','t','s','c'), mov_read_stsc },
10344{ MKTAG('s','t','s','d'), mov_read_stsd }, /* sample description */
10345{ MKTAG('s','t','s','s'), mov_read_stss }, /* sync sample */
10346{ MKTAG('s','t','s','z'), mov_read_stsz }, /* sample size */
10347{ MKTAG('s','t','t','s'), mov_read_stts },
10348{ MKTAG('s','t','z','2'), mov_read_stsz }, /* compact sample size */
10349{ MKTAG('s','d','t','p'), mov_read_sdtp }, /* independent and disposable samples */
10350{ MKTAG('t','k','h','d'), mov_read_tkhd }, /* track header */
10351{ MKTAG('t','f','d','t'), mov_read_tfdt },
10352{ MKTAG('t','f','h','d'), mov_read_tfhd }, /* track fragment header */
10353{ MKTAG('t','r','a','k'), mov_read_trak },
10354{ MKTAG('t','r','a','f'), mov_read_default },
10355{ MKTAG('t','r','e','f'), mov_read_default },
10356{ MKTAG('t','m','c','d'), mov_read_tmcd },
10357{ MKTAG('c','h','a','p'), mov_read_chap },
10358{ MKTAG('t','r','e','x'), mov_read_trex },
10359{ MKTAG('t','r','u','n'), mov_read_trun },
10360{ MKTAG('u','d','t','a'), mov_read_default },
10361{ MKTAG('w','a','v','e'), mov_read_wave },
10362{ MKTAG('e','s','d','s'), mov_read_esds },
10363{ MKTAG('d','a','c','3'), mov_read_dac3 }, /* AC-3 info */
10364{ MKTAG('d','e','c','3'), mov_read_dec3 }, /* EAC-3 info */
10365{ MKTAG('d','d','t','s'), mov_read_ddts }, /* DTS audio descriptor */
10366{ MKTAG('w','i','d','e'), mov_read_wide }, /* place holder */
10367{ MKTAG('w','f','e','x'), mov_read_wfex },
10368{ MKTAG('c','m','o','v'), mov_read_cmov },
10369{ MKTAG('c','h','a','n'), mov_read_chan }, /* channel layout from quicktime */
10370{ MKTAG('c','h','n','l'), mov_read_chnl }, /* channel layout from ISO-14496-12 */
10371{ MKTAG('d','v','c','1'), mov_read_dvc1 },
10372{ MKTAG('s','g','p','d'), mov_read_sgpd },
10373{ MKTAG('s','b','g','p'), mov_read_sbgp },
10374{ MKTAG('h','v','c','C'), mov_read_glbl },
10375{ MKTAG('v','v','c','C'), mov_read_glbl },
10376{ MKTAG('u','u','i','d'), mov_read_uuid },
10377{ MKTAG('C','i','n', 0x8e), mov_read_targa_y216 },
10378{ MKTAG('f','r','e','e'), mov_read_free },
10379{ MKTAG('-','-','-','-'), mov_read_custom },
10380{ MKTAG('s','i','n','f'), mov_read_default },
10381{ MKTAG('f','r','m','a'), mov_read_frma },
10382{ MKTAG('s','e','n','c'), mov_read_senc },
10383{ MKTAG('s','a','i','z'), mov_read_saiz },
10384{ MKTAG('s','a','i','o'), mov_read_saio },
10385{ MKTAG('p','s','s','h'), mov_read_pssh },
10386{ MKTAG('s','c','h','m'), mov_read_schm },
10387{ MKTAG('s','c','h','i'), mov_read_default },
10388{ MKTAG('t','e','n','c'), mov_read_tenc },
10389{ MKTAG('d','f','L','a'), mov_read_dfla },
10390{ MKTAG('s','t','3','d'), mov_read_st3d }, /* stereoscopic 3D video box */
10391{ MKTAG('s','v','3','d'), mov_read_sv3d }, /* spherical video box */
10392{ MKTAG('v','e','x','u'), mov_read_vexu }, /* video extension usage */
10393{ MKTAG('h','f','o','v'), mov_read_hfov },
10394{ MKTAG('d','O','p','s'), mov_read_dops },
10395{ MKTAG('d','m','l','p'), mov_read_dmlp },
10396{ MKTAG('S','m','D','m'), mov_read_smdm },
10397{ MKTAG('C','o','L','L'), mov_read_coll },
10398{ MKTAG('v','p','c','C'), mov_read_vpcc },
10399{ MKTAG('m','d','c','v'), mov_read_mdcv },
10400{ MKTAG('c','l','l','i'), mov_read_clli },
10401{ MKTAG('d','v','c','C'), mov_read_dvcc_dvvc },
10402{ MKTAG('d','v','v','C'), mov_read_dvcc_dvvc },
10403{ MKTAG('d','v','w','C'), mov_read_dvcc_dvvc },
10404{ MKTAG('h','v','c','E'), mov_read_hvce },
10405{ MKTAG('k','i','n','d'), mov_read_kind },
10406{ MKTAG('S','A','3','D'), mov_read_SA3D }, /* ambisonic audio box */
10407{ MKTAG('S','A','N','D'), mov_read_SAND }, /* non diegetic audio box */
10408{ MKTAG('i','l','o','c'), mov_read_iloc },
10409{ MKTAG('p','c','m','C'), mov_read_pcmc }, /* PCM configuration box */
10410{ MKTAG('p','i','t','m'), mov_read_pitm },
10411{ MKTAG('e','v','c','C'), mov_read_glbl },
10412{ MKTAG('a','u','x','C'), mov_read_auxc },
10413{ MKTAG('i','d','a','t'), mov_read_idat },
10414{ MKTAG('i','m','i','r'), mov_read_imir },
10415{ MKTAG('i','r','e','f'), mov_read_iref },
10416{ MKTAG('i','s','p','e'), mov_read_ispe },
10417{ MKTAG('i','r','o','t'), mov_read_irot },
10418{ MKTAG('i','p','r','p'), mov_read_iprp },
10419{ MKTAG('i','i','n','f'), mov_read_iinf },
10420{ MKTAG('a','m','v','e'), mov_read_amve }, /* ambient viewing environment box */
10421{ MKTAG('l','h','v','C'), mov_read_lhvc },
10422{ MKTAG('l','v','c','C'), mov_read_glbl },
10423{ MKTAG('a','p','v','C'), mov_read_glbl },
10424#if CONFIG_IAMFDEC
10425{ MKTAG('i','a','c','b'), mov_read_iacb },
10426#endif
10427{ MKTAG('s','r','a','t'), mov_read_srat },
10428{ MKTAG('v','m','h','d'), mov_read_vmhd },
10429{ MKTAG('m','h','a','C'), mov_read_mhac },
10430{ 0, NULL }
10431};
10432
10434{
10435 int64_t total_size = 0;
10436 MOVAtom a;
10437 int i;
10438
10439 if (c->atom_depth > 10) {
10440 av_log(c->fc, AV_LOG_ERROR, "Atoms too deeply nested\n");
10441 return AVERROR_INVALIDDATA;
10442 }
10443 c->atom_depth ++;
10444
10445 if (atom.size < 0)
10446 atom.size = INT64_MAX;
10447 while (total_size <= atom.size - 8) {
10448 int (*parse)(MOVContext*, AVIOContext*, MOVAtom) = NULL;
10449 a.size = avio_rb32(pb);
10450 a.type = avio_rl32(pb);
10451 if (avio_feof(pb))
10452 break;
10453 if (((a.type == MKTAG('f','r','e','e') && c->moov_retry) ||
10454 a.type == MKTAG('h','o','o','v')) &&
10455 a.size >= 8 &&
10456 c->fc->strict_std_compliance < FF_COMPLIANCE_STRICT) {
10457 uint32_t type;
10458 avio_skip(pb, 4);
10459 type = avio_rl32(pb);
10460 if (avio_feof(pb))
10461 break;
10462 avio_seek(pb, -8, SEEK_CUR);
10463 if (type == MKTAG('m','v','h','d') ||
10464 type == MKTAG('c','m','o','v')) {
10465 av_log(c->fc, AV_LOG_ERROR, "Detected moov in a free or hoov atom.\n");
10466 a.type = MKTAG('m','o','o','v');
10467 }
10468 }
10469 if (atom.type != MKTAG('r','o','o','t') &&
10470 atom.type != MKTAG('m','o','o','v')) {
10471 if (a.type == MKTAG('t','r','a','k') ||
10472 a.type == MKTAG('m','d','a','t')) {
10473 av_log(c->fc, AV_LOG_ERROR, "Broken file, trak/mdat not at top-level\n");
10474 avio_skip(pb, -8);
10475 c->atom_depth --;
10476 return 0;
10477 }
10478 }
10479 total_size += 8;
10480 if (a.size == 1 && total_size + 8 <= atom.size) { /* 64 bit extended size */
10481 a.size = avio_rb64(pb) - 8;
10482 total_size += 8;
10483 }
10484 av_log(c->fc, AV_LOG_TRACE, "type:'%s' parent:'%s' sz: %"PRId64" %"PRId64" %"PRId64"\n",
10485 av_fourcc2str(a.type), av_fourcc2str(atom.type), a.size, total_size, atom.size);
10486 if (a.size == 0) {
10487 a.size = atom.size - total_size + 8;
10488 }
10489 if (a.size < 0)
10490 break;
10491 a.size -= 8;
10492 if (a.size < 0)
10493 break;
10494 a.size = FFMIN(a.size, atom.size - total_size);
10495
10496 for (i = 0; mov_default_parse_table[i].type; i++)
10497 if (mov_default_parse_table[i].type == a.type) {
10499 break;
10500 }
10501
10502 // container is user data
10503 if (!parse && (atom.type == MKTAG('u','d','t','a') ||
10504 atom.type == MKTAG('i','l','s','t')))
10506
10507 // Supports parsing the QuickTime Metadata Keys.
10508 // https://developer.apple.com/library/mac/documentation/QuickTime/QTFF/Metadata/Metadata.html
10509 if (!parse && c->found_hdlr_mdta &&
10510 atom.type == MKTAG('m','e','t','a') &&
10511 a.type == MKTAG('k','e','y','s') &&
10512 c->meta_keys_count == 0) {
10514 }
10515
10516 if (!parse) { /* skip leaf atoms data */
10517 avio_skip(pb, a.size);
10518 } else {
10519 int64_t start_pos = avio_tell(pb);
10520 int64_t left;
10521 int err = parse(c, pb, a);
10522 if (err < 0) {
10523 c->atom_depth --;
10524 return err;
10525 }
10526 if (c->found_moov && c->found_mdat && a.size <= INT64_MAX - start_pos &&
10527 ((!(pb->seekable & AVIO_SEEKABLE_NORMAL) || c->fc->flags & AVFMT_FLAG_IGNIDX || c->frag_index.complete) ||
10528 start_pos + a.size == avio_size(pb))) {
10529 if (!(pb->seekable & AVIO_SEEKABLE_NORMAL) || c->fc->flags & AVFMT_FLAG_IGNIDX || c->frag_index.complete)
10530 c->next_root_atom = start_pos + a.size;
10531 c->atom_depth --;
10532 return 0;
10533 }
10534 left = a.size - avio_tell(pb) + start_pos;
10535 if (left > 0) /* skip garbage at atom end */
10536 avio_skip(pb, left);
10537 else if (left < 0) {
10538 av_log(c->fc, AV_LOG_WARNING,
10539 "overread end of atom '%s' by %"PRId64" bytes\n",
10540 av_fourcc2str(a.type), -left);
10541 avio_seek(pb, left, SEEK_CUR);
10542 }
10543 }
10544
10545 total_size += a.size;
10546 }
10547
10548 if (total_size < atom.size && atom.size < 0x7ffff)
10549 avio_skip(pb, atom.size - total_size);
10550
10551 c->atom_depth --;
10552 return 0;
10553}
10554
10555static int mov_probe(const AVProbeData *p)
10556{
10558 uint32_t tag;
10559 int score = 0;
10560 int moov_offset = -1;
10561
10562 /* check file header */
10563 offset = 0;
10564 for (;;) {
10565 int64_t size;
10566 int minsize = 8;
10567 /* ignore invalid offset */
10568 if ((offset + 8ULL) > (unsigned int)p->buf_size)
10569 break;
10570 size = AV_RB32(p->buf + offset);
10571 if (size == 1 && offset + 16 <= (unsigned int)p->buf_size) {
10572 size = AV_RB64(p->buf+offset + 8);
10573 minsize = 16;
10574 } else if (size == 0) {
10575 size = p->buf_size - offset;
10576 }
10577 if (size < minsize) {
10578 offset += 4;
10579 continue;
10580 }
10581 tag = AV_RL32(p->buf + offset + 4);
10582 switch(tag) {
10583 /* check for obvious tags */
10584 case MKTAG('m','o','o','v'):
10585 moov_offset = offset + 4;
10587 case MKTAG('m','d','a','t'):
10588 case MKTAG('p','n','o','t'): /* detect movs with preview pics like ew.mov and april.mov */
10589 case MKTAG('u','d','t','a'): /* Packet Video PVAuthor adds this and a lot of more junk */
10590 case MKTAG('f','t','y','p'):
10591 if (tag == MKTAG('f','t','y','p') &&
10592 ( AV_RL32(p->buf + offset + 8) == MKTAG('j','p','2',' ')
10593 || AV_RL32(p->buf + offset + 8) == MKTAG('j','p','x',' ')
10594 || AV_RL32(p->buf + offset + 8) == MKTAG('j','x','l',' ')
10595 )) {
10596 score = FFMAX(score, 5);
10597 } else {
10598 score = AVPROBE_SCORE_MAX;
10599 }
10600 break;
10601 /* those are more common words, so rate then a bit less */
10602 case MKTAG('e','d','i','w'): /* xdcam files have reverted first tags */
10603 case MKTAG('w','i','d','e'):
10604 case MKTAG('f','r','e','e'):
10605 case MKTAG('j','u','n','k'):
10606 case MKTAG('p','i','c','t'):
10607 score = FFMAX(score, AVPROBE_SCORE_MAX - 5);
10608 break;
10609 case MKTAG(0x82,0x82,0x7f,0x7d):
10610 score = FFMAX(score, AVPROBE_SCORE_EXTENSION - 5);
10611 break;
10612 case MKTAG('s','k','i','p'):
10613 case MKTAG('u','u','i','d'):
10614 case MKTAG('p','r','f','l'):
10615 /* if we only find those cause probedata is too small at least rate them */
10616 score = FFMAX(score, AVPROBE_SCORE_EXTENSION);
10617 break;
10618 }
10619 if (size > INT64_MAX - offset)
10620 break;
10621 offset += size;
10622 }
10623 if (score > AVPROBE_SCORE_MAX - 50 && moov_offset != -1) {
10624 /* moov atom in the header - we should make sure that this is not a
10625 * MOV-packed MPEG-PS */
10626 offset = moov_offset;
10627
10628 while (offset < (p->buf_size - 16)) { /* Sufficient space */
10629 /* We found an actual hdlr atom */
10630 if (AV_RL32(p->buf + offset ) == MKTAG('h','d','l','r') &&
10631 AV_RL32(p->buf + offset + 8) == MKTAG('m','h','l','r') &&
10632 AV_RL32(p->buf + offset + 12) == MKTAG('M','P','E','G')) {
10633 av_log(NULL, AV_LOG_WARNING, "Found media data tag MPEG indicating this is a MOV-packed MPEG-PS.\n");
10634 /* We found a media handler reference atom describing an
10635 * MPEG-PS-in-MOV, return a
10636 * low score to force expanding the probe window until
10637 * mpegps_probe finds what it needs */
10638 return 5;
10639 } else {
10640 /* Keep looking */
10641 offset += 2;
10642 }
10643 }
10644 }
10645
10646 return score;
10647}
10648
10649// must be done after parsing all trak because there's no order requirement
10651{
10652 MOVContext *mov = s->priv_data;
10653 MOVStreamContext *sc;
10654 int64_t cur_pos;
10655 int i, j;
10656 int chapter_track;
10657
10658 for (j = 0; j < mov->nb_chapter_tracks; j++) {
10659 AVStream *st = NULL;
10660 FFStream *sti = NULL;
10661 chapter_track = mov->chapter_tracks[j];
10662 for (i = 0; i < s->nb_streams; i++) {
10663 sc = mov->fc->streams[i]->priv_data;
10664 if (sc->id == chapter_track) {
10665 st = s->streams[i];
10666 break;
10667 }
10668 }
10669 if (!st) {
10670 av_log(s, AV_LOG_ERROR, "Referenced QT chapter track not found\n");
10671 continue;
10672 }
10673 sti = ffstream(st);
10674
10675 sc = st->priv_data;
10676 cur_pos = avio_tell(sc->pb);
10677
10680 if (!st->attached_pic.data && sti->nb_index_entries) {
10681 // Retrieve the first frame, if possible
10682 AVIndexEntry *sample = &sti->index_entries[0];
10683 if (avio_seek(sc->pb, sample->pos, SEEK_SET) != sample->pos) {
10684 av_log(s, AV_LOG_ERROR, "Failed to retrieve first frame\n");
10685 goto finish;
10686 }
10687
10688 if (ff_add_attached_pic(s, st, sc->pb, NULL, sample->size) < 0)
10689 goto finish;
10690 }
10691 } else {
10694 st->discard = AVDISCARD_ALL;
10695 for (int i = 0; i < sti->nb_index_entries; i++) {
10697 int64_t end = i+1 < sti->nb_index_entries ? sti->index_entries[i+1].timestamp : st->duration;
10698 uint8_t *title;
10699 uint16_t ch;
10700 int len, title_len;
10701
10702 if (end < sample->timestamp) {
10703 av_log(s, AV_LOG_WARNING, "ignoring stream duration which is shorter than chapters\n");
10704 end = AV_NOPTS_VALUE;
10705 }
10706
10707 if (avio_seek(sc->pb, sample->pos, SEEK_SET) != sample->pos) {
10708 av_log(s, AV_LOG_ERROR, "Chapter %d not found in file\n", i);
10709 goto finish;
10710 }
10711
10712 // the first two bytes are the length of the title
10713 len = avio_rb16(sc->pb);
10714 if (len > sample->size-2)
10715 continue;
10716 title_len = 2*len + 1;
10717 if (!(title = av_mallocz(title_len)))
10718 goto finish;
10719
10720 // The samples could theoretically be in any encoding if there's an encd
10721 // atom following, but in practice are only utf-8 or utf-16, distinguished
10722 // instead by the presence of a BOM
10723 if (!len) {
10724 title[0] = 0;
10725 } else {
10726 ch = avio_rb16(sc->pb);
10727 if (ch == 0xfeff)
10728 avio_get_str16be(sc->pb, len, title, title_len);
10729 else if (ch == 0xfffe)
10730 avio_get_str16le(sc->pb, len, title, title_len);
10731 else {
10732 AV_WB16(title, ch);
10733 if (len == 1 || len == 2)
10734 title[len] = 0;
10735 else
10736 avio_get_str(sc->pb, INT_MAX, title + 2, len - 1);
10737 }
10738 }
10739
10740 avpriv_new_chapter(s, i, st->time_base, sample->timestamp, end, title);
10741 av_freep(&title);
10742 }
10743 }
10744finish:
10745 avio_seek(sc->pb, cur_pos, SEEK_SET);
10746 }
10747}
10748
10750 int64_t value, int flags)
10751{
10752 AVTimecode tc;
10753 char buf[AV_TIMECODE_STR_SIZE];
10754 AVRational rate = st->avg_frame_rate;
10755 int ret = av_timecode_init(&tc, rate, flags, 0, s);
10756 if (ret < 0)
10757 return ret;
10758 av_dict_set(&st->metadata, "timecode",
10759 av_timecode_make_string(&tc, buf, value), 0);
10760 return 0;
10761}
10762
10764{
10765 MOVStreamContext *sc = st->priv_data;
10766 FFStream *const sti = ffstream(st);
10767 char buf[AV_TIMECODE_STR_SIZE];
10768 int64_t cur_pos = avio_tell(sc->pb);
10769 int hh, mm, ss, ff, drop;
10770
10771 if (!sti->nb_index_entries)
10772 return -1;
10773
10774 avio_seek(sc->pb, sti->index_entries->pos, SEEK_SET);
10775 avio_skip(s->pb, 13);
10776 hh = avio_r8(s->pb);
10777 mm = avio_r8(s->pb);
10778 ss = avio_r8(s->pb);
10779 drop = avio_r8(s->pb);
10780 ff = avio_r8(s->pb);
10781 snprintf(buf, AV_TIMECODE_STR_SIZE, "%02d:%02d:%02d%c%02d",
10782 hh, mm, ss, drop ? ';' : ':', ff);
10783 av_dict_set(&st->metadata, "timecode", buf, 0);
10784
10785 avio_seek(sc->pb, cur_pos, SEEK_SET);
10786 return 0;
10787}
10788
10790{
10791 MOVStreamContext *sc = st->priv_data;
10792 FFStream *const sti = ffstream(st);
10793 int flags = 0;
10794 int64_t cur_pos = avio_tell(sc->pb);
10795 int64_t value;
10796 AVRational tc_rate = st->avg_frame_rate;
10797 int tmcd_nb_frames = sc->tmcd_nb_frames;
10798 int rounded_tc_rate;
10799
10800 if (!sti->nb_index_entries)
10801 return -1;
10802
10803 if (!tc_rate.num || !tc_rate.den || !tmcd_nb_frames)
10804 return -1;
10805
10806 avio_seek(sc->pb, sti->index_entries->pos, SEEK_SET);
10807 value = avio_rb32(s->pb);
10808
10809 if (sc->tmcd_flags & 0x0001) flags |= AV_TIMECODE_FLAG_DROPFRAME;
10810 if (sc->tmcd_flags & 0x0002) flags |= AV_TIMECODE_FLAG_24HOURSMAX;
10811 if (sc->tmcd_flags & 0x0004) flags |= AV_TIMECODE_FLAG_ALLOWNEGATIVE;
10812
10813 /* Assume Counter flag is set to 1 in tmcd track (even though it is likely
10814 * not the case) and thus assume "frame number format" instead of QT one.
10815 * No sample with tmcd track can be found with a QT timecode at the moment,
10816 * despite what the tmcd track "suggests" (Counter flag set to 0 means QT
10817 * format). */
10818
10819 /* 60 fps content have tmcd_nb_frames set to 30 but tc_rate set to 60, so
10820 * we multiply the frame number with the quotient.
10821 * See tickets #9492, #9710. */
10822 rounded_tc_rate = (tc_rate.num + tc_rate.den / 2LL) / tc_rate.den;
10823 /* Work around files where tmcd_nb_frames is rounded down from frame rate
10824 * instead of up. See ticket #5978. */
10825 if (tmcd_nb_frames == tc_rate.num / tc_rate.den &&
10826 s->strict_std_compliance < FF_COMPLIANCE_STRICT)
10827 tmcd_nb_frames = rounded_tc_rate;
10828 value = av_rescale(value, rounded_tc_rate, tmcd_nb_frames);
10829
10831
10832 avio_seek(sc->pb, cur_pos, SEEK_SET);
10833 return 0;
10834}
10835
10837 int i;
10838 if (!index || !*index) return;
10839 for (i = 0; i < (*index)->nb_encrypted_samples; i++) {
10840 av_encryption_info_free((*index)->encrypted_samples[i]);
10841 }
10842 av_freep(&(*index)->encrypted_samples);
10843 av_freep(&(*index)->auxiliary_info_sizes);
10844 av_freep(&(*index)->auxiliary_offsets);
10845 av_freep(index);
10846}
10847
10849{
10850 MOVStreamContext *sc = st->priv_data;
10851
10852 if (!sc || --sc->refcount) {
10853 st->priv_data = NULL;
10854 return;
10855 }
10856
10857 av_freep(&sc->tts_data);
10858 for (int i = 0; i < sc->drefs_count; i++) {
10859 av_freep(&sc->drefs[i].path);
10860 av_freep(&sc->drefs[i].dir);
10861 }
10862 av_freep(&sc->drefs);
10863
10864 sc->drefs_count = 0;
10865
10866 if (!sc->pb_is_copied)
10867 ff_format_io_close(s, &sc->pb);
10868
10869 sc->pb = NULL;
10870 av_freep(&sc->chunk_offsets);
10871 av_freep(&sc->stsc_data);
10872 av_freep(&sc->sample_sizes);
10873 av_freep(&sc->keyframes);
10874 av_freep(&sc->ctts_data);
10875 av_freep(&sc->stts_data);
10876 av_freep(&sc->sdtp_data);
10877 av_freep(&sc->stps_data);
10878 av_freep(&sc->elst_data);
10879 av_freep(&sc->rap_group);
10880 av_freep(&sc->sync_group);
10881 av_freep(&sc->sgpd_sync);
10885 av_freep(&sc->index_ranges);
10886 for (int i = 0; i < sc->nb_tref_tags; i++)
10887 av_freep(&sc->tref_tags[i].id);
10888 av_freep(&sc->tref_tags);
10889
10890 if (sc->extradata)
10891 for (int i = 0; i < sc->stsd_count; i++)
10892 av_free(sc->extradata[i]);
10893 av_freep(&sc->extradata);
10895
10899
10900 av_freep(&sc->stereo3d);
10901 av_freep(&sc->spherical);
10902 av_freep(&sc->mastering);
10903 av_freep(&sc->coll);
10904 av_freep(&sc->ambient);
10905
10906#if CONFIG_IAMFDEC
10907 if (sc->iamf)
10909#endif
10910 av_freep(&sc->iamf);
10911}
10912
10914{
10915 MOVContext *mov = s->priv_data;
10916 int i, j;
10917
10918 for (i = 0; i < s->nb_streams; i++) {
10919 AVStream *st = s->streams[i];
10920
10922 }
10923
10924 av_freep(&mov->dv_demux);
10926 mov->dv_fctx = NULL;
10927
10928 if (mov->meta_keys) {
10929 for (i = 1; i < mov->meta_keys_count; i++) {
10930 av_freep(&mov->meta_keys[i]);
10931 }
10932 av_freep(&mov->meta_keys);
10933 }
10934
10935 av_freep(&mov->trex_data);
10936 av_freep(&mov->bitrates);
10937
10938 for (i = 0; i < mov->frag_index.nb_items; i++) {
10940 for (j = 0; j < mov->frag_index.item[i].nb_stream_info; j++) {
10941 mov_free_encryption_index(&frag[j].encryption_index);
10942 }
10944 }
10945 av_freep(&mov->frag_index.item);
10946
10947 av_freep(&mov->aes_decrypt);
10948 av_freep(&mov->chapter_tracks);
10949 for (i = 0; i < mov->nb_heif_item; i++) {
10950 if (!mov->heif_item[i])
10951 continue;
10952 av_freep(&mov->heif_item[i]->name);
10956 av_exif_free(&mov->heif_item[i]->ifd);
10957 av_freep(&mov->heif_item[i]);
10958 }
10959 av_freep(&mov->heif_item);
10960 for (i = 0; i < mov->nb_heif_group; i++) {
10964 }
10965 av_freep(&mov->heif_group);
10966
10967 return 0;
10968}
10969
10970static int tmcd_is_referenced(AVFormatContext *s, int tmcd_id)
10971{
10972 int i;
10973
10974 for (i = 0; i < s->nb_streams; i++) {
10975 AVStream *st = s->streams[i];
10976 MOVStreamContext *sc = st->priv_data;
10977 MovTref *tag = mov_find_tref_tag(sc, MKTAG('t','m','c','d'));
10978
10979 if (!tag)
10980 continue;
10981 if (mov_find_tref_id(tag, tmcd_id))
10982 return 1;
10983 }
10984 return 0;
10985}
10986
10987/* look for a tmcd track not referenced by any video track, and export it globally */
10989{
10990 int i;
10991
10992 for (i = 0; i < s->nb_streams; i++) {
10993 AVStream *st = s->streams[i];
10994
10995 if (st->codecpar->codec_tag == MKTAG('t','m','c','d') &&
10996 !tmcd_is_referenced(s, st->id)) {
10997 AVDictionaryEntry *tcr = av_dict_get(st->metadata, "timecode", NULL, 0);
10998 if (tcr) {
10999 av_dict_set(&s->metadata, "timecode", tcr->value, 0);
11000 break;
11001 }
11002 }
11003 }
11004}
11005
11007{
11008 int version, fieldlength, i, j;
11010 uint32_t size = avio_rb32(f);
11011 unsigned track_id, item_count;
11012
11013 if (avio_rb32(f) != MKBETAG('t', 'f', 'r', 'a')) {
11014 return 1;
11015 }
11016 av_log(mov->fc, AV_LOG_VERBOSE, "found tfra\n");
11017
11018 version = avio_r8(f);
11019 avio_rb24(f);
11020 track_id = avio_rb32(f);
11021 fieldlength = avio_rb32(f);
11022 item_count = avio_rb32(f);
11023 for (i = 0; i < item_count; i++) {
11024 int64_t time, offset;
11025 int index;
11026 MOVFragmentStreamInfo * frag_stream_info;
11027
11028 if (avio_feof(f)) {
11029 return AVERROR_INVALIDDATA;
11030 }
11031
11032 if (version == 1) {
11033 time = avio_rb64(f);
11034 offset = avio_rb64(f);
11035 } else {
11036 time = avio_rb32(f);
11037 offset = avio_rb32(f);
11038 }
11039
11040 // The first sample of each stream in a fragment is always a random
11041 // access sample. So it's entry in the tfra can be used as the
11042 // initial PTS of the fragment.
11044 frag_stream_info = get_frag_stream_info(&mov->frag_index, index, track_id);
11045 if (frag_stream_info &&
11046 frag_stream_info->first_tfra_pts == AV_NOPTS_VALUE)
11047 frag_stream_info->first_tfra_pts = time;
11048
11049 for (j = 0; j < ((fieldlength >> 4) & 3) + 1; j++)
11050 avio_r8(f);
11051 for (j = 0; j < ((fieldlength >> 2) & 3) + 1; j++)
11052 avio_r8(f);
11053 for (j = 0; j < ((fieldlength >> 0) & 3) + 1; j++)
11054 avio_r8(f);
11055 }
11056
11057 avio_seek(f, pos + size, SEEK_SET);
11058 return 0;
11059}
11060
11062{
11063 int64_t stream_size = avio_size(f);
11064 int64_t original_pos = avio_tell(f);
11065 int64_t seek_ret;
11066 int ret = -1;
11067 if ((seek_ret = avio_seek(f, stream_size - 4, SEEK_SET)) < 0) {
11068 ret = seek_ret;
11069 goto fail;
11070 }
11071 c->mfra_size = avio_rb32(f);
11072 c->have_read_mfra_size = 1;
11073 if (!c->mfra_size || c->mfra_size > stream_size) {
11074 av_log(c->fc, AV_LOG_DEBUG, "doesn't look like mfra (unreasonable size)\n");
11075 goto fail;
11076 }
11077 if ((seek_ret = avio_seek(f, -((int64_t) c->mfra_size), SEEK_CUR)) < 0) {
11078 ret = seek_ret;
11079 goto fail;
11080 }
11081 if (avio_rb32(f) != c->mfra_size) {
11082 av_log(c->fc, AV_LOG_DEBUG, "doesn't look like mfra (size mismatch)\n");
11083 goto fail;
11084 }
11085 if (avio_rb32(f) != MKBETAG('m', 'f', 'r', 'a')) {
11086 av_log(c->fc, AV_LOG_DEBUG, "doesn't look like mfra (tag mismatch)\n");
11087 goto fail;
11088 }
11089 av_log(c->fc, AV_LOG_VERBOSE, "stream has mfra\n");
11090 do {
11091 ret = read_tfra(c, f);
11092 if (ret < 0)
11093 goto fail;
11094 } while (!ret);
11095 ret = 0;
11096 c->frag_index.complete = 1;
11097fail:
11098 seek_ret = avio_seek(f, original_pos, SEEK_SET);
11099 if (seek_ret < 0) {
11100 av_log(c->fc, AV_LOG_ERROR,
11101 "failed to seek back after looking for mfra\n");
11102 ret = seek_ret;
11103 }
11104 return ret;
11105}
11106
11108 AVPacketSideData **coded_side_data, int *nb_coded_side_data,
11109 const HEIFItem *item)
11110{
11111 AVPacketSideData *sd =
11112 (AVPacketSideData *)av_packet_side_data_get(*coded_side_data,
11113 *nb_coded_side_data,
11115 const AVExifMetadata *ifd = &item->ifd;
11116 AVBufferRef *buf = NULL;
11117 int err;
11118
11119 if (sd)
11120 return 0;
11121
11122 err = av_exif_write(s, ifd, &buf, AV_EXIF_TIFF_HEADER);
11123 if (err < 0)
11124 return err;
11125
11126 sd = av_packet_side_data_new(coded_side_data, nb_coded_side_data,
11127 AV_PKT_DATA_EXIF, buf->size, 0);
11128 if (!sd) {
11129 av_buffer_unref(&buf);
11130 return AVERROR(ENOMEM);
11131 }
11132 memcpy(sd->data, buf->data, buf->size);
11133
11134 av_buffer_unref(&buf);
11135
11136 return 0;
11137}
11138
11139static int set_icc_profile_from_item(AVPacketSideData **coded_side_data, int *nb_coded_side_data,
11140 const HEIFItem *item)
11141{
11142 AVPacketSideData *sd =
11143 (AVPacketSideData *)av_packet_side_data_get(*coded_side_data,
11144 *nb_coded_side_data,
11146
11147 if (sd)
11148 return 0;
11149
11150 sd = av_packet_side_data_new(coded_side_data, nb_coded_side_data,
11152 item->icc_profile_size, 0);
11153 if (!sd)
11154 return AVERROR(ENOMEM);
11155
11156 memcpy(sd->data, item->icc_profile, item->icc_profile_size);
11157
11158 return 0;
11159}
11160
11161static int set_display_matrix_from_item(AVPacketSideData **coded_side_data, int *nb_coded_side_data,
11162 const HEIFItem *item)
11163{
11164 int32_t *matrix;
11165 AVPacketSideData *sd =
11166 (AVPacketSideData *)av_packet_side_data_get(*coded_side_data,
11167 *nb_coded_side_data,
11169
11170 if (sd)
11171 return 0;
11172
11173 sd = av_packet_side_data_new(coded_side_data, nb_coded_side_data,
11175 9 * sizeof(*matrix), 0);
11176 if (!sd)
11177 return AVERROR(ENOMEM);
11178
11179 matrix = (int32_t*)sd->data;
11180 /* rotation is in the counter-clockwise direction whereas
11181 * av_display_rotation_set() expects its argument to be
11182 * oriented clockwise, so we need to negate it. */
11185
11186 return 0;
11187}
11188
11190 AVStreamGroupTileGrid *tile_grid)
11191{
11192 MOVContext *c = s->priv_data;
11193 const HEIFItem *item = grid->item;
11194 int64_t coded_width = 0, coded_height = 0;
11195 int64_t offset = 0, pos = avio_tell(s->pb);
11196 int64_t x = 0, y = 0;
11197 int i = 0;
11198 int tile_rows, tile_cols;
11199 int flags, size;
11200
11201 if (!(s->pb->seekable & AVIO_SEEKABLE_NORMAL)) {
11202 av_log(c->fc, AV_LOG_INFO, "grid box with non seekable input\n");
11203 return AVERROR_PATCHWELCOME;
11204 }
11205 if (item->is_idat_relative) {
11206 if (!c->idat_offset) {
11207 av_log(c->fc, AV_LOG_ERROR, "missing idat box required by the image grid\n");
11208 return AVERROR_INVALIDDATA;
11209 }
11210 offset = c->idat_offset;
11211 }
11212
11213 if (offset > INT64_MAX - item->extent_offset)
11214 return AVERROR_INVALIDDATA;
11215
11216 avio_seek(s->pb, item->extent_offset + offset, SEEK_SET);
11217
11218 avio_r8(s->pb); /* version */
11219 flags = avio_r8(s->pb);
11220
11221 tile_rows = avio_r8(s->pb) + 1;
11222 tile_cols = avio_r8(s->pb) + 1;
11223 /* actual width and height of output image */
11224 tile_grid->width = (flags & 1) ? avio_rb32(s->pb) : avio_rb16(s->pb);
11225 tile_grid->height = (flags & 1) ? avio_rb32(s->pb) : avio_rb16(s->pb);
11226
11227 av_log(c->fc, AV_LOG_TRACE, "grid: grid_rows %d grid_cols %d output_width %d output_height %d\n",
11228 tile_rows, tile_cols, tile_grid->width, tile_grid->height);
11229
11230 avio_seek(s->pb, pos, SEEK_SET);
11231
11233 tile_grid->nb_tiles = grid->nb_items;
11234
11235 if (tile_grid->nb_tiles != size)
11236 return AVERROR_INVALIDDATA;
11237
11238 for (int i = 0; i < tile_cols; i++)
11239 coded_width += grid->item_list[i]->width;
11240 for (int i = 0; i < size; i += tile_cols)
11241 coded_height += grid->item_list[i]->height;
11242
11243 if (coded_width > INT_MAX || coded_height > INT_MAX)
11244 return AVERROR_INVALIDDATA;
11245
11246 tile_grid->coded_width = coded_width;
11247 tile_grid->coded_height = coded_height;
11248
11249 tile_grid->offsets = av_calloc(tile_grid->nb_tiles, sizeof(*tile_grid->offsets));
11250 if (!tile_grid->offsets)
11251 return AVERROR(ENOMEM);
11252
11253 while (y < tile_grid->coded_height) {
11254 int left_col = i;
11255
11256 while (x < tile_grid->coded_width) {
11257 if (i == tile_grid->nb_tiles)
11258 return AVERROR_INVALIDDATA;
11259
11260 tile_grid->offsets[i].idx = grid->item_idx_list[i];
11261 tile_grid->offsets[i].horizontal = x;
11262 tile_grid->offsets[i].vertical = y;
11263
11264 x += grid->item_list[i++]->width;
11265 }
11266
11267 if (x > tile_grid->coded_width) {
11268 av_log(c->fc, AV_LOG_ERROR, "Non uniform HEIF tiles\n");
11269 return AVERROR_INVALIDDATA;
11270 }
11271
11272 x = 0;
11273 y += grid->item_list[left_col]->height;
11274 }
11275
11276 if (y > tile_grid->coded_height || i != tile_grid->nb_tiles) {
11277 av_log(c->fc, AV_LOG_ERROR, "Non uniform HEIF tiles\n");
11278 return AVERROR_INVALIDDATA;
11279 }
11280
11281 return 0;
11282}
11283
11285 AVStreamGroupTileGrid *tile_grid)
11286{
11287 MOVContext *c = s->priv_data;
11288 const HEIFItem *item = grid->item;
11289 uint16_t canvas_fill_value[4];
11290 int64_t offset = 0, pos = avio_tell(s->pb);
11291 int ret = 0, flags;
11292
11293 if (!(s->pb->seekable & AVIO_SEEKABLE_NORMAL)) {
11294 av_log(c->fc, AV_LOG_INFO, "iovl box with non seekable input\n");
11295 return AVERROR_PATCHWELCOME;
11296 }
11297 if (item->is_idat_relative) {
11298 if (!c->idat_offset) {
11299 av_log(c->fc, AV_LOG_ERROR, "missing idat box required by the image overlay\n");
11300 return AVERROR_INVALIDDATA;
11301 }
11302 offset = c->idat_offset;
11303 }
11304
11305 if (offset > INT64_MAX - item->extent_offset)
11306 return AVERROR_INVALIDDATA;
11307
11308 avio_seek(s->pb, item->extent_offset + offset, SEEK_SET);
11309
11310 avio_r8(s->pb); /* version */
11311 flags = avio_r8(s->pb);
11312
11313 for (int i = 0; i < 4; i++)
11314 canvas_fill_value[i] = avio_rb16(s->pb);
11315 av_log(c->fc, AV_LOG_TRACE, "iovl: canvas_fill_value { %u, %u, %u, %u }\n",
11316 canvas_fill_value[0], canvas_fill_value[1],
11317 canvas_fill_value[2], canvas_fill_value[3]);
11318 for (int i = 0; i < 4; i++)
11319 tile_grid->background[i] = canvas_fill_value[i];
11320
11321 /* actual width and height of output image */
11322 tile_grid->width =
11323 tile_grid->coded_width = (flags & 1) ? avio_rb32(s->pb) : avio_rb16(s->pb);
11324 tile_grid->height =
11325 tile_grid->coded_height = (flags & 1) ? avio_rb32(s->pb) : avio_rb16(s->pb);
11326
11327 av_log(c->fc, AV_LOG_TRACE, "iovl: output_width %d, output_height %d\n",
11328 tile_grid->width, tile_grid->height);
11329
11330 tile_grid->nb_tiles = grid->nb_items;
11331 tile_grid->offsets = av_malloc_array(tile_grid->nb_tiles, sizeof(*tile_grid->offsets));
11332 if (!tile_grid->offsets) {
11333 ret = AVERROR(ENOMEM);
11334 goto fail;
11335 }
11336
11337 for (int i = 0; i < tile_grid->nb_tiles; i++) {
11338 tile_grid->offsets[i].idx = grid->item_idx_list[i];
11339 tile_grid->offsets[i].horizontal = (flags & 1) ? avio_rb32(s->pb) : avio_rb16(s->pb);
11340 tile_grid->offsets[i].vertical = (flags & 1) ? avio_rb32(s->pb) : avio_rb16(s->pb);
11341 av_log(c->fc, AV_LOG_TRACE, "iovl: stream_idx[%d] %u, "
11342 "horizontal_offset[%d] %d, vertical_offset[%d] %d\n",
11343 i, tile_grid->offsets[i].idx,
11344 i, tile_grid->offsets[i].horizontal, i, tile_grid->offsets[i].vertical);
11345 }
11346
11347fail:
11348 avio_seek(s->pb, pos, SEEK_SET);
11349
11350 return ret;
11351}
11352
11354{
11355 MOVContext *c = s->priv_data;
11356 AVExifMetadata *ifd = &item->ifd;
11357 uint8_t *buf;
11358 int64_t offset = 0, pos = avio_tell(s->pb);
11359 unsigned orientation_id = av_exif_get_tag_id("Orientation");
11360 int err;
11361
11362 if (!(s->pb->seekable & AVIO_SEEKABLE_NORMAL)) {
11363 av_log(c->fc, AV_LOG_WARNING, "Exif metadata with non seekable input\n");
11364 return AVERROR_PATCHWELCOME;
11365 }
11366 if (ref->is_idat_relative) {
11367 if (!c->idat_offset) {
11368 av_log(c->fc, AV_LOG_ERROR, "missing idat box required by the Exif metadata\n");
11369 return AVERROR_INVALIDDATA;
11370 }
11371 offset = c->idat_offset;
11372 }
11373
11374 buf = av_malloc(ref->extent_length);
11375 if (!buf)
11376 return AVERROR(ENOMEM);
11377
11378 if (offset > INT64_MAX - ref->extent_offset) {
11379 err = AVERROR(ENOMEM);
11380 goto fail;
11381 }
11382
11383 avio_seek(s->pb, ref->extent_offset + offset, SEEK_SET);
11384 err = avio_read(s->pb, buf, ref->extent_length);
11385 if (err != ref->extent_length) {
11386 if (err > 0)
11387 err = AVERROR_INVALIDDATA;
11388 goto fail;
11389 }
11390
11391 // HEIF spec states that Exif metadata is informative. The irot item property is
11392 // the normative source of rotation information. So we remove any Orientation tag
11393 // present in the Exif buffer.
11394 err = av_exif_parse_buffer(s, buf, ref->extent_length, ifd, AV_EXIF_T_OFF);
11395 if (err < 0) {
11396 av_log(s, AV_LOG_ERROR, "Unable to parse Exif metadata\n");
11397 goto fail;
11398 }
11399
11400 err = av_exif_remove_entry(s, ifd, orientation_id, 0);
11401 if (err < 0)
11402 goto fail;
11403
11404 err = 0;
11405fail:
11406 av_free(buf);
11407 if (err < 0)
11408 av_exif_free(ifd);
11409 avio_seek(s->pb, pos, SEEK_SET);
11410
11411 return err;
11412}
11413
11415 AVPacketSideData **coded_side_data,
11416 int *nb_coded_side_data)
11417{
11418 int err;
11419
11420 /* exif */
11421 if (item->ifd.count) {
11422 err = set_exif_from_item(s, coded_side_data, nb_coded_side_data, item);
11423 if (err < 0)
11424 return err;
11425 }
11426
11427 /* rotation */
11428 if (item->rotation || item->hflip || item->vflip) {
11429 err = set_display_matrix_from_item(coded_side_data, nb_coded_side_data, item);
11430 if (err < 0)
11431 return err;
11432 }
11433
11434 /* ICC profile */
11435 if (item->icc_profile_size) {
11436 err = set_icc_profile_from_item(coded_side_data, nb_coded_side_data, item);
11437 if (err < 0)
11438 return err;
11439 }
11440
11441 return 0;
11442}
11443
11445 AVPacketSideData **coded_side_data,
11446 int *nb_coded_side_data)
11447{
11448 MOVContext *mov = s->priv_data;
11449 int err;
11450
11451 for (int j = 0; j < item->nb_iref_from_list; j++) {
11453
11454 av_assert0(ref);
11455 switch(ref->type) {
11456 case MKTAG('E','x','i','f'):
11457 err = mov_parse_exif_item(s, item, ref);
11458 if (err < 0 && (s->error_recognition & AV_EF_EXPLODE))
11459 return err;
11460 break;
11461 default:
11462 break;
11463 }
11464 }
11465
11466 err = mov_apply_heif_item_references(s, item, coded_side_data, nb_coded_side_data);
11467 if (err < 0)
11468 return err;
11469
11470 return 0;
11471}
11472
11474{
11475 MOVContext *mov = s->priv_data;
11476
11477 for (int i = 0; i < mov->nb_heif_group; i++) {
11478 AVStreamGroup *stg;
11479 AVStreamGroupTileGrid *tile_grid;
11480 const HEIFGroup *grid = &mov->heif_group[i];
11481 int err;
11482
11483 if (!grid->item || (grid->item->type != MKTAG('g','r','i','d') &&
11484 grid->item->type != MKTAG('i','o','v','l')))
11485 continue;
11486
11488 if (!stg)
11489 return AVERROR(ENOMEM);
11490
11491 stg->id = grid->item->item_id;
11492 tile_grid = stg->params.tile_grid;
11493
11494 for (int j = 0; j < grid->nb_items; j++) {
11495 int tile_id = grid->item_id_list[j];
11496 HEIFItem *item = get_heif_item(mov, tile_id);
11497 AVStream *st;
11498
11499 if (!item) {
11500 av_log(s, AV_LOG_WARNING, "HEIF item id %d referenced by grid id %d doesn't "
11501 "exist\n",
11502 tile_id, grid->item->item_id);
11504 stg = NULL;
11505 break;
11506 }
11507
11508 st = item->st;
11509 if (!st) {
11510 av_log(s, AV_LOG_WARNING, "HEIF item id %d from grid id %d doesn't "
11511 "reference a stream\n",
11512 tile_id, grid->item->item_id);
11514 stg = NULL;
11515 break;
11516 }
11517
11518 grid->item_list[j] = item;
11519 grid->item_idx_list[j] = stg->nb_entries;
11520
11521 err = avformat_stream_group_add_stream(stg, st);
11522 if (err < 0) {
11523 int l;
11524 if (err != AVERROR(EEXIST))
11525 return err;
11526
11527 for (l = 0; l < stg->nb_entries; l++)
11528 if (stg->entries[l]->stream->index == st->index)
11529 break;
11530 av_assert0(l < stg->nb_entries);
11531 grid->item_idx_list[j] = l;
11532 }
11533
11534 if (item->item_id != mov->primary_item_id)
11536 }
11537 if (!stg)
11538 continue;
11539
11540 switch (grid->item->type) {
11541 case MKTAG('g','r','i','d'):
11542 err = read_image_grid(s, grid, tile_grid);
11543 break;
11544 case MKTAG('i','o','v','l'):
11545 err = read_image_iovl(s, grid, tile_grid);
11546 break;
11547 default:
11548 av_assert0(0);
11549 }
11550 if (err < 0)
11551 return err;
11552
11554 &stg->nb_coded_side_data);
11555 if (err < 0)
11556 return err;
11557
11558 if (grid->item->name)
11559 av_dict_set(&stg->metadata, "title", grid->item->name, 0);
11560 if (grid->item->item_id == mov->primary_item_id)
11562
11563 grid->item->stg = stg;
11564 }
11565
11566 return 0;
11567}
11568
11570{
11571 MOVContext *mov = s->priv_data;
11572 AVStreamGroup *stg;
11573 AVStreamGroupLayeredVideo *layered_video;
11574 AVGainMapParams *gain = NULL;
11575 uint8_t *payload = NULL;
11576 int64_t pos, offset = 0;
11577 size_t gain_size;
11578 int64_t err64;
11579 int err;
11580
11581 if (!(s->pb->seekable & AVIO_SEEKABLE_NORMAL)) {
11582 av_log(s, AV_LOG_WARNING, "tmap box with non seekable input\n");
11583 return 0;
11584 }
11585
11587 if (!stg)
11588 return AVERROR(ENOMEM);
11589
11590 stg->id = tmap->item->item_id;
11591 layered_video = stg->params.layered_video;
11592
11593 for (int j = 0; j < tmap->nb_items; j++) {
11594 int item_id = tmap->item_id_list[j];
11595 HEIFItem *item = get_heif_item(mov, item_id);
11596 AVStreamGroup *child_stg;
11597 AVStream *st;
11598
11599 if (!item) {
11600 av_log(s, AV_LOG_WARNING, "HEIF item id %d referenced by tmap id %d doesn't "
11601 "exist\n",
11602 item_id, tmap->item->item_id);
11604 return 0;
11605 }
11606
11607 st = item->st;
11608 child_stg = item->stg;
11609 if (!st && !child_stg) {
11610 av_log(s, AV_LOG_WARNING, "HEIF item id %d from tmap id %d doesn't "
11611 "reference a stream or tmap\n",
11612 item_id, tmap->item->item_id);
11614 return 0;
11615 }
11616 av_assert0(!st != !child_stg);
11617
11618 tmap->item_list[j] = item;
11619
11620 if (st)
11621 err = avformat_stream_group_add_stream(stg, st);
11622 else
11623 err = avformat_stream_group_add_stream_group(stg, child_stg);
11624 if (err < 0) {
11625 if (err == AVERROR(EEXIST))
11626 err = AVERROR_INVALIDDATA;
11627
11628 return err;
11629 }
11630
11631 if ((item->flags & MOV_INFE_FLAG_HIDDEN)) {
11632 if (st)
11634 else
11636 }
11637 }
11638
11639 layered_video->width = tmap->item->width;
11640 layered_video->height = tmap->item->height;
11641
11642 if (tmap->item->is_idat_relative) {
11643 if (!mov->idat_offset) {
11644 av_log(s, AV_LOG_ERROR, "Missing idat box required by the tmap\n");
11645 return AVERROR_INVALIDDATA;
11646 }
11647 offset = mov->idat_offset;
11648 }
11649
11650 if (offset > INT64_MAX - tmap->item->extent_offset)
11651 return AVERROR_INVALIDDATA;
11652
11653 gain = av_gain_map_params_alloc(&gain_size);
11654 if (!gain)
11655 return AVERROR(ENOMEM);
11656
11657 payload = av_malloc(tmap->item->extent_length);
11658 if (!payload) {
11659 return AVERROR(ENOMEM);
11660 goto fail;
11661 }
11662
11663 pos = avio_tell(s->pb);
11664 err64 = avio_seek(s->pb, tmap->item->extent_offset + offset, SEEK_SET);
11665 if (err64 != tmap->item->extent_offset + offset) {
11666 err64 = err64 < 0 ? err64 : AVERROR_INVALIDDATA;
11667 goto fail;
11668 }
11669 avio_r8(s->pb); /* version */
11670
11671 err = avio_read(s->pb, payload, tmap->item->extent_length - 1);
11672 if (err == (tmap->item->extent_length - 1))
11673 err64 = avio_seek(s->pb, pos, SEEK_SET);
11674 else {
11675 err = err < 0 ? err : AVERROR_INVALIDDATA;
11676 goto fail;
11677 }
11678 if (err64 != pos) {
11679 err = err64 < 0 ? err64 : AVERROR_INVALIDDATA;
11680 goto fail;
11681 }
11682
11683 err = av_gain_map_params_from_iso21496(gain, payload, tmap->item->extent_length - 1);
11684 av_freep(&payload);
11685 if (err < 0) {
11686 av_log(s, AV_LOG_ERROR, "Invalid ISO 21496-1 gain map payload\n");
11688 err = (s->error_recognition & (AV_EF_COMPLIANT|AV_EF_EXPLODE)) ? AVERROR_INVALIDDATA : 0;
11689 goto fail;
11690 }
11691 for (int j = 0; j < tmap->nb_items; j++) {
11692 HEIFItem *item = tmap->item_list[j];
11693 AVPacketSideData *sd;
11694 AVPacketSideData **coded_side_data;
11695 int *nb_coded_side_data;
11696
11697 if (!(item->flags & MOV_INFE_FLAG_HIDDEN))
11698 continue;
11699
11700 layered_video->el_index = j;
11701
11702 if (item->st) {
11703 coded_side_data = &item->st->codecpar->coded_side_data;
11704 nb_coded_side_data = &item->st->codecpar->nb_coded_side_data;
11705 } else {
11706 av_assert0(item->stg);
11707 coded_side_data = &item->stg->coded_side_data;
11708 nb_coded_side_data = &item->stg->nb_coded_side_data;
11709 }
11710
11711 sd = av_packet_side_data_add(coded_side_data, nb_coded_side_data,
11713 (uint8_t *)gain, gain_size, 0);
11714 if (!sd) {
11715 av_free(gain);
11716 return AVERROR(ENOMEM);
11717 }
11718 gain = NULL;
11719
11720 for (int k = 0; k < item->nb_iref_to_list; k++) {
11721 HEIFItem *ref = get_heif_item(mov, item->iref_to_list[k].item_id);
11722
11723 av_assert0(ref);
11724 // Remove auxl reference so we don't create the same group we made with
11725 // this tmap using it. Strictly speaking, the chances for Apple style
11726 // Exif values being present on a base item referenced by a tmap item
11727 // are very low, but better safe than sorry.
11728 if (item->iref_to_list[k].type == MKTAG('a','u','x','l') &&
11729 (ref == tmap->item_list[!j])) {
11730 if (k != (item->nb_iref_to_list - 1))
11731 item->iref_to_list[k] = item->iref_to_list[item->nb_iref_to_list - 1];
11732 --item->nb_iref_to_list;
11733 break;
11734 }
11735 }
11736 break;
11737 }
11738 av_free(gain);
11739
11741 &stg->nb_coded_side_data);
11742 if (err < 0)
11743 return err;
11744
11745 if (tmap->item->name)
11746 av_dict_set(&stg->metadata, "title", tmap->item->name, 0);
11747 if (tmap->item->item_id == mov->primary_item_id)
11749
11750 tmap->item->stg = stg;
11751
11752 return 0;
11753fail:
11754 av_free(gain);
11755 av_free(payload);
11756
11757 return err;
11758}
11759
11762{
11763 AVStreamGroupLayeredVideo *layered_video;
11764 AVStreamGroup *stg;
11765 int err;
11766
11767 if ((!alpha->st && !alpha->stg) ||
11768 (!base->st && !base->stg)) {
11769 av_log(s, AV_LOG_WARNING, "HEIF alpha id %d or its base doesn't reference "
11770 "a stream or group\n",
11771 alpha->item_id);
11772 return 0;
11773 }
11774
11776 if (!stg)
11777 return AVERROR(ENOMEM);
11778
11779 stg->id = alpha->item_id;
11780 layered_video = stg->params.layered_video;
11781
11782 layered_video->width = base->width;
11783 layered_video->height = base->height;
11784 layered_video->el_index = 1;
11785
11786 av_assert0(!base->st != !base->stg);
11787 if (base->st)
11788 err = avformat_stream_group_add_stream(stg, base->st);
11789 else
11791 if (err < 0) {
11792 if (err == AVERROR(EEXIST))
11793 err = AVERROR_INVALIDDATA;
11794 return err;
11795 }
11796
11797 av_assert0(!alpha->st != !alpha->stg);
11798 if (alpha->st)
11800 else
11802 if (err < 0) {
11803 if (err == AVERROR(EEXIST))
11804 err = AVERROR_INVALIDDATA;
11805 return err;
11806 }
11807
11808 // Apply all references from the base image to the Alpha group
11810 &stg->nb_coded_side_data);
11811 if (err < 0)
11812 return err;
11813
11814 return 0;
11815}
11816
11817// Parse Apple style Gain Map metadata from Exif values
11818// See https://developer.apple.com/documentation/appkit/applying-apple-hdr-effect-to-your-photos
11820 HEIFItem *base, HEIFItem *gain_map)
11821{
11822 AVStreamGroupLayeredVideo *layered_video;
11823 AVStreamGroup *stg;
11824 AVGainMapParams *gain;
11825 AVPacketSideData **coded_side_data;
11826 int *nb_coded_side_data;
11827 AVExifEntry *entry, *maker33 = NULL, *maker48 = NULL;
11828 double maker_33 = 0.0, maker_48 = 0.0, headroom;
11829 size_t gain_size;
11830 int err;
11831
11832 if ((!gain_map->st && !gain_map->stg) ||
11833 (!base->st && !base->stg)) {
11834 av_log(s, AV_LOG_WARNING, "HEIF gain_map id %d or its base doesn't reference "
11835 "a stream or group\n",
11836 gain_map->item_id);
11837 return 0;
11838 }
11839
11840 if (!base->ifd.count)
11841 return 0;
11842
11843 err = av_exif_get_entry(s, &base->ifd, 0x8769, 0, &entry);
11844 if (err > 0)
11845 err = av_exif_get_entry(s, &entry->value.ifd, 0x927c, 0, &entry);
11846 if (err > 0) {
11847 av_exif_get_entry(s, &entry->value.ifd, 0x21, 0, &maker33);
11848 av_exif_get_entry(s, &entry->value.ifd, 0x30, 0, &maker48);
11849 }
11850 if ((!maker33 && !maker48) ||
11851 (maker33 && maker33->type != AV_TIFF_SRATIONAL) ||
11852 (maker48 && maker48->type != AV_TIFF_SRATIONAL))
11853 return 0;
11854
11855 if (maker33)
11856 maker_33 = av_q2d(*maker33->value.rat);
11857 if (maker48)
11858 maker_48 = av_q2d(*maker48->value.rat);
11859
11860 if (maker_33 < 1.0) {
11861 if (maker_48 <= 0.01) {
11862 headroom = -20.0 * maker_48 + 1.8;
11863 } else {
11864 headroom = -0.101 * maker_48 + 1.601;
11865 }
11866 } else {
11867 if (maker_48 <= 0.01) {
11868 headroom = -70.0 * maker_48 + 3.0;
11869 } else {
11870 headroom = -0.303 * maker_48 + 2.303;
11871 }
11872 }
11873 if (headroom <= 0.0)
11874 return 0;
11875
11877 if (!stg)
11878 return AVERROR(ENOMEM);
11879
11880 stg->id = gain_map->item_id;
11881 layered_video = stg->params.layered_video;
11882
11883 layered_video->width = base->width;
11884 layered_video->height = base->height;
11885 layered_video->el_index = 1;
11886
11887 av_assert0(!base->st != !base->stg);
11888 if (base->st)
11889 err = avformat_stream_group_add_stream(stg, base->st);
11890 else
11892 if (err < 0) {
11893 if (err == AVERROR(EEXIST))
11894 err = AVERROR_INVALIDDATA;
11895 return err;
11896 }
11897
11898 av_assert0(!gain_map->st != !gain_map->stg);
11899 if (gain_map->st) {
11900 coded_side_data = &gain_map->st->codecpar->coded_side_data;
11901 nb_coded_side_data = &gain_map->st->codecpar->nb_coded_side_data;
11902 err = avformat_stream_group_add_stream(stg, gain_map->st);
11903 } else {
11904 coded_side_data = &gain_map->stg->coded_side_data;
11905 nb_coded_side_data = &gain_map->stg->nb_coded_side_data;
11906 err = avformat_stream_group_add_stream_group(stg, gain_map->stg);
11907 }
11908 if (err < 0) {
11909 if (err == AVERROR(EEXIST))
11910 err = AVERROR_INVALIDDATA;
11911 return err;
11912 }
11913
11914 gain = av_gain_map_params_alloc(&gain_size);
11915 if (!gain)
11916 return AVERROR(ENOMEM);
11917
11918 gain->use_base_color_space = 1;
11919 gain->alternate_hdr_headroom = av_d2q(headroom, INT_MAX);
11920 gain->nb_channels = 1;
11921 gain->channels[0].base_offset = (AVRational) { 0, 1 };
11922 gain->channels[0].alternate_offset = (AVRational) { 0, 1 };
11924
11925 AVPacketSideData *sd = av_packet_side_data_add(coded_side_data, nb_coded_side_data,
11927 (uint8_t *)gain, gain_size, 0);
11928 if (!sd) {
11929 av_free(gain);
11930 return AVERROR(ENOMEM);
11931 }
11932
11933 // Apply all references from the base image except Exif to the Gain Map group
11934 int count = base->ifd.count;
11935 base->ifd.count = 0;
11937 &stg->nb_coded_side_data);
11938 base->ifd.count = count;
11939 if (err < 0)
11940 return err;
11941
11942 return 0;
11943}
11944
11946{
11947 MOVContext *mov = s->priv_data;
11948 int err;
11949
11950 for (int i = 0; i < mov->nb_heif_group; i++) {
11951 const HEIFGroup *tmap = &mov->heif_group[i];
11952
11953 if (!tmap->item)
11954 continue;
11955
11956 switch (tmap->item->type) {
11957 case MKTAG('t','m','a','p'):
11959 if (err < 0)
11960 return err;
11961 break;
11962 default:
11963 break;
11964 }
11965 }
11966
11967 for (int i = 0; i < mov->nb_heif_item; i++) {
11968 HEIFItem *item = mov->heif_item[i];
11969 int err;
11970
11971 if (!item)
11972 continue;
11973
11974 for (int j = 0; j < item->nb_iref_to_list; j++) {
11975 HEIFItem *ref = get_heif_item(mov, item->iref_to_list[j].item_id);
11976
11977 av_assert0(ref);
11978 switch(item->iref_to_list[j].type) {
11979 case MKTAG('a','u','x','l'):
11980 if (item->is_alpha) {
11982 if (err < 0)
11983 return err;
11984 break;
11985 }
11986 if (item->is_gainmap) {
11988 if (err < 0)
11989 return err;
11990 break;
11991 }
11992 }
11993 }
11994 }
11995
11996 return 0;
11997}
11998
12000{
12001 MOVContext *mov = s->priv_data;
12002 int err;
12003
12004 for (int i = 0; i < mov->nb_heif_item; i++) {
12005 HEIFItem *item = mov->heif_item[i];
12006 MOVStreamContext *sc;
12007 AVStream *st;
12008 int64_t offset = 0;
12009
12010 if (!item)
12011 continue;
12012 if (!item->st) {
12013 continue;
12014 }
12015 if (item->is_idat_relative) {
12016 if (!mov->idat_offset) {
12017 av_log(s, AV_LOG_ERROR, "Missing idat box for item %d\n", item->item_id);
12018 return AVERROR_INVALIDDATA;
12019 }
12020 offset = mov->idat_offset;
12021 }
12022
12023 st = item->st;
12024 sc = st->priv_data;
12025 st->codecpar->width = item->width;
12026 st->codecpar->height = item->height;
12027
12028 sc->sample_size = sc->stsz_sample_size = item->extent_length;
12029 sc->sample_count = 1;
12030
12031 err = sanity_checks(s, sc, st->index);
12032 if (err)
12033 return AVERROR_INVALIDDATA;
12034
12035 if (offset > INT64_MAX - item->extent_offset)
12036 return AVERROR_INVALIDDATA;
12037
12038 sc->chunk_offsets[0] = item->extent_offset + offset;
12039
12042 if (err < 0)
12043 return err;
12044
12045 if (item->name)
12046 av_dict_set(&st->metadata, "title", item->name, 0);
12047 if (item->item_id == mov->primary_item_id)
12049
12050 mov_build_index(mov, st);
12051 }
12052
12053 err = mov_parse_tiles(s);
12054 if (err < 0)
12055 return err;
12056
12058 if (err < 0)
12059 return err;
12060
12061 return 0;
12062}
12063
12065{
12066 int err;
12067
12068 for (int i = 0; i < s->nb_streams; i++) {
12069 AVStreamGroup *stg;
12070 const AVDictionaryEntry *tcr;
12071 AVStream *st = s->streams[i];
12072
12073 if (st->codecpar->codec_tag != MKTAG('t','m','c','d'))
12074 continue;
12075
12077 if (!stg)
12078 return AVERROR(ENOMEM);
12079
12080 stg->id = st->id;
12081 tcr = av_dict_get(st->metadata, "timecode", NULL, 0);
12082
12083 for (int j = 0; j < s->nb_streams; j++) {
12084 AVStream *st2 = s->streams[j];
12085 MOVStreamContext *sc2 = st2->priv_data;
12086 MovTref *tag = mov_find_tref_tag(sc2, MKTAG('t','m','c','d'));
12087
12088 if (!tag)
12089 continue;
12090
12091 for (int k = 0; k < tag->nb_id; k++) {
12092 if (tag->id[k] != st->id)
12093 continue;
12094
12095 err = avformat_stream_group_add_stream(stg, st2);
12096 if (err < 0)
12097 return err;
12098
12099 if (tcr)
12100 av_dict_set(&st2->metadata, "timecode", tcr->value, AV_DICT_DONT_OVERWRITE);
12101 }
12102 }
12103
12104 if (!stg->nb_entries) {
12106 continue;
12107 }
12108
12109 err = avformat_stream_group_add_stream(stg, st);
12110 if (err < 0)
12111 return err;
12112
12113 stg->params.tref->metadata_index = stg->nb_entries - 1;
12114 }
12116
12117 return 0;
12118}
12119
12121 uint32_t *tref_id, int nb_tref_id, int first_index)
12122{
12123 if (!nb_tref_id)
12124 return NULL;
12125
12126 for (int i = first_index; i < s->nb_streams; i++)
12127 for (int j = 0; j < nb_tref_id; j++)
12128 if (s->streams[i]->index != st->index &&
12129 s->streams[i]->id == tref_id[j])
12130 return s->streams[i];
12131
12132 return NULL;
12133}
12134
12136{
12137 static const uint32_t tref_tags[] = {
12138 MKTAG('c','d','s','c'),
12139 MKTAG('r','n','d','r'),
12140 };
12141
12142 int err;
12143
12144 // Don't try to add a group if there's only one track
12145 if (s->nb_streams <= 1)
12146 return 0;
12147
12148 for (int i = 0; i < s->nb_streams; i++) {
12149 AVStream *st = s->streams[i];
12150 MOVStreamContext *sc = st->priv_data;
12151
12152 for (int c = 0; c < FF_ARRAY_ELEMS(tref_tags); c++) {
12153 AVStreamGroup *stg;
12154 AVStream *st_ref;
12155 MovTref *tag = mov_find_tref_tag(sc, tref_tags[c]);
12156
12157 if (!tag)
12158 continue;
12159
12160 st_ref = mov_find_reference_track(s, st, tag->id, tag->nb_id, 0);
12161 if (!st_ref) {
12162 av_log(s, AV_LOG_WARNING, "Failed to find referenced stream\n");
12163 continue;
12164 }
12165
12167 if (!stg)
12168 return AVERROR(ENOMEM);
12169
12170 stg->id = st_ref->id;
12171
12172 err = avformat_stream_group_add_stream(stg, st_ref);
12173 if (err < 0)
12174 return err;
12175
12176 err = avformat_stream_group_add_stream(stg, st);
12177 if (err < 0)
12178 return err;
12179
12180 stg->params.tref->metadata_index = stg->nb_entries - 1;
12181 }
12182 }
12183
12184 return 0;
12185}
12186
12188{
12189 int err;
12190
12191 // Don't try to add a group if there's only one track
12192 if (s->nb_streams <= 1)
12193 return 0;
12194
12195 for (int i = 0; i < s->nb_streams; i++) {
12196 AVStreamGroup *stg;
12197 AVStream *st = s->streams[i];
12198 AVStream *st_base;
12199 MOVStreamContext *sc = st->priv_data;
12200 MovTref *tag = mov_find_tref_tag(sc, MKTAG('s','b','a','s'));
12201 int j = 0;
12202
12203 /* Find an enhancement stream. */
12204 if (st->codecpar->codec_id != AV_CODEC_ID_LCEVC || !tag)
12205 continue;
12206
12208 if (!stg)
12209 return AVERROR(ENOMEM);
12210
12211 stg->id = st->id;
12214
12215 while (st_base = mov_find_reference_track(s, st, tag->id, tag->nb_id, j)) {
12216 err = avformat_stream_group_add_stream(stg, st_base);
12217 if (err < 0)
12218 return err;
12219
12220 j = st_base->index + 1;
12221 }
12222 if (!j) {
12223 int loglevel = (s->error_recognition & AV_EF_EXPLODE) ? AV_LOG_ERROR : AV_LOG_WARNING;
12224 av_log(s, loglevel, "Failed to find base stream for LCEVC stream\n");
12226 if (s->error_recognition & AV_EF_EXPLODE)
12227 return AVERROR_INVALIDDATA;
12228 continue;
12229 }
12230
12231 err = avformat_stream_group_add_stream(stg, st);
12232 if (err < 0)
12233 return err;
12234
12235 stg->params.layered_video->el_index = stg->nb_entries - 1;
12236 }
12237
12238 return 0;
12239}
12240
12242{
12243 int err;
12244
12245 if (s->nb_streams <= 1)
12246 return 0;
12247
12248 /* Identify legacy dual-track Dolby Vision profile 7 carriage per Annex
12249 * C of "Dolby Vision Streams Within the ISO Base Media File Format",
12250 * v2.7.1. The 'vdep' track reference type is shared with depth video
12251 * and multi-view dependencies. The spec-mandated DV-specific sample
12252 * entry combined with the dvcC configuration record disambiguates
12253 * those uses. */
12254 for (int i = 0; i < s->nb_streams; i++) {
12255 AVStreamGroup *stg;
12256 AVStream *st = s->streams[i];
12257 AVStream *st_base;
12258 MOVStreamContext *sc = st->priv_data;
12259 MovTref *tag = mov_find_tref_tag(sc, MKTAG('v','d','e','p'));
12260 const AVPacketSideData *sd;
12262
12263 if (st->codecpar->codec_id != AV_CODEC_ID_HEVC || !tag)
12264 continue;
12265
12266 if (st->codecpar->codec_tag != MKTAG('d','v','h','e') &&
12267 st->codecpar->codec_tag != MKTAG('d','v','h','1'))
12268 continue;
12269
12273 if (!sd)
12274 continue;
12275 dovi = (const AVDOVIDecoderConfigurationRecord *)sd->data;
12276
12277 /* EL track of a dual-track stream: rpu_present_flag = 1,
12278 * el_present_flag = 1, bl_present_flag = 0, dv_profile = 7. */
12279 if (dovi->dv_profile != 7 || !dovi->rpu_present_flag ||
12280 !dovi->el_present_flag || dovi->bl_present_flag)
12281 continue;
12282
12283 st_base = mov_find_reference_track(s, st, tag->id, tag->nb_id, 0);
12284 if (!st_base) {
12285 int loglevel = (s->error_recognition & AV_EF_EXPLODE) ? AV_LOG_ERROR : AV_LOG_WARNING;
12286 av_log(s, loglevel, "Failed to find base layer for Dolby Vision EL stream\n");
12287 if (s->error_recognition & AV_EF_EXPLODE)
12288 return AVERROR_INVALIDDATA;
12289 continue;
12290 }
12291
12293 if (!stg)
12294 return AVERROR(ENOMEM);
12295
12296 stg->id = st->id;
12297
12298 err = avformat_stream_group_add_stream(stg, st_base);
12299 if (err < 0)
12300 return err;
12301
12302 err = avformat_stream_group_add_stream(stg, st);
12303 if (err < 0)
12304 return err;
12305
12306 stg->params.layered_video->el_index = stg->nb_entries - 1;
12307 stg->params.layered_video->width = st_base->codecpar->width;
12308 stg->params.layered_video->height = st_base->codecpar->height;
12309 }
12310
12311 return 0;
12312}
12313
12315{
12316 int highest_id = 0, lowest_iamf_id = INT_MAX;
12317
12318 for (int i = 0; i < s->nb_streams; i++) {
12319 const AVStream *st = s->streams[i];
12320 const MOVStreamContext *sc = st->priv_data;
12321 if (!sc->iamf)
12322 highest_id = FFMAX(highest_id, st->id);
12323 }
12324
12325 for (int i = 0; i < s->nb_stream_groups; i++) {
12326 AVStreamGroup *stg = s->stream_groups[i];
12328 continue;
12329 for (int j = 0; j < stg->nb_entries; j++) {
12330 AVStream *st = stg->entries[j]->stream;
12331 lowest_iamf_id = FFMIN(lowest_iamf_id, st->id);
12332 }
12333 }
12334
12335 if (highest_id < lowest_iamf_id)
12336 return;
12337
12338 highest_id += !lowest_iamf_id;
12339 for (int i = 0; highest_id > 1 && i < s->nb_stream_groups; i++) {
12340 AVStreamGroup *stg = s->stream_groups[i];
12342 continue;
12343 for (int j = 0; j < stg->nb_entries; j++) {
12344 AVStream *st = stg->entries[j]->stream;
12345 MOVStreamContext *sc = st->priv_data;
12346 st->id += highest_id;
12347 sc->iamf_stream_offset = highest_id;
12348 }
12349 }
12350}
12351
12353{
12354 MOVContext *mov = s->priv_data;
12355 AVIOContext *pb = s->pb;
12356 int j, err;
12357 MOVAtom atom = { AV_RL32("root") };
12358 int i;
12359
12360 mov->fc = s;
12361 mov->trak_index = -1;
12362 mov->primary_item_id = -1;
12363 mov->cur_item_id = -1;
12364 /* .mov and .mp4 aren't streamable anyway (only progressive download if moov is before mdat) */
12366 atom.size = avio_size(pb);
12367 else
12368 atom.size = INT64_MAX;
12369
12370 /* check MOV header */
12371 do {
12372 if (mov->moov_retry)
12373 avio_seek(pb, 0, SEEK_SET);
12374 if ((err = mov_read_default(mov, pb, atom)) < 0) {
12375 av_log(s, AV_LOG_ERROR, "error reading header\n");
12376 return err;
12377 }
12378 } while ((pb->seekable & AVIO_SEEKABLE_NORMAL) &&
12379 !mov->found_moov && (!mov->found_iloc || !mov->found_iinf) && !mov->moov_retry++);
12380 if (!mov->found_moov && !mov->found_iloc && !mov->found_iinf) {
12381 av_log(s, AV_LOG_ERROR, "moov atom not found\n");
12382 return AVERROR_INVALIDDATA;
12383 }
12384 av_log(mov->fc, AV_LOG_TRACE, "on_parse_exit_offset=%"PRId64"\n", avio_tell(pb));
12385
12386 if (mov->found_iloc && mov->found_iinf) {
12387 err = mov_parse_heif_items(s);
12388 if (err < 0)
12389 return err;
12390 }
12391 // prevent iloc and iinf boxes from being parsed while reading packets.
12392 // this is needed because an iinf box may have been parsed but ignored
12393 // for having old infe boxes which create no streams.
12394 mov->found_iloc = mov->found_iinf = 1;
12395
12396 if (pb->seekable & AVIO_SEEKABLE_NORMAL) {
12397 if (mov->nb_chapter_tracks > 0 && !mov->ignore_chapters)
12399 for (i = 0; i < s->nb_streams; i++)
12400 if (s->streams[i]->codecpar->codec_tag == AV_RL32("tmcd")) {
12401 mov_read_timecode_track(s, s->streams[i]);
12402 } else if (s->streams[i]->codecpar->codec_tag == AV_RL32("rtmd")) {
12403 mov_read_rtmd_track(s, s->streams[i]);
12404 }
12405 }
12406
12407 /* Create metadata stream groups. */
12409 if (err < 0)
12410 return err;
12411
12412 /* copy timecode metadata from tmcd tracks to the related video streams */
12414 if (err < 0)
12415 return err;
12416
12417 /* Create LCEVC stream groups. */
12419 if (err < 0)
12420 return err;
12421
12422 /* Create Dolby Vision Profile 7 stream groups. */
12424 if (err < 0)
12425 return err;
12426
12427 for (i = 0; i < s->nb_streams; i++) {
12428 AVStream *st = s->streams[i];
12429 FFStream *const sti = ffstream(st);
12430 MOVStreamContext *sc = st->priv_data;
12431 uint32_t dvdsub_clut[FF_DVDCLUT_CLUT_LEN] = {0};
12432 fix_timescale(mov, sc);
12433
12434 /* Set the primary extradata based on the first Sample if it doesn't reference the first stsd entry. */
12435 if (sc->stsc_count && sc->extradata_size && !sc->iamf &&
12436 sc->stsc_data[0].id > 1 && sc->stsc_data[0].id <= sc->stsd_count) {
12437 sc->last_stsd_index = sc->stsc_data[0].id - 1;
12440 if (sc->extradata_size[sc->last_stsd_index]) {
12442 if (!st->codecpar->extradata)
12443 return AVERROR(ENOMEM);
12445 }
12446 }
12447
12451 }
12454 sc->time_scale*(int64_t)sc->nb_frames_for_fps, sc->duration_for_fps, INT_MAX);
12456 if (st->codecpar->width <= 0 || st->codecpar->height <= 0) {
12457 st->codecpar->width = sc->width;
12458 st->codecpar->height = sc->height;
12459 }
12462
12463 for (j = 0; j < FF_DVDCLUT_CLUT_LEN; j++)
12464 dvdsub_clut[j] = AV_RB32(st->codecpar->extradata + j * 4);
12465
12466 err = ff_dvdclut_yuv_to_rgb(dvdsub_clut, FF_DVDCLUT_CLUT_SIZE);
12467 if (err < 0)
12468 return err;
12469
12471 st->codecpar->extradata_size = 0;
12472
12474 st->codecpar);
12475 if (err < 0)
12476 return err;
12477 }
12478 }
12479 if (mov->handbrake_version &&
12480 mov->handbrake_version <= 1000000*0 + 1000*10 + 2 && // 0.10.2
12482 av_log(s, AV_LOG_VERBOSE, "Forcing full parsing for mp3 stream\n");
12484 }
12485 }
12486
12487 if (mov->trex_data || mov->use_mfra_for > 0) {
12488 for (i = 0; i < s->nb_streams; i++) {
12489 AVStream *st = s->streams[i];
12490 MOVStreamContext *sc = st->priv_data;
12491 if (sc->duration_for_fps > 0) {
12492 /* Akin to sc->data_size * 8 * sc->time_scale / sc->duration_for_fps but accounting for overflows. */
12494 if (st->codecpar->bit_rate == INT64_MIN) {
12495 av_log(s, AV_LOG_WARNING, "Overflow during bit rate calculation %"PRId64" * 8 * %d\n",
12496 sc->data_size, sc->time_scale);
12497 st->codecpar->bit_rate = 0;
12498 if (s->error_recognition & AV_EF_EXPLODE)
12499 return AVERROR_INVALIDDATA;
12500 }
12501 }
12502 }
12503 }
12504
12505 for (i = 0; i < mov->bitrates_count && i < s->nb_streams; i++) {
12506 if (mov->bitrates[i]) {
12507 s->streams[i]->codecpar->bit_rate = mov->bitrates[i];
12508 }
12509 }
12510
12512
12513 for (i = 0; i < s->nb_streams; i++) {
12514 AVStream *st = s->streams[i];
12515 MOVStreamContext *sc = st->priv_data;
12516
12517 switch (st->codecpar->codec_type) {
12518 case AVMEDIA_TYPE_AUDIO:
12519 err = ff_replaygain_export(st, s->metadata);
12520 if (err < 0)
12521 return err;
12522 break;
12523 case AVMEDIA_TYPE_VIDEO:
12524 if (sc->display_matrix) {
12527 (uint8_t*)sc->display_matrix, sizeof(int32_t) * 9, 0))
12528 return AVERROR(ENOMEM);
12529
12530 sc->display_matrix = NULL;
12531 }
12532 if (sc->stereo3d) {
12535 (uint8_t *)sc->stereo3d, sc->stereo3d_size, 0))
12536 return AVERROR(ENOMEM);
12537
12538 sc->stereo3d = NULL;
12539 }
12540 if (sc->spherical) {
12543 (uint8_t *)sc->spherical, sc->spherical_size, 0))
12544 return AVERROR(ENOMEM);
12545
12546 sc->spherical = NULL;
12547 }
12548 if (sc->mastering) {
12551 (uint8_t *)sc->mastering, sc->mastering_size, 0))
12552 return AVERROR(ENOMEM);
12553
12554 sc->mastering = NULL;
12555 }
12556 if (sc->coll) {
12559 (uint8_t *)sc->coll, sc->coll_size, 0))
12560 return AVERROR(ENOMEM);
12561
12562 sc->coll = NULL;
12563 }
12564 if (sc->ambient) {
12567 (uint8_t *) sc->ambient, sc->ambient_size, 0))
12568 return AVERROR(ENOMEM);
12569
12570 sc->ambient = NULL;
12571 }
12572 break;
12573 }
12574 }
12575
12577
12579
12580 for (i = 0; i < mov->frag_index.nb_items; i++)
12581 if (mov->frag_index.item[i].moof_offset <= mov->fragment.moof_offset)
12582 mov->frag_index.item[i].headers_read = 1;
12583
12584 return 0;
12585}
12586
12588{
12590 int64_t best_dts = INT64_MAX;
12591 int i;
12592 MOVContext *mov = s->priv_data;
12593 int no_interleave = !mov->interleaved_read || !(s->pb->seekable & AVIO_SEEKABLE_NORMAL);
12594 for (i = 0; i < s->nb_streams; i++) {
12595 AVStream *avst = s->streams[i];
12596 FFStream *const avsti = ffstream(avst);
12597 MOVStreamContext *msc = avst->priv_data;
12598 if (msc->pb && msc->current_sample < avsti->nb_index_entries) {
12599 AVIndexEntry *current_sample = &avsti->index_entries[msc->current_sample];
12600 int64_t dts = av_rescale(current_sample->timestamp, AV_TIME_BASE, msc->time_scale);
12601 uint64_t dtsdiff = best_dts > dts ? best_dts - (uint64_t)dts : ((uint64_t)dts - best_dts);
12602 av_log(s, AV_LOG_TRACE, "stream %d, sample %d, dts %"PRId64"\n", i, msc->current_sample, dts);
12603 if (!sample || (no_interleave && current_sample->pos < sample->pos) ||
12604 ((s->pb->seekable & AVIO_SEEKABLE_NORMAL) &&
12605 ((msc->pb != s->pb && dts < best_dts) || (msc->pb == s->pb && dts != AV_NOPTS_VALUE &&
12606 ((dtsdiff <= AV_TIME_BASE && current_sample->pos < sample->pos) ||
12607 (dtsdiff > AV_TIME_BASE && dts < best_dts && mov->interleaved_read)))))) {
12608 sample = current_sample;
12609 best_dts = dts;
12610 *st = avst;
12611 }
12612 }
12613 }
12614 return sample;
12615}
12616
12617static int should_retry(AVIOContext *pb, int error_code) {
12618 if (error_code == AVERROR_EOF || avio_feof(pb))
12619 return 0;
12620
12621 return 1;
12622}
12623
12625{
12626 int ret;
12627 MOVContext *mov = s->priv_data;
12628
12629 if (index >= 0 && index < mov->frag_index.nb_items)
12630 target = mov->frag_index.item[index].moof_offset;
12631 if (target >= 0 && avio_seek(s->pb, target, SEEK_SET) != target) {
12632 av_log(mov->fc, AV_LOG_ERROR, "root atom offset 0x%"PRIx64": partial file\n", target);
12633 return AVERROR_INVALIDDATA;
12634 }
12635
12636 mov->next_root_atom = 0;
12637 if ((index < 0 && target >= 0) || index >= mov->frag_index.nb_items)
12638 index = search_frag_moof_offset(&mov->frag_index, target);
12639 if (index >= 0 && index < mov->frag_index.nb_items &&
12640 mov->frag_index.item[index].moof_offset == target) {
12641 if (index + 1 < mov->frag_index.nb_items)
12644 return 0;
12646 }
12647
12648 mov->found_mdat = 0;
12649 mov->pssh_side_data = NULL;
12650
12651 ret = mov_read_default(mov, s->pb, (MOVAtom){ AV_RL32("root"), INT64_MAX });
12652 if (ret < 0)
12653 return ret;
12654 if (avio_feof(s->pb))
12655 return AVERROR_EOF;
12656 av_log(s, AV_LOG_TRACE, "read fragments, offset 0x%"PRIx64"\n", avio_tell(s->pb));
12657
12658 return 1;
12659}
12660
12662{
12663 MOVStreamContext *sc = st->priv_data;
12664 uint8_t *side, *extradata;
12665 int extradata_size;
12666
12667 /* Save the current index. */
12668 sc->last_stsd_index = sc->stsc_data[sc->stsc_index].id - 1;
12669
12670 /* Notify the decoder that extradata changed. */
12671 extradata_size = sc->extradata_size[sc->last_stsd_index];
12672 extradata = sc->extradata[sc->last_stsd_index];
12673 if (st->discard != AVDISCARD_ALL && extradata_size > 0 && extradata) {
12676 extradata_size);
12677 if (!side)
12678 return AVERROR(ENOMEM);
12679 memcpy(side, extradata, extradata_size);
12680 }
12681
12682 return 0;
12683}
12684
12685static int get_eia608_packet(AVIOContext *pb, AVPacket *pkt, int src_size)
12686{
12687 /* We can't make assumptions about the structure of the payload,
12688 because it may include multiple cdat and cdt2 samples. */
12689 const uint32_t cdat = AV_RB32("cdat");
12690 const uint32_t cdt2 = AV_RB32("cdt2");
12691 int ret, out_size = 0;
12692
12693 /* a valid payload must have size, 4cc, and at least 1 byte pair: */
12694 if (src_size < 10)
12695 return AVERROR_INVALIDDATA;
12696
12697 /* avoid an int overflow: */
12698 if ((src_size - 8) / 2 >= INT_MAX / 3)
12699 return AVERROR_INVALIDDATA;
12700
12701 ret = av_new_packet(pkt, ((src_size - 8) / 2) * 3);
12702 if (ret < 0)
12703 return ret;
12704
12705 /* parse and re-format the c608 payload in one pass. */
12706 while (src_size >= 10) {
12707 const uint32_t atom_size = avio_rb32(pb);
12708 const uint32_t atom_type = avio_rb32(pb);
12709 const uint32_t data_size = atom_size - 8;
12710 const uint8_t cc_field =
12711 atom_type == cdat ? 1 :
12712 atom_type == cdt2 ? 2 :
12713 0;
12714
12715 /* account for bytes consumed for atom size and type. */
12716 src_size -= 8;
12717
12718 /* make sure the data size stays within the buffer boundaries. */
12719 if (data_size < 2 || data_size > src_size) {
12721 break;
12722 }
12723
12724 /* make sure the data size is consistent with N byte pairs. */
12725 if (data_size % 2 != 0) {
12727 break;
12728 }
12729
12730 if (!cc_field) {
12731 /* neither cdat or cdt2 ... skip it */
12732 avio_skip(pb, data_size);
12733 src_size -= data_size;
12734 continue;
12735 }
12736
12737 for (uint32_t i = 0; i < data_size; i += 2) {
12738 pkt->data[out_size] = (0x1F << 3) | (1 << 2) | (cc_field - 1);
12739 pkt->data[out_size + 1] = avio_r8(pb);
12740 pkt->data[out_size + 2] = avio_r8(pb);
12741 out_size += 3;
12742 src_size -= 2;
12743 }
12744 }
12745
12746 if (src_size > 0)
12747 /* skip any remaining unread portion of the input payload */
12748 avio_skip(pb, src_size);
12749
12751 return ret;
12752}
12753
12755 int64_t current_index, AVPacket *pkt)
12756{
12757 MOVContext *mov = s->priv_data;
12758 MOVStreamContext *sc = st->priv_data;
12759
12760 pkt->stream_index = sc->ffindex;
12761 pkt->dts = sample->timestamp;
12762 if (sample->flags & AVINDEX_DISCARD_FRAME) {
12763 pkt->flags |= AV_PKT_FLAG_DISCARD;
12764 }
12765 if (sc->stts_count && sc->tts_index < sc->tts_count)
12766 pkt->duration = sc->tts_data[sc->tts_index].duration;
12767 if (sc->ctts_count && sc->tts_index < sc->tts_count) {
12768 pkt->pts = av_sat_add64(pkt->dts, av_sat_add64(sc->dts_shift, sc->tts_data[sc->tts_index].offset));
12769 } else {
12770 if (pkt->duration == 0) {
12771 int64_t next_dts = (sc->current_sample < ffstream(st)->nb_index_entries) ?
12773 if (next_dts >= pkt->dts)
12774 pkt->duration = next_dts - pkt->dts;
12775 }
12776 pkt->pts = pkt->dts;
12777 }
12778
12780 sc->current_sample >= ffstream(st)->nb_index_entries) {
12781 int64_t pts = av_rescale_q(pkt->pts, st->time_base, (AVRational){ 1, st->codecpar->sample_rate });
12782 int64_t total = av_rescale_q(st->duration, st->time_base, (AVRational){ 1, st->codecpar->sample_rate });
12783 int64_t duration = pkt->duration;
12784
12785 if (st->duration < pkt->pts) {
12786 duration = 0;
12787 } else
12788 duration = FFMIN(duration, (uint64_t)st->duration - pkt->pts);
12789
12790 duration = av_rescale_q(duration, st->time_base, (AVRational){ 1, st->codecpar->sample_rate });
12791
12792 if (!ffstream(st)->first_discard_sample)
12794 if (!ffstream(st)->last_discard_sample)
12795 ffstream(st)->last_discard_sample = total;
12796 }
12797
12798 if (sc->tts_data && sc->tts_index < sc->tts_count) {
12799 /* update tts context */
12800 sc->tts_sample++;
12801 if (sc->tts_index < sc->tts_count &&
12802 sc->tts_data[sc->tts_index].count == sc->tts_sample) {
12803 sc->tts_index++;
12804 sc->tts_sample = 0;
12805 }
12806 }
12807
12808 if (sc->sdtp_data && sc->current_sample <= sc->sdtp_count) {
12809 uint8_t sample_flags = sc->sdtp_data[sc->current_sample - 1];
12810 uint8_t sample_is_depended_on = (sample_flags >> 2) & 0x3;
12811 pkt->flags |= sample_is_depended_on == MOV_SAMPLE_DEPENDENCY_NO ? AV_PKT_FLAG_DISPOSABLE : 0;
12812 }
12813 pkt->flags |= sample->flags & AVINDEX_KEYFRAME ? AV_PKT_FLAG_KEY : 0;
12814 pkt->pos = sample->pos;
12815
12816 /* Multiple stsd handling. */
12817 if (sc->stsc_data) {
12818 if (sc->stsc_data[sc->stsc_index].id > 0 &&
12819 sc->stsc_data[sc->stsc_index].id - 1 < sc->stsd_count &&
12820 sc->stsc_data[sc->stsc_index].id - 1 != sc->last_stsd_index) {
12821 int ret = mov_change_extradata(st, pkt);
12822 if (ret < 0)
12823 return ret;
12824 }
12825
12826 /* Update the stsc index for the next sample */
12827 sc->stsc_sample++;
12830 sc->stsc_index++;
12831 sc->stsc_sample = 0;
12832 }
12833 }
12834
12835 return 0;
12836}
12837
12839{
12840 MOVContext *mov = s->priv_data;
12841 MOVStreamContext *sc;
12843 AVStream *st = NULL;
12844 FFStream *avsti = NULL;
12845 int64_t current_index;
12846 int ret;
12847 int i;
12848 mov->fc = s;
12849 retry:
12850 if (s->pb->pos == 0) {
12851
12852 // Discard current fragment index
12853 if (mov->frag_index.allocated_size > 0) {
12854 for(int i = 0; i < mov->frag_index.nb_items; i++) {
12856 }
12857 av_freep(&mov->frag_index.item);
12858 mov->frag_index.nb_items = 0;
12859 mov->frag_index.allocated_size = 0;
12860 mov->frag_index.current = -1;
12861 mov->frag_index.complete = 0;
12862 }
12863
12864 for (i = 0; i < s->nb_streams; i++) {
12865 AVStream *avst = s->streams[i];
12866 MOVStreamContext *msc = avst->priv_data;
12867
12868 // Clear current sample
12869 mov_current_sample_set(msc, 0);
12870 msc->tts_index = 0;
12871
12872 // Discard current index entries
12873 avsti = ffstream(avst);
12874 if (avsti->index_entries_allocated_size > 0) {
12875 av_freep(&avsti->index_entries);
12877 avsti->nb_index_entries = 0;
12878 }
12879 }
12880
12881 if ((ret = mov_switch_root(s, -1, -1)) < 0)
12882 return ret;
12883 }
12885 if (!sample || (mov->next_root_atom && sample->pos > mov->next_root_atom)) {
12886 if (!mov->next_root_atom)
12887 return AVERROR_EOF;
12888 if ((ret = mov_switch_root(s, mov->next_root_atom, -1)) < 0)
12889 return ret;
12890 goto retry;
12891 }
12892 sc = st->priv_data;
12893 /* must be done just before reading, to avoid infinite loop on sample */
12894 current_index = sc->current_index;
12896
12897 if (mov->next_root_atom) {
12898 sample->pos = FFMIN(sample->pos, mov->next_root_atom);
12899 sample->size = FFMIN(sample->size, (mov->next_root_atom - sample->pos));
12900 }
12901
12902 if (st->discard != AVDISCARD_ALL || sc->iamf) {
12903 int64_t ret64 = avio_seek(sc->pb, sample->pos, SEEK_SET);
12904 if (ret64 != sample->pos) {
12905 av_log(mov->fc, AV_LOG_ERROR, "stream %d, offset 0x%"PRIx64": partial file\n",
12906 sc->ffindex, sample->pos);
12907 if (should_retry(sc->pb, ret64)) {
12909 } else if (ret64 < 0) {
12910 return (int)ret64;
12911 }
12912 return AVERROR_INVALIDDATA;
12913 }
12914
12915 if (st->discard == AVDISCARD_NONKEY && !(sample->flags & AVINDEX_KEYFRAME)) {
12916 av_log(mov->fc, AV_LOG_DEBUG, "Nonkey frame from stream %d discarded due to AVDISCARD_NONKEY\n", sc->ffindex);
12917 goto retry;
12918 }
12919
12920 if (st->codecpar->codec_id == AV_CODEC_ID_EIA_608 && sample->size > 8)
12921 ret = get_eia608_packet(sc->pb, pkt, sample->size);
12922#if CONFIG_IAMFDEC
12923 else if (sc->iamf) {
12924 int64_t pts, dts, pos, duration;
12925 int flags, size = sample->size;
12926 ret = mov_finalize_packet(s, st, sample, current_index, pkt);
12927 pts = pkt->pts; dts = pkt->dts;
12928 pos = pkt->pos; flags = pkt->flags;
12929 duration = pkt->duration;
12930 while (!ret && size > 0) {
12932 if (ret < 0) {
12933 if (should_retry(sc->pb, ret))
12935 return ret;
12936 }
12937 size -= ret;
12938
12939 if (pkt->flags & AV_PKT_FLAG_DISCARD) {
12941 ret = 0;
12942 continue;
12943 }
12944 pkt->pts = pts; pkt->dts = dts;
12945 pkt->pos = pos; pkt->flags |= flags;
12946 pkt->duration = duration;
12948 }
12949 if (!ret)
12950 return FFERROR_REDO;
12951 }
12952#endif
12953 else if (st->codecpar->codec_id == AV_CODEC_ID_APV && sample->size > 4) {
12954 uint32_t au_size = avio_rb32(sc->pb);
12955 int explode = !!(mov->fc->error_recognition & AV_EF_EXPLODE);
12956 if (au_size > sample->size - 4) {
12957 av_log(s, explode ? AV_LOG_ERROR : AV_LOG_WARNING,
12958 "APV au_size %u exceeds sample body %d\n",
12959 au_size, sample->size - 4);
12960 if (explode)
12961 return AVERROR_INVALIDDATA;
12962 au_size = sample->size - 4;
12963 }
12964 ret = av_get_packet(sc->pb, pkt, au_size);
12965 } else
12966 ret = av_get_packet(sc->pb, pkt, sample->size);
12967 if (ret < 0) {
12968 if (should_retry(sc->pb, ret)) {
12970 }
12971 return ret;
12972 }
12973#if CONFIG_DV_DEMUXER
12974 if (mov->dv_demux && sc->dv_audio_container) {
12975 ret = avpriv_dv_produce_packet(mov->dv_demux, NULL, pkt->data, pkt->size, pkt->pos);
12977 if (ret < 0)
12978 return ret;
12980 if (ret < 0)
12981 return ret;
12982 }
12983#endif
12984 if (sc->has_palette) {
12985 uint8_t *pal;
12986
12988 if (!pal) {
12989 av_log(mov->fc, AV_LOG_ERROR, "Cannot append palette to packet\n");
12990 } else {
12991 memcpy(pal, sc->palette, AVPALETTE_SIZE);
12992 sc->has_palette = 0;
12993 }
12994 }
12995 if (st->codecpar->codec_id == AV_CODEC_ID_MP3 && !ffstream(st)->need_parsing && pkt->size > 4) {
12996 if (ff_mpa_check_header(AV_RB32(pkt->data)) < 0)
12998 }
12999 }
13000
13001 ret = mov_finalize_packet(s, st, sample, current_index, pkt);
13002 if (ret < 0)
13003 return ret;
13004
13005 if (st->discard == AVDISCARD_ALL)
13006 goto retry;
13007
13008 if (mov->aax_mode)
13009 aax_filter(pkt->data, pkt->size, mov);
13010
13011 ret = cenc_filter(mov, st, sc, pkt, current_index);
13012 if (ret < 0) {
13013 return ret;
13014 }
13015
13016 return 0;
13017}
13018
13020{
13021 MOVContext *mov = s->priv_data;
13022 int index;
13023
13024 if (!mov->frag_index.complete)
13025 return 0;
13026
13027 index = search_frag_timestamp(s, &mov->frag_index, st, timestamp);
13028 if (index < 0)
13029 index = 0;
13030 if (!mov->frag_index.item[index].headers_read)
13031 return mov_switch_root(s, -1, index);
13032 if (index + 1 < mov->frag_index.nb_items)
13034
13035 return 0;
13036}
13037
13039{
13040 // TODO: a bisect search would scale much better
13041 for (int i = 0; i < sc->open_key_samples_count; i++) {
13042 const int oks = sc->open_key_samples[i];
13043 if (oks == sample)
13044 return 1;
13045 if (oks > sample) /* list is monotically increasing so we can stop early */
13046 break;
13047 }
13048 return 0;
13049}
13050
13051/*
13052 * Some key sample may be key frames but not IDR frames, so a random access to
13053 * them may not be allowed.
13054 */
13055static int can_seek_to_key_sample(AVStream *st, int sample, int64_t requested_pts)
13056{
13057 MOVStreamContext *sc = st->priv_data;
13058 FFStream *const sti = ffstream(st);
13059 int64_t key_sample_dts, key_sample_pts;
13060
13062 return 1;
13063
13064 if (sample >= sc->sample_offsets_count)
13065 return 1;
13066
13067 av_assert0(sample >= 0);
13068 key_sample_dts = sti->index_entries[sample].timestamp;
13069 key_sample_pts = key_sample_dts + sc->sample_offsets[sample] + sc->dts_shift;
13070
13071 /*
13072 * If the sample needs to be presented before an open key sample, they may
13073 * not be decodable properly, even though they come after in decoding
13074 * order.
13075 */
13076 if (is_open_key_sample(sc, sample) && key_sample_pts > requested_pts)
13077 return 0;
13078
13079 return 1;
13080}
13081
13082static int mov_seek_stream(AVFormatContext *s, AVStream *st, int64_t timestamp, int flags)
13083{
13084 MOVStreamContext *sc = st->priv_data;
13085 FFStream *const sti = ffstream(st);
13086 int sample, time_sample, ret, requested_sample;
13087 int64_t next_ts;
13088 unsigned int i;
13089
13090 // Here we consider timestamp to be PTS, hence try to offset it so that we
13091 // can search over the DTS timeline.
13092 timestamp -= (sc->min_corrected_pts + sc->dts_shift);
13093
13094 ret = mov_seek_fragment(s, st, timestamp);
13095 if (ret < 0)
13096 return ret;
13097
13098 for (;;) {
13099 sample = av_index_search_timestamp(st, timestamp, flags);
13100 av_log(s, AV_LOG_TRACE, "stream %d, timestamp %"PRId64", sample %d\n", st->index, timestamp, sample);
13101 if (sample < 0 && sti->nb_index_entries && timestamp < sti->index_entries[0].timestamp)
13102 sample = 0;
13103 if (sample < 0) /* not sure what to do */
13104 return AVERROR_INVALIDDATA;
13105
13106 if (!sample || can_seek_to_key_sample(st, sample, timestamp))
13107 break;
13108
13109 next_ts = timestamp - FFMAX(sc->min_sample_duration, 1);
13110 requested_sample = av_index_search_timestamp(st, next_ts, flags);
13111 if (requested_sample < 0)
13112 return AVERROR_INVALIDDATA;
13113
13114 // If we've reached a different sample trying to find a good pts to
13115 // seek to, give up searching because we'll end up seeking back to
13116 // sample 0 on every seek.
13117 if (sample != requested_sample && !can_seek_to_key_sample(st, requested_sample, next_ts))
13118 break;
13119
13120 timestamp = next_ts;
13121 }
13122
13124 av_log(s, AV_LOG_TRACE, "stream %d, found sample %d\n", st->index, sc->current_sample);
13125 /* adjust time to sample index */
13126 if (sc->tts_data) {
13127 time_sample = 0;
13128 for (i = 0; i < sc->tts_count; i++) {
13129 int next = time_sample + sc->tts_data[i].count;
13130 if (next > sc->current_sample) {
13131 sc->tts_index = i;
13132 sc->tts_sample = sc->current_sample - time_sample;
13133 break;
13134 }
13135 time_sample = next;
13136 }
13137 }
13138
13139 /* adjust stsd index */
13140 if (sc->chunk_count) {
13141 time_sample = 0;
13142 for (i = 0; i < sc->stsc_count; i++) {
13143 int64_t next = time_sample + mov_get_stsc_samples(sc, i);
13144 if (next > sc->current_sample) {
13145 sc->stsc_index = i;
13146 sc->stsc_sample = sc->current_sample - time_sample;
13147 break;
13148 }
13149 av_assert0(next == (int)next);
13150 time_sample = next;
13151 }
13152 }
13153
13154 return sample;
13155}
13156
13158{
13159 FFStream *const sti = ffstream(st);
13160 int64_t first_ts = sti->index_entries[0].timestamp;
13162 int64_t off;
13163
13165 return 0;
13166
13167 /* compute skip samples according to stream initial_padding, seek ts and first ts */
13168 off = av_rescale_q(ts - first_ts, st->time_base,
13169 (AVRational){1, st->codecpar->sample_rate});
13170 return FFMAX(st->codecpar->initial_padding - off, 0);
13171}
13172
13173static int mov_read_seek(AVFormatContext *s, int stream_index, int64_t sample_time, int flags)
13174{
13175 MOVContext *mc = s->priv_data;
13176 AVStream *st;
13177 FFStream *sti;
13178 int sample;
13179 int i;
13180
13181 if (stream_index >= s->nb_streams)
13182 return AVERROR_INVALIDDATA;
13183
13184 st = s->streams[stream_index];
13185 sti = ffstream(st);
13186 sample = mov_seek_stream(s, st, sample_time, flags);
13187 if (sample < 0)
13188 return sample;
13189
13190 if (mc->seek_individually) {
13191 /* adjust seek timestamp to found sample timestamp */
13192 int64_t seek_timestamp = sti->index_entries[sample].timestamp;
13194
13195 for (i = 0; i < s->nb_streams; i++) {
13196 AVStream *const st = s->streams[i];
13197 FFStream *const sti = ffstream(st);
13198 int64_t timestamp;
13199
13200 if (stream_index == i)
13201 continue;
13202
13203 timestamp = av_rescale_q(seek_timestamp, s->streams[stream_index]->time_base, st->time_base);
13204 sample = mov_seek_stream(s, st, timestamp, flags);
13205 if (sample >= 0)
13207 }
13208 } else {
13209 for (i = 0; i < s->nb_streams; i++) {
13210 MOVStreamContext *sc;
13211 st = s->streams[i];
13212 sc = st->priv_data;
13214 }
13215 while (1) {
13216 MOVStreamContext *sc;
13218 if (!entry)
13219 return AVERROR_INVALIDDATA;
13220 sc = st->priv_data;
13221 if (sc->ffindex == stream_index && sc->current_sample == sample)
13222 break;
13224 }
13225 }
13226 return 0;
13227}
13228
13229#define OFFSET(x) offsetof(MOVContext, x)
13230#define FLAGS AV_OPT_FLAG_VIDEO_PARAM | AV_OPT_FLAG_DECODING_PARAM
13231static const AVOption mov_options[] = {
13232 {"use_absolute_path",
13233 "allow using absolute path when opening alias, this is a possible security issue",
13234 OFFSET(use_absolute_path), AV_OPT_TYPE_BOOL, {.i64 = 0},
13235 0, 1, FLAGS},
13236 {"seek_streams_individually",
13237 "Seek each stream individually to the closest point",
13238 OFFSET(seek_individually), AV_OPT_TYPE_BOOL, { .i64 = 1 },
13239 0, 1, FLAGS},
13240 {"ignore_editlist", "Ignore the edit list atom.", OFFSET(ignore_editlist), AV_OPT_TYPE_BOOL, {.i64 = 0},
13241 0, 1, FLAGS},
13242 {"advanced_editlist",
13243 "Modify the AVIndex according to the editlists. Use this option to decode in the order specified by the edits.",
13244 OFFSET(advanced_editlist), AV_OPT_TYPE_BOOL, {.i64 = 1},
13245 0, 1, FLAGS},
13246 {"ignore_chapters", "", OFFSET(ignore_chapters), AV_OPT_TYPE_BOOL, {.i64 = 0},
13247 0, 1, FLAGS},
13248 {"use_mfra_for",
13249 "use mfra for fragment timestamps",
13250 OFFSET(use_mfra_for), AV_OPT_TYPE_INT, {.i64 = FF_MOV_FLAG_MFRA_AUTO},
13252 .unit = "use_mfra_for"},
13253 {"auto", "auto", 0, AV_OPT_TYPE_CONST, {.i64 = FF_MOV_FLAG_MFRA_AUTO}, 0, 0,
13254 FLAGS, .unit = "use_mfra_for" },
13255 {"dts", "dts", 0, AV_OPT_TYPE_CONST, {.i64 = FF_MOV_FLAG_MFRA_DTS}, 0, 0,
13256 FLAGS, .unit = "use_mfra_for" },
13257 {"pts", "pts", 0, AV_OPT_TYPE_CONST, {.i64 = FF_MOV_FLAG_MFRA_PTS}, 0, 0,
13258 FLAGS, .unit = "use_mfra_for" },
13259 {"use_tfdt", "use tfdt for fragment timestamps", OFFSET(use_tfdt), AV_OPT_TYPE_BOOL, {.i64 = 1},
13260 0, 1, FLAGS},
13261 { "export_all", "Export unrecognized metadata entries", OFFSET(export_all),
13262 AV_OPT_TYPE_BOOL, { .i64 = 0 }, 0, 1, .flags = FLAGS },
13263 { "export_xmp", "Export full XMP metadata", OFFSET(export_xmp),
13264 AV_OPT_TYPE_BOOL, { .i64 = 0 }, 0, 1, .flags = FLAGS },
13265 { "activation_bytes", "Secret bytes for Audible AAX files", OFFSET(activation_bytes),
13267 { "audible_key", "AES-128 Key for Audible AAXC files", OFFSET(audible_key),
13269 { "audible_iv", "AES-128 IV for Audible AAXC files", OFFSET(audible_iv),
13271 { "audible_fixed_key", // extracted from libAAX_SDK.so and AAXSDKWin.dll files!
13272 "Fixed key used for handling Audible AAX files", OFFSET(audible_fixed_key),
13273 AV_OPT_TYPE_BINARY, {.str="77214d4b196a87cd520045fd20a51d67"},
13274 .flags = AV_OPT_FLAG_DECODING_PARAM },
13275 { "decryption_key", "The default media decryption key (hex)", OFFSET(decryption_default_key), AV_OPT_TYPE_BINARY, .flags = AV_OPT_FLAG_DECODING_PARAM },
13276 { "decryption_keys", "The media decryption keys by KID (hex)", OFFSET(decryption_keys), AV_OPT_TYPE_DICT, .flags = AV_OPT_FLAG_DECODING_PARAM },
13277 { "enable_drefs", "Enable external track support.", OFFSET(enable_drefs), AV_OPT_TYPE_BOOL,
13278 {.i64 = 0}, 0, 1, FLAGS },
13279 { "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 },
13280 { "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 },
13281
13282 { NULL },
13283};
13284
13285static const AVClass mov_class = {
13286 .class_name = "mov,mp4,m4a,3gp,3g2,mj2",
13287 .item_name = av_default_item_name,
13288 .option = mov_options,
13289 .version = LIBAVUTIL_VERSION_INT,
13290};
13291
13293 .p.name = "mov,mp4,m4a,3gp,3g2,mj2",
13294 .p.long_name = NULL_IF_CONFIG_SMALL("QuickTime / MOV"),
13295 .p.priv_class = &mov_class,
13296 .p.extensions = "mov,mp4,m4a,3gp,3g2,mj2,psp,m4v,m4b,ism,ismv,isma,f4v,avif,heic,heif",
13298 .priv_data_size = sizeof(MOVContext),
13299 .flags_internal = FF_INFMT_FLAG_INIT_CLEANUP,
13305};
uint8_t ptrdiff_t const uint8_t ptrdiff_t int intptr_t intptr_t int int16_t * dst
Definition dsp.h:97
const uint16_t ff_ac3_channel_layout_tab[8]
Map audio coding mode (acmod) to channel layout mask.
static double val(void *priv, double ch)
Definition aeval.c:77
static const char *const format[]
Definition af_aiir.c:445
#define ctype
#define ALAC_EXTRADATA_SIZE
Definition alac.c:63
const FFInputFormat ff_mov_demuxer
Definition mov.c:13292
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_unreachable(msg)
Asserts that are used as compiler optimization hints depending upon ASSERT_LEVEL and NBDEBUG.
Definition avassert.h:109
#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:992
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:865
void ff_remove_stream(AVFormatContext *s, AVStream *st)
Remove a stream from its AVFormatContext and free it.
Definition avformat.c:137
void ff_remove_stream_group(AVFormatContext *s, AVStreamGroup *stg)
Remove a stream group from its AVFormatContext and free it.
Definition avformat.c:145
Main libavformat public API header.
#define AVFMT_EVENT_FLAG_METADATA_UPDATED
Definition avformat.h:1796
#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:1555
@ AV_STREAM_GROUP_PARAMS_DOLBY_VISION
Definition avformat.h:1164
@ AV_STREAM_GROUP_PARAMS_TREF
Definition avformat.h:1163
@ AV_STREAM_GROUP_PARAMS_ALPHA
Definition avformat.h:1166
@ AV_STREAM_GROUP_PARAMS_IAMF_MIX_PRESENTATION
Definition avformat.h:1160
@ AV_STREAM_GROUP_PARAMS_TILE_GRID
Definition avformat.h:1161
@ AV_STREAM_GROUP_PARAMS_IAMF_AUDIO_ELEMENT
Definition avformat.h:1159
@ AV_STREAM_GROUP_PARAMS_LCEVC
Definition avformat.h:1162
@ AV_STREAM_GROUP_PARAMS_GAIN_MAP
Definition avformat.h:1165
#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:2730
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:2728
#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:630
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:507
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:620
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:845
unsigned int avio_rb24(AVIOContext *s)
unsigned int avio_rb32(AVIOContext *s)
int avio_r8(AVIOContext *s)
Definition aviobuf.c:611
int ffio_ensure_seekback(AVIOContext *s, int64_t buf_size)
Ensures that the requested seekback buffer size will be available.
Definition aviobuf.c:994
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:839
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:674
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:898
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
#define AV_BPRINT_SIZE_AUTOMATIC
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 AV_EF_COMPLIANT
consider all spec non compliances as errors
Definition defs.h:55
#define FF_COMPLIANCE_STRICT
Strictly conform to all the things in the spec no matter what consequences.
Definition defs.h:59
#define AV_EF_EXPLODE
abort decoding on minor error detection
Definition defs.h:51
AVFieldOrder
Definition defs.h:225
@ AV_FIELD_TT
Top coded_first, top displayed first.
Definition defs.h:228
@ AV_FIELD_BB
Bottom coded first, bottom displayed first.
Definition defs.h:229
@ AV_FIELD_UNKNOWN
Definition defs.h:226
@ AV_FIELD_PROGRESSIVE
Definition defs.h:227
@ AV_FIELD_BT
Bottom coded first, top displayed first.
Definition defs.h:231
@ AV_FIELD_TB
Top coded first, bottom displayed first.
Definition defs.h:230
#define AV_PROFILE_DTS_96_24
Definition defs.h:98
AVAudioServiceType
Definition defs.h:249
@ AV_AUDIO_SERVICE_TYPE_KARAOKE
Definition defs.h:258
#define AV_PROFILE_DTS_ES
Definition defs.h:97
int ff_buffer_packet(AVFormatContext *s, AVPacket *pkt)
Definition demux.c:645
void ff_rfps_calculate(AVFormatContext *ic)
Definition demux.c:2454
int ff_rfps_add_frame(AVFormatContext *ic, AVStream *st, int64_t ts)
add frame for rfps calculation.
Definition demux.c:2393
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:233
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.
int av_encryption_init_info_append_side_data(uint8_t **side_data, size_t *side_data_size, unsigned int *allocated_size, const AVEncryptionInitInfo *info)
Appends a copy of the given encryption init info list to encryption init info side data,...
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_get_entry(void *logctx, AVExifMetadata *ifd, uint16_t id, int flags, AVExifEntry **value)
Get an entry with the tagged ID from the EXIF metadata struct.
Definition exif.c:1197
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:896
void av_exif_free(AVExifMetadata *ifd)
Frees all resources associated with the given EXIF metadata struct.
Definition exif.c:673
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:767
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:1296
EXIF metadata parser.
@ AV_TIFF_SRATIONAL
Definition exif.h:51
@ AV_EXIF_TIFF_HEADER
The TIFF header starts with 0x49492a00, or 0x4d4d002a.
Definition exif.h:62
@ 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:359
int ret
Definition ffplay.c:391
static int64_t start_time
Definition ffplay.c:358
static int read_header(FFV1Context *f, RangeCoder *c)
Definition ffv1dec.c:578
FLAC (Free Lossless Audio Codec) common stuff.
@ FLAC_METADATA_TYPE_STREAMINFO
Definition flac.h:46
static av_always_inline void flac_parse_block_header(const uint8_t *block_header, int *last, int *type, int *size)
Parse the metadata block parameters from the header.
Definition flac.h:63
#define FLAC_STREAMINFO_SIZE
Definition flac.h:32
#define sample
static av_cold void cleanup(FlashSV2Context *s)
bitstream reader API header.
static unsigned int get_bits_long(GetBitContext *s, int n)
Read 0-32 bits.
Definition get_bits.h:424
static void skip_bits_long(GetBitContext *s, int n)
Skips the specified number of bits.
Definition get_bits.h:280
static void skip_bits(GetBitContext *s, int n)
Definition get_bits.h:383
static unsigned int get_bits(GetBitContext *s, int n)
Read 1-25 bits.
Definition get_bits.h:337
static int init_get_bits(GetBitContext *s, const uint8_t *buffer, int bit_size)
Initialize GetBitContext.
Definition get_bits.h:517
#define fail
Definition test.h:479
#define AV_OPT_FLAG_DECODING_PARAM
A generic parameter which can be set by the user for demuxing or decoding.
Definition opt.h:355
@ AV_OPT_TYPE_CONST
Special option type for declaring named constants.
Definition opt.h:298
@ AV_OPT_TYPE_BINARY
Underlying C type is a uint8_t* that is either NULL or points to an array allocated with the av_mallo...
Definition opt.h:285
@ AV_OPT_TYPE_INT
Underlying C type is int.
Definition opt.h:258
@ AV_OPT_TYPE_DICT
Underlying C type is AVDictionary*.
Definition opt.h:289
@ AV_OPT_TYPE_BOOL
Underlying C type is int.
Definition opt.h:326
#define AV_CH_SIDE_LEFT
#define AV_CH_SIDE_SURROUND_RIGHT
#define AV_CH_WIDE_LEFT
#define AV_CH_WIDE_RIGHT
#define AV_CH_TOP_FRONT_LEFT
#define AV_CH_FRONT_RIGHT
#define AV_CH_SIDE_SURROUND_LEFT
#define AV_CH_TOP_BACK_CENTER
#define AV_CH_FRONT_RIGHT_OF_CENTER
#define AV_CH_BACK_CENTER
#define AV_CH_TOP_FRONT_CENTER
#define AV_CH_FRONT_LEFT_OF_CENTER
#define AV_CH_LOW_FREQUENCY_2
#define AV_CH_BACK_RIGHT
#define AV_CH_TOP_SIDE_RIGHT
#define AV_CH_FRONT_CENTER
#define AV_CH_TOP_BACK_RIGHT
#define AV_CH_TOP_CENTER
#define AV_CH_SIDE_RIGHT
#define AV_CH_BACK_LEFT
#define AV_CH_TOP_SIDE_LEFT
#define AV_CH_TOP_BACK_LEFT
#define AV_CH_LOW_FREQUENCY
#define AV_CH_TOP_FRONT_RIGHT
#define AV_CH_FRONT_LEFT
int av_get_bits_per_sample(enum AVCodecID codec_id)
Return codec bits per sample.
Definition utils.c:557
AVCodecID
Identify the syntax and semantics of the bitstream.
Definition codec_id.h:47
@ AV_CODEC_ID_PCM_F32LE
Definition codec_id.h:354
@ AV_CODEC_ID_PCM_S24BE
Definition codec_id.h:346
@ AV_CODEC_ID_VORBIS
Definition codec_id.h:463
@ 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:498
@ AV_CODEC_ID_PCM_U8
Definition codec_id.h:338
@ AV_CODEC_ID_APV
Definition codec_id.h:323
@ AV_CODEC_ID_LCEVC
Definition codec_id.h:614
@ AV_CODEC_ID_PCM_S16LE
Definition codec_id.h:333
@ AV_CODEC_ID_GSM
as in Berlin toast format
Definition codec_id.h:476
@ AV_CODEC_ID_DVD_SUBTITLE
Definition codec_id.h:571
@ AV_CODEC_ID_TTML
Definition codec_id.h:595
@ AV_CODEC_ID_PCM_F32BE
Definition codec_id.h:353
@ 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:334
@ AV_CODEC_ID_PCM_S24LE
Definition codec_id.h:345
@ AV_CODEC_ID_PCM_S32LE
Definition codec_id.h:341
@ AV_CODEC_ID_PCM_S8
Definition codec_id.h:337
@ AV_CODEC_ID_AV1
Definition codec_id.h:275
@ AV_CODEC_ID_ADPCM_MS
Definition codec_id.h:379
@ 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:356
@ AV_CODEC_ID_ALAC
Definition codec_id.h:474
@ AV_CODEC_ID_EIA_608
Definition codec_id.h:581
@ AV_CODEC_ID_AMR_NB
Definition codec_id.h:439
@ 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:458
@ AV_CODEC_ID_DVAUDIO
Definition codec_id.h:464
@ AV_CODEC_ID_ADPCM_IMA_QT
Definition codec_id.h:373
@ AV_CODEC_ID_HEVC
Definition codec_id.h:223
@ AV_CODEC_ID_BIN_DATA
Definition codec_id.h:612
@ AV_CODEC_ID_AAC
Definition codec_id.h:460
@ 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:355
@ AV_CODEC_ID_H263
Definition codec_id.h:54
@ AV_CODEC_ID_QCELP
Definition codec_id.h:482
@ AV_CODEC_ID_AMR_WB
Definition codec_id.h:440
@ AV_CODEC_ID_AC3
Definition codec_id.h:461
@ AV_CODEC_ID_MACE3
Definition codec_id.h:467
@ AV_CODEC_ID_MACE6
Definition codec_id.h:468
@ AV_CODEC_ID_QDM2
Definition codec_id.h:477
@ AV_CODEC_ID_PCM_S32BE
Definition codec_id.h:342
@ 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:374
@ 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:493
@ AV_CODEC_ID_AVUI
Definition codec_id.h:252
@ AV_CODEC_ID_ILBC
Definition codec_id.h:517
@ AV_CODEC_ID_MP3
preferred ID for decoding MPEG audio layer 1, 2 or 3
Definition codec_id.h:459
@ 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:508
@ AV_CODEC_ID_ITUT_T35
Definition codec_id.h:616
@ AV_CODEC_ID_TARGA_Y216
Definition codec_id.h:253
#define AV_INPUT_BUFFER_PADDING_SIZE
Required number of additionally allocated bytes at the end of the input bitstream for decoding.
Definition defs.h:40
@ AVDISCARD_ALL
discard all
Definition defs.h:246
@ AVDISCARD_NONKEY
discard all frames except keyframes
Definition defs.h:245
AVPacketSideData * av_packet_side_data_new(AVPacketSideData **psd, int *pnb_sd, enum AVPacketSideDataType type, size_t size, int flags)
Allocate a new packet side data.
Definition packet.c:621
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:614
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:571
@ 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_GAIN_MAP_PARAMS
Parameters describing how to combine this gain map with its base image to form an alternate rendition...
Definition packet.h:391
@ 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:664
void av_packet_unref(AVPacket *pkt)
Wipe the packet.
Definition packet.c:435
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:657
#define AV_PKT_FLAG_DISPOSABLE
Flag is used to indicate packets that contain frames that can be discarded by the decoder.
Definition packet.h:676
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:474
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:589
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:165
int avformat_stream_group_add_stream_group(AVStreamGroup *stg, AVStreamGroup *group)
Add an already allocated stream group to another stream group.
Definition options.c:631
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
void av_dict_free(AVDictionary **pm)
Free all the memory allocated for an AVDictionary struct and all keys and values.
Definition dict.c:236
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:61
int av_dict_copy(AVDictionary **dst, const AVDictionary *src, int flags)
Copy entries from one AVDictionary struct into another.
Definition dict.c:250
#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:87
#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:180
#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:247
AVRational av_add_q(AVRational b, AVRational c)
Add two rationals.
Definition rational.c:93
AVRational av_mul_q(AVRational b, AVRational c)
Multiply two rationals.
Definition rational.c:80
int av_reduce(int *dst_num, int *dst_den, int64_t num, int64_t den, int64_t max)
Reduce a fraction.
Definition rational.c:35
static AVRational av_make_q(int num, int den)
Create an AVRational.
Definition rational.h:71
AVRational av_d2q(double d, int max)
Convert a double precision floating point number to a rational.
Definition rational.c:110
static double av_q2d(AVRational a)
Convert an AVRational to a double.
Definition rational.h:104
static int av_cmp_q(AVRational a, AVRational b)
Compare two rationals.
Definition rational.h:89
AVRational av_sub_q(AVRational b, AVRational c)
Subtract one rational from another.
Definition rational.c:101
int64_t av_rescale(int64_t a, int64_t b, int64_t c)
Rescale a 64-bit integer with rounding to nearest.
int64_t av_rescale_q(int64_t a, AVRational bq, AVRational cq)
Rescale a 64-bit integer by 2 rational numbers.
void * av_dynarray2_add(void **tab_ptr, int *nb_ptr, size_t elem_size, const uint8_t *elem_data)
Add an element of size elem_size to a dynamic array.
Definition mem.c:447
void * av_fast_realloc(void *ptr, unsigned int *size, size_t min_size)
Reallocate the given buffer if it is not large enough, otherwise do nothing.
Definition mem.c:601
void * av_realloc_array(void *ptr, size_t nmemb, size_t size)
Definition mem.c:318
int av_reallocp(void *ptr, size_t size)
Allocate, reallocate, or free a block of memory through a pointer to a pointer.
Definition mem.c:289
int av_reallocp_array(void *ptr, size_t nmemb, size_t size)
Allocate, reallocate an array through a pointer to a pointer.
Definition mem.c:326
const char * av_get_media_type_string(enum AVMediaType media_type)
Return a string describing the media_type enum, NULL if media_type is unknown.
Definition utils.c:28
char * av_fourcc_make_string(char *buf, uint32_t fourcc)
Fill the provided buffer with a string containing a FourCC (four-character code) representation.
Definition utils.c:54
#define av_fourcc2str(fourcc)
Definition avutil.h:323
#define AV_FOURCC_MAX_STRING_SIZE
Definition avutil.h:321
@ AVMEDIA_TYPE_AUDIO
Definition avutil.h:201
@ AVMEDIA_TYPE_SUBTITLE
Definition avutil.h:203
@ AVMEDIA_TYPE_VIDEO
Definition avutil.h:200
@ AVMEDIA_TYPE_DATA
Opaque data information usually continuous.
Definition avutil.h:202
void av_sha_update(struct AVSHA *ctx, const uint8_t *data, size_t len)
Update hash value.
Definition sha.c:315
struct AVSHA * av_sha_alloc(void)
Allocate an AVSHA context.
Definition sha.c:46
void av_sha_final(AVSHA *ctx, uint8_t *digest)
Finish hashing and output digest value.
Definition sha.c:347
av_cold int av_sha_init(AVSHA *ctx, int bits)
Initialize SHA-1 or SHA-2 hashing.
Definition sha.c:274
size_t av_strlcat(char *dst, const char *src, size_t size)
Append the string src to the string dst, but to a total length of no more than size - 1 bytes,...
Definition avstring.c:95
char * av_stristr(const char *s1, const char *s2)
Locate the first case-independent occurrence in the string haystack of the string needle.
Definition avstring.c:58
int av_strstart(const char *str, const char *pfx, const char **ptr)
Return non-zero if pfx is a prefix of str.
Definition avstring.c:36
#define AV_NOPTS_VALUE
Undefined timestamp value.
Definition avutil.h:247
#define AV_TIME_BASE
Internal time base represented as integer.
Definition avutil.h:253
#define LIBAVUTIL_VERSION_INT
Definition version.h:85
void av_display_rotation_set(int32_t matrix[9], double angle)
Initialize a transformation matrix describing a pure clockwise rotation by the specified angle (in de...
Definition display.c:50
void av_display_matrix_flip(int32_t matrix[9], int hflip, int vflip)
Flip the input matrix horizontally and/or vertically.
Definition display.c:65
AVSphericalMapping * av_spherical_alloc(size_t *size)
Allocate a AVSphericalVideo structure and initialize its fields to default values.
Definition spherical.c:26
AVSphericalProjection
Projection of the video surface(s) on a sphere.
Definition spherical.h:47
@ AV_SPHERICAL_RECTILINEAR
Video frame displays on a flat, rectangular 2D surface.
Definition spherical.h:78
@ AV_SPHERICAL_EQUIRECTANGULAR
Video represents a sphere mapped on a flat surface using equirectangular projection.
Definition spherical.h:52
@ AV_SPHERICAL_EQUIRECTANGULAR_TILE
Video represents a portion of a sphere mapped on a flat surface using equirectangular projection.
Definition spherical.h:68
@ AV_SPHERICAL_CUBEMAP
Video frame is split into 6 faces of a cube, and arranged on a 3x2 layout.
Definition spherical.h:61
@ AV_SPHERICAL_HALF_EQUIRECTANGULAR
Video frame displays as a 180 degree equirectangular projection.
Definition spherical.h:73
@ AV_SPHERICAL_PARAMETRIC_IMMERSIVE
Parametric Immersive projection (Apple).
Definition spherical.h:90
@ AV_SPHERICAL_FISHEYE
Fisheye projection (Apple).
Definition spherical.h:84
AVStereo3DType
List of possible 3D Types.
Definition stereo3d.h:48
AVStereo3D * av_stereo3d_alloc_size(size_t *size)
Allocate an AVStereo3D structure and set its fields to default values.
Definition stereo3d.c:39
#define AV_STEREO3D_FLAG_INVERT
Inverted views, Right/Bottom represents the left view.
Definition stereo3d.h:194
AVStereo3DPrimaryEye
List of possible primary eyes.
Definition stereo3d.h:174
AVStereo3DView
List of possible view types.
Definition stereo3d.h:149
@ AV_STEREO3D_2D
Video is not stereoscopic (and metadata has to be there).
Definition stereo3d.h:52
@ AV_STEREO3D_TOPBOTTOM
Views are on top of each other.
Definition stereo3d.h:76
@ AV_STEREO3D_UNSPEC
Video is stereoscopic but the packing is unspecified.
Definition stereo3d.h:143
@ AV_STEREO3D_SIDEBYSIDE
Views are next to each other.
Definition stereo3d.h:64
@ AV_PRIMARY_EYE_NONE
Neither eye.
Definition stereo3d.h:178
@ AV_PRIMARY_EYE_LEFT
Left eye.
Definition stereo3d.h:183
@ AV_PRIMARY_EYE_RIGHT
Right eye.
Definition stereo3d.h:188
@ AV_STEREO3D_VIEW_RIGHT
Frame contains only the right view.
Definition stereo3d.h:163
@ AV_STEREO3D_VIEW_PACKED
Frame contains two packed views.
Definition stereo3d.h:153
@ AV_STEREO3D_VIEW_LEFT
Frame contains only the left view.
Definition stereo3d.h:158
@ AV_STEREO3D_VIEW_UNSPEC
Content is unspecified.
Definition stereo3d.h:168
int index
Definition gxfenc.c:90
int a
int tile_rows
#define MAX_REORDER_DELAY
const VDPAUPixFmtMap * map
int ff_iamfdec_read_descriptors(IAMFContext *c, AVIOContext *pb, int max_size, void *log_ctx)
int ff_iamf_read_packet(AVFormatContext *s, IAMFDemuxContext *c, AVIOContext *pb, int max_size, int stream_id_offset, AVPacket *pkt)
void ff_iamf_read_deinit(IAMFDemuxContext *c)
const char *const ff_id3v1_genre_str[ID3v1_GENRE_MAX+1]
ID3v1 genres.
Definition id3v1.c:26
#define ID3v1_GENRE_MAX
Definition id3v1.h:29
static const int16_t alpha[]
Definition ilbcdata.h:55
#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_RB24(x)
#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:428
#define MOV_GRAPHICS_MODE_COPY
Definition isom.h:455
int ff_mov_read_esds(AVFormatContext *fc, AVIOContext *pb)
Definition mov_esds.c:23
#define FF_MOV_FLAG_MFRA_PTS
Definition isom.h:489
#define MOV_TRUN_SAMPLE_CTS
Definition isom.h:431
#define MOV_TKHD_FLAG_ENABLED
Definition isom.h:443
#define MOV_TFHD_DEFAULT_BASE_IS_MOOF
Definition isom.h:424
#define MOV_INFE_FLAG_HIDDEN
Definition isom.h:448
#define FF_MOV_FLAG_MFRA_DTS
Definition isom.h:488
const AVCodecTag ff_codec_movaudio_tags[]
Definition isom_tags.c:307
#define MOV_FRAG_SAMPLE_FLAG_DEPENDS_YES
Definition isom.h:441
const AVCodecTag ff_codec_movvideo_tags[]
Definition isom_tags.c:29
#define MOV_TFHD_DEFAULT_SIZE
Definition isom.h:421
#define MOV_ISMV_TTML_TAG
Definition isom.h:505
#define TAG_IS_AVCI(tag)
Definition isom.h:465
#define MOV_TRUN_FIRST_SAMPLE_FLAGS
Definition isom.h:427
#define MOV_GRAPHICS_MODE_PREMUL_BLACK_ALPHA
Definition isom.h:461
#define MOV_MP4_FPCM_TAG
Definition isom.h:507
#define MOV_FRAG_SAMPLE_FLAG_IS_NON_SYNC
Definition isom.h:434
#define MOV_TFHD_STSD_ID
Definition isom.h:419
#define MOV_GRAPHICS_MODE_DITHER_COPY
Definition isom.h:456
#define MOV_TRUN_SAMPLE_FLAGS
Definition isom.h:430
#define MOV_MP4_TTML_TAG
Definition isom.h:506
#define MOV_TFHD_DEFAULT_FLAGS
Definition isom.h:422
#define MOV_TRUN_DATA_OFFSET
Definition isom.h:426
#define MOV_TFHD_BASE_DATA_OFFSET
Definition isom.h:418
#define MOV_MP4_IPCM_TAG
Definition isom.h:508
static enum AVCodecID ff_mov_get_lpcm_codec_id(int bps, int flags)
Compute codec id for 'lpcm' tag.
Definition isom.h:495
#define MOV_TRUN_SAMPLE_SIZE
Definition isom.h:429
#define MOV_SAMPLE_DEPENDENCY_NO
Definition isom.h:452
#define MOV_GRAPHICS_MODE_STRAIGHT_ALPHA
Definition isom.h:459
#define FF_MOV_FLAG_MFRA_AUTO
Definition isom.h:487
#define MOV_TFHD_DEFAULT_DURATION
Definition isom.h:420
enum MPFType type
Definition jpegmpfenc.c:55
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:384
static av_always_inline const FFStream * cffstream(const AVStream *st)
Definition internal.h:389
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
AVGainMapParams * av_gain_map_params_alloc(size_t *size)
Allocate an AVGainMapParams structure and initialize it to default values.
Definition gain_map.c:224
int av_gain_map_params_from_iso21496(AVGainMapParams *restrict p, const uint8_t *data, size_t size)
Definition gain_map.c:111
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:5735
static int64_t mov_get_skip_samples(AVStream *st, int sample)
Definition mov.c:13157
static int search_frag_moof_offset(MOVFragmentIndex *frag_index, int64_t offset)
Definition mov.c:1776
static int mov_read_sbas(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition mov.c:2743
static int update_frag_index(MOVContext *c, int64_t offset)
Definition mov.c:1877
static int get_eia608_packet(AVIOContext *pb, AVPacket *pkt, int src_size)
Definition mov.c:12685
static int mov_read_iloc(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition mov.c:9478
static int mov_read_pack(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition mov.c:7149
static int read_image_grid(AVFormatContext *s, const HEIFGroup *grid, AVStreamGroupTileGrid *tile_grid)
Definition mov.c:11189
static int mov_apply_heif_item_references(AVFormatContext *s, HEIFItem *item, AVPacketSideData **coded_side_data, int *nb_coded_side_data)
Definition mov.c:11414
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:4247
static int mov_read_seek(AVFormatContext *s, int stream_index, int64_t sample_time, int flags)
Definition mov.c:13173
static HEIFItem * get_heif_item(MOVContext *c, unsigned id)
Get the requested item.
Definition mov.c:198
static void mov_free_stream_context(AVFormatContext *s, AVStream *st)
Definition mov.c:10848
static int mov_read_stsd(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition mov.c:3474
static void mov_parse_stsd_video(MOVContext *c, AVIOContext *pb, AVStream *st, MOVStreamContext *sc)
Definition mov.c:2934
static int heif_add_stream(MOVContext *c, HEIFItem *item)
Definition mov.c:5897
static int mov_read_dops(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition mov.c:9029
static int set_display_matrix_from_item(AVPacketSideData **coded_side_data, int *nb_coded_side_data, const HEIFItem *item)
Definition mov.c:11161
static int mov_compare_presentation_samples(const void *a, const void *b)
Definition mov.c:5304
static int mov_switch_root(AVFormatContext *s, int64_t target, int index)
Definition mov.c:12624
static int mov_read_vexu_proj(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition mov.c:7367
static int mov_read_srat(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition mov.c:1095
static int get_key_from_kid(uint8_t *out, int len, MOVContext *c, AVEncryptionInfo *sample)
Definition mov.c:8613
static int mov_read_aclr(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition mov.c:2484
static int mov_read_idat(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition mov.c:9472
static int mov_parse_tmcd_streams(AVFormatContext *s)
Definition mov.c:12064
static int mov_read_lhvc(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition mov.c:9164
static int aax_filter(uint8_t *input, int size, MOVContext *c)
Definition mov.c:1641
static void mov_current_sample_dec(MOVStreamContext *sc)
Definition mov.c:4484
static int mov_finalize_stsd_entry(MOVContext *c, AVStream *st)
Definition mov.c:3350
static int mov_read_pitm(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition mov.c:9464
static int mov_seek_stream(AVFormatContext *s, AVStream *st, int64_t timestamp, int flags)
Definition mov.c:13082
static int mov_read_packet(AVFormatContext *s, AVPacket *pkt)
Definition mov.c:12838
static int mov_parse_lcevc_streams(AVFormatContext *s)
Definition mov.c:12187
static int mov_read_hvce(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition mov.c:9137
static int cbcs_scheme_decrypt(MOVContext *c, MOVStreamContext *sc, AVEncryptionInfo *sample, uint8_t *input, int size)
Definition mov.c:8846
static int mov_read_default(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition mov.c:10433
static int mov_finalize_packet(AVFormatContext *s, AVStream *st, AVIndexEntry *sample, int64_t current_index, AVPacket *pkt)
Definition mov.c:12754
static int mov_read_stss(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition mov.c:3682
static uint64_t mov_dts_channel_layout_to_mask(unsigned int code)
Definition mov.c:1216
static int64_t get_stream_info_time(MOVFragmentStreamInfo *frag_stream_info)
Definition mov.c:1800
static int mov_read_saio(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition mov.c:8257
static int mov_skip_multiple_stsd(MOVContext *c, AVIOContext *pb, int codec_tag, int format, int64_t size)
Definition mov.c:3324
static int mov_read_iref_auxl(MOVContext *c, AVIOContext *pb, uint32_t type, int version, uint32_t size)
Definition mov.c:9922
#define DRM_BLOB_SIZE
Definition mov.c:1513
static int mov_add_tref_id(MovTref *tag, uint32_t id)
Definition mov.c:2669
static int mov_read_mdhd(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition mov.c:2011
static int mov_read_tmcd(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition mov.c:6848
int ff_mov_read_stsd_entries(MOVContext *c, AVIOContext *pb, int entries)
Definition mov.c:3371
static int mov_metadata_gnre(MOVContext *c, AVIOContext *pb, unsigned len, const char *key)
Definition mov.c:138
static int mov_read_dref(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition mov.c:656
static int mov_read_dpxe(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition mov.c:2412
static MovTref * mov_find_tref_tag(const MOVStreamContext *sc, uint32_t name)
Definition mov.c:2684
static int mov_parse_heif_layered_video_auxl_alpha(AVFormatContext *s, HEIFItem *base, HEIFItem *alpha)
Definition mov.c:11760
static int mov_read_eyes(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition mov.c:7440
static int cenc_scheme_decrypt(MOVContext *c, MOVStreamContext *sc, AVEncryptionInfo *sample, uint8_t *input, int size)
Definition mov.c:8650
static int mov_read_wave(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition mov.c:2532
static int mov_metadata_hmmt(MOVContext *c, AVIOContext *pb, unsigned len)
Definition mov.c:328
static int mov_read_iref_dimg(MOVContext *c, AVIOContext *pb, int version)
Definition mov.c:9815
static int mov_read_stsz(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition mov.c:3737
static int mov_dts_stream_construction_to_profile(unsigned int sc)
Definition mov.c:1183
static int rb_size(AVIOContext *pb, int64_t *value, int size)
Definition mov.c:9420
static int mov_read_chpl(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition mov.c:617
static int mov_read_header(AVFormatContext *s)
Definition mov.c:12352
static int mov_read_dfla(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition mov.c:8573
static int mov_read_stco(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition mov.c:2829
static int mov_read_st3d(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition mov.c:7102
static int mov_read_elst(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition mov.c:6774
static int test_same_origin(const char *src, const char *ref)
Definition mov.c:5402
static int sanity_checks(void *log_obj, MOVStreamContext *sc, int index)
Definition mov.c:5560
static void mov_current_sample_set(MOVStreamContext *sc, int current_sample)
Definition mov.c:4496
static int mov_merge_tts_data(MOVContext *mov, AVStream *st, int flags)
Definition mov.c:4920
static int mov_aaxc_crypto(MOVContext *c)
Definition mov.c:1616
static int mov_read_sv3d(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition mov.c:7230
static int mov_read_ddts(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition mov.c:1244
static int mov_read_ipco(MOVContext *c, AVIOContext *pb, MOVAtom atom, MOVAtomExt **atoms, int *nb_atoms)
Definition mov.c:10093
static int mov_read_sdtp(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition mov.c:3950
static int mov_read_stts(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition mov.c:3830
static int cenc_filter(MOVContext *mov, AVStream *st, MOVStreamContext *sc, AVPacket *pkt, int current_index)
Definition mov.c:8959
static const AVClass mov_class
Definition mov.c:13285
static int mov_read_sample_encryption_info(MOVContext *c, AVIOContext *pb, MOVStreamContext *sc, AVEncryptionInfo **sample, int use_subsamples)
Definition mov.c:8001
static int mov_read_meta(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition mov.c:5956
static int mov_read_smdm(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition mov.c:6920
static const uint32_t mac_to_unicode[128]
Definition mov.c:154
static int mov_parse_heif_layered_video_auxl_gmap(AVFormatContext *s, HEIFItem *base, HEIFItem *gain_map)
Definition mov.c:11819
static int mov_read_sidx(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition mov.c:6562
static int mov_read_strf(MOVContext *c, AVIOContext *pb, MOVAtom atom)
An strf atom is a BITMAPINFOHEADER struct.
Definition mov.c:2807
static uint32_t get_sgpd_sync_index(const MOVStreamContext *sc, int nal_unit_type)
Definition mov.c:4842
static void fix_frag_index_entries(MOVFragmentIndex *frag_index, int index, int id, int entries)
Definition mov.c:1940
static int mov_read_rtmd_track(AVFormatContext *s, AVStream *st)
Definition mov.c:10763
static int mov_read_dec3(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition mov.c:1129
static int mov_read_dmlp(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition mov.c:9082
static int mov_metadata_int8_bypass_padding(MOVContext *c, AVIOContext *pb, unsigned len, const char *key)
Definition mov.c:115
static int mov_read_schm(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition mov.c:8471
static int mov_metadata_loci(MOVContext *c, AVIOContext *pb, unsigned len)
Definition mov.c:278
static int read_tfra(MOVContext *mov, AVIOContext *f)
Definition mov.c:11006
static int mov_seek_fragment(AVFormatContext *s, AVStream *st, int64_t timestamp)
Definition mov.c:13019
static int mov_read_extradata(MOVContext *c, AVIOContext *pb, MOVAtom atom, enum AVCodecID codec_id)
Definition mov.c:2371
static int mov_read_enda(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition mov.c:2125
static int mov_read_covr(MOVContext *c, AVIOContext *pb, int type, int len)
Definition mov.c:235
static int mov_read_adrm(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition mov.c:1515
static int mov_parse_heif_layered_video_tmap(AVFormatContext *s, const HEIFGroup *tmap)
Definition mov.c:11569
static int mov_parse_dovi_streams(AVFormatContext *s)
Definition mov.c:12241
static int mov_read_chnl(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition mov.c:1325
static void mov_metadata_creation_time(MOVContext *c, AVIOContext *pb, AVDictionary **metadata, int version)
Definition mov.c:1981
static int mov_stsc_index_valid(unsigned int index, unsigned int count)
Definition mov.c:3620
static int mov_read_hdlr(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition mov.c:800
#define MOV_MERGE_STTS
Definition mov.c:4914
static int mov_read_dvcc_dvvc(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition mov.c:9117
static int should_retry(AVIOContext *pb, int error_code)
Definition mov.c:12617
static int mov_read_mvhd(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition mov.c:2057
static int mov_read_tfdt(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition mov.c:6181
static int mov_read_moov(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition mov.c:1703
static int mov_read_clli(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition mov.c:7048
static int mov_read_trun(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition mov.c:6220
static void mov_update_dts_shift(MOVStreamContext *sc, int duration, void *logctx)
Definition mov.c:3988
static int mov_read_kind(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition mov.c:9215
static int mov_read_sbgp(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition mov.c:4139
static int mov_metadata_track_or_disc_number(MOVContext *c, AVIOContext *pb, unsigned len, const char *key)
Definition mov.c:95
static int mov_read_ares(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition mov.c:2439
static int mov_read_pssh(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition mov.c:8352
static int mov_finalize_stsd_codec(MOVContext *c, AVIOContext *pb, AVStream *st, MOVStreamContext *sc)
Definition mov.c:3220
static int mov_read_tkhd(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition mov.c:5982
static int mov_read_iprp(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition mov.c:10181
static int mov_read_cdsc_rndr(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition mov.c:2712
static int cens_scheme_decrypt(MOVContext *c, MOVStreamContext *sc, AVEncryptionInfo *sample, uint8_t *input, int size)
Definition mov.c:8775
static int read_image_iovl(AVFormatContext *s, const HEIFGroup *grid, AVStreamGroupTileGrid *tile_grid)
Definition mov.c:11284
static int mov_read_alac(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition mov.c:2397
static int mov_read_mfra(MOVContext *c, AVIOContext *f)
Definition mov.c:11061
static int mov_read_iref_dimg_grid(MOVContext *c, AVIOContext *pb, HEIFItem *item, int version, int entries)
Definition mov.c:9773
#define MIN_DATA_ENTRY_BOX_SIZE
Definition mov.c:655
static int mov_change_extradata(AVStream *st, AVPacket *pkt)
Definition mov.c:12661
static int mov_read_mdcv(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition mov.c:6967
static int mov_parse_stsd_audio(MOVContext *c, AVIOContext *pb, AVStream *st, MOVStreamContext *sc)
Definition mov.c:2998
static int mov_read_timecode_track(AVFormatContext *s, AVStream *st)
Definition mov.c:10789
static int mov_read_imir(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition mov.c:10068
static int mov_read_stps(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition mov.c:3641
static int mov_read_svq3(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition mov.c:2527
static int mov_read_pcmc(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition mov.c:2134
static int mov_read_auxc(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition mov.c:9439
static int mov_parse_cdsc_and_rndr_streams(AVFormatContext *s)
Definition mov.c:12135
static const MOVParseTableEntry mov_default_parse_table[]
Definition mov.c:10296
static int mov_read_jp2h(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition mov.c:2407
static int mov_read_iref(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition mov.c:9970
static int mov_read_trex(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition mov.c:6155
static int mov_read_saiz(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition mov.c:8173
static int mov_read_hfov(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition mov.c:7684
static int mov_read_free(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition mov.c:7881
static int set_icc_profile_from_item(AVPacketSideData **coded_side_data, int *nb_coded_side_data, const HEIFItem *item)
Definition mov.c:11139
static int mov_read_infe(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition mov.c:9575
static int mov_parse_heif_item_references(AVFormatContext *s, HEIFItem *item, AVPacketSideData **coded_side_data, int *nb_coded_side_data)
Definition mov.c:11444
static int mov_read_stsc(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition mov.c:3540
static AVStream * get_curr_st(MOVContext *c)
Get the current stream in the parsing process.
Definition mov.c:217
static int mov_parse_stsd_data(MOVContext *c, AVIOContext *pb, AVStream *st, MOVStreamContext *sc, int64_t size)
Definition mov.c:3147
static int mov_read_mdat(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition mov.c:1505
static int cbc1_scheme_decrypt(MOVContext *c, MOVStreamContext *sc, AVEncryptionInfo *sample, uint8_t *input, int size)
Definition mov.c:8709
static int mov_metadata_int8_no_padding(MOVContext *c, AVIOContext *pb, unsigned len, const char *key)
Definition mov.c:129
static int search_frag_timestamp(AVFormatContext *s, MOVFragmentIndex *frag_index, AVStream *st, int64_t timestamp)
Definition mov.c:1852
static int mov_read_avid(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition mov.c:2417
static int set_exif_from_item(AVFormatContext *s, AVPacketSideData **coded_side_data, int *nb_coded_side_data, const HEIFItem *item)
Definition mov.c:11107
static void fix_timescale(MOVContext *c, MOVStreamContext *sc)
Definition mov.c:5503
static int mov_read_custom(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition mov.c:5796
static int mov_read_dac3(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition mov.c:871
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:7950
static int mov_read_close(AVFormatContext *s)
Definition mov.c:10913
static int mov_read_pasp(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition mov.c:1483
static int mov_open_dref(MOVContext *c, AVIOContext **pb, const char *src, MOVDref *ref)
Definition mov.c:5431
static MOVFragmentStreamInfo * get_frag_stream_info_from_pkt(MOVFragmentIndex *frag_index, AVPacket *pkt, int id)
Definition mov.c:8934
static int mov_read_avss(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition mov.c:2402
static int mov_read_tenc(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition mov.c:8502
static int mov_read_ipma(MOVContext *c, AVIOContext *pb, MOVAtom atom, MOVAtomExt *atoms, int nb_atoms)
Definition mov.c:10126
static int mov_read_uuid(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition mov.c:7776
static int mov_read_chan(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition mov.c:1306
static int build_open_gop_key_points(AVStream *st)
Definition mov.c:4850
static void set_last_stream_little_endian(AVFormatContext *fc)
Definition mov.c:2096
static void mov_build_index(MOVContext *mov, AVStream *st)
Definition mov.c:4983
static void mov_update_sample_durations(MOVContext *mov, AVStream *st)
Definition mov.c:5317
static int mov_read_ctts(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition mov.c:3999
static int mov_find_tref_id(const MovTref *tag, uint32_t id)
Definition mov.c:2660
static int mov_parse_heif_layered_video(AVFormatContext *s)
Definition mov.c:11945
static int mov_read_amve(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition mov.c:7077
static int mov_read_keys(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition mov.c:5744
static int mov_read_wfex(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition mov.c:1359
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:2589
static int mov_read_ftyp(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition mov.c:1655
#define IS_MATRIX_IDENT(matrix)
Definition mov.c:5974
static int can_seek_to_key_sample(AVStream *st, int sample, int64_t requested_pts)
Definition mov.c:13055
static int mov_parse_auxiliary_info(MOVContext *c, MOVStreamContext *sc, AVIOContext *pb, MOVEncryptionIndex *encryption_index)
Definition mov.c:8111
static int64_t mov_get_stsc_samples(MOVStreamContext *sc, unsigned int index)
Definition mov.c:3626
static int mov_read_vpcc(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition mov.c:6876
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:4334
static int mov_parse_tiles(AVFormatContext *s)
Definition mov.c:11473
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:4524
#define DDTS_SIZE
static int mov_read_iref_cdsc(MOVContext *c, AVIOContext *pb, uint32_t type, int version, uint32_t size)
Definition mov.c:9876
static int cenc_decrypt(MOVContext *c, MOVStreamContext *sc, AVEncryptionInfo *sample, uint8_t *input, int size)
Definition mov.c:8918
static int mov_read_senc(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition mov.c:8055
static int mov_read_sgpd(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition mov.c:4080
static AVStream * mov_find_reference_track(AVFormatContext *s, AVStream *st, uint32_t *tref_id, int nb_tref_id, int first_index)
Definition mov.c:12120
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:4375
static int mov_read_trak(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition mov.c:5579
static int mov_read_colr(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition mov.c:2211
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:4387
static void mov_parse_stsd_subtitle(MOVContext *c, AVIOContext *pb, AVStream *st, MOVStreamContext *sc, int64_t size)
Definition mov.c:3131
static int mov_read_clap(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition mov.c:1374
static int mov_read_dvc1(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition mov.c:2635
static int mov_read_vdep(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition mov.c:2775
static int mov_read_SAND(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition mov.c:9394
static int64_t mov_read_atom_into_extradata(MOVContext *c, AVIOContext *pb, MOVAtom atom, AVCodecParameters *par, uint8_t *buf)
Definition mov.c:2349
static void mov_free_encryption_index(MOVEncryptionIndex **index)
Definition mov.c:10836
static int mov_read_mac_string(MOVContext *c, AVIOContext *pb, int len, char *dst, int dstlen)
Definition mov.c:173
static void fix_stream_ids(AVFormatContext *s)
Definition mov.c:12314
#define OFFSET(x)
Definition mov.c:13229
static AVIndexEntry * mov_find_next_sample(AVFormatContext *s, AVStream **st)
Definition mov.c:12587
static int mov_read_chap(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition mov.c:6134
#define MOV_MERGE_CTTS
Definition mov.c:4913
static int is_open_key_sample(const MOVStreamContext *sc, int sample)
Definition mov.c:13038
static int mov_read_moof(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition mov.c:1955
static int mov_read_SA3D(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition mov.c:9304
static int mov_realloc_extradata(AVCodecParameters *par, MOVAtom atom)
Definition mov.c:2334
static int mov_read_udta_string(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition mov.c:349
static int mov_read_coll(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition mov.c:7011
static int mov_read_frma(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition mov.c:7903
static int mov_read_ispe(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition mov.c:10020
static int mov_codec_id(AVStream *st, uint32_t format)
Definition mov.c:2894
static void export_orphan_timecode(AVFormatContext *s)
Definition mov.c:10988
static int mov_parse_heif_items(AVFormatContext *s)
Definition mov.c:11999
static void mov_estimate_video_delay(MOVContext *c, AVStream *st)
Definition mov.c:4416
static int mov_read_vmhd(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition mov.c:10225
static int mov_read_tfhd(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition mov.c:6087
static MOVFragmentStreamInfo * get_frag_stream_info(MOVFragmentIndex *frag_index, int index, int id)
Definition mov.c:1721
static int mov_read_irot(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition mov.c:10048
static int mov_probe(const AVProbeData *p)
Definition mov.c:10555
static int parse_timecode_in_framenum_format(AVFormatContext *s, AVStream *st, int64_t value, int flags)
Definition mov.c:10749
static int mov_parse_uuid_spherical(MOVStreamContext *sc, AVIOContext *pb, size_t len)
Definition mov.c:7713
static void mov_current_sample_inc(MOVStreamContext *sc)
Definition mov.c:4472
static int mov_read_fiel(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition mov.c:2300
static int mov_read_iref_dimg_tmap(MOVContext *c, AVIOContext *pb, HEIFItem *item, int version, int entries)
Definition mov.c:9723
static int mov_read_targa_y216(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition mov.c:2425
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:4200
static int mov_read_wide(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition mov.c:6701
static int64_t get_frag_time(AVFormatContext *s, AVStream *dst_st, MOVFragmentIndex *frag_index, int index)
Definition mov.c:1810
static MOVFragmentStreamInfo * get_current_frag_stream_info(MOVFragmentIndex *frag_index)
Definition mov.c:1760
static int mov_read_esds(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition mov.c:866
static int mov_read_iinf(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition mov.c:9653
static int mov_parse_exif_item(AVFormatContext *s, HEIFItem *item, const HEIFItem *ref)
Definition mov.c:11353
static int tmcd_is_referenced(AVFormatContext *s, int tmcd_id)
Definition mov.c:10970
static void mov_read_chapters(AVFormatContext *s)
Definition mov.c:10650
static int mov_read_mhac(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition mov.c:10258
static int mov_read_cmov(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition mov.c:6721
static void set_frag_stream(MOVFragmentIndex *frag_index, int id)
Definition mov.c:1740
static const AVOption mov_options[]
Definition mov.c:13231
static MovTref * mov_add_tref_tag(MOVStreamContext *sc, uint32_t name)
Definition mov.c:2695
static int mov_read_vexu(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition mov.c:7622
int ff_mov_read_chan(AVFormatContext *s, AVIOContext *pb, AVStream *st, int64_t size)
Read 'chan' tag from the input stream.
Definition mov_chan.c:550
int ff_mov_read_chnl(AVFormatContext *s, AVIOContext *pb, AVStream *st, int version)
Read 'chnl' tag from the input stream.
Definition mov_chan.c:768
uint32_t tag
Definition movenc.c:2128
mpeg audio layer common tables.
const uint64_t ff_mpa_cicp_channel_layout_masks[20]
MPEG Audio header decoder.
static int ff_mpa_check_header(uint32_t header)
const char data[16]
Definition mxf.c:149
int profile
Definition mxfenc.c:2300
uint16_t cid
Definition mxfenc.c:2336
static int headroom(int *la)
Definition nellymoser.c:106
static float distance(float x, float y, int band)
#define OPUS_SEEK_PREROLL_MS
#define av_malloc(s)
Definition ops_static.c:52
AVOptions.
const char * av_color_space_name(enum AVColorSpace space)
Definition pixdesc.c:3884
const char * av_color_transfer_name(enum AVColorTransferCharacteristic transfer)
Definition pixdesc.c:3851
const char * av_color_primaries_name(enum AVColorPrimaries primaries)
Definition pixdesc.c:3818
@ AVCOL_RANGE_MPEG
Narrow or limited range content.
Definition pixfmt.h:771
@ AVCOL_RANGE_JPEG
Full range content.
Definition pixfmt.h:788
@ AVALPHA_MODE_STRAIGHT
Alpha channel is independent of color values.
Definition pixfmt.h:824
@ AVALPHA_MODE_UNSPECIFIED
Unknown alpha handling, or no alpha channel.
Definition pixfmt.h:822
@ AVALPHA_MODE_PREMULTIPLIED
Alpha channel is multiplied into color values.
Definition pixfmt.h:823
#define AVPALETTE_SIZE
Definition pixfmt.h:32
@ AVCOL_PRI_UNSPECIFIED
Definition pixfmt.h:650
@ AVCOL_TRC_UNSPECIFIED
Definition pixfmt.h:680
@ AVCOL_SPC_UNSPECIFIED
Definition pixfmt.h:714
static const uint16_t table[]
Definition prosumer.c:203
const char * name
Definition qsvenc.c:142
int ff_get_qtpalette(int codec_id, AVIOContext *pb, uint32_t *palette)
Retrieve the palette (or "color table" in QuickTime terms), either from the video sample description,...
Definition qtpalette.c:323
int ff_replaygain_export(AVStream *st, AVDictionary *metadata)
Parse replaygain tags and export them as per-stream side data.
Definition replaygain.c:94
const AVCodecTag ff_codec_bmp_tags[]
Definition riff.c:36
const AVCodecTag ff_codec_wav_tags[]
Definition riff.c:526
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.
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.
enum AVTiffDataType type
Definition exif.h:86
union AVExifEntry::@325220332140161067313112036135003363017341144014 value
AVRational * rat
Definition exif.h:113
unsigned int count
Definition exif.h:79
Format I/O context.
Definition avformat.h:1401
AVStream ** streams
A list of all streams in the file.
Definition avformat.h:1469
int error_recognition
Error recognition; higher values will detect more errors but may misdetect some more or less valid pa...
Definition avformat.h:1676
AVRational base_offset
Small constants added before the log-domain math to avoid a singularity at zero.
Definition gain_map.h:76
Parameters describing how to combine a gain map rendition with its base rendition to recover the alte...
Definition gain_map.h:39
AVRational alternate_hdr_headroom
Definition gain_map.h:57
struct AVGainMapParams::AVGainMapChannel channels[3]
int nb_channels
Must be 1 or 3.
Definition gain_map.h:83
int use_base_color_space
If non-zero, the gain map is applied in the colour space of the base rendition; otherwise in that of ...
Definition gain_map.h:50
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:431
uint8_t * data
Definition packet.h:432
enum AVPacketSideDataType type
Definition packet.h:434
This structure stores compressed data.
Definition packet.h:587
int size
Definition packet.h:611
uint8_t * data
Definition packet.h:610
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
AVStream * stream
Definition avformat.h:1180
AVStreamGroupLayeredVideo is meant to define the relation between a base layer video stream and a sep...
Definition avformat.h:1104
int height
Height of the final image for presentation.
Definition avformat.h:1129
unsigned int el_index
Index of the enhancement layer stream in AVStreamGroup.
Definition avformat.h:1113
int width
Width of the final stream for presentation.
Definition avformat.h:1125
unsigned int metadata_index
Index of the metadata stream in the AVStreamGroup.
Definition avformat.h:1154
AVStreamGroupTileGrid holds information on how to combine several independent images on a single canv...
Definition avformat.h:975
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
int vertical
Offset in pixels from the top edge of the canvas where the tile should be placed.
Definition avformat.h:1024
unsigned int nb_entries
Number of elements in AVStreamGroup.entries.
Definition avformat.h:1286
enum AVStreamGroupParamsType type
Group type.
Definition avformat.h:1212
struct AVIAMFMixPresentation * iamf_mix_presentation
Definition avformat.h:1219
AVStreamGroupEntry ** entries
A list of streams or child groups in the group.
Definition avformat.h:1299
struct AVStreamGroupTileGrid * tile_grid
Definition avformat.h:1220
struct AVStreamGroupTREF * tref
Definition avformat.h:1229
int nb_coded_side_data
Amount of entries in coded_side_data.
Definition avformat.h:1312
AVDictionary * metadata
Metadata that applies to the whole group.
Definition avformat.h:1240
union AVStreamGroup::@313244315204024013007202273061153315146016101155 params
Group type-specific parameters.
struct AVIAMFAudioElement * iamf_audio_element
Definition avformat.h:1218
int disposition
Stream group disposition - a combination of AV_DISPOSITION_* flags.
Definition avformat.h:1278
int64_t id
Group type-specific group ID.
Definition avformat.h:1204
AVPacketSideData * coded_side_data
Additional data associated with the group.
Definition avformat.h:1307
struct AVStreamGroupLayeredVideo * layered_video
Definition avformat.h:1221
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:244
int64_t first_discard_sample
If not 0, the first audio sample that should be discarded from the stream.
Definition internal.h:237
int skip_samples
Number of samples to skip at the start of the frame decoded from the next packet.
Definition internal.h:220
int nb_index_entries
Definition internal.h:198
AVRational display_aspect_ratio
display aspect ratio (0 if unknown)
Definition internal.h:322
AVIndexEntry * index_entries
Only used if the format does not support seeking natively.
Definition internal.h:196
enum AVStreamParseType need_parsing
Definition internal.h:340
unsigned int index_entries_allocated_size
Definition internal.h:199
int16_t * item_id_list
Definition isom.h:328
HEIFItem ** item_list
Definition isom.h:327
int nb_items
Definition isom.h:330
unsigned * item_idx_list
Definition isom.h:329
HEIFItem * item
Definition isom.h:326
int item_id
Definition isom.h:296
uint32_t type
Definition isom.h:295
int is_idat_relative
Definition isom.h:319
int type
Definition isom.h:316
int nb_iref_from_list
Definition isom.h:303
AVStreamGroup * stg
Definition isom.h:301
char * name
Definition isom.h:307
int nb_iref_to_list
Definition isom.h:305
uint8_t * icc_profile
Definition isom.h:321
HEIFItemRef * iref_from_list
Definition isom.h:302
int rotation
Definition isom.h:313
int is_alpha
Definition isom.h:318
int hflip
Definition isom.h:314
AVExifMetadata ifd
Definition isom.h:320
int64_t extent_length
Definition isom.h:309
int flags
Definition isom.h:306
AVStream * st
Definition isom.h:300
int is_gainmap
Definition isom.h:317
size_t icc_profile_size
Definition isom.h:322
int vflip
Definition isom.h:315
int64_t extent_offset
Definition isom.h:310
int width
Definition isom.h:311
int height
Definition isom.h:312
int item_id
Definition isom.h:308
HEIFItemRef * iref_to_list
Definition isom.h:304
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
int64_t size
Definition mov.c:10089
uint32_t type
Definition mov.c:10088
uint8_t * data
Definition mov.c:10090
uint32_t type
Definition isom.h:102
int64_t size
Definition isom.h:103
int handbrake_version
Definition isom.h:353
AVDictionary * decryption_keys
Definition isom.h:402
int * bitrates
bitrates read before streams creation
Definition isom.h:365
int cur_item_id
Definition isom.h:395
int ignore_editlist
Definition isom.h:357
HEIFGroup * heif_group
Definition isom.h:398
uint8_t * decryption_default_key
Definition isom.h:387
unsigned meta_keys_count
Definition isom.h:345
char ** meta_keys
Definition isom.h:344
AVFormatContext * fc
Definition isom.h:335
unsigned int aax_mode
'aax' file has been detected
Definition isom.h:375
int found_mdat
'mdat' atom has been found
Definition isom.h:341
int found_iinf
'iinf' atom has been found
Definition isom.h:340
int bitrates_count
Definition isom.h:366
int * chapter_tracks
Definition isom.h:354
int interleaved_read
Definition isom.h:401
int64_t next_root_atom
offset of the next root atom
Definition isom.h:362
int ignore_chapters
Definition isom.h:360
DVDemuxContext * dv_demux
Definition isom.h:346
int nb_heif_item
Definition isom.h:397
unsigned int nb_chapter_tracks
Definition isom.h:355
int64_t idat_offset
Definition isom.h:400
MOVFragmentIndex frag_index
Definition isom.h:371
int nb_heif_group
Definition isom.h:399
MOVTrackExt * trex_data
Definition isom.h:350
uint8_t * pssh_side_data
Definition isom.h:372
struct AVAES * aes_decrypt
Definition isom.h:386
MOVFragment fragment
current fragment in moof atom
Definition isom.h:349
AVFormatContext * dv_fctx
Definition isom.h:347
int moov_retry
Definition isom.h:367
int time_scale
Definition isom.h:336
int advanced_editlist_autodisabled
Definition isom.h:359
int found_moov
'moov' atom has been found
Definition isom.h:338
int primary_item_id
Definition isom.h:394
int advanced_editlist
Definition isom.h:358
int found_iloc
'iloc' atom has been found
Definition isom.h:339
HEIFItem ** heif_item
Definition isom.h:396
int trak_index
Index of the current 'trak'.
Definition isom.h:343
int use_mfra_for
Definition isom.h:368
Definition isom.h:69
unsigned int count
Definition isom.h:70
int offset
Definition isom.h:71
Definition isom.h:86
char volume[28]
Definition isom.h:90
char * dir
Definition isom.h:89
int16_t nlvl_to
Definition isom.h:92
char * path
Definition isom.h:88
uint32_t type
Definition isom.h:87
int16_t nlvl_from
Definition isom.h:92
char filename[64]
Definition isom.h:91
Definition isom.h:80
float rate
Definition isom.h:83
int64_t duration
Definition isom.h:81
int64_t time
Definition isom.h:82
uint64_t * auxiliary_offsets
Absolute seek position.
Definition isom.h:142
unsigned int nb_encrypted_samples
Definition isom.h:136
size_t auxiliary_offsets_count
Definition isom.h:143
size_t auxiliary_info_sample_count
Definition isom.h:140
uint8_t auxiliary_info_default_size
Definition isom.h:141
uint8_t * auxiliary_info_sizes
Definition isom.h:139
AVEncryptionInfo ** encrypted_samples
Definition isom.h:137
MOVFragmentStreamInfo * stream_info
Definition isom.h:164
int64_t moof_offset
Definition isom.h:160
int allocated_size
Definition isom.h:168
MOVFragmentIndexItem * item
Definition isom.h:172
MOVEncryptionIndex * encryption_index
Definition isom.h:155
int64_t next_trun_dts
Definition isom.h:151
int64_t first_tfra_pts
Definition isom.h:149
unsigned track_id
Definition isom.h:110
unsigned flags
Definition isom.h:117
unsigned duration
Definition isom.h:115
int found_tfhd
Definition isom.h:109
unsigned size
Definition isom.h:116
unsigned stsd_id
Definition isom.h:114
uint64_t base_data_offset
Definition isom.h:111
uint64_t moof_offset
Definition isom.h:112
uint64_t implicit_offset
Definition isom.h:113
int64_t start
Definition isom.h:176
int64_t end
Definition isom.h:177
int(* parse)(MOVContext *ctx, AVIOContext *pb, MOVAtom atom)
Definition mov.c:88
uint32_t type
Definition mov.c:87
unsigned int index
Definition isom.h:130
unsigned int count
Definition isom.h:129
int64_t time_offset
time offset of the edit list entries
Definition isom.h:218
int64_t duration_for_fps
Definition isom.h:258
AVIOContext * pb
Definition isom.h:181
size_t spherical_size
Definition isom.h:271
uint32_t min_sample_duration
Definition isom.h:255
uint8_t ** extradata
extradata array (and size) for multiple stsd
Definition isom.h:261
MOVSbgp * rap_group
Definition isom.h:246
int iamf_stream_offset
Definition isom.h:291
MOVEncryptionIndex * encryption_index
Definition isom.h:287
int64_t track_end
used for dts generation in fragmented movie files
Definition isom.h:244
int pseudo_stream_id
-1 means demux all ids
Definition isom.h:227
unsigned int rap_group_count
Definition isom.h:245
int height
tkhd height
Definition isom.h:235
int stsc_sample
Definition isom.h:203
MOVDref * drefs
Definition isom.h:230
int sample_offsets_count
Definition isom.h:252
unsigned int ctts_allocated_size
Definition isom.h:198
unsigned int per_sample_iv_size
Definition isom.h:285
int * extradata_size
Definition isom.h:262
size_t coll_size
Definition isom.h:275
int dv_audio_container
Definition isom.h:226
AVContentLightMetadata * coll
Definition isom.h:274
int64_t * chunk_offsets
Definition isom.h:188
size_t ambient_size
Definition isom.h:277
MOVStsc * stsc_data
Definition isom.h:201
uint8_t * sgpd_sync
Definition isom.h:249
size_t stereo3d_size
Definition isom.h:269
MOVTimeToSample * tts_data
Definition isom.h:191
AVStereo3D * stereo3d
Definition isom.h:268
int32_t * display_matrix
Definition isom.h:267
int current_sample
Definition isom.h:220
uint32_t sgpd_sync_count
Definition isom.h:250
unsigned int samples_per_frame
Definition isom.h:225
int nb_frames_for_fps
Definition isom.h:257
uint32_t format
Definition isom.h:279
int keyframe_absent
Definition isom.h:214
int open_key_samples_count
Definition isom.h:254
MOVElst * elst_data
Definition isom.h:206
int64_t current_index
Definition isom.h:221
int * open_key_samples
Definition isom.h:253
unsigned int stts_count
Definition isom.h:192
uint8_t * sdtp_data
Definition isom.h:196
unsigned int sample_size
may contain value calculated from stsd or value from stsz atom
Definition isom.h:210
AVEncryptionInfo * default_encrypted_sample
Definition isom.h:286
int nb_tref_tags
Definition isom.h:232
int16_t audio_cid
stsd audio compression id
Definition isom.h:228
struct AVAESCTR * aes_ctr
Definition isom.h:283
MOVStts * stts_data
Definition isom.h:194
int last_stsd_index
Definition isom.h:263
unsigned int chunk_count
Definition isom.h:187
size_t mastering_size
Definition isom.h:273
AVAmbientViewingEnvironment * ambient
Definition isom.h:276
int64_t data_size
Definition isom.h:241
int pb_is_copied
Definition isom.h:183
int * keyframes
Definition isom.h:216
struct MOVStreamContext::@212112112267365060330232277203165117121340225276 cenc
unsigned drefs_count
Definition isom.h:229
MOVIndexRange * current_index_range
Definition isom.h:223
unsigned int * sample_sizes
Definition isom.h:213
MOVCtts * ctts_data
Definition isom.h:199
AVMasteringDisplayMetadata * mastering
Definition isom.h:272
int width
tkhd width
Definition isom.h:234
int id
AVStream id.
Definition isom.h:184
uint8_t tmcd_nb_frames
tmcd number of frames per tick / second
Definition isom.h:243
unsigned int sdtp_count
Definition isom.h:195
int v_spacing
pasp vSpacing
Definition isom.h:237
unsigned int sample_count
Definition isom.h:212
MOVSbgp * sync_group
Definition isom.h:248
int dts_shift
dts shift when ctts is negative
Definition isom.h:238
unsigned int tts_count
Definition isom.h:189
int stsd_version
Definition isom.h:265
unsigned int stsc_index
Definition isom.h:202
int64_t min_corrected_pts
minimum Composition time shown by the edits excluding empty edits.
Definition isom.h:219
struct AVAES * aes_ctx
Definition isom.h:284
int32_t * sample_offsets
Definition isom.h:251
int has_palette
Definition isom.h:240
MovTref * tref_tags
Definition isom.h:233
uint32_t palette[256]
Definition isom.h:239
int ffindex
AVStream index.
Definition isom.h:185
AVSphericalMapping * spherical
Definition isom.h:270
unsigned int keyframe_count
Definition isom.h:215
unsigned int bytes_per_frame
Definition isom.h:224
uint32_t tmcd_flags
tmcd track flags
Definition isom.h:242
unsigned * stps_data
partial sync sample for mpeg-2 open gop
Definition isom.h:205
unsigned int stts_allocated_size
Definition isom.h:193
unsigned int sync_group_count
Definition isom.h:247
MOVIndexRange * index_ranges
Definition isom.h:222
struct IAMFDemuxContext * iamf
Definition isom.h:290
unsigned int stsc_count
Definition isom.h:200
unsigned int stsz_sample_size
always contains sample size from stsz atom
Definition isom.h:211
int h_spacing
pasp hSpacing
Definition isom.h:236
unsigned int elst_count
Definition isom.h:207
unsigned int ctts_count
Definition isom.h:197
unsigned int stps_count
Definition isom.h:204
unsigned int tts_allocated_size
Definition isom.h:190
int first
Definition isom.h:75
int count
Definition isom.h:76
int id
Definition isom.h:77
Definition isom.h:64
unsigned int count
Definition isom.h:65
unsigned int duration
Definition isom.h:66
unsigned int count
Definition isom.h:59
unsigned int duration
Definition isom.h:60
unsigned flags
Definition isom.h:125
unsigned duration
Definition isom.h:123
unsigned size
Definition isom.h:124
unsigned track_id
Definition isom.h:121
unsigned stsd_id
Definition isom.h:122
const char * value
Definition isom.h:512
Definition isom.h:95
uint32_t * id
trackID of the referenced track
Definition isom.h:98
Definition swscale.c:82
#define av_free(p)
#define av_malloc_array(a, b)
#define av_mallocz(s)
#define ff_dlog(a,...)
#define av_realloc_f(p, o, n)
#define avpriv_request_sample(...)
#define av_freep(p)
#define av_log(a,...)
static uint8_t tmp[40]
Definition aes_ctr.c:52
static const uint8_t fixed_key[]
Definition aes_ctr.c:45
int tile_cols
Definition av1_levels.c:73
#define src
Definition vp8dsp.c:248
int num
Definition error.c:23
static int ref[MAX_W *MAX_W]
static char buffer[20]
Definition seek.c:33
#define height
Definition dsp.h:99
#define width
Definition dsp.h:99
int av_timecode_init(AVTimecode *tc, AVRational rate, int flags, int frame_start, void *log_ctx)
Init a timecode struct with the passed parameters.
Definition timecode.c:201
char * av_timecode_make_string(const AVTimecode *tc, char *buf, int framenum_arg)
Load timecode string in buf.
Definition timecode.c:104
Timecode helpers header.
#define AV_TIMECODE_STR_SIZE
Definition timecode.h:33
@ AV_TIMECODE_FLAG_ALLOWNEGATIVE
negative time values are allowed
Definition timecode.h:38
@ AV_TIMECODE_FLAG_DROPFRAME
timecode is drop frame
Definition timecode.h:36
@ AV_TIMECODE_FLAG_24HOURSMAX
timecode wraps after 24 hours
Definition timecode.h:37
static int64_t pts
static const int16_t cdt2[8]
int size
UUID parsing and serialization utilities.
static int av_uuid_equal(const AVUUID uu1, const AVUUID uu2)
Compares two UUIDs for equality.
Definition uuid.h:119
#define AV_UUID_LEN
Definition uuid.h:57
uint8_t AVUUID[AV_UUID_LEN]
Definition uuid.h:60
enum AVCodecID codec_id
#define mc
static float mean(const float *input, int size)
Definition vf_nnedi.c:861
color_range
int len
uint8_t base
Definition vp3data.h:128
static double c[64]