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
1032 ret = avformat_stream_group_add_stream(stg, stream);
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");
1589 ret = AVERROR_INVALIDDATA;
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");
1598 ret = AVERROR_INVALIDDATA;
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)
2421 ret = mov_read_extradata(c, pb, atom, AV_CODEC_ID_DNXHD);
2422 return ret;
2423}
2424
2426{
2427 int ret = mov_read_extradata(c, pb, atom, AV_CODEC_ID_TARGA_Y216);
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 avio_rb32(pb); /* sizeof struct only */
3040 channel_count = avio_rb32(pb);
3042 st->codecpar->ch_layout.nb_channels = channel_count;
3043 avio_rb32(pb); /* always 0x7F000000 */
3045
3046 flags = avio_rb32(pb); /* lpcm format specific flag */
3047 sc->bytes_per_frame = avio_rb32(pb);
3048 sc->samples_per_frame = avio_rb32(pb);
3049 if (st->codecpar->codec_tag == MKTAG('l','p','c','m'))
3050 st->codecpar->codec_id =
3052 flags);
3053 }
3054 if (version == 0 || (version == 1 && sc->audio_cid != -2)) {
3055 /* can't correctly handle variable sized packet as audio unit */
3056 switch (st->codecpar->codec_id) {
3057 case AV_CODEC_ID_MP2:
3058 case AV_CODEC_ID_MP3:
3060 break;
3061 }
3062 }
3063 }
3064
3065 if (sc->format == 0) {
3066 if (st->codecpar->bits_per_coded_sample == 8)
3067 st->codecpar->codec_id = mov_codec_id(st, MKTAG('r','a','w',' '));
3068 else if (st->codecpar->bits_per_coded_sample == 16)
3069 st->codecpar->codec_id = mov_codec_id(st, MKTAG('t','w','o','s'));
3070 }
3071
3072 switch (st->codecpar->codec_id) {
3073 case AV_CODEC_ID_PCM_S8:
3074 case AV_CODEC_ID_PCM_U8:
3075 if (st->codecpar->bits_per_coded_sample == 16)
3077 break;
3080 if (st->codecpar->bits_per_coded_sample == 8)
3082 else if (st->codecpar->bits_per_coded_sample == 24)
3083 st->codecpar->codec_id =
3086 else if (st->codecpar->bits_per_coded_sample == 32)
3087 st->codecpar->codec_id =
3090 break;
3091 /* set values for old format before stsd version 1 appeared */
3092 case AV_CODEC_ID_MACE3:
3093 sc->samples_per_frame = 6;
3095 break;
3096 case AV_CODEC_ID_MACE6:
3097 sc->samples_per_frame = 6;
3099 break;
3101 sc->samples_per_frame = 64;
3103 break;
3104 case AV_CODEC_ID_GSM:
3105 sc->samples_per_frame = 160;
3106 sc->bytes_per_frame = 33;
3107 break;
3108 default:
3109 break;
3110 }
3111
3112 bits_per_sample = av_get_bits_per_sample(st->codecpar->codec_id);
3113 if (bits_per_sample && (bits_per_sample >> 3) * (uint64_t)st->codecpar->ch_layout.nb_channels <= INT_MAX) {
3114 st->codecpar->bits_per_coded_sample = bits_per_sample;
3115 sc->sample_size = (bits_per_sample >> 3) * st->codecpar->ch_layout.nb_channels;
3116 }
3117}
3118
3120 AVStream *st, MOVStreamContext *sc,
3121 int64_t size)
3122{
3123 // ttxt stsd contains display flags, justification, background
3124 // color, fonts, and default styles, so fake an atom to read it
3125 MOVAtom fake_atom = { .size = size };
3126 // mp4s contains a regular esds atom, dfxp ISMV TTML has no content
3127 // in extradata unlike stpp MP4 TTML.
3128 if (st->codecpar->codec_tag != AV_RL32("mp4s") &&
3130 mov_read_glbl(c, pb, fake_atom);
3131 st->codecpar->width = sc->width;
3132 st->codecpar->height = sc->height;
3133}
3134
3136 AVStream *st, MOVStreamContext *sc,
3137 int64_t size)
3138{
3139 int ret;
3140
3141 if (st->codecpar->codec_tag == MKTAG('t','m','c','d')) {
3142 if ((int)size != size)
3143 return AVERROR(ENOMEM);
3144
3145 ret = ff_get_extradata(c->fc, st->codecpar, pb, size);
3146 if (ret < 0)
3147 return ret;
3148 if (size > 16) {
3149 MOVStreamContext *tmcd_ctx = st->priv_data;
3150 int val;
3151 val = AV_RB32(st->codecpar->extradata + 4);
3152 tmcd_ctx->tmcd_flags = val;
3153 st->avg_frame_rate.num = AV_RB32(st->codecpar->extradata + 8); /* timescale */
3154 st->avg_frame_rate.den = AV_RB32(st->codecpar->extradata + 12); /* frameDuration */
3155 tmcd_ctx->tmcd_nb_frames = st->codecpar->extradata[16]; /* number of frames */
3156 if (size > 30) {
3157 uint32_t len = AV_RB32(st->codecpar->extradata + 18); /* name atom length */
3158 uint32_t format = AV_RB32(st->codecpar->extradata + 22);
3159 if (format == AV_RB32("name") && (int64_t)size >= (int64_t)len + 18) {
3160 uint16_t str_size = AV_RB16(st->codecpar->extradata + 26); /* string length */
3161 if (str_size > 0 && size >= (int)str_size + 30 &&
3162 st->codecpar->extradata[30] /* Don't add empty string */) {
3163 char *reel_name = av_malloc(str_size + 1);
3164 if (!reel_name)
3165 return AVERROR(ENOMEM);
3166 memcpy(reel_name, st->codecpar->extradata + 30, str_size);
3167 reel_name[str_size] = 0; /* Add null terminator */
3168 av_dict_set(&st->metadata, "reel_name", reel_name,
3170 }
3171 }
3172 }
3173 }
3174 } else if (st->codecpar->codec_id == AV_CODEC_ID_ITUT_T35) {
3175 int t35_identifier_length = avio_r8(pb);
3176
3177 if (t35_identifier_length <= 0 || t35_identifier_length >= size)
3178 return AVERROR_INVALIDDATA;
3179
3180 ret = ff_get_extradata(c->fc, st->codecpar, pb, t35_identifier_length);
3181 if (ret < 0)
3182 return ret;
3183
3184 int hrsd_len = size - t35_identifier_length - 1;
3185 if (hrsd_len > 0) {
3186 uint8_t *hrsd_str = av_malloc(hrsd_len + 1);
3187 if (!hrsd_str)
3188 return AVERROR(ENOMEM);
3189
3190 ret = ffio_read_size(pb, hrsd_str, hrsd_len);
3191 if (ret < 0) {
3192 av_free(hrsd_str);
3193 return ret;
3194 }
3195 if (hrsd_str[0]) {
3196 hrsd_str[hrsd_len] = 0;
3197 ret = av_dict_set(&st->metadata, "description", hrsd_str, AV_DICT_DONT_OVERWRITE);
3198 }
3199 av_free(hrsd_str);
3200 }
3201 } else {
3202 /* other codec type, just skip (rtp, mp4s ...) */
3203 avio_skip(pb, size);
3204 }
3205 return 0;
3206}
3207
3209 AVStream *st, MOVStreamContext *sc)
3210{
3211 FFStream *const sti = ffstream(st);
3212
3214 !st->codecpar->sample_rate && sc->time_scale > 1)
3215 st->codecpar->sample_rate = sc->time_scale;
3216
3217 /* special codec parameters handling */
3218 switch (st->codecpar->codec_id) {
3219#if CONFIG_DV_DEMUXER
3221 if (c->dv_fctx) {
3222 avpriv_request_sample(c->fc, "multiple DV audio streams");
3223 return AVERROR(ENOSYS);
3224 }
3225
3226 c->dv_fctx = avformat_alloc_context();
3227 if (!c->dv_fctx) {
3228 av_log(c->fc, AV_LOG_ERROR, "dv demux context alloc error\n");
3229 return AVERROR(ENOMEM);
3230 }
3231 c->dv_demux = avpriv_dv_init_demux(c->dv_fctx);
3232 if (!c->dv_demux) {
3233 av_log(c->fc, AV_LOG_ERROR, "dv demux context init error\n");
3234 return AVERROR(ENOMEM);
3235 }
3236 sc->dv_audio_container = 1;
3238 break;
3239#endif
3240 /* no ifdef since parameters are always those */
3241 case AV_CODEC_ID_QCELP:
3244 // force sample rate for qcelp when not stored in mov
3245 if (st->codecpar->codec_tag != MKTAG('Q','c','l','p'))
3246 st->codecpar->sample_rate = 8000;
3247 // FIXME: Why is the following needed for some files?
3248 sc->samples_per_frame = 160;
3249 if (!sc->bytes_per_frame)
3250 sc->bytes_per_frame = 35;
3251 break;
3252 case AV_CODEC_ID_AMR_NB:
3255 /* force sample rate for amr, stsd in 3gp does not store sample rate */
3256 st->codecpar->sample_rate = 8000;
3257 break;
3258 case AV_CODEC_ID_AMR_WB:
3261 st->codecpar->sample_rate = 16000;
3262 break;
3263 case AV_CODEC_ID_MP2:
3264 case AV_CODEC_ID_MP3:
3265 /* force type after stsd for m1a hdlr */
3267 break;
3268 case AV_CODEC_ID_GSM:
3271 case AV_CODEC_ID_ILBC:
3272 case AV_CODEC_ID_MACE3:
3273 case AV_CODEC_ID_MACE6:
3274 case AV_CODEC_ID_QDM2:
3276 break;
3277 case AV_CODEC_ID_ALAC:
3278 if (st->codecpar->extradata_size == 36) {
3279 int channel_count = AV_RB8(st->codecpar->extradata + 21);
3280 if (st->codecpar->ch_layout.nb_channels != channel_count) {
3283 st->codecpar->ch_layout.nb_channels = channel_count;
3284 }
3285 st->codecpar->sample_rate = AV_RB32(st->codecpar->extradata + 32);
3286 }
3287 break;
3288 case AV_CODEC_ID_AC3:
3289 case AV_CODEC_ID_EAC3:
3291 case AV_CODEC_ID_VC1:
3292 case AV_CODEC_ID_VP8:
3293 case AV_CODEC_ID_VP9:
3295 break;
3297 case AV_CODEC_ID_PRORES:
3298 case AV_CODEC_ID_APV:
3299 case AV_CODEC_ID_EVC:
3300 case AV_CODEC_ID_LCEVC:
3301 case AV_CODEC_ID_AV1:
3302 /* field_order detection of H264 requires parsing */
3303 case AV_CODEC_ID_H264:
3305 break;
3306 default:
3307 break;
3308 }
3309 return 0;
3310}
3311
3313 int codec_tag, int format,
3314 int64_t size)
3315{
3316 if (codec_tag &&
3317 (codec_tag != format &&
3318 // AVID 1:1 samples with differing data format and codec tag exist
3319 (codec_tag != AV_RL32("AV1x") || format != AV_RL32("AVup")) &&
3320 // prores is allowed to have differing data format and codec tag
3321 codec_tag != AV_RL32("apcn") && codec_tag != AV_RL32("apch") &&
3322 // so is dv (sigh)
3323 codec_tag != AV_RL32("dvpp") && codec_tag != AV_RL32("dvcp") &&
3324 (c->fc->video_codec_id ? ff_codec_get_id(ff_codec_movvideo_tags, format) != c->fc->video_codec_id
3325 : codec_tag != MKTAG('j','p','e','g')))) {
3326 /* Multiple fourcc, we skip JPEG. This is not correct, we should
3327 * export it as a separate AVStream but this needs a few changes
3328 * in the MOV demuxer, patch welcome. */
3329
3330 av_log(c->fc, AV_LOG_WARNING, "multiple fourcc not supported\n");
3331 avio_skip(pb, size);
3332 return 1;
3333 }
3334
3335 return 0;
3336}
3337
3339{
3340 int ret;
3341
3342 /* special codec parameters handling */
3343 switch (st->codecpar->codec_id) {
3344 case AV_CODEC_ID_H264:
3345 // done for ai5q, ai52, ai55, ai1q, ai12 and ai15.
3348 if (ret < 0)
3349 return ret;
3350 }
3351 break;
3352 default:
3353 break;
3354 }
3355
3356 return 0;
3357}
3358
3360{
3361 AVStream *st;
3362 MOVStreamContext *sc;
3363 int pseudo_stream_id;
3364
3365 av_assert0 (c->fc->nb_streams >= 1);
3366 st = c->fc->streams[c->fc->nb_streams-1];
3367 sc = st->priv_data;
3368
3369 for (pseudo_stream_id = 0;
3370 pseudo_stream_id < entries && !pb->eof_reached;
3371 pseudo_stream_id++) {
3372 //Parsing Sample description table
3373 enum AVCodecID id;
3374 int ret, dref_id = 1;
3375 MOVAtom a = { AV_RL32("stsd") };
3376 int64_t start_pos = avio_tell(pb);
3377 int64_t size = avio_rb32(pb); /* size */
3378 uint32_t format = avio_rl32(pb); /* data format */
3379
3380 if (size >= 16) {
3381 avio_rb32(pb); /* reserved */
3382 avio_rb16(pb); /* reserved */
3383 dref_id = avio_rb16(pb);
3384 } else if (size <= 7) {
3385 av_log(c->fc, AV_LOG_ERROR,
3386 "invalid size %"PRId64" in stsd\n", size);
3387 return AVERROR_INVALIDDATA;
3388 }
3389
3391 size - (avio_tell(pb) - start_pos))) {
3392 sc->stsd_count++;
3393 continue;
3394 }
3395
3396 sc->pseudo_stream_id = st->codecpar->codec_tag ? -1 : pseudo_stream_id;
3397 sc->dref_id= dref_id;
3398 sc->format = format;
3399
3400 id = mov_codec_id(st, format);
3401
3402 av_log(c->fc, AV_LOG_TRACE,
3403 "size=%"PRId64" 4CC=%s codec_type=%d\n", size,
3405
3406 st->codecpar->codec_id = id;
3408 mov_parse_stsd_video(c, pb, st, sc);
3409 } else if (st->codecpar->codec_type==AVMEDIA_TYPE_AUDIO) {
3410 mov_parse_stsd_audio(c, pb, st, sc);
3411 if (st->codecpar->sample_rate < 0) {
3412 av_log(c->fc, AV_LOG_ERROR, "Invalid sample rate %d\n", st->codecpar->sample_rate);
3413 return AVERROR_INVALIDDATA;
3414 }
3415 if (st->codecpar->ch_layout.nb_channels < 0) {
3416 av_log(c->fc, AV_LOG_ERROR, "Invalid channels %d\n", st->codecpar->ch_layout.nb_channels);
3417 return AVERROR_INVALIDDATA;
3418 }
3419 } else if (st->codecpar->codec_type==AVMEDIA_TYPE_SUBTITLE){
3420 mov_parse_stsd_subtitle(c, pb, st, sc,
3421 size - (avio_tell(pb) - start_pos));
3422 } else {
3423 ret = mov_parse_stsd_data(c, pb, st, sc,
3424 size - (avio_tell(pb) - start_pos));
3425 if (ret < 0)
3426 return ret;
3427 }
3428 /* this will read extra atoms at the end (wave, alac, damr, avcC, hvcC, SMI ...) */
3429 a.size = size - (avio_tell(pb) - start_pos);
3430 if (a.size > 8) {
3431 if ((ret = mov_read_default(c, pb, a)) < 0)
3432 return ret;
3433 } else if (a.size > 0)
3434 avio_skip(pb, a.size);
3435
3436 ret = mov_finalize_stsd_entry(c, st);
3437 if (ret < 0)
3438 return ret;
3439
3440 if (sc->extradata && st->codecpar->extradata) {
3441 int extra_size = st->codecpar->extradata_size;
3442
3443 /* Move the current stream extradata to the stream context one. */
3444 sc->extradata_size[pseudo_stream_id] = extra_size;
3445 sc->extradata[pseudo_stream_id] = st->codecpar->extradata;
3446 st->codecpar->extradata = NULL;
3447 st->codecpar->extradata_size = 0;
3448 }
3449 sc->stsd_count++;
3450 }
3451
3452 if (pb->eof_reached) {
3453 av_log(c->fc, AV_LOG_WARNING, "reached eof, corrupted STSD atom\n");
3454 return AVERROR_EOF;
3455 }
3456
3457 return 0;
3458}
3459
3461{
3462 AVStream *st;
3463 MOVStreamContext *sc;
3464 int ret, entries;
3465
3466 if (c->fc->nb_streams < 1)
3467 return 0;
3468 st = c->fc->streams[c->fc->nb_streams - 1];
3469 sc = st->priv_data;
3470
3471 if (sc->extradata) {
3472 av_log(c->fc, AV_LOG_ERROR,
3473 "Duplicate stsd found in this track.\n");
3474 return AVERROR_INVALIDDATA;
3475 }
3476
3477 sc->stsd_version = avio_r8(pb);
3478 avio_rb24(pb); /* flags */
3479 entries = avio_rb32(pb);
3480
3481 /* Each entry contains a size (4 bytes) and format (4 bytes). */
3482 if (entries <= 0 || entries > atom.size / 8 || entries > 1024) {
3483 av_log(c->fc, AV_LOG_ERROR, "invalid STSD entries %d\n", entries);
3484 return AVERROR_INVALIDDATA;
3485 }
3486
3487 /* Prepare space for hosting multiple extradata. */
3488 sc->extradata = av_calloc(entries, sizeof(*sc->extradata));
3489 if (!sc->extradata)
3490 return AVERROR(ENOMEM);
3491
3492 sc->extradata_size = av_calloc(entries, sizeof(*sc->extradata_size));
3493 if (!sc->extradata_size) {
3494 ret = AVERROR(ENOMEM);
3495 goto fail;
3496 }
3497
3498 ret = ff_mov_read_stsd_entries(c, pb, entries);
3499 if (ret < 0)
3500 goto fail;
3501
3502 /* Restore back the primary extradata. */
3505 if (sc->extradata_size[0]) {
3507 if (!st->codecpar->extradata)
3508 return AVERROR(ENOMEM);
3509 memcpy(st->codecpar->extradata, sc->extradata[0], sc->extradata_size[0]);
3510 }
3511
3512 return mov_finalize_stsd_codec(c, pb, st, sc);
3513fail:
3514 if (sc->extradata) {
3515 int j;
3516 for (j = 0; j < sc->stsd_count; j++)
3517 av_freep(&sc->extradata[j]);
3518 }
3519
3520 sc->stsd_count = 0;
3521 av_freep(&sc->extradata);
3523 return ret;
3524}
3525
3527{
3528 AVStream *st;
3529 MOVStreamContext *sc;
3530 unsigned int i, entries;
3531
3532 if (c->trak_index < 0) {
3533 av_log(c->fc, AV_LOG_WARNING, "STSC outside TRAK\n");
3534 return 0;
3535 }
3536
3537 if (c->fc->nb_streams < 1)
3538 return 0;
3539 st = c->fc->streams[c->fc->nb_streams-1];
3540 sc = st->priv_data;
3541
3542 avio_r8(pb); /* version */
3543 avio_rb24(pb); /* flags */
3544
3545 entries = avio_rb32(pb);
3546 if ((uint64_t)entries * 12 + 4 > atom.size)
3547 return AVERROR_INVALIDDATA;
3548
3549 av_log(c->fc, AV_LOG_TRACE, "track[%u].stsc.entries = %u\n", c->fc->nb_streams - 1, entries);
3550
3551 if (!entries)
3552 return 0;
3553 if (sc->stsc_data) {
3554 av_log(c->fc, AV_LOG_WARNING, "Ignoring duplicated STSC atom\n");
3555 return 0;
3556 }
3557 av_free(sc->stsc_data);
3558 sc->stsc_count = 0;
3559 sc->stsc_data = av_malloc_array(entries, sizeof(*sc->stsc_data));
3560 if (!sc->stsc_data)
3561 return AVERROR(ENOMEM);
3562
3563 for (i = 0; i < entries && !pb->eof_reached; i++) {
3564 sc->stsc_data[i].first = avio_rb32(pb);
3565 sc->stsc_data[i].count = avio_rb32(pb);
3566 sc->stsc_data[i].id = avio_rb32(pb);
3567 }
3568
3569 sc->stsc_count = i;
3570 for (i = sc->stsc_count - 1; i < UINT_MAX; i--) {
3571 int64_t first_min = i + 1;
3572 if ((i+1 < sc->stsc_count && sc->stsc_data[i].first >= sc->stsc_data[i+1].first) ||
3573 (i > 0 && sc->stsc_data[i].first <= sc->stsc_data[i-1].first) ||
3574 sc->stsc_data[i].first < first_min ||
3575 sc->stsc_data[i].count < 1 ||
3576 sc->stsc_data[i].id < 1) {
3577 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);
3578 if (i+1 >= sc->stsc_count) {
3579 if (sc->stsc_data[i].count == 0 && i > 0) {
3580 sc->stsc_count --;
3581 continue;
3582 }
3583 sc->stsc_data[i].first = FFMAX(sc->stsc_data[i].first, first_min);
3584 if (i > 0 && sc->stsc_data[i].first <= sc->stsc_data[i-1].first)
3585 sc->stsc_data[i].first = FFMIN(sc->stsc_data[i-1].first + 1LL, INT_MAX);
3586 sc->stsc_data[i].count = FFMAX(sc->stsc_data[i].count, 1);
3587 sc->stsc_data[i].id = FFMAX(sc->stsc_data[i].id, 1);
3588 continue;
3589 }
3590 av_assert0(sc->stsc_data[i+1].first >= 2);
3591 // We replace this entry by the next valid
3592 sc->stsc_data[i].first = sc->stsc_data[i+1].first - 1;
3593 sc->stsc_data[i].count = sc->stsc_data[i+1].count;
3594 sc->stsc_data[i].id = sc->stsc_data[i+1].id;
3595 }
3596 }
3597
3598 if (pb->eof_reached) {
3599 av_log(c->fc, AV_LOG_WARNING, "reached eof, corrupted STSC atom\n");
3600 return AVERROR_EOF;
3601 }
3602
3603 return 0;
3604}
3605
3606static inline int mov_stsc_index_valid(unsigned int index, unsigned int count)
3607{
3608 return index < count - 1;
3609}
3610
3611/* Compute the samples value for the stsc entry at the given index. */
3612static inline int64_t mov_get_stsc_samples(MOVStreamContext *sc, unsigned int index)
3613{
3614 int chunk_count;
3615
3617 chunk_count = sc->stsc_data[index + 1].first - sc->stsc_data[index].first;
3618 else {
3619 // Validation for stsc / stco happens earlier in mov_read_stsc + mov_read_trak.
3621 chunk_count = sc->chunk_count - (sc->stsc_data[index].first - 1);
3622 }
3623
3624 return sc->stsc_data[index].count * (int64_t)chunk_count;
3625}
3626
3628{
3629 AVStream *st;
3630 MOVStreamContext *sc;
3631 unsigned i, entries;
3632
3633 if (c->trak_index < 0) {
3634 av_log(c->fc, AV_LOG_WARNING, "STPS outside TRAK\n");
3635 return 0;
3636 }
3637
3638 if (c->fc->nb_streams < 1)
3639 return 0;
3640 st = c->fc->streams[c->fc->nb_streams-1];
3641 sc = st->priv_data;
3642
3643 avio_rb32(pb); // version + flags
3644
3645 entries = avio_rb32(pb);
3646 if (sc->stps_data)
3647 av_log(c->fc, AV_LOG_WARNING, "Duplicated STPS atom\n");
3648 av_free(sc->stps_data);
3649 sc->stps_count = 0;
3650 sc->stps_data = av_malloc_array(entries, sizeof(*sc->stps_data));
3651 if (!sc->stps_data)
3652 return AVERROR(ENOMEM);
3653
3654 for (i = 0; i < entries && !pb->eof_reached; i++) {
3655 sc->stps_data[i] = avio_rb32(pb);
3656 }
3657
3658 sc->stps_count = i;
3659
3660 if (pb->eof_reached) {
3661 av_log(c->fc, AV_LOG_WARNING, "reached eof, corrupted STPS atom\n");
3662 return AVERROR_EOF;
3663 }
3664
3665 return 0;
3666}
3667
3669{
3670 AVStream *st;
3671 FFStream *sti;
3672 MOVStreamContext *sc;
3673 unsigned int i, entries;
3674
3675 if (c->trak_index < 0) {
3676 av_log(c->fc, AV_LOG_WARNING, "STSS outside TRAK\n");
3677 return 0;
3678 }
3679
3680 if (c->fc->nb_streams < 1)
3681 return 0;
3682 st = c->fc->streams[c->fc->nb_streams-1];
3683 sti = ffstream(st);
3684 sc = st->priv_data;
3685
3686 avio_r8(pb); /* version */
3687 avio_rb24(pb); /* flags */
3688
3689 entries = avio_rb32(pb);
3690
3691 av_log(c->fc, AV_LOG_TRACE, "keyframe_count = %u\n", entries);
3692
3693 if (!entries) {
3694 sc->keyframe_absent = 1;
3697 return 0;
3698 }
3699 if (sc->keyframes)
3700 av_log(c->fc, AV_LOG_WARNING, "Duplicated STSS atom\n");
3701 if (entries >= UINT_MAX / sizeof(int))
3702 return AVERROR_INVALIDDATA;
3703 av_freep(&sc->keyframes);
3704 sc->keyframe_count = 0;
3705 sc->keyframes = av_malloc_array(entries, sizeof(*sc->keyframes));
3706 if (!sc->keyframes)
3707 return AVERROR(ENOMEM);
3708
3709 for (i = 0; i < entries && !pb->eof_reached; i++) {
3710 sc->keyframes[i] = avio_rb32(pb);
3711 }
3712
3713 sc->keyframe_count = i;
3714
3715 if (pb->eof_reached) {
3716 av_log(c->fc, AV_LOG_WARNING, "reached eof, corrupted STSS atom\n");
3717 return AVERROR_EOF;
3718 }
3719
3720 return 0;
3721}
3722
3724{
3725 AVStream *st;
3726 MOVStreamContext *sc;
3727 unsigned int i, entries, sample_size, field_size, num_bytes;
3728 GetBitContext gb;
3729 unsigned char* buf;
3730 int ret;
3731
3732 if (c->trak_index < 0) {
3733 av_log(c->fc, AV_LOG_WARNING, "STSZ outside TRAK\n");
3734 return 0;
3735 }
3736
3737 if (c->fc->nb_streams < 1)
3738 return 0;
3739 st = c->fc->streams[c->fc->nb_streams-1];
3740 sc = st->priv_data;
3741
3742 avio_r8(pb); /* version */
3743 avio_rb24(pb); /* flags */
3744
3745 if (atom.type == MKTAG('s','t','s','z')) {
3746 sample_size = avio_rb32(pb);
3747 if (!sc->sample_size) /* do not overwrite value computed in stsd */
3748 sc->sample_size = sample_size;
3749 sc->stsz_sample_size = sample_size;
3750 field_size = 32;
3751 } else {
3752 sample_size = 0;
3753 avio_rb24(pb); /* reserved */
3754 field_size = avio_r8(pb);
3755 }
3756 entries = avio_rb32(pb);
3757
3758 av_log(c->fc, AV_LOG_TRACE, "sample_size = %u sample_count = %u\n", sc->sample_size, entries);
3759
3760 sc->sample_count = entries;
3761 if (sample_size)
3762 return 0;
3763
3764 if (field_size != 4 && field_size != 8 && field_size != 16 && field_size != 32) {
3765 av_log(c->fc, AV_LOG_ERROR, "Invalid sample field size %u\n", field_size);
3766 return AVERROR_INVALIDDATA;
3767 }
3768
3769 if (!entries)
3770 return 0;
3771 if (entries >= (INT_MAX - 4 - 8 * AV_INPUT_BUFFER_PADDING_SIZE) / field_size)
3772 return AVERROR_INVALIDDATA;
3773 if (sc->sample_sizes)
3774 av_log(c->fc, AV_LOG_WARNING, "Duplicated STSZ atom\n");
3775 av_free(sc->sample_sizes);
3776 sc->sample_count = 0;
3777 sc->sample_sizes = av_malloc_array(entries, sizeof(*sc->sample_sizes));
3778 if (!sc->sample_sizes)
3779 return AVERROR(ENOMEM);
3780
3781 num_bytes = (entries*field_size+4)>>3;
3782
3783 buf = av_malloc(num_bytes+AV_INPUT_BUFFER_PADDING_SIZE);
3784 if (!buf) {
3785 av_freep(&sc->sample_sizes);
3786 return AVERROR(ENOMEM);
3787 }
3788
3789 ret = ffio_read_size(pb, buf, num_bytes);
3790 if (ret < 0) {
3791 av_freep(&sc->sample_sizes);
3792 av_free(buf);
3793 av_log(c->fc, AV_LOG_WARNING, "STSZ atom truncated\n");
3794 return 0;
3795 }
3796
3797 init_get_bits(&gb, buf, 8*num_bytes);
3798
3799 for (i = 0; i < entries; i++) {
3800 sc->sample_sizes[i] = get_bits_long(&gb, field_size);
3801 if (sc->sample_sizes[i] > INT64_MAX - sc->data_size) {
3802 av_free(buf);
3803 av_log(c->fc, AV_LOG_ERROR, "Sample size overflow in STSZ\n");
3804 return AVERROR_INVALIDDATA;
3805 }
3806 sc->data_size += sc->sample_sizes[i];
3807 }
3808
3809 sc->sample_count = i;
3810
3811 av_free(buf);
3812
3813 return 0;
3814}
3815
3817{
3818 AVStream *st;
3819 MOVStreamContext *sc;
3820 unsigned int i, entries;
3821 int64_t duration = 0;
3822 int64_t total_sample_count = 0;
3823 int64_t current_dts = 0;
3824 int64_t corrected_dts = 0;
3825
3826 if (c->trak_index < 0) {
3827 av_log(c->fc, AV_LOG_WARNING, "STTS outside TRAK\n");
3828 return 0;
3829 }
3830
3831 if (c->fc->nb_streams < 1)
3832 return 0;
3833 st = c->fc->streams[c->fc->nb_streams-1];
3834 sc = st->priv_data;
3835
3836 avio_r8(pb); /* version */
3837 avio_rb24(pb); /* flags */
3838 entries = avio_rb32(pb);
3839
3840 av_log(c->fc, AV_LOG_TRACE, "track[%u].stts.entries = %u\n",
3841 c->fc->nb_streams-1, entries);
3842
3843 if (sc->stts_data)
3844 av_log(c->fc, AV_LOG_WARNING, "Duplicated STTS atom\n");
3845 av_freep(&sc->stts_data);
3846 sc->stts_count = 0;
3847 if (entries >= INT_MAX / sizeof(*sc->stts_data))
3848 return AVERROR(ENOMEM);
3849
3850 for (i = 0; i < entries && !pb->eof_reached; i++) {
3851 unsigned int sample_duration;
3852 unsigned int sample_count;
3853 unsigned int min_entries = FFMIN(FFMAX(i + 1, 1024 * 1024), entries);
3855 min_entries * sizeof(*sc->stts_data));
3856 if (!stts_data) {
3857 av_freep(&sc->stts_data);
3858 sc->stts_count = 0;
3859 return AVERROR(ENOMEM);
3860 }
3861 sc->stts_count = min_entries;
3862 sc->stts_data = stts_data;
3863
3864 sample_count = avio_rb32(pb);
3865 sample_duration = avio_rb32(pb);
3866
3867 sc->stts_data[i].count= sample_count;
3868 sc->stts_data[i].duration= sample_duration;
3869
3870 av_log(c->fc, AV_LOG_TRACE, "sample_count=%u, sample_duration=%u\n",
3871 sample_count, sample_duration);
3872
3873 /* STTS sample offsets are uint32 but some files store it as int32
3874 * with negative values used to correct DTS delays.
3875 There may be abnormally large values as well. */
3876 if (sample_duration > c->max_stts_delta) {
3877 // assume high delta is a correction if negative when cast as int32
3878 int32_t delta_magnitude = (int32_t)sample_duration;
3879 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",
3880 sample_duration, i, sample_count, st->index);
3881 sc->stts_data[i].duration = 1;
3882 corrected_dts = av_sat_add64(corrected_dts, (delta_magnitude < 0 ? (int64_t)delta_magnitude : 1) * sample_count);
3883 } else {
3884 corrected_dts += sample_duration * (uint64_t)sample_count;
3885 }
3886
3887 current_dts += sc->stts_data[i].duration * (uint64_t)sample_count;
3888
3889 if (current_dts > corrected_dts) {
3890 int64_t drift = av_sat_sub64(current_dts, corrected_dts) / FFMAX(sample_count, 1);
3891 uint32_t correction = (sc->stts_data[i].duration > drift) ? drift : sc->stts_data[i].duration - 1;
3892 current_dts -= correction * (uint64_t)sample_count;
3893 sc->stts_data[i].duration -= correction;
3894 }
3895
3896 duration+=(int64_t)sc->stts_data[i].duration*(uint64_t)sc->stts_data[i].count;
3897 total_sample_count+=sc->stts_data[i].count;
3898 }
3899
3900 sc->stts_count = i;
3901
3902 if (duration > 0 &&
3903 duration <= INT64_MAX - sc->duration_for_fps &&
3904 total_sample_count <= INT_MAX - sc->nb_frames_for_fps) {
3906 sc->nb_frames_for_fps += total_sample_count;
3907 }
3908
3909 if (pb->eof_reached) {
3910 av_log(c->fc, AV_LOG_WARNING, "reached eof, corrupted STTS atom\n");
3911 return AVERROR_EOF;
3912 }
3913
3914 st->nb_frames= total_sample_count;
3915 if (duration)
3916 st->duration= FFMIN(st->duration, duration);
3917
3918 // All samples have zero duration. They have higher chance be chose by
3919 // mov_find_next_sample, which leads to seek again and again.
3920 //
3921 // It's AVERROR_INVALIDDATA actually, but such files exist in the wild.
3922 // So only mark data stream as discarded for safety.
3923 if (!duration && sc->stts_count &&
3925 av_log(c->fc, AV_LOG_WARNING,
3926 "All samples in data stream index:id [%d:%d] have zero "
3927 "duration, stream set to be discarded by default. Override "
3928 "using AVStream->discard or -discard for ffmpeg command.\n",
3929 st->index, sc->id);
3930 st->discard = AVDISCARD_ALL;
3931 }
3932 sc->track_end = duration;
3933 return 0;
3934}
3935
3937{
3938 AVStream *st;
3939 MOVStreamContext *sc;
3940 unsigned int i;
3941 int64_t entries;
3942
3943 if (c->fc->nb_streams < 1)
3944 return 0;
3945 st = c->fc->streams[c->fc->nb_streams - 1];
3946 sc = st->priv_data;
3947
3948 avio_r8(pb); /* version */
3949 avio_rb24(pb); /* flags */
3950 entries = atom.size - 4;
3951
3952 av_log(c->fc, AV_LOG_TRACE, "track[%u].sdtp.entries = %" PRId64 "\n",
3953 c->fc->nb_streams - 1, entries);
3954
3955 if (sc->sdtp_data)
3956 av_log(c->fc, AV_LOG_WARNING, "Duplicated SDTP atom\n");
3957 av_freep(&sc->sdtp_data);
3958 sc->sdtp_count = 0;
3959
3960 if (entries < 0 || entries > UINT_MAX)
3961 return AVERROR(ERANGE);
3962
3963 sc->sdtp_data = av_malloc(entries);
3964 if (!sc->sdtp_data)
3965 return AVERROR(ENOMEM);
3966
3967 for (i = 0; i < entries && !pb->eof_reached; i++)
3968 sc->sdtp_data[i] = avio_r8(pb);
3969 sc->sdtp_count = i;
3970
3971 return 0;
3972}
3973
3974static void mov_update_dts_shift(MOVStreamContext *sc, int duration, void *logctx)
3975{
3976 if (duration < 0) {
3977 if (duration == INT_MIN) {
3978 av_log(logctx, AV_LOG_WARNING, "mov_update_dts_shift(): dts_shift set to %d\n", INT_MAX);
3979 duration++;
3980 }
3981 sc->dts_shift = FFMAX(sc->dts_shift, -duration);
3982 }
3983}
3984
3986{
3987 AVStream *st;
3988 MOVStreamContext *sc;
3989 unsigned int i, entries, ctts_count = 0;
3990
3991 if (c->trak_index < 0) {
3992 av_log(c->fc, AV_LOG_WARNING, "CTTS outside TRAK\n");
3993 return 0;
3994 }
3995
3996 if (c->fc->nb_streams < 1)
3997 return 0;
3998 st = c->fc->streams[c->fc->nb_streams-1];
3999 sc = st->priv_data;
4000
4001 avio_r8(pb); /* version */
4002 avio_rb24(pb); /* flags */
4003 entries = avio_rb32(pb);
4004
4005 av_log(c->fc, AV_LOG_TRACE, "track[%u].ctts.entries = %u\n", c->fc->nb_streams - 1, entries);
4006
4007 if (!entries)
4008 return 0;
4009 if (entries >= UINT_MAX / sizeof(*sc->ctts_data))
4010 return AVERROR_INVALIDDATA;
4011 av_freep(&sc->ctts_data);
4012 sc->ctts_data = av_fast_realloc(NULL, &sc->ctts_allocated_size, entries * sizeof(*sc->ctts_data));
4013 if (!sc->ctts_data)
4014 return AVERROR(ENOMEM);
4015
4016 for (i = 0; i < entries && !pb->eof_reached; i++) {
4017 MOVCtts *ctts_data;
4018 const size_t min_size_needed = (ctts_count + 1) * sizeof(MOVCtts);
4019 const size_t requested_size =
4020 min_size_needed > sc->ctts_allocated_size ?
4021 FFMAX(min_size_needed, 2 * sc->ctts_allocated_size) :
4022 min_size_needed;
4023 int count = avio_rb32(pb);
4024 int duration = avio_rb32(pb);
4025
4026 if (count <= 0) {
4027 av_log(c->fc, AV_LOG_TRACE,
4028 "ignoring CTTS entry with count=%d duration=%d\n",
4029 count, duration);
4030 continue;
4031 }
4032
4033 if (ctts_count >= UINT_MAX / sizeof(MOVCtts) - 1)
4034 return AVERROR(ENOMEM);
4035
4036 ctts_data = av_fast_realloc(sc->ctts_data, &sc->ctts_allocated_size, requested_size);
4037
4038 if (!ctts_data)
4039 return AVERROR(ENOMEM);
4040
4041 sc->ctts_data = ctts_data;
4042
4043 ctts_data[ctts_count].count = count;
4044 ctts_data[ctts_count].offset = duration;
4045 ctts_count++;
4046
4047 av_log(c->fc, AV_LOG_TRACE, "count=%d, duration=%d\n",
4048 count, duration);
4049
4050 if (i+2<entries)
4052 }
4053
4054 sc->ctts_count = ctts_count;
4055
4056 if (pb->eof_reached) {
4057 av_log(c->fc, AV_LOG_WARNING, "reached eof, corrupted CTTS atom\n");
4058 return AVERROR_EOF;
4059 }
4060
4061 av_log(c->fc, AV_LOG_TRACE, "dts shift %d\n", sc->dts_shift);
4062
4063 return 0;
4064}
4065
4067{
4068 AVStream *st;
4069 MOVStreamContext *sc;
4070 uint8_t version;
4071 uint32_t grouping_type;
4072 uint32_t default_length;
4073 av_unused uint32_t default_group_description_index;
4074 uint32_t entry_count;
4075
4076 if (c->fc->nb_streams < 1)
4077 return 0;
4078 st = c->fc->streams[c->fc->nb_streams - 1];
4079 sc = st->priv_data;
4080
4081 version = avio_r8(pb); /* version */
4082 avio_rb24(pb); /* flags */
4083 grouping_type = avio_rl32(pb);
4084
4085 /*
4086 * This function only supports "sync" boxes, but the code is able to parse
4087 * other boxes (such as "tscl", "tsas" and "stsa")
4088 */
4089 if (grouping_type != MKTAG('s','y','n','c'))
4090 return 0;
4091
4092 default_length = version >= 1 ? avio_rb32(pb) : 0;
4093 default_group_description_index = version >= 2 ? avio_rb32(pb) : 0;
4094 entry_count = avio_rb32(pb);
4095
4096 if (entry_count > atom.size)
4097 return AVERROR_INVALIDDATA;
4098
4099 av_freep(&sc->sgpd_sync);
4100 sc->sgpd_sync_count = entry_count;
4101 sc->sgpd_sync = av_calloc(entry_count, sizeof(*sc->sgpd_sync));
4102 if (!sc->sgpd_sync)
4103 return AVERROR(ENOMEM);
4104
4105 for (uint32_t i = 0; i < entry_count && !pb->eof_reached; i++) {
4106 uint32_t description_length = default_length;
4107 if (version >= 1 && default_length == 0)
4108 description_length = avio_rb32(pb);
4109 if (grouping_type == MKTAG('s','y','n','c')) {
4110 const uint8_t nal_unit_type = avio_r8(pb) & 0x3f;
4111 sc->sgpd_sync[i] = nal_unit_type;
4112 description_length -= 1;
4113 }
4114 avio_skip(pb, description_length);
4115 }
4116
4117 if (pb->eof_reached) {
4118 av_log(c->fc, AV_LOG_WARNING, "reached eof, corrupted SGPD atom\n");
4119 return AVERROR_EOF;
4120 }
4121
4122 return 0;
4123}
4124
4126{
4127 AVStream *st;
4128 MOVStreamContext *sc;
4129 unsigned int i, entries;
4130 uint8_t version;
4131 uint32_t grouping_type;
4132 MOVSbgp *table, **tablep;
4133 int *table_count;
4134
4135 if (c->fc->nb_streams < 1)
4136 return 0;
4137 st = c->fc->streams[c->fc->nb_streams-1];
4138 sc = st->priv_data;
4139
4140 version = avio_r8(pb); /* version */
4141 avio_rb24(pb); /* flags */
4142 grouping_type = avio_rl32(pb);
4143
4144 if (grouping_type == MKTAG('r','a','p',' ')) {
4145 tablep = &sc->rap_group;
4146 table_count = &sc->rap_group_count;
4147 } else if (grouping_type == MKTAG('s','y','n','c')) {
4148 tablep = &sc->sync_group;
4149 table_count = &sc->sync_group_count;
4150 } else {
4151 return 0;
4152 }
4153
4154 if (version == 1)
4155 avio_rb32(pb); /* grouping_type_parameter */
4156
4157 entries = avio_rb32(pb);
4158 if (!entries)
4159 return 0;
4160 if (*tablep)
4161 av_log(c->fc, AV_LOG_WARNING, "Duplicated SBGP %s atom\n", av_fourcc2str(grouping_type));
4162 av_freep(tablep);
4163 table = av_malloc_array(entries, sizeof(*table));
4164 if (!table)
4165 return AVERROR(ENOMEM);
4166 *tablep = table;
4167
4168 for (i = 0; i < entries && !pb->eof_reached; i++) {
4169 table[i].count = avio_rb32(pb); /* sample_count */
4170 table[i].index = avio_rb32(pb); /* group_description_index */
4171 }
4172
4173 *table_count = i;
4174
4175 if (pb->eof_reached) {
4176 av_log(c->fc, AV_LOG_WARNING, "reached eof, corrupted SBGP atom\n");
4177 return AVERROR_EOF;
4178 }
4179
4180 return 0;
4181}
4182
4183/**
4184 * Get ith edit list entry (media time, duration).
4185 */
4187 const MOVStreamContext *msc,
4188 unsigned int edit_list_index,
4189 int64_t *edit_list_media_time,
4190 int64_t *edit_list_duration,
4191 int64_t global_timescale)
4192{
4193 if (edit_list_index == msc->elst_count) {
4194 return 0;
4195 }
4196 *edit_list_media_time = msc->elst_data[edit_list_index].time;
4197 *edit_list_duration = msc->elst_data[edit_list_index].duration;
4198
4199 /* duration is in global timescale units;convert to msc timescale */
4200 if (global_timescale == 0) {
4201 avpriv_request_sample(mov->fc, "Support for mvhd.timescale = 0 with editlists");
4202 return 0;
4203 }
4204 *edit_list_duration = av_rescale(*edit_list_duration, msc->time_scale,
4205 global_timescale);
4206
4207 if (*edit_list_duration < 0 ||
4208 *edit_list_media_time > INT64_MAX - *edit_list_duration)
4209 *edit_list_duration = 0;
4210
4211 return 1;
4212}
4213
4214/**
4215 * Find the closest previous frame to the timestamp_pts, in e_old index
4216 * entries. Searching for just any frame / just key frames can be controlled by
4217 * last argument 'flag'.
4218 * Note that if ctts_data is not NULL, we will always search for a key frame
4219 * irrespective of the value of 'flag'. If we don't find any keyframe, we will
4220 * return the first frame of the video.
4221 *
4222 * Here the timestamp_pts is considered to be a presentation timestamp and
4223 * the timestamp of index entries are considered to be decoding timestamps.
4224 *
4225 * Returns 0 if successful in finding a frame, else returns -1.
4226 * Places the found index corresponding output arg.
4227 *
4228 * If ctts_old is not NULL, then refines the searched entry by searching
4229 * backwards from the found timestamp, to find the frame with correct PTS.
4230 *
4231 * Places the found ctts_index and ctts_sample in corresponding output args.
4232 */
4234 AVIndexEntry *e_old,
4235 int nb_old,
4236 MOVTimeToSample *tts_data,
4237 int64_t tts_count,
4238 int64_t timestamp_pts,
4239 int flag,
4240 int64_t* index,
4241 int64_t* tts_index,
4242 int64_t* tts_sample)
4243{
4244 MOVStreamContext *msc = st->priv_data;
4245 FFStream *const sti = ffstream(st);
4246 AVIndexEntry *e_keep = sti->index_entries;
4247 int nb_keep = sti->nb_index_entries;
4248 int64_t i = 0;
4249
4251
4252 // If dts_shift > 0, then all the index timestamps will have to be offset by
4253 // at least dts_shift amount to obtain PTS.
4254 // Hence we decrement the searched timestamp_pts by dts_shift to find the closest index element.
4255 if (msc->dts_shift > 0) {
4256 timestamp_pts -= msc->dts_shift;
4257 }
4258
4259 sti->index_entries = e_old;
4260 sti->nb_index_entries = nb_old;
4262
4263 // Keep going backwards in the index entries until the timestamp is the same.
4264 if (*index >= 0) {
4265 for (i = *index; i > 0 && e_old[i].timestamp == e_old[i - 1].timestamp;
4266 i--) {
4267 if ((flag & AVSEEK_FLAG_ANY) ||
4268 (e_old[i - 1].flags & AVINDEX_KEYFRAME)) {
4269 *index = i - 1;
4270 }
4271 }
4272 }
4273
4274 // If we have CTTS then refine the search, by searching backwards over PTS
4275 // computed by adding corresponding CTTS durations to index timestamps.
4276 if (msc->ctts_count && *index >= 0) {
4277 av_assert0(tts_index);
4278 av_assert0(tts_sample);
4279 // Find out the ctts_index for the found frame.
4280 *tts_index = FFMIN(*index, tts_count);
4281 *tts_sample = 0;
4282
4283 while (*index >= 0 && (*tts_index) >= 0 && (*tts_index) < tts_count) {
4284 // Find a "key frame" with PTS <= timestamp_pts (So that we can decode B-frames correctly).
4285 // No need to add dts_shift to the timestamp here because timestamp_pts has already been
4286 // compensated by dts_shift above.
4287 if ((e_old[*index].timestamp + tts_data[*tts_index].offset) <= timestamp_pts &&
4288 (e_old[*index].flags & AVINDEX_KEYFRAME)) {
4289 break;
4290 }
4291
4292 (*index)--;
4293 if (*tts_sample == 0) {
4294 (*tts_index)--;
4295 if (*tts_index >= 0)
4296 *tts_sample = tts_data[*tts_index].count - 1;
4297 } else {
4298 (*tts_sample)--;
4299 }
4300 }
4301 }
4302
4303 /* restore AVStream state*/
4304 sti->index_entries = e_keep;
4305 sti->nb_index_entries = nb_keep;
4306 return *index >= 0 ? 0 : -1;
4307}
4308
4309/**
4310 * Add index entry with the given values, to the end of ffstream(st)->index_entries.
4311 * Returns the new size ffstream(st)->index_entries if successful, else returns -1.
4312 *
4313 * This function is similar to ff_add_index_entry in libavformat/utils.c
4314 * except that here we are always unconditionally adding an index entry to
4315 * the end, instead of searching the entries list and skipping the add if
4316 * there is an existing entry with the same timestamp.
4317 * This is needed because the mov_fix_index calls this func with the same
4318 * unincremented timestamp for successive discarded frames.
4319 */
4321 int size, int distance, int flags)
4322{
4323 FFStream *const sti = ffstream(st);
4324 AVIndexEntry *entries, *ie;
4325 int64_t index = -1;
4326 const size_t min_size_needed = (sti->nb_index_entries + 1) * sizeof(AVIndexEntry);
4327
4328 // Double the allocation each time, to lower memory fragmentation.
4329 // Another difference from ff_add_index_entry function.
4330 const size_t requested_size =
4331 min_size_needed > sti->index_entries_allocated_size ?
4332 FFMAX(min_size_needed, 2 * sti->index_entries_allocated_size) :
4333 min_size_needed;
4334
4335 if (sti->nb_index_entries + 1U >= UINT_MAX / sizeof(AVIndexEntry))
4336 return -1;
4337
4338 entries = av_fast_realloc(sti->index_entries,
4340 requested_size);
4341 if (!entries)
4342 return -1;
4343
4344 sti->index_entries = entries;
4345
4346 index = sti->nb_index_entries++;
4347 ie= &entries[index];
4348
4349 ie->pos = pos;
4350 ie->timestamp = timestamp;
4352 ie->size= size;
4353 ie->flags = flags;
4354 return index;
4355}
4356
4357/**
4358 * Rewrite timestamps of index entries in the range [end_index - frame_duration_buffer_size, end_index)
4359 * by subtracting end_ts successively by the amounts given in frame_duration_buffer.
4360 */
4361static void fix_index_entry_timestamps(AVStream* st, int end_index, int64_t end_ts,
4362 int64_t* frame_duration_buffer,
4363 int frame_duration_buffer_size) {
4364 FFStream *const sti = ffstream(st);
4365 int i = 0;
4366 av_assert0(end_index >= 0 && end_index <= sti->nb_index_entries);
4367 for (i = 0; i < frame_duration_buffer_size; i++) {
4368 end_ts -= frame_duration_buffer[frame_duration_buffer_size - 1 - i];
4369 sti->index_entries[end_index - 1 - i].timestamp = end_ts;
4370 }
4371}
4372
4373static int add_tts_entry(MOVTimeToSample **tts_data, unsigned int *tts_count, unsigned int *allocated_size,
4374 int count, int offset, unsigned int duration)
4375{
4376 MOVTimeToSample *tts_buf_new;
4377 const size_t min_size_needed = (*tts_count + 1) * sizeof(MOVTimeToSample);
4378 const size_t requested_size =
4379 min_size_needed > *allocated_size ?
4380 FFMAX(min_size_needed, 2 * (*allocated_size)) :
4381 min_size_needed;
4382
4383 if ((unsigned)(*tts_count) >= UINT_MAX / sizeof(MOVTimeToSample) - 1)
4384 return -1;
4385
4386 tts_buf_new = av_fast_realloc(*tts_data, allocated_size, requested_size);
4387
4388 if (!tts_buf_new)
4389 return -1;
4390
4391 *tts_data = tts_buf_new;
4392
4393 tts_buf_new[*tts_count].count = count;
4394 tts_buf_new[*tts_count].offset = offset;
4395 tts_buf_new[*tts_count].duration = duration;
4396
4397 *tts_count = (*tts_count) + 1;
4398 return 0;
4399}
4400
4401#define MAX_REORDER_DELAY 16
4403{
4404 MOVStreamContext *msc = st->priv_data;
4405 FFStream *const sti = ffstream(st);
4406 int ctts_ind = 0;
4407 int ctts_sample = 0;
4408 int64_t pts_buf[MAX_REORDER_DELAY + 1]; // Circular buffer to sort pts.
4409 int buf_start = 0;
4410 int j, r, num_swaps;
4411
4412 for (j = 0; j < MAX_REORDER_DELAY + 1; j++)
4413 pts_buf[j] = INT64_MIN;
4414
4415 if (st->codecpar->video_delay <= 0 && msc->ctts_count &&
4417 st->codecpar->video_delay = 0;
4418 for (int ind = 0; ind < sti->nb_index_entries && ctts_ind < msc->tts_count; ++ind) {
4419 // Point j to the last elem of the buffer and insert the current pts there.
4420 j = buf_start;
4421 buf_start = (buf_start + 1);
4422 if (buf_start == MAX_REORDER_DELAY + 1)
4423 buf_start = 0;
4424
4425 pts_buf[j] = sti->index_entries[ind].timestamp + msc->tts_data[ctts_ind].offset;
4426
4427 // The timestamps that are already in the sorted buffer, and are greater than the
4428 // current pts, are exactly the timestamps that need to be buffered to output PTS
4429 // in correct sorted order.
4430 // Hence the video delay (which is the buffer size used to sort DTS and output PTS),
4431 // can be computed as the maximum no. of swaps any particular timestamp needs to
4432 // go through, to keep this buffer in sorted order.
4433 num_swaps = 0;
4434 while (j != buf_start) {
4435 r = j - 1;
4436 if (r < 0) r = MAX_REORDER_DELAY;
4437 if (pts_buf[j] < pts_buf[r]) {
4438 FFSWAP(int64_t, pts_buf[j], pts_buf[r]);
4439 ++num_swaps;
4440 } else {
4441 break;
4442 }
4443 j = r;
4444 }
4445 st->codecpar->video_delay = FFMAX(st->codecpar->video_delay, num_swaps);
4446
4447 ctts_sample++;
4448 if (ctts_sample == msc->tts_data[ctts_ind].count) {
4449 ctts_ind++;
4450 ctts_sample = 0;
4451 }
4452 }
4453 av_log(c->fc, AV_LOG_DEBUG, "Setting codecpar->delay to %d for stream st: %d\n",
4454 st->codecpar->video_delay, st->index);
4455 }
4456}
4457
4459{
4460 sc->current_sample++;
4461 sc->current_index++;
4462 if (sc->index_ranges &&
4464 sc->current_index_range->end) {
4465 sc->current_index_range++;
4467 }
4468}
4469
4471{
4472 sc->current_sample--;
4473 sc->current_index--;
4474 if (sc->index_ranges &&
4477 sc->current_index_range--;
4478 sc->current_index = sc->current_index_range->end - 1;
4479 }
4480}
4481
4482static void mov_current_sample_set(MOVStreamContext *sc, int current_sample)
4483{
4484 int64_t range_size;
4485
4486 sc->current_sample = current_sample;
4487 sc->current_index = current_sample;
4488 if (!sc->index_ranges) {
4489 return;
4490 }
4491
4492 for (sc->current_index_range = sc->index_ranges;
4494 sc->current_index_range++) {
4495 range_size = sc->current_index_range->end - sc->current_index_range->start;
4496 if (range_size > current_sample) {
4497 sc->current_index = sc->current_index_range->start + current_sample;
4498 break;
4499 }
4500 current_sample -= range_size;
4501 }
4502}
4503
4504/**
4505 * Fix ffstream(st)->index_entries, so that it contains only the entries (and the entries
4506 * which are needed to decode them) that fall in the edit list time ranges.
4507 * Also fixes the timestamps of the index entries to match the timeline
4508 * specified the edit lists.
4509 */
4510static void mov_fix_index(MOVContext *mov, AVStream *st)
4511{
4512 MOVStreamContext *msc = st->priv_data;
4513 FFStream *const sti = ffstream(st);
4514 AVIndexEntry *e_old = sti->index_entries;
4515 int nb_old = sti->nb_index_entries;
4516 const AVIndexEntry *e_old_end = e_old + nb_old;
4517 const AVIndexEntry *current = NULL;
4518 MOVTimeToSample *tts_data_old = msc->tts_data;
4519 int64_t tts_index_old = 0;
4520 int64_t tts_sample_old = 0;
4521 int64_t tts_count_old = msc->tts_count;
4522 int64_t edit_list_media_time = 0;
4523 int64_t edit_list_duration = 0;
4524 int64_t frame_duration = 0;
4525 int64_t edit_list_dts_counter = 0;
4526 int64_t edit_list_dts_entry_end = 0;
4527 int64_t edit_list_start_tts_sample = 0;
4528 int64_t curr_cts;
4529 int64_t curr_ctts = 0;
4530 int64_t empty_edits_sum_duration = 0;
4531 int64_t edit_list_index = 0;
4532 int64_t index;
4533 int flags;
4534 int64_t start_dts = 0;
4535 int64_t edit_list_start_encountered = 0;
4536 int64_t search_timestamp = 0;
4537 int64_t* frame_duration_buffer = NULL;
4538 int num_discarded_begin = 0;
4539 int first_non_zero_audio_edit = -1;
4540 int packet_skip_samples = 0;
4541 MOVIndexRange *current_index_range = NULL;
4542 int found_keyframe_after_edit = 0;
4543 int found_non_empty_edit = 0;
4544
4545 if (!msc->elst_data || msc->elst_count <= 0 || nb_old <= 0) {
4546 return;
4547 }
4548
4549 int64_t max_entries = nb_old * 16LL + (1 << 16);
4550
4551 // allocate the index ranges array
4552 msc->index_ranges = av_malloc_array(msc->elst_count + 1,
4553 sizeof(msc->index_ranges[0]));
4554 if (!msc->index_ranges) {
4555 av_log(mov->fc, AV_LOG_ERROR, "Cannot allocate index ranges buffer\n");
4556 return;
4557 }
4559
4560 // Clean AVStream from traces of old index
4561 sti->index_entries = NULL;
4563 sti->nb_index_entries = 0;
4564
4565 // Clean time to sample fields of MOVStreamContext
4566 msc->tts_data = NULL;
4567 msc->tts_count = 0;
4568 msc->tts_index = 0;
4569 msc->tts_sample = 0;
4570 msc->tts_allocated_size = 0;
4571
4572 // Reinitialize min_corrected_pts so that it can be computed again.
4573 msc->min_corrected_pts = -1;
4574
4575 // If the dts_shift is positive (in case of negative ctts values in mov),
4576 // then negate the DTS by dts_shift
4577 if (msc->dts_shift > 0) {
4578 edit_list_dts_entry_end -= msc->dts_shift;
4579 av_log(mov->fc, AV_LOG_DEBUG, "Shifting DTS by %d because of negative CTTS.\n", msc->dts_shift);
4580 }
4581
4582 start_dts = edit_list_dts_entry_end;
4583
4584 while (get_edit_list_entry(mov, msc, edit_list_index, &edit_list_media_time,
4585 &edit_list_duration, mov->time_scale)) {
4586 av_log(mov->fc, AV_LOG_DEBUG, "Processing st: %d, edit list %"PRId64" - media time: %"PRId64", duration: %"PRId64"\n",
4587 st->index, edit_list_index, edit_list_media_time, edit_list_duration);
4588 edit_list_index++;
4589 edit_list_dts_counter = edit_list_dts_entry_end;
4590 edit_list_dts_entry_end = av_sat_add64(edit_list_dts_entry_end, edit_list_duration);
4591 if (edit_list_dts_entry_end == INT64_MAX) {
4592 av_log(mov->fc, AV_LOG_ERROR, "Cannot calculate dts entry length with duration %"PRId64"\n",
4593 edit_list_duration);
4594 break;
4595 }
4596 num_discarded_begin = 0;
4597 if (edit_list_media_time == -1) {
4598 if (!found_non_empty_edit)
4599 empty_edits_sum_duration += edit_list_duration;
4600 continue;
4601 }
4602 found_non_empty_edit = 1;
4603
4604 // If we encounter a non-negative edit list reset the skip_samples/initial_padding fields and set them
4605 // according to the edit list below.
4607 if (first_non_zero_audio_edit < 0) {
4608 first_non_zero_audio_edit = 1;
4609 } else {
4610 first_non_zero_audio_edit = 0;
4611 }
4612
4613 if (first_non_zero_audio_edit > 0)
4614 sti->skip_samples = st->codecpar->initial_padding = 0;
4615 }
4616
4617 // While reordering frame index according to edit list we must handle properly
4618 // the scenario when edit list entry starts from none key frame.
4619 // We find closest previous key frame and preserve it and consequent frames in index.
4620 // All frames which are outside edit list entry time boundaries will be dropped after decoding.
4621 search_timestamp = edit_list_media_time;
4623 // Audio decoders like AAC need need a decoder delay samples previous to the current sample,
4624 // to correctly decode this frame. Hence for audio we seek to a frame 1 sec. before the
4625 // edit_list_media_time to cover the decoder delay.
4626 search_timestamp = FFMAX(av_sat_sub64(search_timestamp, msc->time_scale), e_old[0].timestamp);
4627 }
4628
4629 if (find_prev_closest_index(st, e_old, nb_old, tts_data_old, tts_count_old, search_timestamp, 0,
4630 &index, &tts_index_old, &tts_sample_old) < 0) {
4631 av_log(mov->fc, AV_LOG_WARNING,
4632 "st: %d edit list: %"PRId64" Missing key frame while searching for timestamp: %"PRId64"\n",
4633 st->index, edit_list_index, search_timestamp);
4634 if (find_prev_closest_index(st, e_old, nb_old, tts_data_old, tts_count_old, search_timestamp, AVSEEK_FLAG_ANY,
4635 &index, &tts_index_old, &tts_sample_old) < 0) {
4636 av_log(mov->fc, AV_LOG_WARNING,
4637 "st: %d edit list %"PRId64" Cannot find an index entry before timestamp: %"PRId64".\n",
4638 st->index, edit_list_index, search_timestamp);
4639 index = 0;
4640 tts_index_old = 0;
4641 tts_sample_old = 0;
4642 }
4643 }
4644 current = e_old + index;
4645 edit_list_start_tts_sample = tts_sample_old;
4646
4647 // Iterate over index and arrange it according to edit list
4648 edit_list_start_encountered = 0;
4649 found_keyframe_after_edit = 0;
4650 for (; current < e_old_end; current++, index++) {
4651 if (sti->nb_index_entries >= max_entries) {
4652 av_log(mov->fc, AV_LOG_ERROR, "Edit list expands the sample index beyond %"PRId64" entries\n",
4653 max_entries);
4654 goto truncated;
4655 }
4656 // check if frame outside edit list mark it for discard
4657 frame_duration = (current + 1 < e_old_end) ?
4658 ((current + 1)->timestamp - current->timestamp) : edit_list_duration;
4659
4660 flags = current->flags;
4661
4662 // frames (pts) before or after edit list
4663 curr_cts = current->timestamp + msc->dts_shift;
4664 curr_ctts = 0;
4665
4666 if (tts_data_old && tts_index_old < tts_count_old) {
4667 curr_ctts = tts_data_old[tts_index_old].offset;
4668 av_log(mov->fc, AV_LOG_TRACE, "stts: %"PRId64" ctts: %"PRId64", tts_index: %"PRId64", tts_count: %"PRId64"\n",
4669 curr_cts, curr_ctts, tts_index_old, tts_count_old);
4670 curr_cts += curr_ctts;
4671 tts_sample_old++;
4672 if (tts_sample_old == tts_data_old[tts_index_old].count) {
4673 if (add_tts_entry(&msc->tts_data, &msc->tts_count,
4674 &msc->tts_allocated_size,
4675 tts_data_old[tts_index_old].count - edit_list_start_tts_sample,
4676 tts_data_old[tts_index_old].offset, tts_data_old[tts_index_old].duration) == -1) {
4677 av_log(mov->fc, AV_LOG_ERROR, "Cannot add Time To Sample entry %"PRId64" - {%"PRId64", %d}\n",
4678 tts_index_old,
4679 tts_data_old[tts_index_old].count - edit_list_start_tts_sample,
4680 tts_data_old[tts_index_old].offset);
4681 break;
4682 }
4683 tts_index_old++;
4684 tts_sample_old = 0;
4685 edit_list_start_tts_sample = 0;
4686 }
4687 }
4688
4689 if (curr_cts < edit_list_media_time || curr_cts >= (edit_list_duration + edit_list_media_time)) {
4691 curr_cts < edit_list_media_time && curr_cts + frame_duration > edit_list_media_time &&
4692 first_non_zero_audio_edit > 0) {
4693 packet_skip_samples = edit_list_media_time - curr_cts;
4694 sti->skip_samples += packet_skip_samples;
4695
4696 // Shift the index entry timestamp by packet_skip_samples to be correct.
4697 edit_list_dts_counter -= packet_skip_samples;
4698 if (edit_list_start_encountered == 0) {
4699 edit_list_start_encountered = 1;
4700 // Make timestamps strictly monotonically increasing for audio, by rewriting timestamps for
4701 // discarded packets.
4702 if (frame_duration_buffer) {
4703 fix_index_entry_timestamps(st, sti->nb_index_entries, edit_list_dts_counter,
4704 frame_duration_buffer, num_discarded_begin);
4705 av_freep(&frame_duration_buffer);
4706 }
4707 }
4708
4709 av_log(mov->fc, AV_LOG_DEBUG, "skip %d audio samples from curr_cts: %"PRId64"\n", packet_skip_samples, curr_cts);
4710 } else {
4712 av_log(mov->fc, AV_LOG_DEBUG, "drop a frame at curr_cts: %"PRId64" @ %"PRId64"\n", curr_cts, index);
4713
4714 if (edit_list_start_encountered == 0) {
4715 num_discarded_begin++;
4716 if (av_reallocp_array(&frame_duration_buffer, num_discarded_begin,
4717 sizeof(*frame_duration_buffer)) < 0) {
4718 av_log(mov->fc, AV_LOG_ERROR, "Cannot reallocate frame duration buffer\n");
4719 break;
4720 }
4721 frame_duration_buffer[num_discarded_begin - 1] = frame_duration;
4722
4723 // Increment skip_samples for the first non-zero audio edit list
4725 first_non_zero_audio_edit > 0 && st->codecpar->codec_id != AV_CODEC_ID_VORBIS) {
4726 sti->skip_samples += frame_duration;
4727 }
4728 }
4729 }
4730 } else {
4731 if (msc->min_corrected_pts < 0) {
4732 msc->min_corrected_pts = edit_list_dts_counter + curr_ctts + msc->dts_shift;
4733 } else {
4734 msc->min_corrected_pts = FFMIN(msc->min_corrected_pts, edit_list_dts_counter + curr_ctts + msc->dts_shift);
4735 }
4736 if (edit_list_start_encountered == 0) {
4737 edit_list_start_encountered = 1;
4738 // Make timestamps strictly monotonically increasing by rewriting timestamps for
4739 // discarded packets.
4740 if (frame_duration_buffer) {
4741 fix_index_entry_timestamps(st, sti->nb_index_entries, edit_list_dts_counter,
4742 frame_duration_buffer, num_discarded_begin);
4743 av_freep(&frame_duration_buffer);
4744 }
4745 }
4746 }
4747
4748 if (add_index_entry(st, current->pos, edit_list_dts_counter, current->size,
4749 current->min_distance, flags) == -1) {
4750 av_log(mov->fc, AV_LOG_ERROR, "Cannot add index entry\n");
4751 break;
4752 }
4753
4754 // Update the index ranges array
4755 if (!current_index_range || index != current_index_range->end) {
4756 current_index_range = current_index_range ? current_index_range + 1
4757 : msc->index_ranges;
4758 current_index_range->start = index;
4759 }
4760 current_index_range->end = index + 1;
4761
4762 // Only start incrementing DTS in frame_duration amounts, when we encounter a frame in edit list.
4763 if (edit_list_start_encountered > 0) {
4764 edit_list_dts_counter = edit_list_dts_counter + frame_duration;
4765 }
4766
4767 // Break when found first key frame after edit entry completion
4768 if ((curr_cts + frame_duration >= (edit_list_duration + edit_list_media_time)) &&
4770 if (msc->ctts_count) {
4771 // If we have CTTS and this is the first keyframe after edit elist,
4772 // wait for one more, because there might be trailing B-frames after this I-frame
4773 // that do belong to the edit.
4774 if (st->codecpar->codec_type != AVMEDIA_TYPE_AUDIO && found_keyframe_after_edit == 0) {
4775 found_keyframe_after_edit = 1;
4776 continue;
4777 }
4778 if (tts_sample_old != 0) {
4779 if (add_tts_entry(&msc->tts_data, &msc->tts_count,
4780 &msc->tts_allocated_size,
4781 tts_sample_old - edit_list_start_tts_sample,
4782 tts_data_old[tts_index_old].offset, tts_data_old[tts_index_old].duration) == -1) {
4783 av_log(mov->fc, AV_LOG_ERROR, "Cannot add Time To Sample entry %"PRId64" - {%"PRId64", %d}\n",
4784 tts_index_old, tts_sample_old - edit_list_start_tts_sample,
4785 tts_data_old[tts_index_old].offset);
4786 break;
4787 }
4788 }
4789 }
4790 break;
4791 }
4792 }
4793 }
4794truncated:
4795 // If there are empty edits, then msc->min_corrected_pts might be positive
4796 // intentionally. So we subtract the sum duration of empty edits here.
4797 msc->min_corrected_pts -= empty_edits_sum_duration;
4798
4799 // If the minimum pts turns out to be greater than zero after fixing the index, then we subtract the
4800 // dts by that amount to make the first pts zero.
4802 if (msc->min_corrected_pts > 0) {
4803 av_log(mov->fc, AV_LOG_DEBUG, "Offset DTS by %"PRId64" to make first pts zero.\n", msc->min_corrected_pts);
4804 for (int i = 0; i < sti->nb_index_entries; ++i)
4806 }
4807 }
4808 // Start time should be equal to zero or the duration of any empty edits.
4809 st->start_time = empty_edits_sum_duration;
4810
4811 // Update av stream length, if it ends up shorter than the track's media duration
4812 st->duration = FFMIN(st->duration, edit_list_dts_entry_end - start_dts);
4814
4815 // Free the old index and the old CTTS structures
4816 av_free(e_old);
4817 av_free(tts_data_old);
4818 av_freep(&frame_duration_buffer);
4819
4820 // Null terminate the index ranges array
4821 current_index_range = current_index_range ? current_index_range + 1
4822 : msc->index_ranges;
4823 current_index_range->start = 0;
4824 current_index_range->end = 0;
4825 msc->current_index = msc->index_ranges[0].start;
4826}
4827
4828static uint32_t get_sgpd_sync_index(const MOVStreamContext *sc, int nal_unit_type)
4829{
4830 for (uint32_t i = 0; i < sc->sgpd_sync_count; i++)
4831 if (sc->sgpd_sync[i] == nal_unit_type)
4832 return i + 1;
4833 return 0;
4834}
4835
4837{
4838 int k;
4839 int sample_id = 0;
4840 uint32_t cra_index;
4841 MOVStreamContext *sc = st->priv_data;
4842
4844 return 0;
4845
4846 /* Build an unrolled index of the samples */
4847 sc->sample_offsets_count = 0;
4848 for (uint32_t i = 0; i < sc->ctts_count; i++) {
4849 if (sc->ctts_data[i].count > INT_MAX - sc->sample_offsets_count)
4850 return AVERROR(ENOMEM);
4852 }
4855 if (!sc->sample_offsets)
4856 return AVERROR(ENOMEM);
4857 k = 0;
4858 for (uint32_t i = 0; i < sc->ctts_count; i++)
4859 for (int j = 0; j < sc->ctts_data[i].count; j++)
4860 sc->sample_offsets[k++] = sc->ctts_data[i].offset;
4861
4862 /* The following HEVC NAL type reveal the use of open GOP sync points
4863 * (TODO: BLA types may also be concerned) */
4864 cra_index = get_sgpd_sync_index(sc, HEVC_NAL_CRA_NUT); /* Clean Random Access */
4865 if (!cra_index)
4866 return 0;
4867
4868 /* Build a list of open-GOP key samples */
4869 sc->open_key_samples_count = 0;
4870 for (uint32_t i = 0; i < sc->sync_group_count; i++)
4871 if (sc->sync_group[i].index == cra_index) {
4872 if (sc->sync_group[i].count > INT_MAX - sc->open_key_samples_count)
4873 return AVERROR(ENOMEM);
4875 }
4878 if (!sc->open_key_samples)
4879 return AVERROR(ENOMEM);
4880 k = 0;
4881 for (uint32_t i = 0; i < sc->sync_group_count; i++) {
4882 const MOVSbgp *sg = &sc->sync_group[i];
4883 if (sg->index == cra_index)
4884 for (uint32_t j = 0; j < sg->count; j++)
4885 sc->open_key_samples[k++] = sample_id;
4886 if (sg->count > INT_MAX - sample_id)
4887 return AVERROR_PATCHWELCOME;
4888 sample_id += sg->count;
4889 }
4890
4891 /* Identify the minimal time step between samples */
4892 sc->min_sample_duration = UINT_MAX;
4893 for (uint32_t i = 0; i < sc->stts_count; i++)
4895
4896 return 0;
4897}
4898
4899#define MOV_MERGE_CTTS 1
4900#define MOV_MERGE_STTS 2
4901/*
4902 * Merge stts and ctts arrays into a new combined array.
4903 * stts_count and ctts_count may be left untouched as they will be
4904 * used to check for the presence of either of them.
4905 */
4907{
4908 MOVStreamContext *sc = st->priv_data;
4909 int ctts = sc->ctts_data && (flags & MOV_MERGE_CTTS);
4910 int stts = sc->stts_data && (flags & MOV_MERGE_STTS);
4911 int idx = 0;
4912
4913 if (!sc->ctts_data && !sc->stts_data)
4914 return 0;
4915 // Expand time to sample entries such that we have a 1-1 mapping with samples
4916 if (!sc->sample_count || sc->sample_count >= UINT_MAX / sizeof(*sc->tts_data))
4917 return -1;
4918
4919 if (ctts) {
4921 sc->sample_count * sizeof(*sc->tts_data));
4922 if (!sc->tts_data)
4923 return -1;
4924
4925 memset(sc->tts_data, 0, sc->tts_allocated_size);
4926
4927 for (int i = 0; i < sc->ctts_count &&
4928 idx < sc->sample_count; i++)
4929 for (int j = 0; j < sc->ctts_data[i].count &&
4930 idx < sc->sample_count; j++) {
4931 sc->tts_data[idx].offset = sc->ctts_data[i].offset;
4932 sc->tts_data[idx++].count = 1;
4933 }
4934
4935 sc->tts_count = idx;
4936 } else
4937 sc->ctts_count = 0;
4938 av_freep(&sc->ctts_data);
4939 sc->ctts_allocated_size = 0;
4940
4941 idx = 0;
4942 if (stts) {
4944 sc->sample_count * sizeof(*sc->tts_data));
4945 if (!tts_data)
4946 return -1;
4947
4948 if (!sc->tts_data)
4949 memset(tts_data, 0, sc->tts_allocated_size);
4950 sc->tts_data = tts_data;
4951
4952 for (int i = 0; i < sc->stts_count &&
4953 idx < sc->sample_count; i++)
4954 for (int j = 0; j < sc->stts_data[i].count &&
4955 idx < sc->sample_count; j++) {
4956 sc->tts_data[idx].duration = sc->stts_data[i].duration;
4957 sc->tts_data[idx++].count = 1;
4958 }
4959
4960 sc->tts_count = FFMAX(sc->tts_count, idx);
4961 } else
4962 sc->stts_count = 0;
4963 av_freep(&sc->stts_data);
4964 sc->stts_allocated_size = 0;
4965
4966 return 0;
4967}
4968
4970{
4971 MOVStreamContext *sc = st->priv_data;
4972 FFStream *const sti = ffstream(st);
4973 int64_t current_offset;
4974 int64_t current_dts = 0;
4975 unsigned int stts_index = 0;
4976 unsigned int stsc_index = 0;
4977 unsigned int stss_index = 0;
4978 unsigned int stps_index = 0;
4979 unsigned int i, j;
4980 uint64_t stream_size = 0;
4981
4982 int ret = build_open_gop_key_points(st);
4983 if (ret < 0)
4984 return;
4985
4986 if (sc->elst_count) {
4987 int i, edit_start_index = 0, multiple_edits = 0;
4988 int64_t empty_duration = 0; // empty duration of the first edit list entry
4989 int64_t start_time = 0; // start time of the media
4990
4991 for (i = 0; i < sc->elst_count; i++) {
4992 const MOVElst *e = &sc->elst_data[i];
4993 if (i == 0 && e->time == -1) {
4994 /* if empty, the first entry is the start time of the stream
4995 * relative to the presentation itself */
4996 empty_duration = e->duration;
4997 edit_start_index = 1;
4998 } else if (i == edit_start_index && e->time >= 0) {
4999 start_time = e->time;
5000 } else {
5001 multiple_edits = 1;
5002 }
5003 }
5004
5005 if (multiple_edits && !mov->advanced_editlist) {
5007 av_log(mov->fc, AV_LOG_WARNING, "multiple edit list entries, "
5008 "not supported in fragmented MP4 files\n");
5009 else
5010 av_log(mov->fc, AV_LOG_WARNING, "multiple edit list entries, "
5011 "Use -advanced_editlist to correctly decode otherwise "
5012 "a/v desync might occur\n");
5013 }
5014
5015 /* adjust first dts according to edit list */
5016 if ((empty_duration || start_time) && mov->time_scale > 0) {
5017 if (empty_duration)
5018 empty_duration = av_rescale(empty_duration, sc->time_scale, mov->time_scale);
5019
5020 if (av_sat_sub64(start_time, empty_duration) != start_time - (uint64_t)empty_duration)
5021 av_log(mov->fc, AV_LOG_WARNING, "start_time - empty_duration is not representable\n");
5022
5023 sc->time_offset = start_time - (uint64_t)empty_duration;
5025 if (!mov->advanced_editlist)
5026 current_dts = -av_clip64(sc->time_offset, -INT64_MAX, INT64_MAX);
5027 }
5028
5029 if (!multiple_edits && !mov->advanced_editlist &&
5032 (AVRational){1, st->codecpar->sample_rate});
5033 }
5034
5035 /* only use old uncompressed audio chunk demuxing when stts specifies it */
5036 if (!(st->codecpar->codec_type == AVMEDIA_TYPE_AUDIO &&
5037 sc->stts_count == 1 && sc->stts_data && sc->stts_data[0].duration == 1)) {
5038 unsigned int current_sample = 0;
5039 unsigned int stts_sample = 0;
5040 unsigned int sample_size;
5041 unsigned int distance = 0;
5042 unsigned int rap_group_index = 0;
5043 unsigned int rap_group_sample = 0;
5044 int rap_group_present = sc->rap_group_count && sc->rap_group;
5045 int key_off = (sc->keyframe_count && sc->keyframes[0] > 0) || (sc->stps_count && sc->stps_data[0] > 0);
5046
5047 av_assert0(sc->dts_shift >= 0);
5048 if (current_dts < INT64_MIN + sc->dts_shift)
5049 return;
5050 current_dts -= sc->dts_shift;
5051 if (!sc->sample_count || sti->nb_index_entries || sc->tts_count)
5052 return;
5053 if (sc->sample_count >= UINT_MAX / sizeof(*sti->index_entries) - sti->nb_index_entries)
5054 return;
5056 sti->nb_index_entries + sc->sample_count,
5057 sizeof(*sti->index_entries)) < 0) {
5058 sti->nb_index_entries = 0;
5059 return;
5060 }
5061 sti->index_entries_allocated_size = (sti->nb_index_entries + sc->sample_count) * sizeof(*sti->index_entries);
5062
5064 if (ret < 0)
5065 return;
5066
5067 for (i = 0; i < sc->chunk_count; i++) {
5068 int64_t next_offset = i+1 < sc->chunk_count ? sc->chunk_offsets[i+1] : INT64_MAX;
5069 current_offset = sc->chunk_offsets[i];
5070 while (mov_stsc_index_valid(stsc_index, sc->stsc_count) &&
5071 i + 1 == sc->stsc_data[stsc_index + 1].first)
5072 stsc_index++;
5073
5074 if (next_offset > current_offset && sc->sample_size>0 && sc->sample_size < sc->stsz_sample_size &&
5075 sc->stsc_data[stsc_index].count * (int64_t)sc->stsz_sample_size > next_offset - current_offset) {
5076 av_log(mov->fc, AV_LOG_WARNING, "STSZ sample size %d invalid (too large), ignoring\n", sc->stsz_sample_size);
5077 sc->stsz_sample_size = sc->sample_size;
5078 }
5079 if (sc->stsz_sample_size>0 && sc->stsz_sample_size < sc->sample_size) {
5080 av_log(mov->fc, AV_LOG_WARNING, "STSZ sample size %d invalid (too small), ignoring\n", sc->stsz_sample_size);
5081 sc->stsz_sample_size = sc->sample_size;
5082 }
5083
5084 for (j = 0; j < sc->stsc_data[stsc_index].count; j++) {
5085 int keyframe = 0;
5086 if (current_sample >= sc->sample_count) {
5087 av_log(mov->fc, AV_LOG_ERROR, "wrong sample count\n");
5088 return;
5089 }
5090
5091 if (!sc->keyframe_absent && (!sc->keyframe_count || current_sample+key_off == sc->keyframes[stss_index])) {
5092 keyframe = 1;
5093 if (stss_index + 1 < sc->keyframe_count)
5094 stss_index++;
5095 } else if (sc->stps_count && current_sample+key_off == sc->stps_data[stps_index]) {
5096 keyframe = 1;
5097 if (stps_index + 1 < sc->stps_count)
5098 stps_index++;
5099 }
5100 if (rap_group_present && rap_group_index < sc->rap_group_count) {
5101 if (sc->rap_group[rap_group_index].index > 0)
5102 keyframe = 1;
5103 if (++rap_group_sample == sc->rap_group[rap_group_index].count) {
5104 rap_group_sample = 0;
5105 rap_group_index++;
5106 }
5107 }
5108 if (sc->keyframe_absent
5109 && !sc->stps_count
5110 && !rap_group_present
5111 && (st->codecpar->codec_type == AVMEDIA_TYPE_AUDIO || (i==0 && j==0)))
5112 keyframe = 1;
5113 if (keyframe)
5114 distance = 0;
5115 sample_size = sc->stsz_sample_size > 0 ? sc->stsz_sample_size : sc->sample_sizes[current_sample];
5116 if (current_offset > INT64_MAX - sample_size) {
5117 av_log(mov->fc, AV_LOG_ERROR, "Current offset %"PRId64" or sample size %u is too large\n",
5118 current_offset,
5119 sample_size);
5120 return;
5121 }
5122
5123 if (sc->pseudo_stream_id == -1 ||
5124 sc->stsc_data[stsc_index].id - 1 == sc->pseudo_stream_id) {
5125 AVIndexEntry *e;
5126 if (sample_size > 0x3FFFFFFF) {
5127 av_log(mov->fc, AV_LOG_ERROR, "Sample size %u is too large\n", sample_size);
5128 return;
5129 }
5130 e = &sti->index_entries[sti->nb_index_entries++];
5131 e->pos = current_offset;
5132 e->timestamp = current_dts;
5133 e->size = sample_size;
5135 e->flags = keyframe ? AVINDEX_KEYFRAME : 0;
5136 av_log(mov->fc, AV_LOG_TRACE, "AVIndex stream %d, sample %u, offset %"PRIx64", dts %"PRId64", "
5137 "size %u, distance %u, keyframe %d\n", st->index, current_sample,
5138 current_offset, current_dts, sample_size, distance, keyframe);
5139 if (st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO && sti->nb_index_entries < 100)
5140 ff_rfps_add_frame(mov->fc, st, current_dts);
5141 }
5142
5143 current_offset += sample_size;
5144 stream_size += sample_size;
5145
5146 if (current_dts > INT64_MAX - sc->tts_data[stts_index].duration)
5147 return;
5148 current_dts += sc->tts_data[stts_index].duration;
5149
5150 distance++;
5151 stts_sample++;
5152 current_sample++;
5153 if (stts_index + 1 < sc->tts_count && stts_sample == sc->tts_data[stts_index].count) {
5154 stts_sample = 0;
5155 stts_index++;
5156 }
5157 }
5158 }
5159 if (st->duration > 0)
5160 st->codecpar->bit_rate = stream_size*8*sc->time_scale/st->duration;
5161 } else {
5162 unsigned chunk_samples, total = 0;
5163
5164 if (!sc->chunk_count || sc->tts_count)
5165 return;
5166
5167 // compute total chunk count
5168 for (i = 0; i < sc->stsc_count; i++) {
5169 unsigned count, chunk_count;
5170
5171 chunk_samples = sc->stsc_data[i].count;
5172 if (i != sc->stsc_count - 1 &&
5173 sc->samples_per_frame && chunk_samples % sc->samples_per_frame) {
5174 av_log(mov->fc, AV_LOG_ERROR, "error unaligned chunk\n");
5175 return;
5176 }
5177
5178 if (sc->samples_per_frame >= 160) { // gsm
5179 count = chunk_samples / sc->samples_per_frame;
5180 } else if (sc->samples_per_frame > 1) {
5181 unsigned samples = (1024/sc->samples_per_frame)*sc->samples_per_frame;
5182 count = (chunk_samples+samples-1) / samples;
5183 } else {
5184 count = (chunk_samples+1023) / 1024;
5185 }
5186
5188 chunk_count = sc->stsc_data[i+1].first - sc->stsc_data[i].first;
5189 else
5190 chunk_count = sc->chunk_count - (sc->stsc_data[i].first - 1);
5191 total += chunk_count * count;
5192 }
5193
5194 av_log(mov->fc, AV_LOG_TRACE, "chunk count %u\n", total);
5195 if (total >= UINT_MAX / sizeof(*sti->index_entries) - sti->nb_index_entries)
5196 return;
5198 sti->nb_index_entries + total,
5199 sizeof(*sti->index_entries)) < 0) {
5200 sti->nb_index_entries = 0;
5201 return;
5202 }
5203 sti->index_entries_allocated_size = (sti->nb_index_entries + total) * sizeof(*sti->index_entries);
5204
5205 // populate index
5206 for (i = 0; i < sc->chunk_count; i++) {
5207 current_offset = sc->chunk_offsets[i];
5208 if (mov_stsc_index_valid(stsc_index, sc->stsc_count) &&
5209 i + 1 == sc->stsc_data[stsc_index + 1].first)
5210 stsc_index++;
5211 chunk_samples = sc->stsc_data[stsc_index].count;
5212
5213 while (chunk_samples > 0) {
5214 AVIndexEntry *e;
5215 unsigned size, samples;
5216
5217 if (sc->samples_per_frame > 1 && !sc->bytes_per_frame) {
5219 "Zero bytes per frame, but %d samples per frame",
5220 sc->samples_per_frame);
5221 return;
5222 }
5223
5224 if (sc->samples_per_frame >= 160) { // gsm
5225 samples = sc->samples_per_frame;
5226 size = sc->bytes_per_frame;
5227 } else {
5228 if (sc->samples_per_frame > 1) {
5229 samples = FFMIN((1024 / sc->samples_per_frame)*
5230 sc->samples_per_frame, chunk_samples);
5231 size = (samples / sc->samples_per_frame) * sc->bytes_per_frame;
5232 } else {
5233 samples = FFMIN(1024, chunk_samples);
5234 size = samples * sc->sample_size;
5235 }
5236 }
5237
5238 if (sti->nb_index_entries >= total) {
5239 av_log(mov->fc, AV_LOG_ERROR, "wrong chunk count %u\n", total);
5240 return;
5241 }
5242 if (size > 0x3FFFFFFF) {
5243 av_log(mov->fc, AV_LOG_ERROR, "Sample size %u is too large\n", size);
5244 return;
5245 }
5246 e = &sti->index_entries[sti->nb_index_entries++];
5247 e->pos = current_offset;
5248 e->timestamp = current_dts;
5249 e->size = size;
5250 e->min_distance = 0;
5252 av_log(mov->fc, AV_LOG_TRACE, "AVIndex stream %d, chunk %u, offset %"PRIx64", dts %"PRId64", "
5253 "size %u, duration %u\n", st->index, i, current_offset, current_dts,
5254 size, samples);
5255
5256 current_offset += size;
5257 if (current_dts > INT64_MAX - samples)
5258 return;
5259 current_dts += samples;
5260 chunk_samples -= samples;
5261 }
5262 }
5263
5264 ret = mov_merge_tts_data(mov, st, MOV_MERGE_CTTS);
5265 if (ret < 0)
5266 return;
5267 }
5268
5269 if (!mov->ignore_editlist && mov->advanced_editlist) {
5270 // Fix index according to edit lists.
5271 mov_fix_index(mov, st);
5272 }
5273
5274 // Update start time of the stream.
5277 if (sc->tts_data) {
5279 }
5280 }
5281
5282 mov_estimate_video_delay(mov, st);
5283}
5284
5289
5290static int mov_compare_presentation_samples(const void *a, const void *b)
5291{
5292 const MOVPresentationSample *sa = a;
5293 const MOVPresentationSample *sb = b;
5294
5295 if (sa->pts != sb->pts)
5296 return (sa->pts > sb->pts) - (sa->pts < sb->pts);
5297 return (sa->index > sb->index) - (sa->index < sb->index);
5298}
5299
5300/*
5301 * Set sample durations from adjacent presentation timestamps.
5302 */
5304{
5305 MOVStreamContext *sc = st->priv_data;
5306 FFStream *const sti = ffstream(st);
5307 MOVPresentationSample *samples = NULL;
5308 MOVTimeToSample *tts_data = NULL;
5309 unsigned int tts_index = 0, tts_sample = 0;
5310 int count = sti->nb_index_entries;
5311
5312 /* A single STTS entry describes a fixed sample delta. */
5314 !sc->ctts_count || sc->stts_count < 2 ||
5315 !sc->tts_data || count < 2 ||
5316 count >= UINT_MAX / sizeof(*tts_data))
5317 return;
5318
5319 samples = av_malloc_array(count, sizeof(*samples));
5320 tts_data = av_malloc_array(count, sizeof(*tts_data));
5321 if (!samples || !tts_data)
5322 goto fail;
5323
5324 for (int i = 0; i < count; i++) {
5325 int64_t dts, offset;
5326
5327 if (tts_index >= sc->tts_count || !sc->tts_data[tts_index].count)
5328 goto fail;
5329
5330 tts_data[i] = sc->tts_data[tts_index];
5331 tts_data[i].count = 1;
5332
5333 dts = sti->index_entries[i].timestamp;
5334 offset = (int64_t)sc->dts_shift + tts_data[i].offset;
5335 if (dts == AV_NOPTS_VALUE ||
5336 (offset > 0 && dts > INT64_MAX - offset) ||
5337 (offset < 0 && dts < INT64_MIN - offset))
5338 goto fail;
5339
5340 samples[i].index = i;
5341 samples[i].pts = dts + offset;
5342
5343 if (++tts_sample == sc->tts_data[tts_index].count) {
5344 tts_index++;
5345 tts_sample = 0;
5346 }
5347 }
5348 if (tts_index != sc->tts_count || tts_sample)
5349 goto fail;
5350
5351 qsort(samples, count, sizeof(*samples), mov_compare_presentation_samples);
5352
5353 for (int i = 0; i + 1 < count; i++) {
5354 uint64_t duration;
5355
5356 if (samples[i].pts >= samples[i + 1].pts)
5357 goto fail;
5358
5359 /*
5360 * In VFR streams with reordered frames, STTS deltas follow decode
5361 * order while AVPacket.duration follows presentation order. CTTS
5362 * may produce presentation intervals that cannot be obtained by
5363 * merely permuting the STTS deltas, so derive each known duration
5364 * from adjacent PTS.
5365 */
5366 duration = (uint64_t)samples[i + 1].pts - samples[i].pts;
5367 if (!duration || duration > UINT_MAX)
5368 goto fail;
5369
5370 tts_data[samples[i].index].duration = (unsigned int)duration;
5371 }
5372
5373 av_log(mov->fc, AV_LOG_DEBUG,
5374 "Updated sample durations in presentation order for stream %d\n",
5375 st->index);
5376
5377 av_freep(&sc->tts_data);
5378 sc->tts_data = tts_data;
5379 sc->tts_count = count;
5380 sc->tts_allocated_size = count * sizeof(*tts_data);
5381 tts_data = NULL;
5382
5383fail:
5384 av_free(samples);
5385 av_free(tts_data);
5386}
5387
5388static int test_same_origin(const char *src, const char *ref) {
5389 char src_proto[64];
5390 char ref_proto[64];
5391 char src_auth[256];
5392 char ref_auth[256];
5393 char src_host[256];
5394 char ref_host[256];
5395 int src_port=-1;
5396 int ref_port=-1;
5397
5398 av_url_split(src_proto, sizeof(src_proto), src_auth, sizeof(src_auth), src_host, sizeof(src_host), &src_port, NULL, 0, src);
5399 av_url_split(ref_proto, sizeof(ref_proto), ref_auth, sizeof(ref_auth), ref_host, sizeof(ref_host), &ref_port, NULL, 0, ref);
5400
5401 if (strlen(src) == 0) {
5402 return -1;
5403 } else if (strlen(src_auth) + 1 >= sizeof(src_auth) ||
5404 strlen(ref_auth) + 1 >= sizeof(ref_auth) ||
5405 strlen(src_host) + 1 >= sizeof(src_host) ||
5406 strlen(ref_host) + 1 >= sizeof(ref_host)) {
5407 return 0;
5408 } else if (strcmp(src_proto, ref_proto) ||
5409 strcmp(src_auth, ref_auth) ||
5410 strcmp(src_host, ref_host) ||
5411 src_port != ref_port) {
5412 return 0;
5413 } else
5414 return 1;
5415}
5416
5417static int mov_open_dref(MOVContext *c, AVIOContext **pb, const char *src, MOVDref *ref)
5418{
5419 /* try relative path, we do not try the absolute because it can leak information about our
5420 system to an attacker */
5421 if (ref->nlvl_to > 0 && ref->nlvl_from > 0) {
5422 char filename[1025];
5423 const char *src_path;
5424 int i, l;
5425
5426 /* find a source dir */
5427 src_path = strrchr(src, '/');
5428 if (src_path)
5429 src_path++;
5430 else
5431 src_path = src;
5432
5433 /* find a next level down to target */
5434 for (i = 0, l = strlen(ref->path) - 1; l >= 0; l--)
5435 if (ref->path[l] == '/') {
5436 if (i == ref->nlvl_to - 1)
5437 break;
5438 else
5439 i++;
5440 }
5441
5442 /* compose filename if next level down to target was found */
5443 if (i == ref->nlvl_to - 1 && src_path - src < sizeof(filename)) {
5444 memcpy(filename, src, src_path - src);
5445 filename[src_path - src] = 0;
5446
5447 for (i = 1; i < ref->nlvl_from; i++)
5448 av_strlcat(filename, "../", sizeof(filename));
5449
5450 av_strlcat(filename, ref->path + l + 1, sizeof(filename));
5451 if (!c->use_absolute_path) {
5452 int same_origin = test_same_origin(src, filename);
5453
5454 if (!same_origin) {
5455 av_log(c->fc, AV_LOG_ERROR,
5456 "Reference with mismatching origin, %s not tried for security reasons, "
5457 "set demuxer option use_absolute_path to allow it anyway\n",
5458 ref->path);
5459 return AVERROR(ENOENT);
5460 }
5461
5462 if (strstr(ref->path + l + 1, "..") ||
5463 strstr(ref->path + l + 1, ":") ||
5464 (ref->nlvl_from > 1 && same_origin < 0) ||
5465 (filename[0] == '/' && src_path == src))
5466 return AVERROR(ENOENT);
5467 }
5468
5469 if (strlen(filename) + 1 == sizeof(filename))
5470 return AVERROR(ENOENT);
5471 if (!c->fc->io_open(c->fc, pb, filename, AVIO_FLAG_READ, NULL))
5472 return 0;
5473 }
5474 } else if (c->use_absolute_path) {
5475 av_log(c->fc, AV_LOG_WARNING, "Using absolute path on user request, "
5476 "this is a possible security issue\n");
5477 if (!c->fc->io_open(c->fc, pb, ref->path, AVIO_FLAG_READ, NULL))
5478 return 0;
5479 } else {
5480 av_log(c->fc, AV_LOG_ERROR,
5481 "Absolute path %s not tried for security reasons, "
5482 "set demuxer option use_absolute_path to allow absolute paths\n",
5483 ref->path);
5484 }
5485
5486 return AVERROR(ENOENT);
5487}
5488
5490{
5491 if (sc->time_scale <= 0) {
5492 av_log(c->fc, AV_LOG_WARNING, "stream %d, timescale not set\n", sc->ffindex);
5493 sc->time_scale = c->time_scale;
5494 if (sc->time_scale <= 0)
5495 sc->time_scale = 1;
5496 }
5497}
5498
5499#if CONFIG_IAMFDEC
5500static int mov_update_iamf_streams(MOVContext *c, const AVStream *st)
5501{
5502 const MOVStreamContext *sc = st->priv_data;
5503 const IAMFContext *iamf = &sc->iamf->iamf;
5504
5505 for (int i = 0; i < iamf->nb_audio_elements; i++) {
5506 const AVStreamGroup *stg = NULL;
5507
5508 for (int j = 0; j < c->fc->nb_stream_groups; j++)
5509 if (c->fc->stream_groups[j]->id == iamf->audio_elements[i]->audio_element_id)
5510 stg = c->fc->stream_groups[j];
5511 av_assert0(stg);
5512
5513 for (int j = 0; j < stg->nb_entries; j++) {
5514 const FFStream *sti = cffstream(st);
5515 AVStream *out = stg->entries[j]->stream;
5516 FFStream *out_sti = ffstream(stg->entries[j]->stream);
5517
5518 out->codecpar->bit_rate = 0;
5519
5520 if (out == st)
5521 continue;
5522
5523 out->time_base = st->time_base;
5524 out->start_time = st->start_time;
5525 out->duration = st->duration;
5526 out->nb_frames = st->nb_frames;
5527 out->discard = st->discard;
5528
5529 av_assert0(!out_sti->index_entries);
5531 if (!out_sti->index_entries)
5532 return AVERROR(ENOMEM);
5533
5535 out_sti->nb_index_entries = sti->nb_index_entries;
5536 out_sti->skip_samples = sti->skip_samples;
5537 memcpy(out_sti->index_entries, sti->index_entries, sti->index_entries_allocated_size);
5538 }
5539 }
5540
5541 return 0;
5542}
5543#endif
5544
5545static int sanity_checks(void *log_obj, MOVStreamContext *sc, int index)
5546{
5547 if ((sc->chunk_count && (!sc->stts_count || !sc->stsc_count ||
5548 (!sc->sample_size && !sc->sample_count))) ||
5549 (sc->sample_count && (!sc->chunk_count ||
5550 (!sc->sample_size && !sc->sample_sizes)))) {
5551 av_log(log_obj, AV_LOG_ERROR, "stream %d, missing mandatory atoms, broken header\n",
5552 index);
5553 return 1;
5554 }
5555
5556 if (sc->stsc_count && sc->stsc_data[ sc->stsc_count - 1 ].first > sc->chunk_count) {
5557 av_log(log_obj, AV_LOG_ERROR, "stream %d, contradictionary STSC and STCO\n",
5558 index);
5559 return 2;
5560 }
5561 return 0;
5562}
5563
5565{
5566 AVStream *st;
5567 MOVStreamContext *sc;
5568 int ret;
5569
5570 st = avformat_new_stream(c->fc, NULL);
5571 if (!st) return AVERROR(ENOMEM);
5572 st->id = -1;
5573 sc = av_mallocz(sizeof(MOVStreamContext));
5574 if (!sc) return AVERROR(ENOMEM);
5575
5576 st->priv_data = sc;
5578 sc->ffindex = st->index;
5579 c->trak_index = st->index;
5580 sc->refcount = 1;
5581
5582 if ((ret = mov_read_default(c, pb, atom)) < 0)
5583 return ret;
5584
5585 c->trak_index = -1;
5586
5587 // Here stsc refers to a chunk not described in stco. This is technically invalid,
5588 // but we can overlook it (clearing stsc) whenever stts_count == 0 (indicating no samples).
5589 if (!sc->chunk_count && !sc->stts_count && sc->stsc_count) {
5590 sc->stsc_count = 0;
5591 av_freep(&sc->stsc_data);
5592 }
5593
5594 ret = sanity_checks(c->fc, sc, st->index);
5595 if (ret)
5596 return ret > 1 ? AVERROR_INVALIDDATA : 0;
5597
5598 fix_timescale(c, sc);
5599
5600 avpriv_set_pts_info(st, 64, 1, sc->time_scale);
5601
5602 /*
5603 * Advanced edit list support does not work with fragemented MP4s, which
5604 * have stsc, stsz, stco, and stts with zero entries in the moov atom.
5605 * In these files, trun atoms may be streamed in.
5606 */
5607 if (!sc->stts_count && c->advanced_editlist) {
5608
5609 av_log(c->fc, AV_LOG_VERBOSE, "advanced_editlist does not work with fragmented "
5610 "MP4. disabling.\n");
5611 c->advanced_editlist = 0;
5612 c->advanced_editlist_autodisabled = 1;
5613 }
5614
5615 mov_build_index(c, st);
5616 /*
5617 * Fragment samples are appended later by mov_read_trun() and are not
5618 * covered by this non-fragmented track update.
5619 */
5621
5622#if CONFIG_IAMFDEC
5623 if (sc->iamf) {
5624 ret = mov_update_iamf_streams(c, st);
5625 if (ret < 0)
5626 return ret;
5627 }
5628#endif
5629
5630 if (sc->dref_id-1 < sc->drefs_count && sc->drefs[sc->dref_id-1].path) {
5631 MOVDref *dref = &sc->drefs[sc->dref_id - 1];
5632 if (c->enable_drefs) {
5633 if (mov_open_dref(c, &sc->pb, c->fc->url, dref) < 0)
5634 av_log(c->fc, AV_LOG_ERROR,
5635 "stream %d, error opening alias: path='%s', dir='%s', "
5636 "filename='%s', volume='%s', nlvl_from=%d, nlvl_to=%d\n",
5637 st->index, dref->path, dref->dir, dref->filename,
5638 dref->volume, dref->nlvl_from, dref->nlvl_to);
5639 } else {
5640 av_log(c->fc, AV_LOG_WARNING,
5641 "Skipped opening external track: "
5642 "stream %d, alias: path='%s', dir='%s', "
5643 "filename='%s', volume='%s', nlvl_from=%d, nlvl_to=%d."
5644 "Set enable_drefs to allow this.\n",
5645 st->index, dref->path, dref->dir, dref->filename,
5646 dref->volume, dref->nlvl_from, dref->nlvl_to);
5647 }
5648 } else {
5649 sc->pb = c->fc->pb;
5650 sc->pb_is_copied = 1;
5651 }
5652
5654 int stts_constant = sc->stts_count && sc->tts_count;
5655 if (sc->h_spacing && sc->v_spacing)
5657 sc->h_spacing, sc->v_spacing, INT_MAX);
5658 if (!st->sample_aspect_ratio.num && st->codecpar->width && st->codecpar->height &&
5659 sc->height && sc->width &&
5660 (st->codecpar->width != sc->width || st->codecpar->height != sc->height)) {
5662 (int64_t)st->codecpar->height * sc->width,
5663 (int64_t)st->codecpar->width * sc->height, INT_MAX);
5664 }
5665
5666#if FF_API_R_FRAME_RATE
5667 for (unsigned int i = 1; sc->stts_count && i + 1 < sc->tts_count; i++) {
5668 if (sc->tts_data[i].duration == sc->tts_data[0].duration)
5669 continue;
5670 stts_constant = 0;
5671 }
5672 if (stts_constant)
5674 sc->time_scale, sc->tts_data[0].duration, INT_MAX);
5675#endif
5676 }
5677
5678#if CONFIG_H261_DECODER || CONFIG_H263_DECODER || CONFIG_MPEG4_DECODER
5679 switch (st->codecpar->codec_id) {
5680#if CONFIG_H261_DECODER
5681 case AV_CODEC_ID_H261:
5682#endif
5683#if CONFIG_H263_DECODER
5684 case AV_CODEC_ID_H263:
5685#endif
5686#if CONFIG_MPEG4_DECODER
5687 case AV_CODEC_ID_MPEG4:
5688#endif
5689 st->codecpar->width = 0; /* let decoder init width/height */
5690 st->codecpar->height= 0;
5691 break;
5692 }
5693#endif
5694
5695 // If the duration of the mp3 packets is not constant, then they could need a parser
5697 && sc->time_scale == st->codecpar->sample_rate) {
5698 int stts_constant = 1;
5699 for (int i = 1; sc->stts_count && i < sc->tts_count; i++) {
5700 if (sc->tts_data[i].duration == sc->tts_data[0].duration)
5701 continue;
5702 stts_constant = 0;
5703 }
5704 if (!stts_constant)
5706 }
5707 /* Do not need those anymore. */
5708 av_freep(&sc->chunk_offsets);
5709 av_freep(&sc->sample_sizes);
5710 av_freep(&sc->keyframes);
5711 av_freep(&sc->stps_data);
5712 av_freep(&sc->elst_data);
5713 av_freep(&sc->rap_group);
5714 av_freep(&sc->sync_group);
5715 av_freep(&sc->sgpd_sync);
5716
5717 return 0;
5718}
5719
5721{
5722 int ret;
5723 c->itunes_metadata = 1;
5724 ret = mov_read_default(c, pb, atom);
5725 c->itunes_metadata = 0;
5726 return ret;
5727}
5728
5730{
5731 uint32_t count;
5732 uint32_t i;
5733
5734 if (atom.size < 8)
5735 return 0;
5736
5737 avio_skip(pb, 4);
5738 count = avio_rb32(pb);
5739 atom.size -= 8;
5740 if (count > atom.size / 8 || count >= UINT_MAX / sizeof(*c->meta_keys)) {
5741 av_log(c->fc, AV_LOG_ERROR,
5742 "The 'keys' atom with the invalid key count: %"PRIu32"\n", count);
5743 return AVERROR_INVALIDDATA;
5744 }
5745
5746 c->meta_keys = av_malloc_array(count + 1, sizeof(*c->meta_keys));
5747 if (!c->meta_keys)
5748 return AVERROR(ENOMEM);
5749
5750 c->meta_keys[0] = NULL;
5751 c->meta_keys_count = 1;
5752 for (i = 1; i <= count; ++i) {
5753 uint32_t key_size = avio_rb32(pb);
5754 uint32_t type = avio_rl32(pb);
5755 c->meta_keys[i] = NULL;
5756 c->meta_keys_count = i + 1;
5757 if (key_size < 8 || key_size > atom.size) {
5758 av_log(c->fc, AV_LOG_ERROR,
5759 "The key# %"PRIu32" in meta has invalid size:"
5760 "%"PRIu32"\n", i, key_size);
5761 return AVERROR_INVALIDDATA;
5762 }
5763 atom.size -= key_size;
5764 key_size -= 8;
5765 if (type != MKTAG('m','d','t','a')) {
5766 avio_skip(pb, key_size);
5767 continue;
5768 }
5769 c->meta_keys[i] = av_malloc(key_size + 1);
5770 if (!c->meta_keys[i])
5771 return AVERROR(ENOMEM);
5772 int ret = ffio_read_size(pb, c->meta_keys[i], key_size);
5773 if (ret < 0)
5774 return ret;
5775 c->meta_keys[i][key_size] = 0;
5776 }
5777
5778 return 0;
5779}
5780
5782{
5783 int64_t end = av_sat_add64(avio_tell(pb), atom.size);
5784 uint8_t *key = NULL, *val = NULL, *mean = NULL;
5785 int i;
5786 int ret = 0;
5787 AVStream *st;
5788
5789 if (c->fc->nb_streams < 1)
5790 return 0;
5791 st = c->fc->streams[c->fc->nb_streams-1];
5792
5793 for (i = 0; i < 3; i++) {
5794 uint8_t **p;
5795 uint32_t len, tag;
5796
5797 if (end - avio_tell(pb) <= 12)
5798 break;
5799
5800 len = avio_rb32(pb);
5801 tag = avio_rl32(pb);
5802 avio_skip(pb, 4); // flags
5803
5804 if (len < 12 || len - 12 > end - avio_tell(pb))
5805 break;
5806 len -= 12;
5807
5808 if (tag == MKTAG('m', 'e', 'a', 'n'))
5809 p = &mean;
5810 else if (tag == MKTAG('n', 'a', 'm', 'e'))
5811 p = &key;
5812 else if (tag == MKTAG('d', 'a', 't', 'a') && len > 4) {
5813 avio_skip(pb, 4);
5814 len -= 4;
5815 p = &val;
5816 } else
5817 break;
5818
5819 if (*p)
5820 break;
5821
5822 *p = av_malloc(len + 1);
5823 if (!*p) {
5824 ret = AVERROR(ENOMEM);
5825 break;
5826 }
5827 ret = ffio_read_size(pb, *p, len);
5828 if (ret < 0) {
5829 av_freep(p);
5830 break;
5831 }
5832 (*p)[len] = 0;
5833 }
5834
5835 if (mean && key && val) {
5836 if (strcmp(key, "iTunSMPB") == 0) {
5837 int64_t priming, remainder, samples;
5838 if (ff_itunes_parse_smpb(val, &priming, &remainder, &samples) >= 0) {
5839 if(priming>0 && priming<16384)
5840 st->codecpar->initial_padding = priming = av_rescale_q(priming, st->time_base,
5841 (AVRational){ 1, st->codecpar->sample_rate });
5842 if (remainder > 0) {
5844 (AVRational){ 1, st->codecpar->sample_rate });
5845 remainder = av_rescale_q(remainder, st->time_base,
5846 (AVRational){ 1, st->codecpar->sample_rate });
5847 samples = av_rescale_q(samples, st->time_base,
5848 (AVRational){ 1, st->codecpar->sample_rate });
5849 if (duration > remainder && duration > samples) {
5850 ffstream(st)->first_discard_sample = duration - remainder;
5852 }
5853 }
5854 av_log(c->fc, AV_LOG_DEBUG, "Parsed iTunSMPB: priming %"PRId64", "
5855 "remainder %"PRId64" samples %"PRId64"\n",
5856 priming, remainder, samples);
5857 }
5858 }
5859 if (strcmp(mean, "com.apple.iTunes") == 0 &&
5860 strcmp(key, "DISCSUBTITLE") == 0) {
5861 av_dict_set(&c->fc->metadata, "disc_subtitle", val,
5863 val = NULL;
5864 }
5865 if (strcmp(key, "cdec") != 0) {
5866 av_dict_set(&c->fc->metadata, key, val,
5868 key = val = NULL;
5869 }
5870 } else {
5871 av_log(c->fc, AV_LOG_VERBOSE,
5872 "Unhandled or malformed custom metadata of size %"PRId64"\n", atom.size);
5873 }
5874
5875 avio_seek(pb, end, SEEK_SET);
5876 av_freep(&key);
5877 av_freep(&val);
5878 av_freep(&mean);
5879 return ret;
5880}
5881
5883{
5884 MOVStreamContext *sc;
5885 AVStream *st;
5886
5887 st = avformat_new_stream(c->fc, NULL);
5888 if (!st)
5889 return AVERROR(ENOMEM);
5890 sc = av_mallocz(sizeof(MOVStreamContext));
5891 if (!sc)
5892 goto fail;
5893
5894 item->st = st;
5895 st->id = item->item_id;
5896 st->priv_data = sc;
5898 st->codecpar->codec_id = mov_codec_id(st, item->type);
5899 sc->id = st->id;
5900 sc->ffindex = st->index;
5901 st->avg_frame_rate.num = st->avg_frame_rate.den = 1;
5902 st->time_base.num = st->time_base.den = 1;
5903 st->nb_frames = 1;
5904 sc->time_scale = 1;
5905 sc->pb = c->fc->pb;
5906 sc->pb_is_copied = 1;
5907 sc->refcount = 1;
5908
5909 if (item->name)
5910 av_dict_set(&st->metadata, "title", item->name, 0);
5911
5912 // Populate the necessary fields used by mov_build_index.
5913 sc->stsc_data = av_malloc_array(1, sizeof(*sc->stsc_data));
5914 if (!sc->stsc_data)
5915 goto fail;
5916 sc->stsc_count = 1;
5917 sc->stsc_data[0].first = 1;
5918 sc->stsc_data[0].count = 1;
5919 sc->stsc_data[0].id = 1;
5920 sc->chunk_offsets = av_malloc_array(1, sizeof(*sc->chunk_offsets));
5921 if (!sc->chunk_offsets)
5922 goto fail;
5923 sc->chunk_count = 1;
5924 sc->stts_data = av_malloc_array(1, sizeof(*sc->stts_data));
5925 if (!sc->stts_data)
5926 goto fail;
5927 sc->stts_count = 1;
5928 sc->stts_data[0].count = 1;
5929 // Not used for still images. But needed by mov_build_index.
5930 sc->stts_data[0].duration = 0;
5931
5932 return 0;
5933fail:
5934 mov_free_stream_context(c->fc, st);
5935 ff_remove_stream(c->fc, st);
5936 item->st = NULL;
5937
5938 return AVERROR(ENOMEM);
5939}
5940
5942{
5943 while (atom.size > 8) {
5944 uint32_t tag;
5945 if (avio_feof(pb))
5946 return AVERROR_EOF;
5947 tag = avio_rl32(pb);
5948 atom.size -= 4;
5949 if (tag == MKTAG('h','d','l','r')) {
5950 avio_seek(pb, -8, SEEK_CUR);
5951 atom.size += 8;
5952 return mov_read_default(c, pb, atom);
5953 }
5954 }
5955 return 0;
5956}
5957
5958// return 1 when matrix is identity, 0 otherwise
5959#define IS_MATRIX_IDENT(matrix) \
5960 ( (matrix)[0][0] == (1 << 16) && \
5961 (matrix)[1][1] == (1 << 16) && \
5962 (matrix)[2][2] == (1 << 30) && \
5963 !(matrix)[0][1] && !(matrix)[0][2] && \
5964 !(matrix)[1][0] && !(matrix)[1][2] && \
5965 !(matrix)[2][0] && !(matrix)[2][1])
5966
5968{
5969 int i, j, e;
5970 int width;
5971 int height;
5972 int display_matrix[3][3];
5973 int res_display_matrix[3][3] = { { 0 } };
5974 AVStream *st;
5975 MOVStreamContext *sc;
5976 int version;
5977 int flags;
5978
5979 if (c->fc->nb_streams < 1)
5980 return 0;
5981 st = c->fc->streams[c->fc->nb_streams-1];
5982 sc = st->priv_data;
5983
5984 // Each stream (trak) should have exactly 1 tkhd. This catches bad files and
5985 // avoids corrupting AVStreams mapped to an earlier tkhd.
5986 if (st->id != -1)
5987 return AVERROR_INVALIDDATA;
5988
5989 version = avio_r8(pb);
5990 flags = avio_rb24(pb);
5992
5993 if (version == 1) {
5994 avio_rb64(pb);
5995 avio_rb64(pb);
5996 } else {
5997 avio_rb32(pb); /* creation time */
5998 avio_rb32(pb); /* modification time */
5999 }
6000 st->id = (int)avio_rb32(pb); /* track id (NOT 0 !)*/
6001 sc->id = st->id;
6002 avio_rb32(pb); /* reserved */
6003
6004 /* highlevel (considering edits) duration in movie timebase */
6005 (version == 1) ? avio_rb64(pb) : avio_rb32(pb);
6006 avio_rb32(pb); /* reserved */
6007 avio_rb32(pb); /* reserved */
6008
6009 avio_rb16(pb); /* layer */
6010 avio_rb16(pb); /* alternate group */
6011 avio_rb16(pb); /* volume */
6012 avio_rb16(pb); /* reserved */
6013
6014 //read in the display matrix (outlined in ISO 14496-12, Section 6.2.2)
6015 // they're kept in fixed point format through all calculations
6016 // save u,v,z to store the whole matrix in the AV_PKT_DATA_DISPLAYMATRIX
6017 // side data, but the scale factor is not needed to calculate aspect ratio
6018 for (i = 0; i < 3; i++) {
6019 display_matrix[i][0] = avio_rb32(pb); // 16.16 fixed point
6020 display_matrix[i][1] = avio_rb32(pb); // 16.16 fixed point
6021 display_matrix[i][2] = avio_rb32(pb); // 2.30 fixed point
6022 }
6023
6024 width = avio_rb32(pb); // 16.16 fixed point track width
6025 height = avio_rb32(pb); // 16.16 fixed point track height
6026 sc->width = width >> 16;
6027 sc->height = height >> 16;
6028
6029 // apply the moov display matrix (after the tkhd one)
6030 for (i = 0; i < 3; i++) {
6031 const int sh[3] = { 16, 16, 30 };
6032 for (j = 0; j < 3; j++) {
6033 for (e = 0; e < 3; e++) {
6034 res_display_matrix[i][j] +=
6035 ((int64_t) display_matrix[i][e] *
6036 c->movie_display_matrix[e][j]) >> sh[e];
6037 }
6038 }
6039 }
6040
6041 // save the matrix when it is not the default identity
6042 if (!IS_MATRIX_IDENT(res_display_matrix)) {
6044 sc->display_matrix = av_malloc(sizeof(int32_t) * 9);
6045 if (!sc->display_matrix)
6046 return AVERROR(ENOMEM);
6047
6048 for (i = 0; i < 3; i++)
6049 for (j = 0; j < 3; j++)
6050 sc->display_matrix[i * 3 + j] = res_display_matrix[i][j];
6051 }
6052
6053 // transform the display width/height according to the matrix
6054 // to keep the same scale, use [width height 1<<16]
6055 if (width && height && sc->display_matrix) {
6056 double disp_transform[2];
6057
6058 for (i = 0; i < 2; i++)
6059 disp_transform[i] = hypot(sc->display_matrix[0 + i],
6060 sc->display_matrix[3 + i]);
6061
6062 if (disp_transform[0] > 1 && disp_transform[1] > 1 &&
6063 disp_transform[0] < (1<<24) && disp_transform[1] < (1<<24) &&
6064 fabs((disp_transform[0] / disp_transform[1]) - 1.0) > 0.01)
6066 disp_transform[0] / disp_transform[1],
6067 INT_MAX);
6068 }
6069 return 0;
6070}
6071
6073{
6074 MOVFragment *frag = &c->fragment;
6075 MOVTrackExt *trex = NULL;
6076 int flags, track_id, i;
6077 MOVFragmentStreamInfo * frag_stream_info;
6078
6079 avio_r8(pb); /* version */
6080 flags = avio_rb24(pb);
6081
6082 track_id = avio_rb32(pb);
6083 if (!track_id)
6084 return AVERROR_INVALIDDATA;
6085 for (i = 0; i < c->trex_count; i++)
6086 if (c->trex_data[i].track_id == track_id) {
6087 trex = &c->trex_data[i];
6088 break;
6089 }
6090 if (!trex) {
6091 av_log(c->fc, AV_LOG_WARNING, "could not find corresponding trex (id %u)\n", track_id);
6092 return 0;
6093 }
6094 c->fragment.found_tfhd = 1;
6095 frag->track_id = track_id;
6096 set_frag_stream(&c->frag_index, track_id);
6097
6100 frag->moof_offset : frag->implicit_offset;
6101 frag->stsd_id = flags & MOV_TFHD_STSD_ID ? avio_rb32(pb) : trex->stsd_id;
6102
6104 avio_rb32(pb) : trex->duration;
6105 frag->size = flags & MOV_TFHD_DEFAULT_SIZE ?
6106 avio_rb32(pb) : trex->size;
6108 avio_rb32(pb) : trex->flags;
6109 av_log(c->fc, AV_LOG_TRACE, "frag flags 0x%x\n", frag->flags);
6110
6111 frag_stream_info = get_current_frag_stream_info(&c->frag_index);
6112 if (frag_stream_info) {
6113 frag_stream_info->next_trun_dts = AV_NOPTS_VALUE;
6114 frag_stream_info->stsd_id = frag->stsd_id;
6115 }
6116 return 0;
6117}
6118
6120{
6121 unsigned i, num;
6122 void *new_tracks;
6123
6124 num = atom.size / 4;
6125 if (!(new_tracks = av_malloc_array(num, sizeof(int))))
6126 return AVERROR(ENOMEM);
6127
6128 av_free(c->chapter_tracks);
6129 c->chapter_tracks = new_tracks;
6130 c->nb_chapter_tracks = num;
6131
6132 for (i = 0; i < num && !pb->eof_reached; i++)
6133 c->chapter_tracks[i] = avio_rb32(pb);
6134
6135 c->nb_chapter_tracks = i;
6136
6137 return 0;
6138}
6139
6141{
6142 MOVTrackExt *trex;
6143 int err;
6144
6145 if ((uint64_t)c->trex_count+1 >= UINT_MAX / sizeof(*c->trex_data))
6146 return AVERROR_INVALIDDATA;
6147 if ((err = av_reallocp_array(&c->trex_data, c->trex_count + 1,
6148 sizeof(*c->trex_data))) < 0) {
6149 c->trex_count = 0;
6150 return err;
6151 }
6152
6153 c->fc->duration = AV_NOPTS_VALUE; // the duration from mvhd is not representing the whole file when fragments are used.
6154
6155 trex = &c->trex_data[c->trex_count++];
6156 avio_r8(pb); /* version */
6157 avio_rb24(pb); /* flags */
6158 trex->track_id = avio_rb32(pb);
6159 trex->stsd_id = avio_rb32(pb);
6160 trex->duration = avio_rb32(pb);
6161 trex->size = avio_rb32(pb);
6162 trex->flags = avio_rb32(pb);
6163 return 0;
6164}
6165
6167{
6168 MOVFragment *frag = &c->fragment;
6169 AVStream *st = NULL;
6170 MOVStreamContext *sc;
6171 int version, i;
6172 MOVFragmentStreamInfo * frag_stream_info;
6173 int64_t base_media_decode_time;
6174
6175 for (i = 0; i < c->fc->nb_streams; i++) {
6176 sc = c->fc->streams[i]->priv_data;
6177 if (sc->id == frag->track_id) {
6178 st = c->fc->streams[i];
6179 break;
6180 }
6181 }
6182 if (!st) {
6183 av_log(c->fc, AV_LOG_WARNING, "could not find corresponding track id %u\n", frag->track_id);
6184 return 0;
6185 }
6186 sc = st->priv_data;
6187 if (sc->pseudo_stream_id + 1 != frag->stsd_id && sc->pseudo_stream_id != -1)
6188 return 0;
6189 version = avio_r8(pb);
6190 avio_rb24(pb); /* flags */
6191 if (version) {
6192 base_media_decode_time = avio_rb64(pb);
6193 } else {
6194 base_media_decode_time = avio_rb32(pb);
6195 }
6196
6197 frag_stream_info = get_current_frag_stream_info(&c->frag_index);
6198 if (frag_stream_info)
6199 frag_stream_info->tfdt_dts = base_media_decode_time;
6200 sc->track_end = base_media_decode_time;
6201
6202 return 0;
6203}
6204
6206{
6207 MOVFragment *frag = &c->fragment;
6208 AVStream *st = NULL;
6209 FFStream *sti = NULL;
6210 MOVStreamContext *sc;
6211 MOVTimeToSample *tts_data;
6212 uint64_t offset;
6213 int64_t dts, pts = AV_NOPTS_VALUE;
6214 int data_offset = 0;
6215 unsigned entries, first_sample_flags = frag->flags;
6216 int flags, distance, i;
6217 int64_t prev_dts = AV_NOPTS_VALUE;
6218 int next_frag_index = -1, index_entry_pos;
6219 size_t requested_size;
6220 AVIndexEntry *new_entries;
6221 MOVFragmentStreamInfo * frag_stream_info;
6222
6223 if (!frag->found_tfhd) {
6224 av_log(c->fc, AV_LOG_ERROR, "trun track id unknown, no tfhd was found\n");
6225 return AVERROR_INVALIDDATA;
6226 }
6227
6228 for (i = 0; i < c->fc->nb_streams; i++) {
6229 sc = c->fc->streams[i]->priv_data;
6230 if (sc->id == frag->track_id) {
6231 st = c->fc->streams[i];
6232 sti = ffstream(st);
6233 break;
6234 }
6235 }
6236 if (!st) {
6237 av_log(c->fc, AV_LOG_WARNING, "could not find corresponding track id %u\n", frag->track_id);
6238 return 0;
6239 }
6240 sc = st->priv_data;
6241 if (sc->pseudo_stream_id+1 != frag->stsd_id && sc->pseudo_stream_id != -1)
6242 return 0;
6243
6244 // Find the next frag_index index that has a valid index_entry for
6245 // the current track_id.
6246 //
6247 // A valid index_entry means the trun for the fragment was read
6248 // and it's samples are in index_entries at the given position.
6249 // New index entries will be inserted before the index_entry found.
6250 index_entry_pos = sti->nb_index_entries;
6251 for (i = c->frag_index.current + 1; i < c->frag_index.nb_items; i++) {
6252 frag_stream_info = get_frag_stream_info(&c->frag_index, i, frag->track_id);
6253 if (frag_stream_info && frag_stream_info->index_entry >= 0) {
6254 next_frag_index = i;
6255 index_entry_pos = frag_stream_info->index_entry;
6256 break;
6257 }
6258 }
6259 av_assert0(index_entry_pos <= sti->nb_index_entries);
6260
6261 avio_r8(pb); /* version */
6262 flags = avio_rb24(pb);
6263 entries = avio_rb32(pb);
6264 av_log(c->fc, AV_LOG_TRACE, "flags 0x%x entries %u\n", flags, entries);
6265
6266 /* Explicit zero sizes are bounded by the trun payload. Reject a zero
6267 * default size before allocating or updating the sample index. */
6268 if (entries && !frag->size && !(flags & MOV_TRUN_SAMPLE_SIZE))
6269 return AVERROR_INVALIDDATA;
6270
6271 if ((uint64_t)entries+sc->tts_count >= UINT_MAX/sizeof(*sc->tts_data))
6272 return AVERROR_INVALIDDATA;
6273 if (flags & MOV_TRUN_DATA_OFFSET) data_offset = avio_rb32(pb);
6274 if (flags & MOV_TRUN_FIRST_SAMPLE_FLAGS) first_sample_flags = avio_rb32(pb);
6275
6276 int entry_size = !!(flags & MOV_TRUN_SAMPLE_DURATION) * 4
6277 + !!(flags & MOV_TRUN_SAMPLE_SIZE) * 4
6278 + !!(flags & MOV_TRUN_SAMPLE_FLAGS) * 4
6279 + !!(flags & MOV_TRUN_SAMPLE_CTS) * 4;
6280 int64_t sample_data_size = avio_size(sc->pb);
6281 int64_t max_entries = INT64_MAX;
6282
6283 if (sample_data_size > 0)
6284 max_entries = sample_data_size - sti->nb_index_entries;
6285 if (entry_size) {
6286 int64_t size = sc->pb == pb ? sample_data_size : avio_size(pb);
6287 int64_t pos = avio_tell(pb);
6288 int64_t left = atom.size - 8 - !!(flags & MOV_TRUN_DATA_OFFSET) * 4
6290
6291 if (pos >= 0 && size >= pos)
6292 left = FFMIN(left, size - pos);
6293 max_entries = FFMIN(max_entries, left / entry_size);
6294 }
6295 if (entries > max_entries) {
6296 av_log(c->fc, AV_LOG_ERROR, "trun sample count %u exceeds the %"PRId64" "
6297 "samples the input can hold\n", entries, max_entries);
6298 return AVERROR_INVALIDDATA;
6299 }
6300
6301 frag_stream_info = get_current_frag_stream_info(&c->frag_index);
6302 if (frag_stream_info) {
6303 if (frag_stream_info->next_trun_dts != AV_NOPTS_VALUE) {
6304 dts = frag_stream_info->next_trun_dts - sc->time_offset;
6305 } else if (frag_stream_info->first_tfra_pts != AV_NOPTS_VALUE &&
6306 c->use_mfra_for == FF_MOV_FLAG_MFRA_PTS) {
6307 pts = frag_stream_info->first_tfra_pts;
6308 av_log(c->fc, AV_LOG_DEBUG, "found mfra time %"PRId64
6309 ", using it for pts\n", pts);
6310 } else if (frag_stream_info->first_tfra_pts != AV_NOPTS_VALUE &&
6311 c->use_mfra_for == FF_MOV_FLAG_MFRA_DTS) {
6312 dts = frag_stream_info->first_tfra_pts;
6313 av_log(c->fc, AV_LOG_DEBUG, "found mfra time %"PRId64
6314 ", using it for dts\n", pts);
6315 } else {
6316 int has_tfdt = frag_stream_info->tfdt_dts != AV_NOPTS_VALUE;
6317 int has_sidx = frag_stream_info->sidx_pts != AV_NOPTS_VALUE;
6318 int fallback_tfdt = !c->use_tfdt && !has_sidx && has_tfdt;
6319 int fallback_sidx = c->use_tfdt && !has_tfdt && has_sidx;
6320
6321 if (fallback_sidx) {
6322 av_log(c->fc, AV_LOG_DEBUG, "use_tfdt set but no tfdt found, using sidx instead\n");
6323 }
6324 if (fallback_tfdt) {
6325 av_log(c->fc, AV_LOG_DEBUG, "use_tfdt not set but no sidx found, using tfdt instead\n");
6326 }
6327
6328 if (has_tfdt && c->use_tfdt || fallback_tfdt) {
6329 dts = frag_stream_info->tfdt_dts - sc->time_offset;
6330 av_log(c->fc, AV_LOG_DEBUG, "found tfdt time %"PRId64
6331 ", using it for dts\n", dts);
6332 } else if (has_sidx && !c->use_tfdt || fallback_sidx) {
6333 // FIXME: sidx earliest_presentation_time is *PTS*, s.b.
6334 // pts = frag_stream_info->sidx_pts;
6335 dts = frag_stream_info->sidx_pts;
6336 av_log(c->fc, AV_LOG_DEBUG, "found sidx time %"PRId64
6337 ", using it for dts\n", frag_stream_info->sidx_pts);
6338 } else {
6339 dts = sc->track_end - sc->time_offset;
6340 av_log(c->fc, AV_LOG_DEBUG, "found track end time %"PRId64
6341 ", using it for dts\n", dts);
6342 }
6343 }
6344 } else {
6345 dts = sc->track_end - sc->time_offset;
6346 av_log(c->fc, AV_LOG_DEBUG, "found track end time %"PRId64
6347 ", using it for dts\n", dts);
6348 }
6349 offset = frag->base_data_offset + data_offset;
6350 distance = 0;
6351 av_log(c->fc, AV_LOG_TRACE, "first sample flags 0x%x\n", first_sample_flags);
6352
6353 // realloc space for new index entries
6354 if ((uint64_t)sti->nb_index_entries + entries >= UINT_MAX / sizeof(AVIndexEntry)) {
6355 entries = UINT_MAX / sizeof(AVIndexEntry) - sti->nb_index_entries;
6356 av_log(c->fc, AV_LOG_ERROR, "Failed to add index entry\n");
6357 }
6358 if (entries == 0)
6359 return 0;
6360
6361 requested_size = (sti->nb_index_entries + entries) * sizeof(AVIndexEntry);
6362 new_entries = av_fast_realloc(sti->index_entries,
6364 requested_size);
6365 if (!new_entries)
6366 return AVERROR(ENOMEM);
6367 sti->index_entries= new_entries;
6368
6369 requested_size = (sti->nb_index_entries + entries) * sizeof(*sc->tts_data);
6370 tts_data = av_fast_realloc(sc->tts_data, &sc->tts_allocated_size,
6371 requested_size);
6372 if (!tts_data)
6373 return AVERROR(ENOMEM);
6374 sc->tts_data = tts_data;
6375
6376 // In case there were samples without time to sample entries, ensure they get
6377 // zero valued entries. This ensures clips which mix boxes with and
6378 // without time to sample entries don't pickup uninitialized data.
6379 if (sc->tts_count < sti->nb_index_entries)
6380 memset(sc->tts_data + sc->tts_count, 0,
6381 sizeof(*sc->tts_data) * (sti->nb_index_entries - sc->tts_count));
6382
6383 if (index_entry_pos < sti->nb_index_entries) {
6384 // Make hole in index_entries and tts_data for new samples
6385 memmove(sti->index_entries + index_entry_pos + entries,
6386 sti->index_entries + index_entry_pos,
6387 sizeof(*sti->index_entries) *
6388 (sti->nb_index_entries - index_entry_pos));
6389 memmove(sc->tts_data + index_entry_pos + entries,
6390 sc->tts_data + index_entry_pos,
6391 sizeof(*sc->tts_data) * (sti->nb_index_entries - index_entry_pos));
6392 if (index_entry_pos < sc->current_sample) {
6393 sc->current_sample += entries;
6394 }
6395 }
6396
6397 sti->nb_index_entries += entries;
6398 sc->tts_count = sti->nb_index_entries;
6399 sc->stts_count = sti->nb_index_entries;
6401 sc->ctts_count = sti->nb_index_entries;
6402
6403 // Record the index_entry position in frag_index of this fragment
6404 if (frag_stream_info) {
6405 frag_stream_info->index_entry = index_entry_pos;
6406 if (frag_stream_info->index_base < 0)
6407 frag_stream_info->index_base = index_entry_pos;
6408 }
6409
6410 if (index_entry_pos > 0)
6411 prev_dts = sti->index_entries[index_entry_pos-1].timestamp;
6412
6413 for (i = 0; i < entries && !pb->eof_reached; i++) {
6414 unsigned sample_size = frag->size;
6415 int sample_flags = i ? frag->flags : first_sample_flags;
6416 unsigned sample_duration = frag->duration;
6417 unsigned ctts_duration = 0;
6418 int keyframe = 0;
6419 int index_entry_flags = 0;
6420
6421 if (flags & MOV_TRUN_SAMPLE_DURATION) sample_duration = avio_rb32(pb);
6422 if (flags & MOV_TRUN_SAMPLE_SIZE) sample_size = avio_rb32(pb);
6423 if (flags & MOV_TRUN_SAMPLE_FLAGS) sample_flags = avio_rb32(pb);
6424 if (flags & MOV_TRUN_SAMPLE_CTS) ctts_duration = avio_rb32(pb);
6425
6426 if (sample_duration > c->max_stts_delta) {
6427 av_log(c->fc, AV_LOG_WARNING,
6428 "Too large sample duration %u in trun entry %u in st:%d. Clipping to 1.\n",
6429 sample_duration, i, st->index);
6430 sample_duration = 1;
6431 }
6432
6433 mov_update_dts_shift(sc, ctts_duration, c->fc);
6434 if (pts != AV_NOPTS_VALUE) {
6435 dts = pts - sc->dts_shift;
6436 if (flags & MOV_TRUN_SAMPLE_CTS) {
6437 dts -= ctts_duration;
6438 } else {
6439 dts -= sc->time_offset;
6440 }
6441 av_log(c->fc, AV_LOG_DEBUG,
6442 "pts %"PRId64" calculated dts %"PRId64
6443 " sc->dts_shift %d ctts.duration %d"
6444 " sc->time_offset %"PRId64
6445 " flags & MOV_TRUN_SAMPLE_CTS %d\n",
6446 pts, dts,
6447 sc->dts_shift, ctts_duration,
6450 }
6451
6452 keyframe =
6453 !(sample_flags & (MOV_FRAG_SAMPLE_FLAG_IS_NON_SYNC |
6455 if (keyframe) {
6456 distance = 0;
6457 index_entry_flags |= AVINDEX_KEYFRAME;
6458 }
6459 // Fragments can overlap in time. Discard overlapping frames after
6460 // decoding.
6461 if (prev_dts >= dts)
6462 index_entry_flags |= AVINDEX_DISCARD_FRAME;
6463
6464 sti->index_entries[index_entry_pos].pos = offset;
6465 sti->index_entries[index_entry_pos].timestamp = dts;
6466 sti->index_entries[index_entry_pos].size = sample_size;
6467 sti->index_entries[index_entry_pos].min_distance = distance;
6468 sti->index_entries[index_entry_pos].flags = index_entry_flags;
6469
6470 sc->tts_data[index_entry_pos].count = 1;
6471 sc->tts_data[index_entry_pos].offset = ctts_duration;
6472 sc->tts_data[index_entry_pos].duration = sample_duration;
6473 index_entry_pos++;
6474
6475 av_log(c->fc, AV_LOG_TRACE, "AVIndex stream %d, sample %d, offset %"PRIx64", dts %"PRId64", "
6476 "size %u, distance %d, keyframe %d\n", st->index,
6477 index_entry_pos, offset, dts, sample_size, distance, keyframe);
6478 distance++;
6479 if (av_sat_add64(dts, sample_duration) != dts + (uint64_t)sample_duration)
6480 return AVERROR_INVALIDDATA;
6481 dts += sample_duration;
6482 offset += sample_size;
6483 sc->data_size += sample_size;
6484
6485 if (sample_duration <= INT64_MAX - sc->duration_for_fps &&
6486 1 <= INT_MAX - sc->nb_frames_for_fps
6487 ) {
6488 sc->duration_for_fps += sample_duration;
6489 sc->nb_frames_for_fps ++;
6490 }
6491 }
6492 if (frag_stream_info)
6493 frag_stream_info->next_trun_dts = dts + sc->time_offset;
6494 if (i < entries) {
6495 // EOF found before reading all entries. Fix the hole this would
6496 // leave in index_entries and tts_data
6497 int gap = entries - i;
6498 memmove(sti->index_entries + index_entry_pos,
6499 sti->index_entries + index_entry_pos + gap,
6500 sizeof(*sti->index_entries) *
6501 (sti->nb_index_entries - (index_entry_pos + gap)));
6502 memmove(sc->tts_data + index_entry_pos,
6503 sc->tts_data + index_entry_pos + gap,
6504 sizeof(*sc->tts_data) *
6505 (sc->tts_count - (index_entry_pos + gap)));
6506
6507 sti->nb_index_entries -= gap;
6508 sc->tts_count -= gap;
6509 if (index_entry_pos < sc->current_sample) {
6510 sc->current_sample -= gap;
6511 }
6512 entries = i;
6513 }
6514
6515 // The end of this new fragment may overlap in time with the start
6516 // of the next fragment in index_entries. Mark the samples in the next
6517 // fragment that overlap with AVINDEX_DISCARD_FRAME
6518 prev_dts = AV_NOPTS_VALUE;
6519 if (index_entry_pos > 0)
6520 prev_dts = sti->index_entries[index_entry_pos-1].timestamp;
6521 for (int i = index_entry_pos; i < sti->nb_index_entries; i++) {
6522 if (prev_dts < sti->index_entries[i].timestamp)
6523 break;
6525 }
6526
6527 // If a hole was created to insert the new index_entries into,
6528 // the index_entry recorded for all subsequent moof must
6529 // be incremented by the number of entries inserted.
6530 fix_frag_index_entries(&c->frag_index, next_frag_index,
6531 frag->track_id, entries);
6532
6533 if (pb->eof_reached) {
6534 av_log(c->fc, AV_LOG_WARNING, "reached eof, corrupted TRUN atom\n");
6535 return AVERROR_EOF;
6536 }
6537
6538 frag->implicit_offset = offset;
6539
6540 sc->track_end = dts + sc->time_offset;
6541 if (st->duration < sc->track_end)
6542 st->duration = sc->track_end;
6543
6544 return 0;
6545}
6546
6548{
6549 int64_t stream_size = avio_size(pb);
6550 int64_t offset = av_sat_add64(avio_tell(pb), atom.size), pts, timestamp;
6551 uint8_t version, is_complete;
6552 int64_t offadd;
6553 unsigned i, j, track_id, item_count;
6554 AVStream *st = NULL;
6555 AVStream *ref_st = NULL;
6556 MOVStreamContext *sc, *ref_sc = NULL;
6557 AVRational timescale;
6558
6559 version = avio_r8(pb);
6560 if (version > 1) {
6561 avpriv_request_sample(c->fc, "sidx version %u", version);
6562 return 0;
6563 }
6564
6565 avio_rb24(pb); // flags
6566
6567 track_id = avio_rb32(pb); // Reference ID
6568 for (i = 0; i < c->fc->nb_streams; i++) {
6569 sc = c->fc->streams[i]->priv_data;
6570 if (sc->id == track_id) {
6571 st = c->fc->streams[i];
6572 break;
6573 }
6574 }
6575 if (!st) {
6576 av_log(c->fc, AV_LOG_WARNING, "could not find corresponding track id %d\n", track_id);
6577 return 0;
6578 }
6579
6580 sc = st->priv_data;
6581
6582 timescale = av_make_q(1, avio_rb32(pb));
6583
6584 if (timescale.den <= 0) {
6585 av_log(c->fc, AV_LOG_ERROR, "Invalid sidx timescale 1/%d\n", timescale.den);
6586 return AVERROR_INVALIDDATA;
6587 }
6588
6589 if (version == 0) {
6590 pts = avio_rb32(pb);
6591 offadd= avio_rb32(pb);
6592 } else {
6593 pts = avio_rb64(pb);
6594 offadd= avio_rb64(pb);
6595 }
6596 if (av_sat_add64(offset, offadd) != offset + (uint64_t)offadd)
6597 return AVERROR_INVALIDDATA;
6598
6599 offset += (uint64_t)offadd;
6600
6601 avio_rb16(pb); // reserved
6602
6603 item_count = avio_rb16(pb);
6604 if (item_count == 0)
6605 return AVERROR_INVALIDDATA;
6606
6607 for (i = 0; i < item_count; i++) {
6608 int index;
6609 MOVFragmentStreamInfo * frag_stream_info;
6610 uint32_t size = avio_rb32(pb);
6611 uint32_t duration = avio_rb32(pb);
6612 if (size & 0x80000000) {
6613 avpriv_request_sample(c->fc, "sidx reference_type 1");
6614 return AVERROR_PATCHWELCOME;
6615 }
6616 avio_rb32(pb); // sap_flags
6617 timestamp = av_rescale_q(pts, timescale, st->time_base);
6618
6620 frag_stream_info = get_frag_stream_info(&c->frag_index, index, track_id);
6621 if (frag_stream_info)
6622 frag_stream_info->sidx_pts = timestamp;
6623
6624 if (av_sat_add64(offset, size) != offset + (uint64_t)size ||
6625 av_sat_add64(pts, duration) != pts + (uint64_t)duration
6626 )
6627 return AVERROR_INVALIDDATA;
6628 offset += size;
6629 pts += duration;
6630 }
6631
6632 st->duration = sc->track_end = pts;
6633
6634 sc->has_sidx = 1;
6635
6636 // See if the remaining bytes are just an mfra which we can ignore.
6637 is_complete = offset == stream_size;
6638 if (!is_complete && (pb->seekable & AVIO_SEEKABLE_NORMAL) && stream_size > 0 ) {
6639 int64_t ret;
6640 int64_t original_pos = avio_tell(pb);
6641 if (!c->have_read_mfra_size) {
6642 if ((ret = avio_seek(pb, stream_size - 4, SEEK_SET)) < 0)
6643 return ret;
6644 c->mfra_size = avio_rb32(pb);
6645 c->have_read_mfra_size = 1;
6646 if ((ret = avio_seek(pb, original_pos, SEEK_SET)) < 0)
6647 return ret;
6648 }
6649 if (offset == stream_size - c->mfra_size)
6650 is_complete = 1;
6651 }
6652
6653 if (is_complete) {
6654 // Find first entry in fragment index that came from an sidx.
6655 // This will pretty much always be the first entry.
6656 for (i = 0; i < c->frag_index.nb_items; i++) {
6657 MOVFragmentIndexItem * item = &c->frag_index.item[i];
6658 for (j = 0; ref_st == NULL && j < item->nb_stream_info; j++) {
6660 si = &item->stream_info[j];
6661 if (si->sidx_pts != AV_NOPTS_VALUE) {
6662 ref_st = c->fc->streams[j];
6663 ref_sc = ref_st->priv_data;
6664 break;
6665 }
6666 }
6667 }
6668 if (ref_st) for (i = 0; i < c->fc->nb_streams; i++) {
6669 st = c->fc->streams[i];
6670 sc = st->priv_data;
6671 if (!sc->has_sidx) {
6672 st->duration = sc->track_end = av_rescale(ref_st->duration, sc->time_scale, ref_sc->time_scale);
6673 }
6674 }
6675
6676 if (offadd == 0)
6677 c->frag_index.complete = 1;
6678 }
6679
6680 return 0;
6681}
6682
6683/* this atom should be null (from specs), but some buggy files put the 'moov' atom inside it... */
6684/* like the files created with Adobe Premiere 5.0, for samples see */
6685/* http://graphics.tudelft.nl/~wouter/publications/soundtests/ */
6687{
6688 int err;
6689
6690 if (atom.size < 8)
6691 return 0; /* continue */
6692 if (avio_rb32(pb) != 0) { /* 0 sized mdat atom... use the 'wide' atom size */
6693 avio_skip(pb, atom.size - 4);
6694 return 0;
6695 }
6696 atom.type = avio_rl32(pb);
6697 atom.size -= 8;
6698 if (atom.type != MKTAG('m','d','a','t')) {
6699 avio_skip(pb, atom.size);
6700 return 0;
6701 }
6702 err = mov_read_mdat(c, pb, atom);
6703 return err;
6704}
6705
6707{
6708#if CONFIG_ZLIB
6710 uint8_t *cmov_data;
6711 uint8_t *moov_data; /* uncompressed data */
6712 long cmov_len, moov_len;
6713 int ret = -1;
6714
6715 avio_rb32(pb); /* dcom atom */
6716 if (avio_rl32(pb) != MKTAG('d','c','o','m'))
6717 return AVERROR_INVALIDDATA;
6718 if (avio_rl32(pb) != MKTAG('z','l','i','b')) {
6719 av_log(c->fc, AV_LOG_ERROR, "unknown compression for cmov atom !\n");
6720 return AVERROR_INVALIDDATA;
6721 }
6722 avio_rb32(pb); /* cmvd atom */
6723 if (avio_rl32(pb) != MKTAG('c','m','v','d'))
6724 return AVERROR_INVALIDDATA;
6725 moov_len = avio_rb32(pb); /* uncompressed size */
6726 cmov_len = atom.size - 6 * 4;
6727
6728 cmov_data = av_malloc(cmov_len);
6729 if (!cmov_data)
6730 return AVERROR(ENOMEM);
6731 moov_data = av_malloc(moov_len);
6732 if (!moov_data) {
6733 av_free(cmov_data);
6734 return AVERROR(ENOMEM);
6735 }
6736 ret = ffio_read_size(pb, cmov_data, cmov_len);
6737 if (ret < 0)
6738 goto free_and_return;
6739
6740 ret = AVERROR_INVALIDDATA;
6741 if (uncompress (moov_data, (uLongf *) &moov_len, (const Bytef *)cmov_data, cmov_len) != Z_OK)
6742 goto free_and_return;
6743 ffio_init_read_context(&ctx, moov_data, moov_len);
6744 ctx.pub.seekable = AVIO_SEEKABLE_NORMAL;
6745 atom.type = MKTAG('m','o','o','v');
6746 atom.size = moov_len;
6747 ret = mov_read_default(c, &ctx.pub, atom);
6748free_and_return:
6749 av_free(moov_data);
6750 av_free(cmov_data);
6751 return ret;
6752#else
6753 av_log(c->fc, AV_LOG_ERROR, "this file requires zlib support compiled in\n");
6754 return AVERROR(ENOSYS);
6755#endif
6756}
6757
6758/* edit list atom */
6760{
6761 MOVStreamContext *sc;
6762 int i, edit_count, version;
6763 int64_t elst_entry_size;
6764
6765 if (c->fc->nb_streams < 1 || c->ignore_editlist)
6766 return 0;
6767 sc = c->fc->streams[c->fc->nb_streams-1]->priv_data;
6768
6769 version = avio_r8(pb); /* version */
6770 avio_rb24(pb); /* flags */
6771 edit_count = avio_rb32(pb); /* entries */
6772 atom.size -= 8;
6773
6774 elst_entry_size = version == 1 ? 20 : 12;
6775 if (atom.size != edit_count * elst_entry_size) {
6776 if (c->fc->strict_std_compliance >= FF_COMPLIANCE_STRICT) {
6777 av_log(c->fc, AV_LOG_ERROR, "Invalid edit list entry_count: %d for elst atom of size: %"PRId64" bytes.\n",
6778 edit_count, atom.size + 8);
6779 return AVERROR_INVALIDDATA;
6780 } else {
6781 edit_count = atom.size / elst_entry_size;
6782 if (edit_count * elst_entry_size != atom.size) {
6783 av_log(c->fc, AV_LOG_WARNING, "ELST atom of %"PRId64" bytes, bigger than %d entries.\n", atom.size, edit_count);
6784 }
6785 }
6786 }
6787
6788 if (!edit_count)
6789 return 0;
6790 if (sc->elst_data)
6791 av_log(c->fc, AV_LOG_WARNING, "Duplicated ELST atom\n");
6792 av_free(sc->elst_data);
6793 sc->elst_count = 0;
6794 sc->elst_data = av_malloc_array(edit_count, sizeof(*sc->elst_data));
6795 if (!sc->elst_data)
6796 return AVERROR(ENOMEM);
6797
6798 av_log(c->fc, AV_LOG_TRACE, "track[%u].edit_count = %i\n", c->fc->nb_streams - 1, edit_count);
6799 for (i = 0; i < edit_count && atom.size > 0 && !pb->eof_reached; i++) {
6800 MOVElst *e = &sc->elst_data[i];
6801
6802 if (version == 1) {
6803 e->duration = avio_rb64(pb);
6804 e->time = avio_rb64(pb);
6805 atom.size -= 16;
6806 } else {
6807 e->duration = avio_rb32(pb); /* segment duration */
6808 e->time = (int32_t)avio_rb32(pb); /* media time */
6809 atom.size -= 8;
6810 }
6811 e->rate = avio_rb32(pb) / 65536.0;
6812 atom.size -= 4;
6813 av_log(c->fc, AV_LOG_TRACE, "duration=%"PRId64" time=%"PRId64" rate=%f\n",
6814 e->duration, e->time, e->rate);
6815
6816 if (e->time < 0 && e->time != -1 &&
6817 c->fc->strict_std_compliance >= FF_COMPLIANCE_STRICT) {
6818 av_log(c->fc, AV_LOG_ERROR, "Track %d, edit %d: Invalid edit list media time=%"PRId64"\n",
6819 c->fc->nb_streams-1, i, e->time);
6820 return AVERROR_INVALIDDATA;
6821 }
6822 if (e->duration < 0) {
6823 av_log(c->fc, AV_LOG_ERROR, "Track %d, edit %d: Invalid edit list duration=%"PRId64"\n",
6824 c->fc->nb_streams-1, i, e->duration);
6825 return AVERROR_INVALIDDATA;
6826 }
6827 }
6828 sc->elst_count = i;
6829
6830 return 0;
6831}
6832
6834{
6835 MOVStreamContext *sc;
6836 int err;
6837
6838 if (c->fc->nb_streams < 1)
6839 return AVERROR_INVALIDDATA;
6840 sc = c->fc->streams[c->fc->nb_streams - 1]->priv_data;
6841
6842 if (atom.size % sizeof(uint32_t))
6843 return AVERROR_INVALIDDATA;
6844
6845 MovTref *tag = mov_add_tref_tag(sc, atom.type);
6846 if (!tag)
6847 return AVERROR(ENOMEM);
6848
6849 int nb_timecode_track = atom.size >> 2;
6850 for (int i = 0; i < nb_timecode_track; i++) {
6851 if (avio_feof(pb))
6852 return AVERROR_INVALIDDATA;
6853 err = mov_add_tref_id(tag, avio_rb32(pb));
6854 if (err < 0)
6855 return err;
6856 }
6857
6858 return 0;
6859}
6860
6862{
6863 AVStream *st;
6864 int version, color_range, color_primaries, color_trc, color_space;
6865
6866 if (c->fc->nb_streams < 1)
6867 return 0;
6868 st = c->fc->streams[c->fc->nb_streams - 1];
6869
6870 if (atom.size < 5) {
6871 av_log(c->fc, AV_LOG_ERROR, "Empty VP Codec Configuration box\n");
6872 return AVERROR_INVALIDDATA;
6873 }
6874
6875 version = avio_r8(pb);
6876 if (version != 1) {
6877 av_log(c->fc, AV_LOG_WARNING, "Unsupported VP Codec Configuration box version %d\n", version);
6878 return 0;
6879 }
6880 avio_skip(pb, 3); /* flags */
6881
6882 avio_skip(pb, 2); /* profile + level */
6883 color_range = avio_r8(pb); /* bitDepth, chromaSubsampling, videoFullRangeFlag */
6885 color_trc = avio_r8(pb);
6886 color_space = avio_r8(pb);
6887 if (avio_rb16(pb)) /* codecIntializationDataSize */
6888 return AVERROR_INVALIDDATA;
6889
6892 if (!av_color_transfer_name(color_trc))
6893 color_trc = AVCOL_TRC_UNSPECIFIED;
6894 if (!av_color_space_name(color_space))
6895 color_space = AVCOL_SPC_UNSPECIFIED;
6896
6899 st->codecpar->color_trc = color_trc;
6900 st->codecpar->color_space = color_space;
6901
6902 return 0;
6903}
6904
6906{
6907 MOVStreamContext *sc;
6908 int i, version;
6909
6910 if (c->fc->nb_streams < 1)
6911 return AVERROR_INVALIDDATA;
6912
6913 sc = c->fc->streams[c->fc->nb_streams - 1]->priv_data;
6914
6915 if (atom.size < 5) {
6916 av_log(c->fc, AV_LOG_ERROR, "Empty Mastering Display Metadata box\n");
6917 return AVERROR_INVALIDDATA;
6918 }
6919
6920 version = avio_r8(pb);
6921 if (version) {
6922 av_log(c->fc, AV_LOG_WARNING, "Unsupported Mastering Display Metadata box version %d\n", version);
6923 return 0;
6924 }
6925 if (sc->mastering) {
6926 av_log(c->fc, AV_LOG_WARNING, "Ignoring duplicate Mastering Display Metadata\n");
6927 return 0;
6928 }
6929
6930 avio_skip(pb, 3); /* flags */
6931
6933 if (!sc->mastering)
6934 return AVERROR(ENOMEM);
6935
6936 for (i = 0; i < 3; i++) {
6937 sc->mastering->display_primaries[i][0] = av_make_q(avio_rb16(pb), 1 << 16);
6938 sc->mastering->display_primaries[i][1] = av_make_q(avio_rb16(pb), 1 << 16);
6939 }
6940 sc->mastering->white_point[0] = av_make_q(avio_rb16(pb), 1 << 16);
6941 sc->mastering->white_point[1] = av_make_q(avio_rb16(pb), 1 << 16);
6942
6943 sc->mastering->max_luminance = av_make_q(avio_rb32(pb), 1 << 8);
6944 sc->mastering->min_luminance = av_make_q(avio_rb32(pb), 1 << 14);
6945
6946 sc->mastering->has_primaries = 1;
6947 sc->mastering->has_luminance = 1;
6948
6949 return 0;
6950}
6951
6953{
6954 MOVStreamContext *sc;
6955 const int mapping[3] = {1, 2, 0};
6956 const int chroma_den = 50000;
6957 const int luma_den = 10000;
6958 int i;
6959
6960 if (c->fc->nb_streams < 1)
6961 return AVERROR_INVALIDDATA;
6962
6963 sc = c->fc->streams[c->fc->nb_streams - 1]->priv_data;
6964
6965 if (atom.size < 24) {
6966 av_log(c->fc, AV_LOG_ERROR, "Invalid Mastering Display Color Volume box\n");
6967 return AVERROR_INVALIDDATA;
6968 }
6969
6970 if (sc->mastering) {
6971 av_log(c->fc, AV_LOG_WARNING, "Ignoring duplicate Mastering Display Color Volume\n");
6972 return 0;
6973 }
6974
6976 if (!sc->mastering)
6977 return AVERROR(ENOMEM);
6978
6979 for (i = 0; i < 3; i++) {
6980 const int j = mapping[i];
6981 sc->mastering->display_primaries[j][0] = av_make_q(avio_rb16(pb), chroma_den);
6982 sc->mastering->display_primaries[j][1] = av_make_q(avio_rb16(pb), chroma_den);
6983 }
6984 sc->mastering->white_point[0] = av_make_q(avio_rb16(pb), chroma_den);
6985 sc->mastering->white_point[1] = av_make_q(avio_rb16(pb), chroma_den);
6986
6987 sc->mastering->max_luminance = av_make_q(avio_rb32(pb), luma_den);
6988 sc->mastering->min_luminance = av_make_q(avio_rb32(pb), luma_den);
6989
6990 sc->mastering->has_luminance = 1;
6991 sc->mastering->has_primaries = 1;
6992
6993 return 0;
6994}
6995
6997{
6998 MOVStreamContext *sc;
6999 int version;
7000
7001 if (c->fc->nb_streams < 1)
7002 return AVERROR_INVALIDDATA;
7003
7004 sc = c->fc->streams[c->fc->nb_streams - 1]->priv_data;
7005
7006 if (atom.size < 5) {
7007 av_log(c->fc, AV_LOG_ERROR, "Empty Content Light Level box\n");
7008 return AVERROR_INVALIDDATA;
7009 }
7010
7011 version = avio_r8(pb);
7012 if (version) {
7013 av_log(c->fc, AV_LOG_WARNING, "Unsupported Content Light Level box version %d\n", version);
7014 return 0;
7015 }
7016 avio_skip(pb, 3); /* flags */
7017
7018 if (sc->coll){
7019 av_log(c->fc, AV_LOG_WARNING, "Ignoring duplicate COLL\n");
7020 return 0;
7021 }
7022
7024 if (!sc->coll)
7025 return AVERROR(ENOMEM);
7026
7027 sc->coll->MaxCLL = avio_rb16(pb);
7028 sc->coll->MaxFALL = avio_rb16(pb);
7029
7030 return 0;
7031}
7032
7034{
7035 MOVStreamContext *sc;
7036
7037 if (c->fc->nb_streams < 1)
7038 return AVERROR_INVALIDDATA;
7039
7040 sc = c->fc->streams[c->fc->nb_streams - 1]->priv_data;
7041
7042 if (atom.size < 4) {
7043 av_log(c->fc, AV_LOG_ERROR, "Empty Content Light Level Info box\n");
7044 return AVERROR_INVALIDDATA;
7045 }
7046
7047 if (sc->coll){
7048 av_log(c->fc, AV_LOG_WARNING, "Ignoring duplicate CLLI/COLL\n");
7049 return 0;
7050 }
7051
7053 if (!sc->coll)
7054 return AVERROR(ENOMEM);
7055
7056 sc->coll->MaxCLL = avio_rb16(pb);
7057 sc->coll->MaxFALL = avio_rb16(pb);
7058
7059 return 0;
7060}
7061
7063{
7064 MOVStreamContext *sc;
7065 const int illuminance_den = 10000;
7066 const int ambient_den = 50000;
7067 if (c->fc->nb_streams < 1)
7068 return AVERROR_INVALIDDATA;
7069 sc = c->fc->streams[c->fc->nb_streams - 1]->priv_data;
7070 if (atom.size < 6) {
7071 av_log(c->fc, AV_LOG_ERROR, "Empty Ambient Viewing Environment Info box\n");
7072 return AVERROR_INVALIDDATA;
7073 }
7074 if (sc->ambient){
7075 av_log(c->fc, AV_LOG_WARNING, "Ignoring duplicate AMVE\n");
7076 return 0;
7077 }
7079 if (!sc->ambient)
7080 return AVERROR(ENOMEM);
7081 sc->ambient->ambient_illuminance = av_make_q(avio_rb32(pb), illuminance_den);
7082 sc->ambient->ambient_light_x = av_make_q(avio_rb16(pb), ambient_den);
7083 sc->ambient->ambient_light_y = av_make_q(avio_rb16(pb), ambient_den);
7084 return 0;
7085}
7086
7088{
7089 AVStream *st;
7090 MOVStreamContext *sc;
7091 enum AVStereo3DType type;
7092 int mode;
7093
7094 if (c->fc->nb_streams < 1)
7095 return 0;
7096
7097 st = c->fc->streams[c->fc->nb_streams - 1];
7098 sc = st->priv_data;
7099
7100 if (atom.size < 5) {
7101 av_log(c->fc, AV_LOG_ERROR, "Empty stereoscopic video box\n");
7102 return AVERROR_INVALIDDATA;
7103 }
7104
7105 if (sc->stereo3d)
7106 return AVERROR_INVALIDDATA;
7107
7108 avio_skip(pb, 4); /* version + flags */
7109
7110 mode = avio_r8(pb);
7111 switch (mode) {
7112 case 0:
7114 break;
7115 case 1:
7117 break;
7118 case 2:
7120 break;
7121 default:
7122 av_log(c->fc, AV_LOG_WARNING, "Unknown st3d mode value %d\n", mode);
7123 return 0;
7124 }
7125
7127 if (!sc->stereo3d)
7128 return AVERROR(ENOMEM);
7129
7130 sc->stereo3d->type = type;
7131 return 0;
7132}
7133
7135{
7136 AVStream *st;
7137 MOVStreamContext *sc;
7138 int size = 0;
7139 int64_t remaining;
7140 uint32_t tag = 0;
7142
7143 if (c->fc->nb_streams < 1)
7144 return 0;
7145
7146 st = c->fc->streams[c->fc->nb_streams - 1];
7147 sc = st->priv_data;
7148
7149 remaining = atom.size;
7150 while (remaining > 0) {
7151 size = avio_rb32(pb);
7152 if (size < 8 || size > remaining ) {
7153 av_log(c->fc, AV_LOG_ERROR, "Invalid child size in pack box\n");
7154 return AVERROR_INVALIDDATA;
7155 }
7156
7157 tag = avio_rl32(pb);
7158 switch (tag) {
7159 case MKTAG('p','k','i','n'): {
7160 if (size != 16) {
7161 av_log(c->fc, AV_LOG_ERROR, "Invalid size of pkin box: %d\n", size);
7162 return AVERROR_INVALIDDATA;
7163 }
7164 avio_skip(pb, 1); // version
7165 avio_skip(pb, 3); // flags
7166
7167 tag = avio_rl32(pb);
7168 switch (tag) {
7169 case MKTAG('s','i','d','e'):
7171 break;
7172 case MKTAG('o','v','e','r'):
7174 break;
7175 case 0:
7176 // This means value will be set in another layer
7177 break;
7178 default:
7179 av_log(c->fc, AV_LOG_WARNING, "Unknown tag in pkin: %s\n",
7181 avio_skip(pb, size - 8);
7182 break;
7183 }
7184
7185 break;
7186 }
7187 default:
7188 av_log(c->fc, AV_LOG_WARNING, "Unknown tag in pack: %s\n",
7190 avio_skip(pb, size - 8);
7191 break;
7192 }
7193 remaining -= size;
7194 }
7195
7196 if (remaining != 0) {
7197 av_log(c->fc, AV_LOG_ERROR, "Broken pack box\n");
7198 return AVERROR_INVALIDDATA;
7199 }
7200
7201 if (type == AV_STEREO3D_2D)
7202 return 0;
7203
7204 if (!sc->stereo3d) {
7206 if (!sc->stereo3d)
7207 return AVERROR(ENOMEM);
7208 }
7209
7210 sc->stereo3d->type = type;
7211
7212 return 0;
7213}
7214
7216{
7217 AVStream *st;
7218 MOVStreamContext *sc;
7219 int size, version, layout;
7220 int32_t yaw, pitch, roll;
7221 uint32_t l = 0, t = 0, r = 0, b = 0;
7222 uint32_t tag, padding = 0;
7223 enum AVSphericalProjection projection;
7224
7225 if (c->fc->nb_streams < 1)
7226 return 0;
7227
7228 st = c->fc->streams[c->fc->nb_streams - 1];
7229 sc = st->priv_data;
7230
7231 if (atom.size < 8) {
7232 av_log(c->fc, AV_LOG_ERROR, "Empty spherical video box\n");
7233 return AVERROR_INVALIDDATA;
7234 }
7235
7236 size = avio_rb32(pb);
7237 if (size <= 12 || size > atom.size)
7238 return AVERROR_INVALIDDATA;
7239
7240 tag = avio_rl32(pb);
7241 if (tag != MKTAG('s','v','h','d')) {
7242 av_log(c->fc, AV_LOG_ERROR, "Missing spherical video header\n");
7243 return 0;
7244 }
7245 version = avio_r8(pb);
7246 if (version != 0) {
7247 av_log(c->fc, AV_LOG_WARNING, "Unknown spherical version %d\n",
7248 version);
7249 return 0;
7250 }
7251 avio_skip(pb, 3); /* flags */
7252 avio_skip(pb, size - 12); /* metadata_source */
7253
7254 size = avio_rb32(pb);
7255 if (size > atom.size)
7256 return AVERROR_INVALIDDATA;
7257
7258 tag = avio_rl32(pb);
7259 if (tag != MKTAG('p','r','o','j')) {
7260 av_log(c->fc, AV_LOG_ERROR, "Missing projection box\n");
7261 return 0;
7262 }
7263
7264 size = avio_rb32(pb);
7265 if (size > atom.size)
7266 return AVERROR_INVALIDDATA;
7267
7268 tag = avio_rl32(pb);
7269 if (tag != MKTAG('p','r','h','d')) {
7270 av_log(c->fc, AV_LOG_ERROR, "Missing projection header box\n");
7271 return 0;
7272 }
7273 version = avio_r8(pb);
7274 if (version != 0) {
7275 av_log(c->fc, AV_LOG_WARNING, "Unknown spherical version %d\n",
7276 version);
7277 return 0;
7278 }
7279 avio_skip(pb, 3); /* flags */
7280
7281 /* 16.16 fixed point */
7282 yaw = avio_rb32(pb);
7283 pitch = avio_rb32(pb);
7284 roll = avio_rb32(pb);
7285
7286 size = avio_rb32(pb);
7287 if (size > atom.size)
7288 return AVERROR_INVALIDDATA;
7289
7290 tag = avio_rl32(pb);
7291 version = avio_r8(pb);
7292 if (version != 0) {
7293 av_log(c->fc, AV_LOG_WARNING, "Unknown spherical version %d\n",
7294 version);
7295 return 0;
7296 }
7297 avio_skip(pb, 3); /* flags */
7298 switch (tag) {
7299 case MKTAG('c','b','m','p'):
7300 layout = avio_rb32(pb);
7301 if (layout) {
7302 av_log(c->fc, AV_LOG_WARNING,
7303 "Unsupported cubemap layout %d\n", layout);
7304 return 0;
7305 }
7306 projection = AV_SPHERICAL_CUBEMAP;
7307 padding = avio_rb32(pb);
7308 break;
7309 case MKTAG('e','q','u','i'):
7310 t = avio_rb32(pb);
7311 b = avio_rb32(pb);
7312 l = avio_rb32(pb);
7313 r = avio_rb32(pb);
7314
7315 if (b >= UINT_MAX - t || r >= UINT_MAX - l) {
7316 av_log(c->fc, AV_LOG_ERROR,
7317 "Invalid bounding rectangle coordinates "
7318 "%"PRIu32",%"PRIu32",%"PRIu32",%"PRIu32"\n", l, t, r, b);
7319 return AVERROR_INVALIDDATA;
7320 }
7321
7322 if (l || t || r || b)
7324 else
7325 projection = AV_SPHERICAL_EQUIRECTANGULAR;
7326 break;
7327 default:
7328 av_log(c->fc, AV_LOG_ERROR, "Unknown projection type: %s\n", av_fourcc2str(tag));
7329 return 0;
7330 }
7331
7333 if (!sc->spherical)
7334 return AVERROR(ENOMEM);
7335
7336 sc->spherical->projection = projection;
7337
7338 sc->spherical->yaw = yaw;
7339 sc->spherical->pitch = pitch;
7340 sc->spherical->roll = roll;
7341
7342 sc->spherical->padding = padding;
7343
7344 sc->spherical->bound_left = l;
7345 sc->spherical->bound_top = t;
7346 sc->spherical->bound_right = r;
7347 sc->spherical->bound_bottom = b;
7348
7349 return 0;
7350}
7351
7353{
7354 AVStream *st;
7355 MOVStreamContext *sc;
7356 int size;
7357 uint32_t tag;
7358 enum AVSphericalProjection projection;
7359
7360 if (c->fc->nb_streams < 1)
7361 return 0;
7362
7363 st = c->fc->streams[c->fc->nb_streams - 1];
7364 sc = st->priv_data;
7365
7366 if (atom.size < 16) {
7367 av_log(c->fc, AV_LOG_ERROR, "Invalid size for proj box: %"PRIu64"\n", atom.size);
7368 return AVERROR_INVALIDDATA;
7369 }
7370
7371 size = avio_rb32(pb);
7372 if (size < 16) {
7373 av_log(c->fc, AV_LOG_ERROR, "Invalid size for prji box: %d\n", size);
7374 return AVERROR_INVALIDDATA;
7375 } else if (size > 16) {
7376 av_log(c->fc, AV_LOG_WARNING, "Box has more bytes (%d) than prji box required (16) \n", size);
7377 }
7378
7379 tag = avio_rl32(pb);
7380 if (tag != MKTAG('p','r','j','i')) {
7381 av_log(c->fc, AV_LOG_ERROR, "Invalid child box of proj box: %s\n",
7383 return AVERROR_INVALIDDATA;
7384 }
7385
7386 // version and flags, only support (0, 0)
7387 unsigned n = avio_rl32(pb);
7388 if (n != 0) {
7389 av_log(c->fc, AV_LOG_ERROR, "prji version %u, flag %u are not supported\n",
7390 n & 0xFF, n >> 8);
7391 return AVERROR_PATCHWELCOME;
7392 }
7393
7394 tag = avio_rl32(pb);
7395 switch (tag) {
7396 case MKTAG('r','e','c','t'):
7397 projection = AV_SPHERICAL_RECTILINEAR;
7398 break;
7399 case MKTAG('e','q','u','i'):
7400 projection = AV_SPHERICAL_EQUIRECTANGULAR;
7401 break;
7402 case MKTAG('h','e','q','u'):
7404 break;
7405 case MKTAG('f','i','s','h'):
7406 projection = AV_SPHERICAL_FISHEYE;
7407 break;
7408 case MKTAG('p','r','i','m'):
7410 break;
7411 default:
7412 av_log(c->fc, AV_LOG_ERROR, "Invalid projection type in prji box: %s\n", av_fourcc2str(tag));
7413 return AVERROR_INVALIDDATA;
7414 }
7415
7417 if (!sc->spherical)
7418 return AVERROR(ENOMEM);
7419
7420 sc->spherical->projection = projection;
7421
7422 return 0;
7423}
7424
7426{
7427 AVStream *st;
7428 MOVStreamContext *sc;
7429 int size, flags = 0;
7430 int64_t remaining;
7431 uint32_t tag, baseline = 0;
7434 enum AVStereo3DPrimaryEye primary_eye = AV_PRIMARY_EYE_NONE;
7435 AVRational horizontal_disparity_adjustment = { 0, 1 };
7436
7437 if (c->fc->nb_streams < 1)
7438 return 0;
7439
7440 st = c->fc->streams[c->fc->nb_streams - 1];
7441 sc = st->priv_data;
7442
7443 remaining = atom.size;
7444 while (remaining > 0) {
7445 size = avio_rb32(pb);
7446 if (size < 8 || size > remaining ) {
7447 av_log(c->fc, AV_LOG_ERROR, "Invalid child size in eyes box\n");
7448 return AVERROR_INVALIDDATA;
7449 }
7450
7451 tag = avio_rl32(pb);
7452 switch (tag) {
7453 case MKTAG('s','t','r','i'): {
7454 int has_right, has_left;
7455 uint8_t tmp;
7456 if (size != 13) {
7457 av_log(c->fc, AV_LOG_ERROR, "Invalid size of stri box: %d\n", size);
7458 return AVERROR_INVALIDDATA;
7459 }
7460 avio_skip(pb, 1); // version
7461 avio_skip(pb, 3); // flags
7462
7463 tmp = avio_r8(pb);
7464
7465 // eye_views_reversed
7466 if (tmp & 8) {
7468 }
7469 // has_additional_views
7470 if (tmp & 4) {
7471 // skip...
7472 }
7473
7474 has_right = tmp & 2; // has_right_eye_view
7475 has_left = tmp & 1; // has_left_eye_view
7476
7477 if (has_left && has_right)
7479 else if (has_left)
7480 view = AV_STEREO3D_VIEW_LEFT;
7481 else if (has_right)
7483 if (has_left || has_right)
7485
7486 break;
7487 }
7488 case MKTAG('h','e','r','o'): {
7489 int tmp;
7490 if (size != 13) {
7491 av_log(c->fc, AV_LOG_ERROR, "Invalid size of hero box: %d\n", size);
7492 return AVERROR_INVALIDDATA;
7493 }
7494 avio_skip(pb, 1); // version
7495 avio_skip(pb, 3); // flags
7496
7497 tmp = avio_r8(pb);
7498 if (tmp == 0)
7499 primary_eye = AV_PRIMARY_EYE_NONE;
7500 else if (tmp == 1)
7501 primary_eye = AV_PRIMARY_EYE_LEFT;
7502 else if (tmp == 2)
7503 primary_eye = AV_PRIMARY_EYE_RIGHT;
7504 else
7505 av_log(c->fc, AV_LOG_WARNING, "Unknown hero eye type: %d\n", tmp);
7506
7507 break;
7508 }
7509 case MKTAG('c','a','m','s'): {
7510 uint32_t subtag;
7511 int subsize;
7512 if (size != 24) {
7513 av_log(c->fc, AV_LOG_ERROR, "Invalid size of cams box: %d\n", size);
7514 return AVERROR_INVALIDDATA;
7515 }
7516
7517 subsize = avio_rb32(pb);
7518 if (subsize != 16) {
7519 av_log(c->fc, AV_LOG_ERROR, "Invalid size of blin box: %d\n", size);
7520 return AVERROR_INVALIDDATA;
7521 }
7522
7523 subtag = avio_rl32(pb);
7524 if (subtag != MKTAG('b','l','i','n')) {
7525 av_log(c->fc, AV_LOG_ERROR, "Expected blin box, got %s\n",
7526 av_fourcc2str(subtag));
7527 return AVERROR_INVALIDDATA;
7528 }
7529
7530 avio_skip(pb, 1); // version
7531 avio_skip(pb, 3); // flags
7532
7533 baseline = avio_rb32(pb);
7534
7535 break;
7536 }
7537 case MKTAG('c','m','f','y'): {
7538 uint32_t subtag;
7539 int subsize;
7540 int32_t adjustment;
7541 if (size != 24) {
7542 av_log(c->fc, AV_LOG_ERROR, "Invalid size of cmfy box: %d\n", size);
7543 return AVERROR_INVALIDDATA;
7544 }
7545
7546 subsize = avio_rb32(pb);
7547 if (subsize != 16) {
7548 av_log(c->fc, AV_LOG_ERROR, "Invalid size of dadj box: %d\n", size);
7549 return AVERROR_INVALIDDATA;
7550 }
7551
7552 subtag = avio_rl32(pb);
7553 if (subtag != MKTAG('d','a','d','j')) {
7554 av_log(c->fc, AV_LOG_ERROR, "Expected dadj box, got %s\n",
7555 av_fourcc2str(subtag));
7556 return AVERROR_INVALIDDATA;
7557 }
7558
7559 avio_skip(pb, 1); // version
7560 avio_skip(pb, 3); // flags
7561
7562 adjustment = (int32_t) avio_rb32(pb);
7563
7564 horizontal_disparity_adjustment.num = (int) adjustment;
7565 horizontal_disparity_adjustment.den = 10000;
7566
7567 break;
7568 }
7569 default:
7570 av_log(c->fc, AV_LOG_WARNING, "Unknown tag in eyes: %s\n",
7572 avio_skip(pb, size - 8);
7573 break;
7574 }
7575 remaining -= size;
7576 }
7577
7578 if (remaining != 0) {
7579 av_log(c->fc, AV_LOG_ERROR, "Broken eyes box\n");
7580 return AVERROR_INVALIDDATA;
7581 }
7582
7583 if (type == AV_STEREO3D_2D)
7584 return 0;
7585
7586 if (!sc->stereo3d) {
7588 if (!sc->stereo3d)
7589 return AVERROR(ENOMEM);
7590 }
7591
7592 sc->stereo3d->flags = flags;
7593 /* eyes/stri only records packed vs single-eye, not SBS/TB. Keep a more
7594 * specific type already set by st3d. */
7595 if (type != AV_STEREO3D_UNSPEC)
7596 sc->stereo3d->type = type;
7597 else if (sc->stereo3d->type == AV_STEREO3D_2D)
7598 sc->stereo3d->type = type;
7599 sc->stereo3d->view = view;
7600 sc->stereo3d->primary_eye = primary_eye;
7601 sc->stereo3d->baseline = baseline;
7602 sc->stereo3d->horizontal_disparity_adjustment = horizontal_disparity_adjustment;
7603
7604 return 0;
7605}
7606
7608{
7609 int size;
7610 int64_t remaining;
7611 uint32_t tag;
7612
7613 if (c->fc->nb_streams < 1)
7614 return 0;
7615
7616 if (atom.size < 8) {
7617 av_log(c->fc, AV_LOG_ERROR, "Empty video extension usage box\n");
7618 return AVERROR_INVALIDDATA;
7619 }
7620
7621 remaining = atom.size;
7622 while (remaining > 0) {
7623 size = avio_rb32(pb);
7624 if (size < 8 || size > remaining ) {
7625 av_log(c->fc, AV_LOG_ERROR, "Invalid child size in vexu box\n");
7626 return AVERROR_INVALIDDATA;
7627 }
7628
7629 tag = avio_rl32(pb);
7630 switch (tag) {
7631 case MKTAG('p','r','o','j'): {
7632 MOVAtom proj = { tag, size - 8 };
7633 int ret = mov_read_vexu_proj(c, pb, proj);
7634 if (ret < 0)
7635 return ret;
7636 break;
7637 }
7638 case MKTAG('e','y','e','s'): {
7639 MOVAtom eyes = { tag, size - 8 };
7640 int ret = mov_read_eyes(c, pb, eyes);
7641 if (ret < 0)
7642 return ret;
7643 break;
7644 }
7645 case MKTAG('p','a','c','k'): {
7646 MOVAtom pack = { tag, size - 8 };
7647 int ret = mov_read_pack(c, pb, pack);
7648 if (ret < 0)
7649 return ret;
7650 break;
7651 }
7652 default:
7653 av_log(c->fc, AV_LOG_WARNING, "Unknown tag in vexu: %s\n",
7655 avio_skip(pb, size - 8);
7656 break;
7657 }
7658 remaining -= size;
7659 }
7660
7661 if (remaining != 0) {
7662 av_log(c->fc, AV_LOG_ERROR, "Broken vexu box\n");
7663 return AVERROR_INVALIDDATA;
7664 }
7665
7666 return 0;
7667}
7668
7670{
7671 AVStream *st;
7672 MOVStreamContext *sc;
7673
7674 if (c->fc->nb_streams < 1)
7675 return 0;
7676
7677 st = c->fc->streams[c->fc->nb_streams - 1];
7678 sc = st->priv_data;
7679
7680 if (atom.size != 4) {
7681 av_log(c->fc, AV_LOG_ERROR, "Invalid size of hfov box: %"PRIu64"\n", atom.size);
7682 return AVERROR_INVALIDDATA;
7683 }
7684
7685
7686 if (!sc->stereo3d) {
7688 if (!sc->stereo3d)
7689 return AVERROR(ENOMEM);
7690 }
7691
7693 sc->stereo3d->horizontal_field_of_view.den = 1000; // thousands of a degree
7694
7695 return 0;
7696}
7697
7699{
7700 int ret = 0;
7701 uint8_t *buffer = av_malloc(len + 1);
7702 const char *val;
7703
7704 if (!buffer)
7705 return AVERROR(ENOMEM);
7706 buffer[len] = '\0';
7707
7708 ret = ffio_read_size(pb, buffer, len);
7709 if (ret < 0)
7710 goto out;
7711
7712 /* Check for mandatory keys and values, try to support XML as best-effort */
7713 if (!sc->spherical &&
7714 av_stristr(buffer, "<GSpherical:StitchingSoftware>") &&
7715 (val = av_stristr(buffer, "<GSpherical:Spherical>")) &&
7716 av_stristr(val, "true") &&
7717 (val = av_stristr(buffer, "<GSpherical:Stitched>")) &&
7718 av_stristr(val, "true") &&
7719 (val = av_stristr(buffer, "<GSpherical:ProjectionType>")) &&
7720 av_stristr(val, "equirectangular")) {
7722 if (!sc->spherical)
7723 goto out;
7724
7726
7727 if (av_stristr(buffer, "<GSpherical:StereoMode>") && !sc->stereo3d) {
7728 enum AVStereo3DType mode;
7729
7730 if (av_stristr(buffer, "left-right"))
7732 else if (av_stristr(buffer, "top-bottom"))
7734 else
7736
7738 if (!sc->stereo3d)
7739 goto out;
7740
7741 sc->stereo3d->type = mode;
7742 }
7743
7744 /* orientation */
7745 val = av_stristr(buffer, "<GSpherical:InitialViewHeadingDegrees>");
7746 if (val)
7747 sc->spherical->yaw = strtol(val, NULL, 10) * (1 << 16);
7748 val = av_stristr(buffer, "<GSpherical:InitialViewPitchDegrees>");
7749 if (val)
7750 sc->spherical->pitch = strtol(val, NULL, 10) * (1 << 16);
7751 val = av_stristr(buffer, "<GSpherical:InitialViewRollDegrees>");
7752 if (val)
7753 sc->spherical->roll = strtol(val, NULL, 10) * (1 << 16);
7754 }
7755
7756out:
7757 av_free(buffer);
7758 return ret;
7759}
7760
7762{
7763 AVStream *st;
7764 MOVStreamContext *sc;
7765 int64_t ret;
7766 AVUUID uuid;
7767 static const AVUUID uuid_isml_manifest = {
7768 0xa5, 0xd4, 0x0b, 0x30, 0xe8, 0x14, 0x11, 0xdd,
7769 0xba, 0x2f, 0x08, 0x00, 0x20, 0x0c, 0x9a, 0x66
7770 };
7771 static const AVUUID uuid_xmp = {
7772 0xbe, 0x7a, 0xcf, 0xcb, 0x97, 0xa9, 0x42, 0xe8,
7773 0x9c, 0x71, 0x99, 0x94, 0x91, 0xe3, 0xaf, 0xac
7774 };
7775 static const AVUUID uuid_spherical = {
7776 0xff, 0xcc, 0x82, 0x63, 0xf8, 0x55, 0x4a, 0x93,
7777 0x88, 0x14, 0x58, 0x7a, 0x02, 0x52, 0x1f, 0xdd,
7778 };
7779
7780 if (atom.size < AV_UUID_LEN || atom.size >= FFMIN(INT_MAX, SIZE_MAX))
7781 return AVERROR_INVALIDDATA;
7782
7783 if (c->fc->nb_streams < 1)
7784 return 0;
7785 st = c->fc->streams[c->fc->nb_streams - 1];
7786 sc = st->priv_data;
7787
7788 ret = ffio_read_size(pb, uuid, AV_UUID_LEN);
7789 if (ret < 0)
7790 return ret;
7791 if (av_uuid_equal(uuid, uuid_isml_manifest)) {
7792 uint8_t *buffer, *ptr;
7793 char *endptr;
7794 size_t len = atom.size - AV_UUID_LEN;
7795
7796 if (len < 4) {
7797 return AVERROR_INVALIDDATA;
7798 }
7799 ret = avio_skip(pb, 4); // zeroes
7800 len -= 4;
7801
7802 buffer = av_mallocz(len + 1);
7803 if (!buffer) {
7804 return AVERROR(ENOMEM);
7805 }
7806 ret = ffio_read_size(pb, buffer, len);
7807 if (ret < 0) {
7808 av_free(buffer);
7809 return ret;
7810 }
7811
7812 ptr = buffer;
7813 while ((ptr = av_stristr(ptr, "systemBitrate=\""))) {
7814 ptr += sizeof("systemBitrate=\"") - 1;
7815 c->bitrates_count++;
7816 c->bitrates = av_realloc_f(c->bitrates, c->bitrates_count, sizeof(*c->bitrates));
7817 if (!c->bitrates) {
7818 c->bitrates_count = 0;
7819 av_free(buffer);
7820 return AVERROR(ENOMEM);
7821 }
7822 errno = 0;
7823 ret = strtol(ptr, &endptr, 10);
7824 if (ret < 0 || errno || *endptr != '"') {
7825 c->bitrates[c->bitrates_count - 1] = 0;
7826 } else {
7827 c->bitrates[c->bitrates_count - 1] = ret;
7828 }
7829 }
7830
7831 av_free(buffer);
7832 } else if (av_uuid_equal(uuid, uuid_xmp)) {
7833 uint8_t *buffer;
7834 size_t len = atom.size - AV_UUID_LEN;
7835 if (c->export_xmp) {
7836 buffer = av_mallocz(len + 1);
7837 if (!buffer) {
7838 return AVERROR(ENOMEM);
7839 }
7840 ret = ffio_read_size(pb, buffer, len);
7841 if (ret < 0) {
7842 av_free(buffer);
7843 return ret;
7844 }
7845 buffer[len] = '\0';
7846 av_dict_set(&c->fc->metadata, "xmp",
7848 } else {
7849 // skip all uuid atom, which makes it fast for long uuid-xmp file
7850 ret = avio_skip(pb, len);
7851 if (ret < 0)
7852 return ret;
7853 }
7854 } else if (av_uuid_equal(uuid, uuid_spherical)) {
7855 size_t len = atom.size - AV_UUID_LEN;
7856 ret = mov_parse_uuid_spherical(sc, pb, len);
7857 if (ret < 0)
7858 return ret;
7859 if (!sc->spherical)
7860 av_log(c->fc, AV_LOG_WARNING, "Invalid spherical metadata found\n");
7861 }
7862
7863 return 0;
7864}
7865
7867{
7868 int ret;
7869 uint8_t content[16];
7870
7871 if (atom.size < 8)
7872 return 0;
7873
7874 ret = ffio_read_size(pb, content, FFMIN(sizeof(content), atom.size));
7875 if (ret < 0)
7876 return ret;
7877
7878 if ( !c->found_moov
7879 && !c->found_mdat
7880 && !memcmp(content, "Anevia\x1A\x1A", 8)
7881 && c->use_mfra_for == FF_MOV_FLAG_MFRA_AUTO) {
7882 c->use_mfra_for = FF_MOV_FLAG_MFRA_PTS;
7883 }
7884
7885 return 0;
7886}
7887
7889{
7890 uint32_t format = avio_rl32(pb);
7891 MOVStreamContext *sc;
7892 enum AVCodecID id;
7893 AVStream *st;
7894
7895 if (c->fc->nb_streams < 1)
7896 return 0;
7897 st = c->fc->streams[c->fc->nb_streams - 1];
7898 sc = st->priv_data;
7899
7900 switch (sc->format)
7901 {
7902 case MKTAG('e','n','c','v'): // encrypted video
7903 case MKTAG('e','n','c','a'): // encrypted audio
7904 id = mov_codec_id(st, format);
7905 if (st->codecpar->codec_id != AV_CODEC_ID_NONE &&
7906 st->codecpar->codec_id != id) {
7907 av_log(c->fc, AV_LOG_WARNING,
7908 "ignoring 'frma' atom of '%.4s', stream has codec id %d\n",
7909 (char*)&format, st->codecpar->codec_id);
7910 break;
7911 }
7912
7913 st->codecpar->codec_id = id;
7914 sc->format = format;
7915 break;
7916
7917 default:
7918 if (format != sc->format) {
7919 av_log(c->fc, AV_LOG_WARNING,
7920 "ignoring 'frma' atom of '%.4s', stream format is '%.4s'\n",
7921 (char*)&format, (char*)&sc->format);
7922 }
7923 break;
7924 }
7925
7926 return 0;
7927}
7928
7929/**
7930 * Gets the current encryption info and associated current stream context. If
7931 * we are parsing a track fragment, this will return the specific encryption
7932 * info for this fragment; otherwise this will return the global encryption
7933 * info for the current stream.
7934 */
7936{
7937 MOVFragmentStreamInfo *frag_stream_info;
7938 AVStream *st;
7939 int i;
7940
7941 frag_stream_info = get_current_frag_stream_info(&c->frag_index);
7942 if (frag_stream_info) {
7943 for (i = 0; i < c->fc->nb_streams; i++) {
7944 *sc = c->fc->streams[i]->priv_data;
7945 if ((*sc)->id == frag_stream_info->id) {
7946 st = c->fc->streams[i];
7947 break;
7948 }
7949 }
7950 if (i == c->fc->nb_streams)
7951 return 0;
7952 *sc = st->priv_data;
7953
7954 if (!frag_stream_info->encryption_index) {
7955 // If this stream isn't encrypted, don't create the index.
7956 if (!(*sc)->cenc.default_encrypted_sample)
7957 return 0;
7958 frag_stream_info->encryption_index = av_mallocz(sizeof(*frag_stream_info->encryption_index));
7959 if (!frag_stream_info->encryption_index)
7960 return AVERROR(ENOMEM);
7961 }
7962 *encryption_index = frag_stream_info->encryption_index;
7963 return 1;
7964 } else {
7965 // No current track fragment, using stream level encryption info.
7966
7967 if (c->fc->nb_streams < 1)
7968 return 0;
7969 st = c->fc->streams[c->fc->nb_streams - 1];
7970 *sc = st->priv_data;
7971
7972 if (!(*sc)->cenc.encryption_index) {
7973 // If this stream isn't encrypted, don't create the index.
7974 if (!(*sc)->cenc.default_encrypted_sample)
7975 return 0;
7976 (*sc)->cenc.encryption_index = av_mallocz(sizeof(*frag_stream_info->encryption_index));
7977 if (!(*sc)->cenc.encryption_index)
7978 return AVERROR(ENOMEM);
7979 }
7980
7981 *encryption_index = (*sc)->cenc.encryption_index;
7982 return 1;
7983 }
7984}
7985
7987{
7988 int i, ret;
7989 unsigned int subsample_count;
7990 AVSubsampleEncryptionInfo *subsamples;
7991
7992 if (!sc->cenc.default_encrypted_sample) {
7993 av_log(c->fc, AV_LOG_ERROR, "Missing schm or tenc\n");
7994 return AVERROR_INVALIDDATA;
7995 }
7996
7997 if (sc->cenc.per_sample_iv_size || use_subsamples) {
7999 if (!*sample)
8000 return AVERROR(ENOMEM);
8001 } else
8002 *sample = NULL;
8003
8004 if (sc->cenc.per_sample_iv_size != 0) {
8005 if ((ret = ffio_read_size(pb, (*sample)->iv, sc->cenc.per_sample_iv_size)) < 0) {
8006 av_log(c->fc, AV_LOG_ERROR, "failed to read the initialization vector\n");
8008 *sample = NULL;
8009 return ret;
8010 }
8011 }
8012
8013 if (use_subsamples) {
8014 subsample_count = avio_rb16(pb);
8015 av_free((*sample)->subsamples);
8016 (*sample)->subsamples = av_calloc(subsample_count, sizeof(*subsamples));
8017 if (!(*sample)->subsamples) {
8019 *sample = NULL;
8020 return AVERROR(ENOMEM);
8021 }
8022
8023 for (i = 0; i < subsample_count && !pb->eof_reached; i++) {
8024 (*sample)->subsamples[i].bytes_of_clear_data = avio_rb16(pb);
8025 (*sample)->subsamples[i].bytes_of_protected_data = avio_rb32(pb);
8026 }
8027
8028 if (pb->eof_reached) {
8029 av_log(c->fc, AV_LOG_ERROR, "hit EOF while reading sub-sample encryption info\n");
8031 *sample = NULL;
8032 return AVERROR_INVALIDDATA;
8033 }
8034 (*sample)->subsample_count = subsample_count;
8035 }
8036
8037 return 0;
8038}
8039
8041{
8042 AVEncryptionInfo **encrypted_samples;
8043 MOVEncryptionIndex *encryption_index;
8044 MOVStreamContext *sc;
8045 int use_subsamples, ret;
8046 unsigned int sample_count, i, alloc_size = 0;
8047
8048 ret = get_current_encryption_info(c, &encryption_index, &sc);
8049 if (ret != 1)
8050 return ret;
8051
8052 if (encryption_index->nb_encrypted_samples) {
8053 // This can happen if we have both saio/saiz and senc atoms.
8054 av_log(c->fc, AV_LOG_DEBUG, "Ignoring duplicate encryption info in senc\n");
8055 return 0;
8056 }
8057
8058 avio_r8(pb); /* version */
8059 use_subsamples = avio_rb24(pb) & 0x02; /* flags */
8060
8061 sample_count = avio_rb32(pb);
8062 if (sample_count >= INT_MAX / sizeof(*encrypted_samples))
8063 return AVERROR(ENOMEM);
8064
8065 for (i = 0; i < sample_count; i++) {
8066 unsigned int min_samples = FFMIN(FFMAX(i + 1, 1024 * 1024), sample_count);
8067 encrypted_samples = av_fast_realloc(encryption_index->encrypted_samples, &alloc_size,
8068 min_samples * sizeof(*encrypted_samples));
8069 if (encrypted_samples) {
8070 encryption_index->encrypted_samples = encrypted_samples;
8071
8073 c, pb, sc, &encryption_index->encrypted_samples[i], use_subsamples);
8074 } else {
8075 ret = AVERROR(ENOMEM);
8076 }
8077 if (pb->eof_reached) {
8078 av_log(c->fc, AV_LOG_ERROR, "Hit EOF while reading senc\n");
8079 if (ret >= 0)
8080 av_encryption_info_free(encryption_index->encrypted_samples[i]);
8081 ret = AVERROR_INVALIDDATA;
8082 }
8083
8084 if (ret < 0) {
8085 for (; i > 0; i--)
8086 av_encryption_info_free(encryption_index->encrypted_samples[i - 1]);
8087 av_freep(&encryption_index->encrypted_samples);
8088 return ret;
8089 }
8090 }
8091 encryption_index->nb_encrypted_samples = sample_count;
8092
8093 return 0;
8094}
8095
8097{
8098 AVEncryptionInfo **sample, **encrypted_samples;
8099 int64_t prev_pos;
8100 size_t sample_count, sample_info_size, i;
8101 int ret = 0;
8102 unsigned int alloc_size = 0;
8103
8104 if (encryption_index->nb_encrypted_samples)
8105 return 0;
8106 sample_count = encryption_index->auxiliary_info_sample_count;
8107 if (encryption_index->auxiliary_offsets_count != 1) {
8108 av_log(c->fc, AV_LOG_ERROR, "Multiple auxiliary info chunks are not supported\n");
8109 return AVERROR_PATCHWELCOME;
8110 }
8111 if (sample_count >= INT_MAX / sizeof(*encrypted_samples))
8112 return AVERROR(ENOMEM);
8113
8114 prev_pos = avio_tell(pb);
8115 if (!(pb->seekable & AVIO_SEEKABLE_NORMAL) ||
8116 avio_seek(pb, encryption_index->auxiliary_offsets[0], SEEK_SET) != encryption_index->auxiliary_offsets[0]) {
8117 av_log(c->fc, AV_LOG_INFO, "Failed to seek for auxiliary info, will only parse senc atoms for encryption info\n");
8118 goto finish;
8119 }
8120
8121 for (i = 0; i < sample_count && !pb->eof_reached; i++) {
8122 unsigned int min_samples = FFMIN(FFMAX(i + 1, 1024 * 1024), sample_count);
8123 encrypted_samples = av_fast_realloc(encryption_index->encrypted_samples, &alloc_size,
8124 min_samples * sizeof(*encrypted_samples));
8125 if (!encrypted_samples) {
8126 ret = AVERROR(ENOMEM);
8127 goto finish;
8128 }
8129 encryption_index->encrypted_samples = encrypted_samples;
8130
8131 sample = &encryption_index->encrypted_samples[i];
8132 sample_info_size = encryption_index->auxiliary_info_default_size
8133 ? encryption_index->auxiliary_info_default_size
8134 : encryption_index->auxiliary_info_sizes[i];
8135
8136 ret = mov_read_sample_encryption_info(c, pb, sc, sample, sample_info_size > sc->cenc.per_sample_iv_size);
8137 if (ret < 0)
8138 goto finish;
8139 }
8140 if (pb->eof_reached) {
8141 av_log(c->fc, AV_LOG_ERROR, "Hit EOF while reading auxiliary info\n");
8142 ret = AVERROR_INVALIDDATA;
8143 } else {
8144 encryption_index->nb_encrypted_samples = sample_count;
8145 }
8146
8147finish:
8148 avio_seek(pb, prev_pos, SEEK_SET);
8149 if (ret < 0) {
8150 for (; i > 0; i--) {
8151 av_encryption_info_free(encryption_index->encrypted_samples[i - 1]);
8152 }
8153 av_freep(&encryption_index->encrypted_samples);
8154 }
8155 return ret;
8156}
8157
8159{
8160 MOVEncryptionIndex *encryption_index;
8161 MOVStreamContext *sc;
8162 int ret;
8163 unsigned int sample_count, aux_info_type, aux_info_param;
8164
8165 ret = get_current_encryption_info(c, &encryption_index, &sc);
8166 if (ret != 1)
8167 return ret;
8168
8169 if (encryption_index->nb_encrypted_samples) {
8170 // This can happen if we have both saio/saiz and senc atoms.
8171 av_log(c->fc, AV_LOG_DEBUG, "Ignoring duplicate encryption info in saiz\n");
8172 return 0;
8173 }
8174
8175 if (encryption_index->auxiliary_info_sample_count) {
8176 av_log(c->fc, AV_LOG_ERROR, "Duplicate saiz atom\n");
8177 return AVERROR_INVALIDDATA;
8178 }
8179
8180 avio_r8(pb); /* version */
8181 if (avio_rb24(pb) & 0x01) { /* flags */
8182 aux_info_type = avio_rb32(pb);
8183 aux_info_param = avio_rb32(pb);
8185 if (aux_info_type != sc->cenc.default_encrypted_sample->scheme) {
8186 av_log(c->fc, AV_LOG_DEBUG, "Ignoring saiz box with non-zero aux_info_type\n");
8187 return 0;
8188 }
8189 if (aux_info_param != 0) {
8190 av_log(c->fc, AV_LOG_DEBUG, "Ignoring saiz box with non-zero aux_info_type_parameter\n");
8191 return 0;
8192 }
8193 } else {
8194 // Didn't see 'schm' or 'tenc', so this isn't encrypted.
8195 if ((aux_info_type == MKBETAG('c','e','n','c') ||
8196 aux_info_type == MKBETAG('c','e','n','s') ||
8197 aux_info_type == MKBETAG('c','b','c','1') ||
8198 aux_info_type == MKBETAG('c','b','c','s')) &&
8199 aux_info_param == 0) {
8200 av_log(c->fc, AV_LOG_ERROR, "Saw encrypted saiz without schm/tenc\n");
8201 return AVERROR_INVALIDDATA;
8202 } else {
8203 return 0;
8204 }
8205 }
8206 } else if (!sc->cenc.default_encrypted_sample) {
8207 // Didn't see 'schm' or 'tenc', so this isn't encrypted.
8208 return 0;
8209 }
8210
8211 encryption_index->auxiliary_info_default_size = avio_r8(pb);
8212 sample_count = avio_rb32(pb);
8213
8214 if (encryption_index->auxiliary_info_default_size == 0) {
8215 if (sample_count == 0)
8216 return AVERROR_INVALIDDATA;
8217
8218 encryption_index->auxiliary_info_sizes = av_malloc(sample_count);
8219 if (!encryption_index->auxiliary_info_sizes)
8220 return AVERROR(ENOMEM);
8221
8222 ret = avio_read(pb, encryption_index->auxiliary_info_sizes, sample_count);
8223 if (ret != sample_count) {
8224 av_freep(&encryption_index->auxiliary_info_sizes);
8225
8226 if (ret >= 0)
8227 ret = AVERROR_INVALIDDATA;
8228 av_log(c->fc, AV_LOG_ERROR, "Failed to read the auxiliary info, %s\n",
8229 av_err2str(ret));
8230 return ret;
8231 }
8232 }
8233 encryption_index->auxiliary_info_sample_count = sample_count;
8234
8235 if (encryption_index->auxiliary_offsets_count) {
8236 return mov_parse_auxiliary_info(c, sc, pb, encryption_index);
8237 }
8238
8239 return 0;
8240}
8241
8243{
8244 uint64_t *auxiliary_offsets;
8245 MOVEncryptionIndex *encryption_index;
8246 MOVStreamContext *sc;
8247 int i, ret;
8248 unsigned int version, entry_count, aux_info_type, aux_info_param;
8249 unsigned int alloc_size = 0;
8250
8251 ret = get_current_encryption_info(c, &encryption_index, &sc);
8252 if (ret != 1)
8253 return ret;
8254
8255 if (encryption_index->nb_encrypted_samples) {
8256 // This can happen if we have both saio/saiz and senc atoms.
8257 av_log(c->fc, AV_LOG_DEBUG, "Ignoring duplicate encryption info in saio\n");
8258 return 0;
8259 }
8260
8261 if (encryption_index->auxiliary_offsets_count) {
8262 av_log(c->fc, AV_LOG_ERROR, "Duplicate saio atom\n");
8263 return AVERROR_INVALIDDATA;
8264 }
8265
8266 version = avio_r8(pb); /* version */
8267 if (avio_rb24(pb) & 0x01) { /* flags */
8268 aux_info_type = avio_rb32(pb);
8269 aux_info_param = avio_rb32(pb);
8271 if (aux_info_type != sc->cenc.default_encrypted_sample->scheme) {
8272 av_log(c->fc, AV_LOG_DEBUG, "Ignoring saio box with non-zero aux_info_type\n");
8273 return 0;
8274 }
8275 if (aux_info_param != 0) {
8276 av_log(c->fc, AV_LOG_DEBUG, "Ignoring saio box with non-zero aux_info_type_parameter\n");
8277 return 0;
8278 }
8279 } else {
8280 // Didn't see 'schm' or 'tenc', so this isn't encrypted.
8281 if ((aux_info_type == MKBETAG('c','e','n','c') ||
8282 aux_info_type == MKBETAG('c','e','n','s') ||
8283 aux_info_type == MKBETAG('c','b','c','1') ||
8284 aux_info_type == MKBETAG('c','b','c','s')) &&
8285 aux_info_param == 0) {
8286 av_log(c->fc, AV_LOG_ERROR, "Saw encrypted saio without schm/tenc\n");
8287 return AVERROR_INVALIDDATA;
8288 } else {
8289 return 0;
8290 }
8291 }
8292 } else if (!sc->cenc.default_encrypted_sample) {
8293 // Didn't see 'schm' or 'tenc', so this isn't encrypted.
8294 return 0;
8295 }
8296
8297 entry_count = avio_rb32(pb);
8298 if (entry_count >= INT_MAX / sizeof(*auxiliary_offsets))
8299 return AVERROR(ENOMEM);
8300
8301 for (i = 0; i < entry_count && !pb->eof_reached; i++) {
8302 unsigned int min_offsets = FFMIN(FFMAX(i + 1, 1024), entry_count);
8303 auxiliary_offsets = av_fast_realloc(
8304 encryption_index->auxiliary_offsets, &alloc_size,
8305 min_offsets * sizeof(*auxiliary_offsets));
8306 if (!auxiliary_offsets) {
8307 av_freep(&encryption_index->auxiliary_offsets);
8308 return AVERROR(ENOMEM);
8309 }
8310 encryption_index->auxiliary_offsets = auxiliary_offsets;
8311
8312 if (version == 0) {
8313 encryption_index->auxiliary_offsets[i] = avio_rb32(pb);
8314 } else {
8315 encryption_index->auxiliary_offsets[i] = avio_rb64(pb);
8316 }
8317 if (c->frag_index.current >= 0) {
8318 encryption_index->auxiliary_offsets[i] += c->fragment.base_data_offset;
8319 }
8320 }
8321
8322 if (pb->eof_reached) {
8323 av_log(c->fc, AV_LOG_ERROR, "Hit EOF while reading saio\n");
8324 av_freep(&encryption_index->auxiliary_offsets);
8325 return AVERROR_INVALIDDATA;
8326 }
8327
8328 encryption_index->auxiliary_offsets_count = entry_count;
8329
8330 if (encryption_index->auxiliary_info_sample_count) {
8331 return mov_parse_auxiliary_info(c, sc, pb, encryption_index);
8332 }
8333
8334 return 0;
8335}
8336
8338{
8339 AVEncryptionInitInfo *info, *old_init_info;
8340 uint8_t **key_ids;
8341 AVStream *st;
8342 const AVPacketSideData *old_side_data;
8343 uint8_t *side_data, *extra_data;
8344 size_t side_data_size;
8345 int ret = 0;
8346 unsigned int version, kid_count, extra_data_size, alloc_size = 0;
8347
8348 if (c->fc->nb_streams < 1)
8349 return 0;
8350 st = c->fc->streams[c->fc->nb_streams-1];
8351
8352 version = avio_r8(pb); /* version */
8353 avio_rb24(pb); /* flags */
8354
8355 info = av_encryption_init_info_alloc(/* system_id_size */ 16, /* num_key_ids */ 0,
8356 /* key_id_size */ 16, /* data_size */ 0);
8357 if (!info)
8358 return AVERROR(ENOMEM);
8359
8360 if ((ret = ffio_read_size(pb, info->system_id, 16)) < 0) {
8361 av_log(c->fc, AV_LOG_ERROR, "Failed to read the system id\n");
8362 goto finish;
8363 }
8364
8365 if (version > 0) {
8366 kid_count = avio_rb32(pb);
8367 if (kid_count >= INT_MAX / sizeof(*key_ids)) {
8368 ret = AVERROR(ENOMEM);
8369 goto finish;
8370 }
8371
8372 for (unsigned int i = 0; i < kid_count && !pb->eof_reached; i++) {
8373 unsigned int min_kid_count = FFMIN(FFMAX(i + 1, 1024), kid_count);
8374 key_ids = av_fast_realloc(info->key_ids, &alloc_size,
8375 min_kid_count * sizeof(*key_ids));
8376 if (!key_ids) {
8377 ret = AVERROR(ENOMEM);
8378 goto finish;
8379 }
8380 info->key_ids = key_ids;
8381
8382 info->key_ids[i] = av_mallocz(16);
8383 if (!info->key_ids[i]) {
8384 ret = AVERROR(ENOMEM);
8385 goto finish;
8386 }
8387 info->num_key_ids = i + 1;
8388
8389 if ((ret = ffio_read_size(pb, info->key_ids[i], 16)) < 0) {
8390 av_log(c->fc, AV_LOG_ERROR, "Failed to read the key id\n");
8391 goto finish;
8392 }
8393 }
8394
8395 if (pb->eof_reached) {
8396 av_log(c->fc, AV_LOG_ERROR, "Hit EOF while reading pssh\n");
8397 ret = AVERROR_INVALIDDATA;
8398 goto finish;
8399 }
8400 }
8401
8402 extra_data_size = avio_rb32(pb);
8403 extra_data = av_malloc(extra_data_size);
8404 if (!extra_data) {
8405 ret = AVERROR(ENOMEM);
8406 goto finish;
8407 }
8408 ret = avio_read(pb, extra_data, extra_data_size);
8409 if (ret != extra_data_size) {
8410 av_free(extra_data);
8411
8412 if (ret >= 0)
8413 ret = AVERROR_INVALIDDATA;
8414 goto finish;
8415 }
8416
8417 av_freep(&info->data); // malloc(0) may still allocate something.
8418 info->data = extra_data;
8419 info->data_size = extra_data_size;
8420
8421 // If there is existing initialization data, append to the list.
8424 if (old_side_data) {
8425 old_init_info = av_encryption_init_info_get_side_data(old_side_data->data, old_side_data->size);
8426 if (old_init_info) {
8427 // Append to the end of the list.
8428 for (AVEncryptionInitInfo *cur = old_init_info;; cur = cur->next) {
8429 if (!cur->next) {
8430 cur->next = info;
8431 break;
8432 }
8433 }
8434 info = old_init_info;
8435 } else {
8436 // Assume existing side-data will be valid, so the only error we could get is OOM.
8437 ret = AVERROR(ENOMEM);
8438 goto finish;
8439 }
8440 }
8441
8442 side_data = av_encryption_init_info_add_side_data(info, &side_data_size);
8443 if (!side_data) {
8444 ret = AVERROR(ENOMEM);
8445 goto finish;
8446 }
8450 side_data, side_data_size, 0))
8451 av_free(side_data);
8452
8453finish:
8455 return ret;
8456}
8457
8459{
8460 AVStream *st;
8461 MOVStreamContext *sc;
8462
8463 if (c->fc->nb_streams < 1)
8464 return 0;
8465 st = c->fc->streams[c->fc->nb_streams-1];
8466 sc = st->priv_data;
8467
8468 if (sc->pseudo_stream_id != 0) {
8469 av_log(c->fc, AV_LOG_ERROR, "schm boxes are only supported in first sample descriptor\n");
8470 return AVERROR_PATCHWELCOME;
8471 }
8472
8473 if (atom.size < 8)
8474 return AVERROR_INVALIDDATA;
8475
8476 avio_rb32(pb); /* version and flags */
8477
8478 if (!sc->cenc.default_encrypted_sample) {
8480 if (!sc->cenc.default_encrypted_sample) {
8481 return AVERROR(ENOMEM);
8482 }
8483 }
8484
8486 return 0;
8487}
8488
8490{
8491 AVStream *st;
8492 MOVStreamContext *sc;
8493 unsigned int version, pattern, is_protected, iv_size;
8494
8495 if (c->fc->nb_streams < 1)
8496 return 0;
8497 st = c->fc->streams[c->fc->nb_streams-1];
8498 sc = st->priv_data;
8499
8500 if (sc->pseudo_stream_id != 0) {
8501 av_log(c->fc, AV_LOG_ERROR, "tenc atom are only supported in first sample descriptor\n");
8502 return AVERROR_PATCHWELCOME;
8503 }
8504
8505 if (!sc->cenc.default_encrypted_sample) {
8507 if (!sc->cenc.default_encrypted_sample) {
8508 return AVERROR(ENOMEM);
8509 }
8510 }
8511
8512 if (atom.size < 20)
8513 return AVERROR_INVALIDDATA;
8514
8515 version = avio_r8(pb); /* version */
8516 avio_rb24(pb); /* flags */
8517
8518 avio_r8(pb); /* reserved */
8519 pattern = avio_r8(pb);
8520
8521 if (version > 0) {
8523 sc->cenc.default_encrypted_sample->skip_byte_block = pattern & 0xf;
8524 }
8525
8526 is_protected = avio_r8(pb);
8527 if (is_protected && !sc->cenc.encryption_index) {
8528 // The whole stream should be by-default encrypted.
8530 if (!sc->cenc.encryption_index)
8531 return AVERROR(ENOMEM);
8532 }
8533 iv_size = avio_r8(pb);
8534 if (iv_size != 0 && iv_size != 8 && iv_size != 16) {
8535 av_log(c->fc, AV_LOG_ERROR, "invalid per-sample IV size value\n");
8536 return AVERROR_INVALIDDATA;
8537 }
8538 sc->cenc.per_sample_iv_size = iv_size;
8539 if (avio_read(pb, sc->cenc.default_encrypted_sample->key_id, 16) != 16) {
8540 av_log(c->fc, AV_LOG_ERROR, "failed to read the default key ID\n");
8541 return AVERROR_INVALIDDATA;
8542 }
8543
8544 if (is_protected && !sc->cenc.per_sample_iv_size) {
8545 iv_size = avio_r8(pb);
8546 if (iv_size != 8 && iv_size != 16) {
8547 av_log(c->fc, AV_LOG_ERROR, "invalid default_constant_IV_size in tenc atom\n");
8548 return AVERROR_INVALIDDATA;
8549 }
8550
8551 if (avio_read(pb, sc->cenc.default_encrypted_sample->iv, iv_size) != iv_size) {
8552 av_log(c->fc, AV_LOG_ERROR, "failed to read the default IV\n");
8553 return AVERROR_INVALIDDATA;
8554 }
8555 }
8556
8557 return 0;
8558}
8559
8561{
8562 AVStream *st;
8563 int last, type, size, ret;
8564 uint8_t buf[4];
8565
8566 if (c->fc->nb_streams < 1)
8567 return 0;
8568 st = c->fc->streams[c->fc->nb_streams-1];
8569
8570 if ((uint64_t)atom.size > (1<<30) || atom.size < 42)
8571 return AVERROR_INVALIDDATA;
8572
8573 /* Check FlacSpecificBox version. */
8574 if (avio_r8(pb) != 0)
8575 return AVERROR_INVALIDDATA;
8576
8577 avio_rb24(pb); /* Flags */
8578
8579 if (avio_read(pb, buf, sizeof(buf)) != sizeof(buf)) {
8580 av_log(c->fc, AV_LOG_ERROR, "failed to read FLAC metadata block header\n");
8581 return pb->error < 0 ? pb->error : AVERROR_INVALIDDATA;
8582 }
8583 flac_parse_block_header(buf, &last, &type, &size);
8584
8586 av_log(c->fc, AV_LOG_ERROR, "STREAMINFO must be first FLACMetadataBlock\n");
8587 return AVERROR_INVALIDDATA;
8588 }
8589
8590 ret = ff_get_extradata(c->fc, st->codecpar, pb, size);
8591 if (ret < 0)
8592 return ret;
8593
8594 if (!last)
8595 av_log(c->fc, AV_LOG_WARNING, "non-STREAMINFO FLACMetadataBlock(s) ignored\n");
8596
8597 return 0;
8598}
8599
8601 AVDictionaryEntry *key_entry_hex;
8602 char kid_hex[16*2+1];
8603
8604 if (c->decryption_default_key && c->decryption_default_key_len != len) {
8605 av_log(c->fc, AV_LOG_ERROR, "invalid default decryption key length: got %d, expected %d\n", c->decryption_default_key_len, len);
8606 return -1;
8607 }
8608
8609 if (!c->decryption_keys) {
8610 av_assert0(c->decryption_default_key);
8611 memcpy(out, c->decryption_default_key, len);
8612 return 0;
8613 }
8614
8615 if (sample->key_id_size != 16) {
8616 av_log(c->fc, AV_LOG_ERROR, "invalid key ID size: got %u, expected 16\n", sample->key_id_size);
8617 return -1;
8618 }
8619
8620 ff_data_to_hex(kid_hex, sample->key_id, 16, 1);
8621 key_entry_hex = av_dict_get(c->decryption_keys, kid_hex, NULL, AV_DICT_DONT_STRDUP_KEY|AV_DICT_DONT_STRDUP_VAL);
8622 if (!key_entry_hex) {
8623 if (!c->decryption_default_key) {
8624 av_log(c->fc, AV_LOG_ERROR, "unable to find KID %s\n", kid_hex);
8625 return -1;
8626 }
8627 memcpy(out, c->decryption_default_key, len);
8628 return 0;
8629 }
8630 if (strlen(key_entry_hex->value) != len*2) {
8631 return -1;
8632 }
8633 ff_hex_to_data(out, key_entry_hex->value);
8634 return 0;
8635}
8636
8638{
8639 int i, ret;
8640 int bytes_of_protected_data;
8641 uint8_t decryption_key[AES_CTR_KEY_SIZE];
8642
8643 if (!sc->cenc.aes_ctr) {
8644 ret = get_key_from_kid(decryption_key, sizeof(decryption_key), c, sample);
8645 if (ret < 0) {
8646 return ret;
8647 }
8648
8649 /* initialize the cipher */
8651 if (!sc->cenc.aes_ctr) {
8652 return AVERROR(ENOMEM);
8653 }
8654
8655 ret = av_aes_ctr_init(sc->cenc.aes_ctr, decryption_key);
8656 if (ret < 0) {
8657 return ret;
8658 }
8659 }
8660
8662
8663 if (!sample->subsample_count) {
8664 /* decrypt the whole packet */
8665 av_aes_ctr_crypt(sc->cenc.aes_ctr, input, input, size);
8666 return 0;
8667 }
8668
8669 for (i = 0; i < sample->subsample_count; i++) {
8670 if (sample->subsamples[i].bytes_of_clear_data + (int64_t)sample->subsamples[i].bytes_of_protected_data > size) {
8671 av_log(c->fc, AV_LOG_ERROR, "subsample size exceeds the packet size left\n");
8672 return AVERROR_INVALIDDATA;
8673 }
8674
8675 /* skip the clear bytes */
8676 input += sample->subsamples[i].bytes_of_clear_data;
8677 size -= sample->subsamples[i].bytes_of_clear_data;
8678
8679 /* decrypt the encrypted bytes */
8680
8681 bytes_of_protected_data = sample->subsamples[i].bytes_of_protected_data;
8682 av_aes_ctr_crypt(sc->cenc.aes_ctr, input, input, bytes_of_protected_data);
8683
8684 input += bytes_of_protected_data;
8685 size -= bytes_of_protected_data;
8686 }
8687
8688 if (size > 0) {
8689 av_log(c->fc, AV_LOG_ERROR, "leftover packet bytes after subsample processing\n");
8690 return AVERROR_INVALIDDATA;
8691 }
8692
8693 return 0;
8694}
8695
8697{
8698 int i, ret;
8699 int num_of_encrypted_blocks;
8700 uint8_t iv[16];
8701 uint8_t decryption_key[16];
8702
8703 if (!sc->cenc.aes_ctx) {
8704 ret = get_key_from_kid(decryption_key, sizeof(decryption_key), c, sample);
8705 if (ret < 0) {
8706 return ret;
8707 }
8708
8709 /* initialize the cipher */
8710 sc->cenc.aes_ctx = av_aes_alloc();
8711 if (!sc->cenc.aes_ctx) {
8712 return AVERROR(ENOMEM);
8713 }
8714
8715 ret = av_aes_init(sc->cenc.aes_ctx, decryption_key, 16 * 8, 1);
8716 if (ret < 0) {
8717 return ret;
8718 }
8719 }
8720
8721 memcpy(iv, sample->iv, 16);
8722
8723 /* whole-block full sample encryption */
8724 if (!sample->subsample_count) {
8725 /* decrypt the whole packet */
8726 av_aes_crypt(sc->cenc.aes_ctx, input, input, size/16, iv, 1);
8727 return 0;
8728 }
8729
8730 for (i = 0; i < sample->subsample_count; i++) {
8731 if (sample->subsamples[i].bytes_of_clear_data + (int64_t)sample->subsamples[i].bytes_of_protected_data > size) {
8732 av_log(c->fc, AV_LOG_ERROR, "subsample size exceeds the packet size left\n");
8733 return AVERROR_INVALIDDATA;
8734 }
8735
8736 if (sample->subsamples[i].bytes_of_protected_data % 16) {
8737 av_log(c->fc, AV_LOG_ERROR, "subsample BytesOfProtectedData is not a multiple of 16\n");
8738 return AVERROR_INVALIDDATA;
8739 }
8740
8741 /* skip the clear bytes */
8742 input += sample->subsamples[i].bytes_of_clear_data;
8743 size -= sample->subsamples[i].bytes_of_clear_data;
8744
8745 /* decrypt the encrypted bytes */
8746 num_of_encrypted_blocks = sample->subsamples[i].bytes_of_protected_data/16;
8747 if (num_of_encrypted_blocks > 0) {
8748 av_aes_crypt(sc->cenc.aes_ctx, input, input, num_of_encrypted_blocks, iv, 1);
8749 }
8750 input += sample->subsamples[i].bytes_of_protected_data;
8751 size -= sample->subsamples[i].bytes_of_protected_data;
8752 }
8753
8754 if (size > 0) {
8755 av_log(c->fc, AV_LOG_ERROR, "leftover packet bytes after subsample processing\n");
8756 return AVERROR_INVALIDDATA;
8757 }
8758
8759 return 0;
8760}
8761
8763{
8764 int i, ret, rem_bytes;
8765 uint8_t *data;
8766 uint8_t decryption_key[AES_CTR_KEY_SIZE];
8767
8768 if (!sc->cenc.aes_ctr) {
8769 ret = get_key_from_kid(decryption_key, sizeof(decryption_key), c, sample);
8770 if (ret < 0) {
8771 return ret;
8772 }
8773
8774 /* initialize the cipher */
8776 if (!sc->cenc.aes_ctr) {
8777 return AVERROR(ENOMEM);
8778 }
8779
8780 ret = av_aes_ctr_init(sc->cenc.aes_ctr, decryption_key);
8781 if (ret < 0) {
8782 return ret;
8783 }
8784 }
8785
8787
8788 /* whole-block full sample encryption */
8789 if (!sample->subsample_count) {
8790 /* decrypt the whole packet */
8791 av_aes_ctr_crypt(sc->cenc.aes_ctr, input, input, size);
8792 return 0;
8793 } else if (!sample->crypt_byte_block && !sample->skip_byte_block) {
8794 av_log(c->fc, AV_LOG_ERROR, "pattern encryption is not present in 'cens' scheme\n");
8795 return AVERROR_INVALIDDATA;
8796 }
8797
8798 for (i = 0; i < sample->subsample_count; i++) {
8799 if (sample->subsamples[i].bytes_of_clear_data + (int64_t)sample->subsamples[i].bytes_of_protected_data > size) {
8800 av_log(c->fc, AV_LOG_ERROR, "subsample size exceeds the packet size left\n");
8801 return AVERROR_INVALIDDATA;
8802 }
8803
8804 /* skip the clear bytes */
8805 input += sample->subsamples[i].bytes_of_clear_data;
8806 size -= sample->subsamples[i].bytes_of_clear_data;
8807
8808 /* decrypt the encrypted bytes */
8809 data = input;
8810 rem_bytes = sample->subsamples[i].bytes_of_protected_data;
8811 while (rem_bytes > 0) {
8812 if (rem_bytes < 16*sample->crypt_byte_block) {
8813 break;
8814 }
8815 av_aes_ctr_crypt(sc->cenc.aes_ctr, data, data, 16*sample->crypt_byte_block);
8816 data += 16*sample->crypt_byte_block;
8817 rem_bytes -= 16*sample->crypt_byte_block;
8818 data += FFMIN(16*sample->skip_byte_block, rem_bytes);
8819 rem_bytes -= FFMIN(16*sample->skip_byte_block, rem_bytes);
8820 }
8821 input += sample->subsamples[i].bytes_of_protected_data;
8822 size -= sample->subsamples[i].bytes_of_protected_data;
8823 }
8824
8825 if (size > 0) {
8826 av_log(c->fc, AV_LOG_ERROR, "leftover packet bytes after subsample processing\n");
8827 return AVERROR_INVALIDDATA;
8828 }
8829
8830 return 0;
8831}
8832
8834{
8835 int i, ret, rem_bytes;
8836 uint8_t iv[16];
8837 uint8_t *data;
8838 uint8_t decryption_key[16];
8839
8840 if (!sc->cenc.aes_ctx) {
8841 ret = get_key_from_kid(decryption_key, sizeof(decryption_key), c, sample);
8842 if (ret < 0) {
8843 return ret;
8844 }
8845
8846 /* initialize the cipher */
8847 sc->cenc.aes_ctx = av_aes_alloc();
8848 if (!sc->cenc.aes_ctx) {
8849 return AVERROR(ENOMEM);
8850 }
8851
8852 ret = av_aes_init(sc->cenc.aes_ctx, decryption_key, 16 * 8, 1);
8853 if (ret < 0) {
8854 return ret;
8855 }
8856 }
8857
8858 /* whole-block full sample encryption */
8859 if (!sample->subsample_count) {
8860 /* decrypt the whole packet */
8861 memcpy(iv, sample->iv, 16);
8862 av_aes_crypt(sc->cenc.aes_ctx, input, input, size/16, iv, 1);
8863 return 0;
8864 } else if (!sample->crypt_byte_block && !sample->skip_byte_block) {
8865 av_log(c->fc, AV_LOG_ERROR, "pattern encryption is not present in 'cbcs' scheme\n");
8866 return AVERROR_INVALIDDATA;
8867 }
8868
8869 for (i = 0; i < sample->subsample_count; i++) {
8870 if (sample->subsamples[i].bytes_of_clear_data + (int64_t)sample->subsamples[i].bytes_of_protected_data > size) {
8871 av_log(c->fc, AV_LOG_ERROR, "subsample size exceeds the packet size left\n");
8872 return AVERROR_INVALIDDATA;
8873 }
8874
8875 /* skip the clear bytes */
8876 input += sample->subsamples[i].bytes_of_clear_data;
8877 size -= sample->subsamples[i].bytes_of_clear_data;
8878
8879 /* decrypt the encrypted bytes */
8880 memcpy(iv, sample->iv, 16);
8881 data = input;
8882 rem_bytes = sample->subsamples[i].bytes_of_protected_data;
8883 while (rem_bytes > 0) {
8884 if (rem_bytes < 16*sample->crypt_byte_block) {
8885 break;
8886 }
8887 av_aes_crypt(sc->cenc.aes_ctx, data, data, sample->crypt_byte_block, iv, 1);
8888 data += 16*sample->crypt_byte_block;
8889 rem_bytes -= 16*sample->crypt_byte_block;
8890 data += FFMIN(16*sample->skip_byte_block, rem_bytes);
8891 rem_bytes -= FFMIN(16*sample->skip_byte_block, rem_bytes);
8892 }
8893 input += sample->subsamples[i].bytes_of_protected_data;
8894 size -= sample->subsamples[i].bytes_of_protected_data;
8895 }
8896
8897 if (size > 0) {
8898 av_log(c->fc, AV_LOG_ERROR, "leftover packet bytes after subsample processing\n");
8899 return AVERROR_INVALIDDATA;
8900 }
8901
8902 return 0;
8903}
8904
8905static int cenc_decrypt(MOVContext *c, MOVStreamContext *sc, AVEncryptionInfo *sample, uint8_t *input, int size)
8906{
8907 if (sample->scheme == MKBETAG('c','e','n','c') && !sample->crypt_byte_block && !sample->skip_byte_block) {
8908 return cenc_scheme_decrypt(c, sc, sample, input, size);
8909 } else if (sample->scheme == MKBETAG('c','b','c','1') && !sample->crypt_byte_block && !sample->skip_byte_block) {
8910 return cbc1_scheme_decrypt(c, sc, sample, input, size);
8911 } else if (sample->scheme == MKBETAG('c','e','n','s')) {
8912 return cens_scheme_decrypt(c, sc, sample, input, size);
8913 } else if (sample->scheme == MKBETAG('c','b','c','s')) {
8914 return cbcs_scheme_decrypt(c, sc, sample, input, size);
8915 } else {
8916 av_log(c->fc, AV_LOG_ERROR, "invalid encryption scheme\n");
8917 return AVERROR_INVALIDDATA;
8918 }
8919}
8920
8922{
8923 int current = frag_index->current;
8924
8925 if (!frag_index->nb_items)
8926 return NULL;
8927
8928 // Check frag_index->current is the right one for pkt. It can out of sync.
8929 if (current >= 0 && current < frag_index->nb_items) {
8930 if (frag_index->item[current].moof_offset < pkt->pos &&
8931 (current + 1 == frag_index->nb_items ||
8932 frag_index->item[current + 1].moof_offset > pkt->pos))
8933 return get_frag_stream_info(frag_index, current, id);
8934 }
8935
8936
8937 for (int i = 0; i < frag_index->nb_items; i++) {
8938 if (frag_index->item[i].moof_offset > pkt->pos)
8939 break;
8940 current = i;
8941 }
8942 frag_index->current = current;
8943 return get_frag_stream_info(frag_index, current, id);
8944}
8945
8946static int cenc_filter(MOVContext *mov, AVStream* st, MOVStreamContext *sc, AVPacket *pkt, int current_index)
8947{
8948 MOVFragmentStreamInfo *frag_stream_info;
8949 MOVEncryptionIndex *encryption_index;
8950 AVEncryptionInfo *encrypted_sample;
8951 int encrypted_index, ret;
8952
8953 frag_stream_info = get_frag_stream_info_from_pkt(&mov->frag_index, pkt, sc->id);
8954 encrypted_index = current_index;
8955 encryption_index = NULL;
8956 if (frag_stream_info) {
8957 // Note this only supports encryption info in the first sample descriptor.
8958 if (frag_stream_info->stsd_id == 1) {
8959 if (frag_stream_info->encryption_index) {
8960 encrypted_index = current_index - frag_stream_info->index_base;
8961 encryption_index = frag_stream_info->encryption_index;
8962 } else {
8963 encryption_index = sc->cenc.encryption_index;
8964 }
8965 }
8966 } else {
8967 encryption_index = sc->cenc.encryption_index;
8968 }
8969
8970 if (encryption_index) {
8971 if (encryption_index->auxiliary_info_sample_count &&
8972 !encryption_index->nb_encrypted_samples) {
8973 av_log(mov->fc, AV_LOG_ERROR, "saiz atom found without saio\n");
8974 return AVERROR_INVALIDDATA;
8975 }
8976 if (encryption_index->auxiliary_offsets_count &&
8977 !encryption_index->nb_encrypted_samples) {
8978 av_log(mov->fc, AV_LOG_ERROR, "saio atom found without saiz\n");
8979 return AVERROR_INVALIDDATA;
8980 }
8981
8982 encrypted_sample = NULL;
8983 if (!encryption_index->nb_encrypted_samples) {
8984 // Full-sample encryption with default settings.
8985 encrypted_sample = sc->cenc.default_encrypted_sample;
8986 } else if (encrypted_index >= 0 && encrypted_index < encryption_index->nb_encrypted_samples) {
8987 // Per-sample setting override.
8988 encrypted_sample = encryption_index->encrypted_samples[encrypted_index];
8989 if (!encrypted_sample) {
8990 encrypted_sample = sc->cenc.default_encrypted_sample;
8991 }
8992 }
8993
8994 if (!encrypted_sample) {
8995 av_log(mov->fc, AV_LOG_ERROR, "Incorrect number of samples in encryption info\n");
8996 return AVERROR_INVALIDDATA;
8997 }
8998
8999 if (mov->decryption_keys || mov->decryption_default_key) {
9000 return cenc_decrypt(mov, sc, encrypted_sample, pkt->data, pkt->size);
9001 } else {
9002 size_t size;
9003 uint8_t *side_data = av_encryption_info_add_side_data(encrypted_sample, &size);
9004 if (!side_data)
9005 return AVERROR(ENOMEM);
9007 if (ret < 0)
9008 av_free(side_data);
9009 return ret;
9010 }
9011 }
9012
9013 return 0;
9014}
9015
9017{
9018 const int OPUS_SEEK_PREROLL_MS = 80;
9019 int ret;
9020 AVStream *st;
9021 size_t size;
9022 uint16_t pre_skip;
9023
9024 if (c->fc->nb_streams < 1)
9025 return 0;
9026 st = c->fc->streams[c->fc->nb_streams-1];
9027
9028 if ((uint64_t)atom.size > (1<<30) || atom.size < 11 || st->codecpar->extradata)
9029 return AVERROR_INVALIDDATA;
9030
9031 /* Check OpusSpecificBox version. */
9032 if (avio_r8(pb) != 0) {
9033 av_log(c->fc, AV_LOG_ERROR, "unsupported OpusSpecificBox version\n");
9034 return AVERROR_INVALIDDATA;
9035 }
9036
9037 /* OpusSpecificBox size plus magic for Ogg OpusHead header. */
9038 size = atom.size + 8;
9039
9040 if ((ret = ff_alloc_extradata(st->codecpar, size)) < 0)
9041 return ret;
9042
9043 AV_WL32A(st->codecpar->extradata, MKTAG('O','p','u','s'));
9044 AV_WL32A(st->codecpar->extradata + 4, MKTAG('H','e','a','d'));
9045 AV_WB8(st->codecpar->extradata + 8, 1); /* OpusHead version */
9046 if ((ret = ffio_read_size(pb, st->codecpar->extradata + 9, size - 9)) < 0) {
9048 st->codecpar->extradata_size = 0;
9049 return ret;
9050 }
9051
9052 /* OpusSpecificBox is stored in big-endian, but OpusHead is
9053 little-endian; aside from the preceding magic and version they're
9054 otherwise currently identical. Data after output gain at offset 16
9055 doesn't need to be bytewapped. */
9056 pre_skip = AV_RB16A(st->codecpar->extradata + 10);
9057 AV_WL16A(st->codecpar->extradata + 10, pre_skip);
9058 AV_WL32A(st->codecpar->extradata + 12, AV_RB32A(st->codecpar->extradata + 12));
9059 AV_WL16A(st->codecpar->extradata + 16, AV_RB16A(st->codecpar->extradata + 16));
9060
9061 st->codecpar->initial_padding = pre_skip;
9063 (AVRational){1, 1000},
9064 (AVRational){1, 48000});
9065
9066 return 0;
9067}
9068
9070{
9071 AVStream *st;
9072 unsigned format_info;
9073 int channel_assignment, channel_assignment1, channel_assignment2;
9074 int ratebits;
9075 uint64_t chmask;
9076
9077 if (c->fc->nb_streams < 1)
9078 return 0;
9079 st = c->fc->streams[c->fc->nb_streams-1];
9080
9081 if (atom.size < 10)
9082 return AVERROR_INVALIDDATA;
9083
9084 format_info = avio_rb32(pb);
9085
9086 ratebits = (format_info >> 28) & 0xF;
9087 channel_assignment1 = (format_info >> 15) & 0x1F;
9088 channel_assignment2 = format_info & 0x1FFF;
9089 if (channel_assignment2)
9090 channel_assignment = channel_assignment2;
9091 else
9092 channel_assignment = channel_assignment1;
9093
9094 st->codecpar->frame_size = 40 << (ratebits & 0x7);
9095 st->codecpar->sample_rate = mlp_samplerate(ratebits);
9096
9098 chmask = truehd_layout(channel_assignment);
9100
9101 return 0;
9102}
9103
9105{
9106 AVStream *st;
9107 uint8_t buf[ISOM_DVCC_DVVC_SIZE];
9108 int ret;
9109 int64_t read_size = atom.size;
9110
9111 if (c->fc->nb_streams < 1)
9112 return 0;
9113 st = c->fc->streams[c->fc->nb_streams-1];
9114
9115 // At most 24 bytes
9116 read_size = FFMIN(read_size, ISOM_DVCC_DVVC_SIZE);
9117
9118 if ((ret = ffio_read_size(pb, buf, read_size)) < 0)
9119 return ret;
9120
9121 return ff_isom_parse_dvcc_dvvc(c->fc, st, buf, read_size);
9122}
9123
9125{
9126 AVStream *st;
9127 AVPacketSideData *sd;
9128 int ret;
9129
9130 if (c->fc->nb_streams < 1)
9131 return 0;
9132 st = c->fc->streams[c->fc->nb_streams - 1];
9133
9134 if (atom.size < 23 || atom.size > INT_MAX - AV_INPUT_BUFFER_PADDING_SIZE)
9135 return AVERROR_INVALIDDATA;
9136
9140 atom.size, 0);
9141 if (!sd)
9142 return AVERROR(ENOMEM);
9143
9144 ret = ffio_read_size(pb, sd->data, atom.size);
9145 if (ret < 0)
9146 return ret;
9147
9148 return 0;
9149}
9150
9152{
9153 AVStream *st;
9154 uint8_t *buf;
9155 int ret, old_size, num_arrays;
9156
9157 if (c->fc->nb_streams < 1)
9158 return 0;
9159 st = c->fc->streams[c->fc->nb_streams-1];
9160
9161 if (!st->codecpar->extradata_size)
9162 // TODO: handle lhvC when present before hvcC
9163 return 0;
9164
9165 if (atom.size < 6 || st->codecpar->extradata_size < 23 ||
9166 atom.size > INT_MAX - AV_INPUT_BUFFER_PADDING_SIZE) {
9167 return AVERROR_INVALIDDATA;
9168 }
9169
9171 if (!buf)
9172 return AVERROR(ENOMEM);
9173 memset(buf + atom.size, 0, AV_INPUT_BUFFER_PADDING_SIZE);
9174
9175 ret = ffio_read_size(pb, buf, atom.size);
9176 if (ret < 0) {
9177 av_free(buf);
9178 av_log(c->fc, AV_LOG_WARNING, "lhvC atom truncated\n");
9179 return 0;
9180 }
9181
9182 num_arrays = buf[5];
9183 old_size = st->codecpar->extradata_size;
9184 atom.size -= 8 /* account for mov_realloc_extradata offsetting */
9185 + 6 /* lhvC bytes before the arrays*/;
9186
9187 ret = mov_realloc_extradata(st->codecpar, atom);
9188 if (ret < 0) {
9189 av_free(buf);
9190 return ret;
9191 }
9192
9193 st->codecpar->extradata[22] += num_arrays;
9194 memcpy(st->codecpar->extradata + old_size, buf + 6, atom.size + 8);
9195
9197
9198 av_free(buf);
9199 return 0;
9200}
9201
9203{
9204 AVFormatContext *ctx = c->fc;
9205 AVStream *st = NULL;
9206 AVBPrint scheme_buf, value_buf;
9207 int64_t scheme_str_len = 0, value_str_len = 0;
9208 int version, flags, ret = AVERROR_BUG;
9209 int64_t size = atom.size;
9210
9211 if (atom.size < 6)
9212 // 4 bytes for version + flags, 2x 1 byte for null
9213 return AVERROR_INVALIDDATA;
9214
9215 if (c->fc->nb_streams < 1)
9216 return 0;
9217 st = c->fc->streams[c->fc->nb_streams-1];
9218
9219 version = avio_r8(pb);
9220 flags = avio_rb24(pb);
9221 size -= 4;
9222
9223 if (version != 0 || flags != 0) {
9225 "Unsupported 'kind' box with version %d, flags: %x",
9226 version, flags);
9227 return AVERROR_INVALIDDATA;
9228 }
9229
9232
9233 if ((scheme_str_len = ff_read_string_to_bprint_overwrite(pb, &scheme_buf,
9234 size)) < 0) {
9235 ret = scheme_str_len;
9236 goto cleanup;
9237 }
9238
9239 if (scheme_str_len + 1 >= size) {
9240 // we need to have another string, even if nullptr.
9241 // we check with + 1 since we expect that if size was not hit,
9242 // an additional null was read.
9243 ret = AVERROR_INVALIDDATA;
9244 goto cleanup;
9245 }
9246
9247 size -= scheme_str_len + 1;
9248
9249 if ((value_str_len = ff_read_string_to_bprint_overwrite(pb, &value_buf,
9250 size)) < 0) {
9251 ret = value_str_len;
9252 goto cleanup;
9253 }
9254
9255 if (value_str_len == size) {
9256 // in case of no trailing null, box is not valid.
9257 ret = AVERROR_INVALIDDATA;
9258 goto cleanup;
9259 }
9260
9262 "%s stream %d KindBox(scheme: %s, value: %s)\n",
9264 st->index,
9265 scheme_buf.str, value_buf.str);
9266
9267 for (int i = 0; ff_mov_track_kind_table[i].scheme_uri; i++) {
9269 if (!av_strstart(scheme_buf.str, map.scheme_uri, NULL))
9270 continue;
9271
9272 for (int j = 0; map.value_maps[j].disposition; j++) {
9273 const struct MP4TrackKindValueMapping value_map = map.value_maps[j];
9274 if (!av_strstart(value_buf.str, value_map.value, NULL))
9275 continue;
9276
9277 st->disposition |= value_map.disposition;
9278 }
9279 }
9280
9281 ret = 0;
9282
9283cleanup:
9284
9285 av_bprint_finalize(&scheme_buf, NULL);
9286 av_bprint_finalize(&value_buf, NULL);
9287
9288 return ret;
9289}
9290
9292{
9293 AVStream *st;
9294 AVChannelLayout ch_layout = { 0 };
9295 int ret, i, version, type;
9296 int ambisonic_order, channel_order, normalization, channel_count;
9297 int ambi_channels, non_diegetic_channels;
9298
9299 if (c->fc->nb_streams < 1)
9300 return 0;
9301
9302 st = c->fc->streams[c->fc->nb_streams - 1];
9303
9304 if (atom.size < 16) {
9305 av_log(c->fc, AV_LOG_ERROR, "SA3D audio box too small\n");
9306 return AVERROR_INVALIDDATA;
9307 }
9308
9309 version = avio_r8(pb);
9310 if (version) {
9311 av_log(c->fc, AV_LOG_WARNING, "Unsupported SA3D box version %d\n", version);
9312 return 0;
9313 }
9314
9315 type = avio_r8(pb);
9316 if (type & 0x7f) {
9317 av_log(c->fc, AV_LOG_WARNING,
9318 "Unsupported ambisonic type %d\n", type & 0x7f);
9319 return 0;
9320 }
9321 non_diegetic_channels = (type >> 7) * 2; // head_locked_stereo
9322
9323 ambisonic_order = avio_rb32(pb);
9324
9325 channel_order = avio_r8(pb);
9326 if (channel_order) {
9327 av_log(c->fc, AV_LOG_WARNING,
9328 "Unsupported channel_order %d\n", channel_order);
9329 return 0;
9330 }
9331
9332 normalization = avio_r8(pb);
9333 if (normalization) {
9334 av_log(c->fc, AV_LOG_WARNING,
9335 "Unsupported normalization %d\n", normalization);
9336 return 0;
9337 }
9338
9339 channel_count = avio_rb32(pb);
9340 if (ambisonic_order < 0 || ambisonic_order > 31 ||
9341 channel_count != ((ambisonic_order + 1LL) * (ambisonic_order + 1LL) +
9342 non_diegetic_channels)) {
9343 av_log(c->fc, AV_LOG_ERROR,
9344 "Invalid number of channels (%d / %d)\n",
9345 channel_count, ambisonic_order);
9346 return 0;
9347 }
9348 ambi_channels = channel_count - non_diegetic_channels;
9349
9350 ret = av_channel_layout_custom_init(&ch_layout, channel_count);
9351 if (ret < 0)
9352 return 0;
9353
9354 for (i = 0; i < channel_count; i++) {
9355 unsigned channel = avio_rb32(pb);
9356
9357 if (channel >= channel_count) {
9358 av_log(c->fc, AV_LOG_ERROR, "Invalid channel index (%d / %d)\n",
9359 channel, ambisonic_order);
9360 av_channel_layout_uninit(&ch_layout);
9361 return 0;
9362 }
9363 if (channel >= ambi_channels)
9364 ch_layout.u.map[i].id = channel - ambi_channels;
9365 else
9366 ch_layout.u.map[i].id = AV_CHAN_AMBISONIC_BASE + channel;
9367 }
9368
9370 if (ret < 0) {
9371 av_channel_layout_uninit(&ch_layout);
9372 return 0;
9373 }
9374
9376 st->codecpar->ch_layout = ch_layout;
9377
9378 return 0;
9379}
9380
9382{
9383 AVStream *st;
9384 int version;
9385
9386 if (c->fc->nb_streams < 1)
9387 return 0;
9388
9389 st = c->fc->streams[c->fc->nb_streams - 1];
9390
9391 if (atom.size < 5) {
9392 av_log(c->fc, AV_LOG_ERROR, "Empty SAND audio box\n");
9393 return AVERROR_INVALIDDATA;
9394 }
9395
9396 version = avio_r8(pb);
9397 if (version) {
9398 av_log(c->fc, AV_LOG_WARNING, "Unsupported SAND box version %d\n", version);
9399 return 0;
9400 }
9401
9403
9404 return 0;
9405}
9406
9407static int rb_size(AVIOContext *pb, int64_t *value, int size)
9408{
9409 if (size == 0)
9410 *value = 0;
9411 else if (size == 1)
9412 *value = avio_r8(pb);
9413 else if (size == 2)
9414 *value = avio_rb16(pb);
9415 else if (size == 4)
9416 *value = avio_rb32(pb);
9417 else if (size == 8) {
9418 *value = avio_rb64(pb);
9419 if (*value < 0)
9420 return -1;
9421 } else
9422 return -1;
9423 return size;
9424}
9425
9427{
9428 AVBPrint aux_type;
9429 HEIFItem *item;
9430
9431 avio_r8(pb); /* version */
9432 avio_rb24(pb); /* flags */
9433
9435 ff_read_string_to_bprint_overwrite(pb, &aux_type, atom.size - 4);
9436
9437 av_log(c->fc, AV_LOG_TRACE, "auxC: item_id %d, aux_type %s\n",
9438 c->cur_item_id, aux_type.str);
9439
9440 item = get_heif_item(c, c->cur_item_id);
9441 if (item && (av_stristr(aux_type.str, "hdrgainmap")))
9442 item->is_gainmap = 1;
9443
9444 return 0;
9445}
9446
9448{
9449 avio_rb32(pb); // version & flags.
9450 c->primary_item_id = avio_rb16(pb);
9451 av_log(c->fc, AV_LOG_TRACE, "pitm: primary_item_id %d\n", c->primary_item_id);
9452 return atom.size;
9453}
9454
9456{
9457 c->idat_offset = avio_tell(pb);
9458 return 0;
9459}
9460
9462{
9463 HEIFItem **heif_item;
9464 int version, offset_size, length_size, base_offset_size, index_size;
9465 int item_count, extent_count;
9466 int64_t base_offset, extent_offset, extent_length;
9467 uint8_t value;
9468
9469 if (c->found_iloc) {
9470 av_log(c->fc, AV_LOG_INFO, "Duplicate iloc box found\n");
9471 return 0;
9472 }
9473
9474 version = avio_r8(pb);
9475 avio_rb24(pb); // flags.
9476
9477 value = avio_r8(pb);
9478 offset_size = (value >> 4) & 0xF;
9479 length_size = value & 0xF;
9480 value = avio_r8(pb);
9481 base_offset_size = (value >> 4) & 0xF;
9482 index_size = !version ? 0 : (value & 0xF);
9483 if (index_size) {
9484 avpriv_report_missing_feature(c->fc, "iloc: index_size != 0");
9485 return AVERROR_PATCHWELCOME;
9486 }
9487 item_count = (version < 2) ? avio_rb16(pb) : avio_rb32(pb);
9488
9489 if (item_count > atom.size)
9490 return AVERROR_INVALIDDATA;
9491
9492 heif_item = av_realloc_array(c->heif_item, FFMAX(item_count, c->nb_heif_item), sizeof(*c->heif_item));
9493 if (!heif_item)
9494 return AVERROR(ENOMEM);
9495 c->heif_item = heif_item;
9496 if (item_count > c->nb_heif_item)
9497 memset(&c->heif_item[c->nb_heif_item], 0,
9498 sizeof(*c->heif_item) * (item_count - c->nb_heif_item));
9499 c->nb_heif_item = FFMAX(c->nb_heif_item, item_count);
9500
9501 av_log(c->fc, AV_LOG_TRACE, "iloc: item_count %d\n", item_count);
9502 for (int i = 0; i < item_count; i++) {
9503 HEIFItem *item = NULL;
9504 int item_id = (version < 2) ? avio_rb16(pb) : avio_rb32(pb);
9505 int offset_type = (version > 0) ? avio_rb16(pb) & 0xf : 0;
9506 int j;
9507
9508 if (avio_feof(pb))
9509 return AVERROR_INVALIDDATA;
9510 if (offset_type > 1) {
9511 avpriv_report_missing_feature(c->fc, "iloc offset type %d", offset_type);
9512 return AVERROR_PATCHWELCOME;
9513 }
9514
9515 avio_rb16(pb); // data_reference_index.
9516 if (rb_size(pb, &base_offset, base_offset_size) < 0)
9517 return AVERROR_INVALIDDATA;
9518 extent_count = avio_rb16(pb);
9519 if (extent_count > 1) {
9520 // For still AVIF images, we only support one extent item.
9521 avpriv_report_missing_feature(c->fc, "iloc: extent_count > 1");
9522 return AVERROR_PATCHWELCOME;
9523 }
9524
9525 if (rb_size(pb, &extent_offset, offset_size) < 0 ||
9526 rb_size(pb, &extent_length, length_size) < 0 ||
9527 base_offset > INT64_MAX - extent_offset)
9528 return AVERROR_INVALIDDATA;
9529
9530 for (j = 0; j < c->nb_heif_item; j++) {
9531 item = c->heif_item[j];
9532 if (!item)
9533 item = c->heif_item[j] = av_mallocz(sizeof(*item));
9534 else if (item->item_id != item_id)
9535 continue;
9536 break;
9537 }
9538 if (!item)
9539 return AVERROR(ENOMEM);
9540 if (j == c->nb_heif_item)
9541 return AVERROR_INVALIDDATA;
9542
9543 item->item_id = item_id;
9544
9545 if (offset_type == 1)
9546 item->is_idat_relative = 1;
9547 item->extent_length = extent_length;
9548 item->extent_offset = base_offset + extent_offset;
9549 av_log(c->fc, AV_LOG_TRACE, "iloc: item_idx %d, item->item_id %d, offset_type %d, "
9550 "extent_offset %"PRId64", extent_length %"PRId64"\n",
9551 i, item->item_id, offset_type, item->extent_offset, item->extent_length);
9552 }
9553
9554 c->found_iloc = 1;
9555 return atom.size;
9556}
9557
9559{
9560 HEIFItem *item = NULL;
9561 AVBPrint item_name;
9562 int64_t size = atom.size;
9563 uint32_t item_type;
9564 int item_id;
9565 int i, version, flags, ret;
9566
9567 version = avio_r8(pb);
9568 flags = avio_rb24(pb);
9569 size -= 4;
9570 if (size < 0)
9571 return AVERROR_INVALIDDATA;
9572
9573 if (version < 2) {
9574 avpriv_report_missing_feature(c->fc, "infe version < 2");
9575 avio_skip(pb, size);
9576 return 1;
9577 }
9578
9579 item_id = version > 2 ? avio_rb32(pb) : avio_rb16(pb);
9580 avio_rb16(pb); // item_protection_index
9581 item_type = avio_rl32(pb);
9582 size -= 8;
9583 if (size < 1)
9584 return AVERROR_INVALIDDATA;
9585
9588 if (ret < 0) {
9590 return ret;
9591 }
9592
9593 av_log(c->fc, AV_LOG_TRACE, "infe: item_id %d, item_type %s, item_name %s\n",
9594 item_id, av_fourcc2str(item_type), item_name.str);
9595
9596 size -= ret + 1;
9597 if (size > 0)
9598 avio_skip(pb, size);
9599
9600 for (i = 0; i < c->nb_heif_item; i++) {
9601 item = c->heif_item[i];
9602 if (!item)
9603 item = c->heif_item[i] = av_mallocz(sizeof(*item));
9604 else if (item->item_id != item_id)
9605 continue;
9606 break;
9607 }
9608 if (!item) {
9610 return AVERROR(ENOMEM);
9611 }
9612 if (i == c->nb_heif_item) {
9614 return AVERROR_INVALIDDATA;
9615 }
9616
9617 av_freep(&item->name);
9618 av_bprint_finalize(&item_name, ret ? &item->name : NULL);
9619 item->item_id = item_id;
9620 item->type = item_type;
9621 item->flags = flags;
9622
9623 switch (item_type) {
9624 case MKTAG('a','v','0','1'):
9625 case MKTAG('j','p','e','g'):
9626 case MKTAG('h','v','c','1'):
9627 ret = heif_add_stream(c, item);
9628 if (ret < 0)
9629 return ret;
9630 break;
9631 }
9632
9633 return 0;
9634}
9635
9637{
9638 HEIFItem **heif_item;
9639 int entry_count;
9640 int version, got_stream = 0, ret, i;
9641
9642 if (c->found_iinf) {
9643 av_log(c->fc, AV_LOG_WARNING, "Duplicate iinf box found\n");
9644 return 0;
9645 }
9646
9647 version = avio_r8(pb);
9648 avio_rb24(pb); // flags.
9649 entry_count = version ? avio_rb32(pb) : avio_rb16(pb);
9650
9651 if (entry_count > atom.size)
9652 return AVERROR_INVALIDDATA;
9653
9654 /* account for the version/flags/entry_count fields already consumed,
9655 * so the per-entry loop below can bound each infe box by what is
9656 * actually left in this iinf box, the same way mov_read_iprp() bounds
9657 * ipco/ipma entries by the remaining iprp size. */
9658 atom.size -= version ? 8 : 6;
9659 if (atom.size < 0)
9660 return AVERROR_INVALIDDATA;
9661
9662 heif_item = av_realloc_array(c->heif_item, FFMAX(entry_count, c->nb_heif_item), sizeof(*c->heif_item));
9663 if (!heif_item)
9664 return AVERROR(ENOMEM);
9665 c->heif_item = heif_item;
9666 if (entry_count > c->nb_heif_item)
9667 memset(&c->heif_item[c->nb_heif_item], 0,
9668 sizeof(*c->heif_item) * (entry_count - c->nb_heif_item));
9669 c->nb_heif_item = FFMAX(c->nb_heif_item, entry_count);
9670
9671 for (i = 0; i < entry_count; i++) {
9672 MOVAtom infe;
9673
9674 infe.size = avio_rb32(pb);
9675 infe.type = avio_rl32(pb);
9676 if (avio_feof(pb) || infe.size < 8 || infe.size > atom.size ||
9677 infe.type != MKTAG('i','n','f','e')) {
9678 ret = AVERROR_INVALIDDATA;
9679 goto fail;
9680 }
9681
9682 atom.size -= infe.size;
9683 infe.size -= 8;
9684
9685 ret = mov_read_infe(c, pb, infe);
9686 if (ret < 0)
9687 goto fail;
9688 if (!ret)
9689 got_stream = 1;
9690 }
9691
9692 c->found_iinf = got_stream;
9693 return 0;
9694fail:
9695 for (; i >= 0; i--) {
9696 HEIFItem *item = c->heif_item[i];
9697
9698 if (!item)
9699 continue;
9700
9701 av_freep(&item->name);
9702 }
9703 return ret;
9704}
9705
9707 HEIFItem *item, int version, int entries)
9708{
9709 HEIFGroup *tmap = av_realloc_array(c->heif_group, c->nb_heif_group + 1U,
9710 sizeof(*c->heif_group));
9711 int ret;
9712
9713 if (!tmap)
9714 return AVERROR(ENOMEM);
9715 c->heif_group = tmap;
9716
9717 if (entries != 2) {
9718 avpriv_report_missing_feature(c->fc, "Derived image item of type %s with an "
9719 "item reference count other than 2",
9720 av_fourcc2str(item->type));
9721 return 0;
9722 }
9723
9724 tmap = &tmap[c->nb_heif_group];
9725
9726 tmap->item_idx_list = NULL; // Not needed
9727 tmap->item_id_list = av_malloc_array(entries, sizeof(*tmap->item_id_list));
9728 tmap->item_list = av_calloc(entries, sizeof(*tmap->item_list));
9729 if (!tmap->item_id_list || !tmap->item_list) {
9730 ret = AVERROR(ENOMEM);
9731 goto fail;
9732 }
9733
9734 /* 'to' item ids */
9735 for (int i = 0; i < entries; i++) {
9736 tmap->item_id_list[i] = version ? avio_rb32(pb) : avio_rb16(pb);
9737
9738 if (avio_feof(pb)) {
9739 ret = AVERROR_INVALIDDATA;
9740 goto fail;
9741 }
9742 }
9743
9744 tmap->nb_items = entries;
9745 tmap->item = item;
9746 ++c->nb_heif_group;
9747
9748 return 0;
9749fail:
9750 av_freep(&tmap->item_id_list);
9751 av_freep(&tmap->item_list);
9752
9753 return ret;
9754}
9755
9757 HEIFItem *item, int version, int entries)
9758{
9759 HEIFGroup *grid = av_realloc_array(c->heif_group, c->nb_heif_group + 1U,
9760 sizeof(*c->heif_group));
9761 int ret;
9762
9763 if (!grid)
9764 return AVERROR(ENOMEM);
9765 c->heif_group = grid;
9766 grid = &grid[c->nb_heif_group];
9767
9768 grid->item_id_list = av_malloc_array(entries, sizeof(*grid->item_id_list));
9769 grid->item_idx_list = av_calloc(entries, sizeof(*grid->item_idx_list));
9770 grid->item_list = av_calloc(entries, sizeof(*grid->item_list));
9771 if (!grid->item_id_list || !grid->item_list || !grid->item_idx_list) {
9772 ret = AVERROR(ENOMEM);
9773 goto fail;
9774 }
9775 /* 'to' item ids */
9776 for (int i = 0; i < entries; i++) {
9777 grid->item_id_list[i] = version ? avio_rb32(pb) : avio_rb16(pb);
9778
9779 if (avio_feof(pb)) {
9780 ret = AVERROR_INVALIDDATA;
9781 goto fail;
9782 }
9783 }
9784
9785 grid->nb_items = entries;
9786 grid->item = item;
9787 ++c->nb_heif_group;
9788
9789 return 0;
9790fail:
9791 av_freep(&grid->item_id_list);
9792 av_freep(&grid->item_idx_list);
9793 av_freep(&grid->item_list);
9794
9795 return ret;
9796}
9797
9799{
9800 HEIFItem *item = NULL;
9801 int entries;
9802 int from_item_id = version ? avio_rb32(pb) : avio_rb16(pb);
9803 int ret;
9804
9805 for (int i = 0; i < c->nb_heif_group; i++) {
9806 if (c->heif_group[i].item->item_id == from_item_id) {
9807 av_log(c->fc, AV_LOG_ERROR, "More than one 'dimg' box "
9808 "referencing the same Derived Image item\n");
9809 return AVERROR_INVALIDDATA;
9810 }
9811 }
9812 for (int i = 0; i < c->nb_heif_item; i++) {
9813 if (!c->heif_item[i] || c->heif_item[i]->item_id != from_item_id)
9814 continue;
9815 item = c->heif_item[i];
9816
9817 switch (item->type) {
9818 case MKTAG('g','r','i','d'):
9819 case MKTAG('i','o','v','l'):
9820 case MKTAG('t','m','a','p'):
9821 break;
9822 default:
9823 avpriv_report_missing_feature(c->fc, "Derived Image item of type %s",
9824 av_fourcc2str(item->type));
9825 return 0;
9826 }
9827 break;
9828 }
9829 if (!item) {
9830 av_log(c->fc, AV_LOG_ERROR, "Missing derived image information\n");
9831 return AVERROR_INVALIDDATA;
9832 }
9833
9834 entries = avio_rb16(pb);
9835 if (!entries) {
9836 av_log(c->fc, AV_LOG_ERROR,
9837 "Derived image item references no input images\n");
9838 return AVERROR_INVALIDDATA;
9839 }
9840
9841 av_log(c->fc, AV_LOG_TRACE, "dimg: from_item_id %d, entries %d\n",
9842 from_item_id, entries);
9843
9844 switch (item->type) {
9845 case MKTAG('g','r','i','d'):
9846 case MKTAG('i','o','v','l'):
9847 ret = mov_read_iref_dimg_grid(c, pb, item, version, entries);
9848 break;
9849 case MKTAG('t','m','a','p'):
9850 ret = mov_read_iref_dimg_tmap(c, pb, item, version, entries);
9851 break;
9852 default:
9853 av_unreachable("item->type should have been checked above");
9854 }
9855
9856 return ret;
9857}
9858
9860 int version, uint32_t size)
9861{
9862 HEIFItem *from_item = NULL;
9863 int entries;
9864 int item_id_size = version ? 4 : 2;
9865 int from_item_id = version ? avio_rb32(pb) : avio_rb16(pb);
9866 const HEIFItemRef ref = { type, from_item_id };
9867
9868 from_item = get_heif_item(c, from_item_id);
9869 if (!from_item) {
9870 av_log(c->fc, AV_LOG_ERROR, "Missing stream referenced by %s iref\n",
9872 return AVERROR_INVALIDDATA;
9873 }
9874
9875 entries = avio_rb16(pb);
9876 if ((int64_t)entries * item_id_size > (int64_t)size - item_id_size - 2) {
9877 av_log(c->fc, AV_LOG_ERROR, "iref %s entry count %d exceeds the sub-box size\n",
9878 av_fourcc2str(type), entries);
9879 return AVERROR_INVALIDDATA;
9880 }
9881 /* 'to' item ids */
9882 for (int i = 0; i < entries; i++) {
9883 HEIFItem *item = get_heif_item(c, version ? avio_rb32(pb) : avio_rb16(pb));
9884
9885 if (avio_feof(pb))
9886 return AVERROR_INVALIDDATA;
9887
9888 if (!item) {
9889 av_log(c->fc, AV_LOG_WARNING, "Missing stream referenced by %s item\n",
9891 continue;
9892 }
9893
9894 if (!av_dynarray2_add((void **)&item->iref_from_list, &item->nb_iref_from_list,
9895 sizeof(*item->iref_from_list), (const uint8_t *)&ref))
9896 return AVERROR(ENOMEM);
9897 }
9898
9899 av_log(c->fc, AV_LOG_TRACE, "%s: from_item_id %d, entries %d\n",
9900 av_fourcc2str(type), from_item_id, entries);
9901
9902 return 0;
9903}
9904
9906 int version, uint32_t size)
9907{
9908 HEIFItem *from_item = NULL;
9909 int entries;
9910 unsigned from_item_id = version ? avio_rb32(pb) : avio_rb16(pb);
9911
9912 from_item = get_heif_item(c, from_item_id);
9913 if (!from_item) {
9914 av_log(c->fc, AV_LOG_ERROR, "Missing item referenced by %s iref\n",
9916 return AVERROR_INVALIDDATA;
9917 }
9918
9919 entries = avio_rb16(pb);
9920 if (entries != 1) {
9921 avpriv_report_missing_feature(c->fc, "%s iref with an item reference "
9922 "count other than 1",
9924 return 0;
9925 }
9926
9927 /* 'to' item ids */
9928 for (int i = 0; i < entries; i++) {
9929 unsigned to_item_id = version ? avio_rb32(pb) : avio_rb16(pb);
9930 const HEIFItemRef ref = { type, to_item_id };
9931 HEIFItem *item = get_heif_item(c, to_item_id);
9932
9933 if (avio_feof(pb))
9934 return AVERROR_INVALIDDATA;
9935
9936 if (!item) {
9937 av_log(c->fc, AV_LOG_WARNING, "Missing item referenced by %s iref\n",
9939 continue;
9940 }
9941
9942 if (!av_dynarray2_add((void **)&from_item->iref_to_list, &from_item->nb_iref_to_list,
9943 sizeof(*from_item->iref_to_list), (const uint8_t *)&ref))
9944 return AVERROR(ENOMEM);
9945 }
9946
9947 av_log(c->fc, AV_LOG_TRACE, "%s: from_item_id %d, entries %d\n",
9948 av_fourcc2str(type), from_item_id, entries);
9949
9950 return 0;
9951}
9952
9954{
9955 int version = avio_r8(pb);
9956 int ret;
9957
9958 avio_rb24(pb); // flags
9959 atom.size -= 4;
9960
9961 if (version > 1) {
9962 av_log(c->fc, AV_LOG_WARNING, "Unknown iref box version %d\n", version);
9963 return 0;
9964 }
9965
9966 while (atom.size) {
9967 int64_t next = avio_tell(pb);
9968 uint32_t type, size = avio_rb32(pb);
9969
9970 if (size < 14 || size > atom.size || next > INT64_MAX - size)
9971 return AVERROR_INVALIDDATA;
9972
9973 next += size;
9974 type = avio_rl32(pb);
9975 switch (type) {
9976 case MKTAG('d','i','m','g'):
9977 ret = mov_read_iref_dimg(c, pb, version);
9978 if (ret < 0)
9979 return ret;
9980 break;
9981 case MKTAG('c','d','s','c'):
9982 ret = mov_read_iref_cdsc(c, pb, type, version, size - 8);
9983 if (ret < 0)
9984 return ret;
9985 break;
9986 case MKTAG('a','u','x','l'):
9987 case MKTAG('t','h','m','b'):
9988 ret = mov_read_iref_auxl(c, pb, type, version, size - 8);
9989 if (ret < 0)
9990 return ret;
9991 break;
9992 default:
9993 av_log(c->fc, AV_LOG_DEBUG, "Unknown iref type %s size %"PRIu32"\n",
9995 }
9996
9997 atom.size -= size;
9998 avio_seek(pb, next, SEEK_SET);
9999 }
10000 return 0;
10001}
10002
10004{
10005 HEIFItem *item;
10006 uint32_t width, height;
10007
10008 avio_r8(pb); /* version */
10009 avio_rb24(pb); /* flags */
10010 width = avio_rb32(pb);
10011 height = avio_rb32(pb);
10012
10013 av_log(c->fc, AV_LOG_TRACE, "ispe: item_id %d, width %"PRIu32", height %"PRIu32"\n",
10014 c->cur_item_id, width, height);
10015
10016 if (!width || !height || width > INT_MAX || height > INT_MAX) {
10017 av_log(c->fc, AV_LOG_ERROR, "Invalid ispe dimensions %"PRIu32"x%"PRIu32"\n",
10018 width, height);
10019 return AVERROR_INVALIDDATA;
10020 }
10021
10022 item = get_heif_item(c, c->cur_item_id);
10023 if (item) {
10024 item->width = width;
10025 item->height = height;
10026 }
10027
10028 return 0;
10029}
10030
10032{
10033 HEIFItem *item;
10034 int angle;
10035
10036 angle = avio_r8(pb) & 0x3;
10037
10038 av_log(c->fc, AV_LOG_TRACE, "irot: item_id %d, angle %u\n",
10039 c->cur_item_id, angle);
10040
10041 item = get_heif_item(c, c->cur_item_id);
10042 if (item) {
10043 // angle * 90 specifies the angle (in anti-clockwise direction)
10044 // in units of degrees.
10045 item->rotation = angle * 90;
10046 }
10047
10048 return 0;
10049}
10050
10052{
10053 HEIFItem *item;
10054 int axis;
10055
10056 axis = avio_r8(pb) & 0x1;
10057
10058 av_log(c->fc, AV_LOG_TRACE, "imir: item_id %d, axis %u\n",
10059 c->cur_item_id, axis);
10060
10061 item = get_heif_item(c, c->cur_item_id);
10062 if (item) {
10063 item->hflip = axis;
10064 item->vflip = !axis;
10065 }
10066
10067 return 0;
10068}
10069
10071{
10072 typedef struct MOVAtoms {
10073 FFIOContext b;
10074 uint32_t type;
10075 int64_t size;
10076 uint8_t *data;
10077 } MOVAtoms;
10078 MOVAtoms *atoms = NULL;
10079 MOVAtom a;
10080 unsigned count;
10081 int nb_atoms = 0;
10082 int version, flags;
10083 int ret;
10084
10085 a.size = avio_rb32(pb);
10086 a.type = avio_rl32(pb);
10087
10088 if (a.size < 8 || a.size > atom.size || a.type != MKTAG('i','p','c','o'))
10089 return AVERROR_INVALIDDATA;
10090
10091 atom.size -= a.size;
10092 a.size -= 8;
10093 while (a.size >= 8) {
10094 MOVAtoms *ref = av_dynarray2_add((void**)&atoms, &nb_atoms, sizeof(MOVAtoms), NULL);
10095 if (!ref) {
10096 ret = AVERROR(ENOMEM);
10097 goto fail;
10098 }
10099 ref->data = NULL;
10100 ref->size = avio_rb32(pb);
10101 ref->type = avio_rl32(pb);
10102 if (ref->size > a.size || ref->size < 8)
10103 break;
10104 ref->data = av_malloc(ref->size);
10105 if (!ref->data) {
10106 ret = AVERROR_INVALIDDATA;
10107 goto fail;
10108 }
10109 av_log(c->fc, AV_LOG_TRACE, "ipco: index %d, box type %s\n", nb_atoms, av_fourcc2str(ref->type));
10110 AV_WB32(ref->data, ref->size);
10111 AV_WL32(ref->data + 4, ref->type);
10112 if (avio_read(pb, ref->data + 8, ref->size - 8) != ref->size - 8) {
10113 ret = AVERROR_INVALIDDATA;
10114 goto fail;
10115 }
10116 ffio_init_read_context(&ref->b, ref->data, ref->size);
10117 a.size -= ref->size;
10118 }
10119
10120 if (a.size) {
10121 ret = AVERROR_INVALIDDATA;
10122 goto fail;
10123 }
10124
10125 a.size = avio_rb32(pb);
10126 a.type = avio_rl32(pb);
10127
10128 if (a.size < 16 || a.size > atom.size || a.type != MKTAG('i','p','m','a')) {
10129 ret = AVERROR_INVALIDDATA;
10130 goto fail;
10131 }
10132
10133 version = avio_r8(pb);
10134 flags = avio_rb24(pb);
10135 count = avio_rb32(pb);
10136 a.size -= 16;
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 a.size -= (version ? 5 : 3) + assoc_count * (1 + (flags & 1));
10143 if (avio_feof(pb) || a.size < 0) {
10144 ret = AVERROR_INVALIDDATA;
10145 goto fail;
10146 }
10147
10148 for (int j = 0; j < assoc_count; j++) {
10149 MOVAtoms *ref;
10150 int index = avio_r8(pb) & 0x7f;
10151 if (flags & 1) {
10152 index <<= 8;
10153 index |= avio_r8(pb);
10154 }
10155 if (!index)
10156 continue;
10157 if (index > nb_atoms) {
10158 ret = AVERROR_INVALIDDATA;
10159 goto fail;
10160 }
10161 ref = &atoms[--index];
10162
10163 av_log(c->fc, AV_LOG_TRACE, "ipma: property_index %d, item_id %d, item_type %s\n",
10164 index + 1, item_id, av_fourcc2str(ref->type));
10165
10166 c->cur_item_id = item_id;
10167
10168 ret = mov_read_default(c, &ref->b.pub,
10169 (MOVAtom) { .size = ref->size,
10170 .type = MKTAG('i','p','c','o') });
10171 if (ret < 0)
10172 goto fail;
10173 ffio_init_read_context(&ref->b, ref->data, ref->size);
10174 }
10175 }
10176
10177 ret = 0;
10178fail:
10179 c->cur_item_id = -1;
10180 for (int i = 0; i < nb_atoms; i++)
10181 av_free(atoms[i].data);
10182 av_free(atoms);
10183
10184 return ret;
10185}
10186
10188{
10189 avio_rb32(pb); // version & flags
10190 uint16_t graphics_mode = avio_rb16(pb);
10191 // ignored: opcolor[3]
10192
10193 if (c->fc->nb_streams < 1)
10194 return 0;
10195 AVStream *st = c->fc->streams[c->fc->nb_streams - 1];
10197 return 0;
10198
10199 switch (graphics_mode) {
10203 break;
10206 break;
10209 break;
10210 default:
10212 av_log(c->fc, AV_LOG_WARNING, "Unhandled graphics mode: 0x%x\n",
10213 graphics_mode);
10214 break;
10215 }
10216
10217 return 0;
10218}
10219
10221{
10222 AVFormatContext *ctx = c->fc;
10223 AVStream *st;
10224 int profile_level_indication, reference_ch_layout, config_length;
10225 int ret = 0;
10226
10227 if (ctx->nb_streams < 1)
10228 return 0;
10229
10230 st = ctx->streams[ctx->nb_streams - 1];
10232 return 0;
10233
10234 if (avio_r8(pb) != 1) // ConfigurationVersion
10235 return 0;
10236
10237 profile_level_indication = avio_r8(pb);
10238 st->codecpar->profile = (profile_level_indication - 1) / 5;
10239 st->codecpar->level = ((profile_level_indication - 1) % 5) + 1;
10240
10241 reference_ch_layout = avio_r8(pb);
10242 config_length = avio_rb16(pb);
10243 if (config_length)
10244 ret = ff_get_extradata(ctx, st->codecpar, pb, config_length);
10245
10246 if (!reference_ch_layout ||
10247 reference_ch_layout >= FF_ARRAY_ELEMS(ff_mpa_cicp_channel_layout_masks)) {
10248 av_log(ctx, AV_LOG_WARNING, "Unknown referenceChannelLayout value: %d\n", reference_ch_layout);
10249 return ret;
10250 }
10251
10253 ff_mpa_cicp_channel_layout_masks[reference_ch_layout]);
10254
10255 return ret;
10256}
10257
10259{ MKTAG('A','C','L','R'), mov_read_aclr },
10260{ MKTAG('A','P','R','G'), mov_read_avid },
10261{ MKTAG('A','A','L','P'), mov_read_avid },
10262{ MKTAG('A','R','E','S'), mov_read_ares },
10263{ MKTAG('a','v','s','s'), mov_read_avss },
10264{ MKTAG('a','v','1','C'), mov_read_glbl },
10265{ MKTAG('c','h','p','l'), mov_read_chpl },
10266{ MKTAG('c','o','6','4'), mov_read_stco },
10267{ MKTAG('c','o','l','r'), mov_read_colr },
10268{ MKTAG('c','t','t','s'), mov_read_ctts }, /* composition time to sample */
10269{ MKTAG('d','i','n','f'), mov_read_default },
10270{ MKTAG('D','p','x','E'), mov_read_dpxe },
10271{ MKTAG('d','r','e','f'), mov_read_dref },
10272{ MKTAG('e','d','t','s'), mov_read_default },
10273{ MKTAG('e','l','s','t'), mov_read_elst },
10274{ MKTAG('e','n','d','a'), mov_read_enda },
10275{ MKTAG('f','i','e','l'), mov_read_fiel },
10276{ MKTAG('a','d','r','m'), mov_read_adrm },
10277{ MKTAG('f','t','y','p'), mov_read_ftyp },
10278{ MKTAG('g','l','b','l'), mov_read_glbl },
10279{ MKTAG('h','d','l','r'), mov_read_hdlr },
10280{ MKTAG('i','l','s','t'), mov_read_ilst },
10281{ MKTAG('j','p','2','h'), mov_read_jp2h },
10282{ MKTAG('m','d','a','t'), mov_read_mdat },
10283{ MKTAG('m','d','h','d'), mov_read_mdhd },
10284{ MKTAG('m','d','i','a'), mov_read_default },
10285{ MKTAG('m','e','t','a'), mov_read_meta },
10286{ MKTAG('m','i','n','f'), mov_read_default },
10287{ MKTAG('m','o','o','f'), mov_read_moof },
10288{ MKTAG('m','o','o','v'), mov_read_moov },
10289{ MKTAG('m','v','e','x'), mov_read_default },
10290{ MKTAG('m','v','h','d'), mov_read_mvhd },
10291{ MKTAG('S','M','I',' '), mov_read_svq3 },
10292{ MKTAG('a','l','a','c'), mov_read_alac }, /* alac specific atom */
10293{ MKTAG('a','v','c','C'), mov_read_glbl },
10294{ MKTAG('p','a','s','p'), mov_read_pasp },
10295{ MKTAG('c','l','a','p'), mov_read_clap },
10296{ MKTAG('c','d','s','c'), mov_read_cdsc_rndr },
10297{ MKTAG('r','n','d','r'), mov_read_cdsc_rndr },
10298{ MKTAG('s','b','a','s'), mov_read_sbas },
10299{ MKTAG('v','d','e','p'), mov_read_vdep },
10300{ MKTAG('s','i','d','x'), mov_read_sidx },
10301{ MKTAG('s','t','b','l'), mov_read_default },
10302{ MKTAG('s','t','c','o'), mov_read_stco },
10303{ MKTAG('s','t','p','s'), mov_read_stps },
10304{ MKTAG('s','t','r','f'), mov_read_strf },
10305{ MKTAG('s','t','s','c'), mov_read_stsc },
10306{ MKTAG('s','t','s','d'), mov_read_stsd }, /* sample description */
10307{ MKTAG('s','t','s','s'), mov_read_stss }, /* sync sample */
10308{ MKTAG('s','t','s','z'), mov_read_stsz }, /* sample size */
10309{ MKTAG('s','t','t','s'), mov_read_stts },
10310{ MKTAG('s','t','z','2'), mov_read_stsz }, /* compact sample size */
10311{ MKTAG('s','d','t','p'), mov_read_sdtp }, /* independent and disposable samples */
10312{ MKTAG('t','k','h','d'), mov_read_tkhd }, /* track header */
10313{ MKTAG('t','f','d','t'), mov_read_tfdt },
10314{ MKTAG('t','f','h','d'), mov_read_tfhd }, /* track fragment header */
10315{ MKTAG('t','r','a','k'), mov_read_trak },
10316{ MKTAG('t','r','a','f'), mov_read_default },
10317{ MKTAG('t','r','e','f'), mov_read_default },
10318{ MKTAG('t','m','c','d'), mov_read_tmcd },
10319{ MKTAG('c','h','a','p'), mov_read_chap },
10320{ MKTAG('t','r','e','x'), mov_read_trex },
10321{ MKTAG('t','r','u','n'), mov_read_trun },
10322{ MKTAG('u','d','t','a'), mov_read_default },
10323{ MKTAG('w','a','v','e'), mov_read_wave },
10324{ MKTAG('e','s','d','s'), mov_read_esds },
10325{ MKTAG('d','a','c','3'), mov_read_dac3 }, /* AC-3 info */
10326{ MKTAG('d','e','c','3'), mov_read_dec3 }, /* EAC-3 info */
10327{ MKTAG('d','d','t','s'), mov_read_ddts }, /* DTS audio descriptor */
10328{ MKTAG('w','i','d','e'), mov_read_wide }, /* place holder */
10329{ MKTAG('w','f','e','x'), mov_read_wfex },
10330{ MKTAG('c','m','o','v'), mov_read_cmov },
10331{ MKTAG('c','h','a','n'), mov_read_chan }, /* channel layout from quicktime */
10332{ MKTAG('c','h','n','l'), mov_read_chnl }, /* channel layout from ISO-14496-12 */
10333{ MKTAG('d','v','c','1'), mov_read_dvc1 },
10334{ MKTAG('s','g','p','d'), mov_read_sgpd },
10335{ MKTAG('s','b','g','p'), mov_read_sbgp },
10336{ MKTAG('h','v','c','C'), mov_read_glbl },
10337{ MKTAG('v','v','c','C'), mov_read_glbl },
10338{ MKTAG('u','u','i','d'), mov_read_uuid },
10339{ MKTAG('C','i','n', 0x8e), mov_read_targa_y216 },
10340{ MKTAG('f','r','e','e'), mov_read_free },
10341{ MKTAG('-','-','-','-'), mov_read_custom },
10342{ MKTAG('s','i','n','f'), mov_read_default },
10343{ MKTAG('f','r','m','a'), mov_read_frma },
10344{ MKTAG('s','e','n','c'), mov_read_senc },
10345{ MKTAG('s','a','i','z'), mov_read_saiz },
10346{ MKTAG('s','a','i','o'), mov_read_saio },
10347{ MKTAG('p','s','s','h'), mov_read_pssh },
10348{ MKTAG('s','c','h','m'), mov_read_schm },
10349{ MKTAG('s','c','h','i'), mov_read_default },
10350{ MKTAG('t','e','n','c'), mov_read_tenc },
10351{ MKTAG('d','f','L','a'), mov_read_dfla },
10352{ MKTAG('s','t','3','d'), mov_read_st3d }, /* stereoscopic 3D video box */
10353{ MKTAG('s','v','3','d'), mov_read_sv3d }, /* spherical video box */
10354{ MKTAG('v','e','x','u'), mov_read_vexu }, /* video extension usage */
10355{ MKTAG('h','f','o','v'), mov_read_hfov },
10356{ MKTAG('d','O','p','s'), mov_read_dops },
10357{ MKTAG('d','m','l','p'), mov_read_dmlp },
10358{ MKTAG('S','m','D','m'), mov_read_smdm },
10359{ MKTAG('C','o','L','L'), mov_read_coll },
10360{ MKTAG('v','p','c','C'), mov_read_vpcc },
10361{ MKTAG('m','d','c','v'), mov_read_mdcv },
10362{ MKTAG('c','l','l','i'), mov_read_clli },
10363{ MKTAG('d','v','c','C'), mov_read_dvcc_dvvc },
10364{ MKTAG('d','v','v','C'), mov_read_dvcc_dvvc },
10365{ MKTAG('d','v','w','C'), mov_read_dvcc_dvvc },
10366{ MKTAG('h','v','c','E'), mov_read_hvce },
10367{ MKTAG('k','i','n','d'), mov_read_kind },
10368{ MKTAG('S','A','3','D'), mov_read_SA3D }, /* ambisonic audio box */
10369{ MKTAG('S','A','N','D'), mov_read_SAND }, /* non diegetic audio box */
10370{ MKTAG('i','l','o','c'), mov_read_iloc },
10371{ MKTAG('p','c','m','C'), mov_read_pcmc }, /* PCM configuration box */
10372{ MKTAG('p','i','t','m'), mov_read_pitm },
10373{ MKTAG('e','v','c','C'), mov_read_glbl },
10374{ MKTAG('a','u','x','C'), mov_read_auxc },
10375{ MKTAG('i','d','a','t'), mov_read_idat },
10376{ MKTAG('i','m','i','r'), mov_read_imir },
10377{ MKTAG('i','r','e','f'), mov_read_iref },
10378{ MKTAG('i','s','p','e'), mov_read_ispe },
10379{ MKTAG('i','r','o','t'), mov_read_irot },
10380{ MKTAG('i','p','r','p'), mov_read_iprp },
10381{ MKTAG('i','i','n','f'), mov_read_iinf },
10382{ MKTAG('a','m','v','e'), mov_read_amve }, /* ambient viewing environment box */
10383{ MKTAG('l','h','v','C'), mov_read_lhvc },
10384{ MKTAG('l','v','c','C'), mov_read_glbl },
10385{ MKTAG('a','p','v','C'), mov_read_glbl },
10386#if CONFIG_IAMFDEC
10387{ MKTAG('i','a','c','b'), mov_read_iacb },
10388#endif
10389{ MKTAG('s','r','a','t'), mov_read_srat },
10390{ MKTAG('v','m','h','d'), mov_read_vmhd },
10391{ MKTAG('m','h','a','C'), mov_read_mhac },
10392{ 0, NULL }
10393};
10394
10396{
10397 int64_t total_size = 0;
10398 MOVAtom a;
10399 int i;
10400
10401 if (c->atom_depth > 10) {
10402 av_log(c->fc, AV_LOG_ERROR, "Atoms too deeply nested\n");
10403 return AVERROR_INVALIDDATA;
10404 }
10405 c->atom_depth ++;
10406
10407 if (atom.size < 0)
10408 atom.size = INT64_MAX;
10409 while (total_size <= atom.size - 8) {
10410 int (*parse)(MOVContext*, AVIOContext*, MOVAtom) = NULL;
10411 a.size = avio_rb32(pb);
10412 a.type = avio_rl32(pb);
10413 if (avio_feof(pb))
10414 break;
10415 if (((a.type == MKTAG('f','r','e','e') && c->moov_retry) ||
10416 a.type == MKTAG('h','o','o','v')) &&
10417 a.size >= 8 &&
10418 c->fc->strict_std_compliance < FF_COMPLIANCE_STRICT) {
10419 uint32_t type;
10420 avio_skip(pb, 4);
10421 type = avio_rl32(pb);
10422 if (avio_feof(pb))
10423 break;
10424 avio_seek(pb, -8, SEEK_CUR);
10425 if (type == MKTAG('m','v','h','d') ||
10426 type == MKTAG('c','m','o','v')) {
10427 av_log(c->fc, AV_LOG_ERROR, "Detected moov in a free or hoov atom.\n");
10428 a.type = MKTAG('m','o','o','v');
10429 }
10430 }
10431 if (atom.type != MKTAG('r','o','o','t') &&
10432 atom.type != MKTAG('m','o','o','v')) {
10433 if (a.type == MKTAG('t','r','a','k') ||
10434 a.type == MKTAG('m','d','a','t')) {
10435 av_log(c->fc, AV_LOG_ERROR, "Broken file, trak/mdat not at top-level\n");
10436 avio_skip(pb, -8);
10437 c->atom_depth --;
10438 return 0;
10439 }
10440 }
10441 total_size += 8;
10442 if (a.size == 1 && total_size + 8 <= atom.size) { /* 64 bit extended size */
10443 a.size = avio_rb64(pb) - 8;
10444 total_size += 8;
10445 }
10446 av_log(c->fc, AV_LOG_TRACE, "type:'%s' parent:'%s' sz: %"PRId64" %"PRId64" %"PRId64"\n",
10447 av_fourcc2str(a.type), av_fourcc2str(atom.type), a.size, total_size, atom.size);
10448 if (a.size == 0) {
10449 a.size = atom.size - total_size + 8;
10450 }
10451 if (a.size < 0)
10452 break;
10453 a.size -= 8;
10454 if (a.size < 0)
10455 break;
10456 a.size = FFMIN(a.size, atom.size - total_size);
10457
10458 for (i = 0; mov_default_parse_table[i].type; i++)
10459 if (mov_default_parse_table[i].type == a.type) {
10461 break;
10462 }
10463
10464 // container is user data
10465 if (!parse && (atom.type == MKTAG('u','d','t','a') ||
10466 atom.type == MKTAG('i','l','s','t')))
10468
10469 // Supports parsing the QuickTime Metadata Keys.
10470 // https://developer.apple.com/library/mac/documentation/QuickTime/QTFF/Metadata/Metadata.html
10471 if (!parse && c->found_hdlr_mdta &&
10472 atom.type == MKTAG('m','e','t','a') &&
10473 a.type == MKTAG('k','e','y','s') &&
10474 c->meta_keys_count == 0) {
10476 }
10477
10478 if (!parse) { /* skip leaf atoms data */
10479 avio_skip(pb, a.size);
10480 } else {
10481 int64_t start_pos = avio_tell(pb);
10482 int64_t left;
10483 int err = parse(c, pb, a);
10484 if (err < 0) {
10485 c->atom_depth --;
10486 return err;
10487 }
10488 if (c->found_moov && c->found_mdat && a.size <= INT64_MAX - start_pos &&
10489 ((!(pb->seekable & AVIO_SEEKABLE_NORMAL) || c->fc->flags & AVFMT_FLAG_IGNIDX || c->frag_index.complete) ||
10490 start_pos + a.size == avio_size(pb))) {
10491 if (!(pb->seekable & AVIO_SEEKABLE_NORMAL) || c->fc->flags & AVFMT_FLAG_IGNIDX || c->frag_index.complete)
10492 c->next_root_atom = start_pos + a.size;
10493 c->atom_depth --;
10494 return 0;
10495 }
10496 left = a.size - avio_tell(pb) + start_pos;
10497 if (left > 0) /* skip garbage at atom end */
10498 avio_skip(pb, left);
10499 else if (left < 0) {
10500 av_log(c->fc, AV_LOG_WARNING,
10501 "overread end of atom '%s' by %"PRId64" bytes\n",
10502 av_fourcc2str(a.type), -left);
10503 avio_seek(pb, left, SEEK_CUR);
10504 }
10505 }
10506
10507 total_size += a.size;
10508 }
10509
10510 if (total_size < atom.size && atom.size < 0x7ffff)
10511 avio_skip(pb, atom.size - total_size);
10512
10513 c->atom_depth --;
10514 return 0;
10515}
10516
10517static int mov_probe(const AVProbeData *p)
10518{
10520 uint32_t tag;
10521 int score = 0;
10522 int moov_offset = -1;
10523
10524 /* check file header */
10525 offset = 0;
10526 for (;;) {
10527 int64_t size;
10528 int minsize = 8;
10529 /* ignore invalid offset */
10530 if ((offset + 8ULL) > (unsigned int)p->buf_size)
10531 break;
10532 size = AV_RB32(p->buf + offset);
10533 if (size == 1 && offset + 16 <= (unsigned int)p->buf_size) {
10534 size = AV_RB64(p->buf+offset + 8);
10535 minsize = 16;
10536 } else if (size == 0) {
10537 size = p->buf_size - offset;
10538 }
10539 if (size < minsize) {
10540 offset += 4;
10541 continue;
10542 }
10543 tag = AV_RL32(p->buf + offset + 4);
10544 switch(tag) {
10545 /* check for obvious tags */
10546 case MKTAG('m','o','o','v'):
10547 moov_offset = offset + 4;
10549 case MKTAG('m','d','a','t'):
10550 case MKTAG('p','n','o','t'): /* detect movs with preview pics like ew.mov and april.mov */
10551 case MKTAG('u','d','t','a'): /* Packet Video PVAuthor adds this and a lot of more junk */
10552 case MKTAG('f','t','y','p'):
10553 if (tag == MKTAG('f','t','y','p') &&
10554 ( AV_RL32(p->buf + offset + 8) == MKTAG('j','p','2',' ')
10555 || AV_RL32(p->buf + offset + 8) == MKTAG('j','p','x',' ')
10556 || AV_RL32(p->buf + offset + 8) == MKTAG('j','x','l',' ')
10557 )) {
10558 score = FFMAX(score, 5);
10559 } else {
10560 score = AVPROBE_SCORE_MAX;
10561 }
10562 break;
10563 /* those are more common words, so rate then a bit less */
10564 case MKTAG('e','d','i','w'): /* xdcam files have reverted first tags */
10565 case MKTAG('w','i','d','e'):
10566 case MKTAG('f','r','e','e'):
10567 case MKTAG('j','u','n','k'):
10568 case MKTAG('p','i','c','t'):
10569 score = FFMAX(score, AVPROBE_SCORE_MAX - 5);
10570 break;
10571 case MKTAG(0x82,0x82,0x7f,0x7d):
10572 score = FFMAX(score, AVPROBE_SCORE_EXTENSION - 5);
10573 break;
10574 case MKTAG('s','k','i','p'):
10575 case MKTAG('u','u','i','d'):
10576 case MKTAG('p','r','f','l'):
10577 /* if we only find those cause probedata is too small at least rate them */
10578 score = FFMAX(score, AVPROBE_SCORE_EXTENSION);
10579 break;
10580 }
10581 if (size > INT64_MAX - offset)
10582 break;
10583 offset += size;
10584 }
10585 if (score > AVPROBE_SCORE_MAX - 50 && moov_offset != -1) {
10586 /* moov atom in the header - we should make sure that this is not a
10587 * MOV-packed MPEG-PS */
10588 offset = moov_offset;
10589
10590 while (offset < (p->buf_size - 16)) { /* Sufficient space */
10591 /* We found an actual hdlr atom */
10592 if (AV_RL32(p->buf + offset ) == MKTAG('h','d','l','r') &&
10593 AV_RL32(p->buf + offset + 8) == MKTAG('m','h','l','r') &&
10594 AV_RL32(p->buf + offset + 12) == MKTAG('M','P','E','G')) {
10595 av_log(NULL, AV_LOG_WARNING, "Found media data tag MPEG indicating this is a MOV-packed MPEG-PS.\n");
10596 /* We found a media handler reference atom describing an
10597 * MPEG-PS-in-MOV, return a
10598 * low score to force expanding the probe window until
10599 * mpegps_probe finds what it needs */
10600 return 5;
10601 } else {
10602 /* Keep looking */
10603 offset += 2;
10604 }
10605 }
10606 }
10607
10608 return score;
10609}
10610
10611// must be done after parsing all trak because there's no order requirement
10613{
10614 MOVContext *mov = s->priv_data;
10615 MOVStreamContext *sc;
10616 int64_t cur_pos;
10617 int i, j;
10618 int chapter_track;
10619
10620 for (j = 0; j < mov->nb_chapter_tracks; j++) {
10621 AVStream *st = NULL;
10622 FFStream *sti = NULL;
10623 chapter_track = mov->chapter_tracks[j];
10624 for (i = 0; i < s->nb_streams; i++) {
10625 sc = mov->fc->streams[i]->priv_data;
10626 if (sc->id == chapter_track) {
10627 st = s->streams[i];
10628 break;
10629 }
10630 }
10631 if (!st) {
10632 av_log(s, AV_LOG_ERROR, "Referenced QT chapter track not found\n");
10633 continue;
10634 }
10635 sti = ffstream(st);
10636
10637 sc = st->priv_data;
10638 cur_pos = avio_tell(sc->pb);
10639
10642 if (!st->attached_pic.data && sti->nb_index_entries) {
10643 // Retrieve the first frame, if possible
10644 AVIndexEntry *sample = &sti->index_entries[0];
10645 if (avio_seek(sc->pb, sample->pos, SEEK_SET) != sample->pos) {
10646 av_log(s, AV_LOG_ERROR, "Failed to retrieve first frame\n");
10647 goto finish;
10648 }
10649
10650 if (ff_add_attached_pic(s, st, sc->pb, NULL, sample->size) < 0)
10651 goto finish;
10652 }
10653 } else {
10656 st->discard = AVDISCARD_ALL;
10657 for (int i = 0; i < sti->nb_index_entries; i++) {
10659 int64_t end = i+1 < sti->nb_index_entries ? sti->index_entries[i+1].timestamp : st->duration;
10660 uint8_t *title;
10661 uint16_t ch;
10662 int len, title_len;
10663
10664 if (end < sample->timestamp) {
10665 av_log(s, AV_LOG_WARNING, "ignoring stream duration which is shorter than chapters\n");
10666 end = AV_NOPTS_VALUE;
10667 }
10668
10669 if (avio_seek(sc->pb, sample->pos, SEEK_SET) != sample->pos) {
10670 av_log(s, AV_LOG_ERROR, "Chapter %d not found in file\n", i);
10671 goto finish;
10672 }
10673
10674 // the first two bytes are the length of the title
10675 len = avio_rb16(sc->pb);
10676 if (len > sample->size-2)
10677 continue;
10678 title_len = 2*len + 1;
10679 if (!(title = av_mallocz(title_len)))
10680 goto finish;
10681
10682 // The samples could theoretically be in any encoding if there's an encd
10683 // atom following, but in practice are only utf-8 or utf-16, distinguished
10684 // instead by the presence of a BOM
10685 if (!len) {
10686 title[0] = 0;
10687 } else {
10688 ch = avio_rb16(sc->pb);
10689 if (ch == 0xfeff)
10690 avio_get_str16be(sc->pb, len, title, title_len);
10691 else if (ch == 0xfffe)
10692 avio_get_str16le(sc->pb, len, title, title_len);
10693 else {
10694 AV_WB16(title, ch);
10695 if (len == 1 || len == 2)
10696 title[len] = 0;
10697 else
10698 avio_get_str(sc->pb, INT_MAX, title + 2, len - 1);
10699 }
10700 }
10701
10702 avpriv_new_chapter(s, i, st->time_base, sample->timestamp, end, title);
10703 av_freep(&title);
10704 }
10705 }
10706finish:
10707 avio_seek(sc->pb, cur_pos, SEEK_SET);
10708 }
10709}
10710
10712 int64_t value, int flags)
10713{
10714 AVTimecode tc;
10715 char buf[AV_TIMECODE_STR_SIZE];
10716 AVRational rate = st->avg_frame_rate;
10717 int ret = av_timecode_init(&tc, rate, flags, 0, s);
10718 if (ret < 0)
10719 return ret;
10720 av_dict_set(&st->metadata, "timecode",
10721 av_timecode_make_string(&tc, buf, value), 0);
10722 return 0;
10723}
10724
10726{
10727 MOVStreamContext *sc = st->priv_data;
10728 FFStream *const sti = ffstream(st);
10729 char buf[AV_TIMECODE_STR_SIZE];
10730 int64_t cur_pos = avio_tell(sc->pb);
10731 int hh, mm, ss, ff, drop;
10732
10733 if (!sti->nb_index_entries)
10734 return -1;
10735
10736 avio_seek(sc->pb, sti->index_entries->pos, SEEK_SET);
10737 avio_skip(s->pb, 13);
10738 hh = avio_r8(s->pb);
10739 mm = avio_r8(s->pb);
10740 ss = avio_r8(s->pb);
10741 drop = avio_r8(s->pb);
10742 ff = avio_r8(s->pb);
10743 snprintf(buf, AV_TIMECODE_STR_SIZE, "%02d:%02d:%02d%c%02d",
10744 hh, mm, ss, drop ? ';' : ':', ff);
10745 av_dict_set(&st->metadata, "timecode", buf, 0);
10746
10747 avio_seek(sc->pb, cur_pos, SEEK_SET);
10748 return 0;
10749}
10750
10752{
10753 MOVStreamContext *sc = st->priv_data;
10754 FFStream *const sti = ffstream(st);
10755 int flags = 0;
10756 int64_t cur_pos = avio_tell(sc->pb);
10757 int64_t value;
10758 AVRational tc_rate = st->avg_frame_rate;
10759 int tmcd_nb_frames = sc->tmcd_nb_frames;
10760 int rounded_tc_rate;
10761
10762 if (!sti->nb_index_entries)
10763 return -1;
10764
10765 if (!tc_rate.num || !tc_rate.den || !tmcd_nb_frames)
10766 return -1;
10767
10768 avio_seek(sc->pb, sti->index_entries->pos, SEEK_SET);
10769 value = avio_rb32(s->pb);
10770
10771 if (sc->tmcd_flags & 0x0001) flags |= AV_TIMECODE_FLAG_DROPFRAME;
10772 if (sc->tmcd_flags & 0x0002) flags |= AV_TIMECODE_FLAG_24HOURSMAX;
10773 if (sc->tmcd_flags & 0x0004) flags |= AV_TIMECODE_FLAG_ALLOWNEGATIVE;
10774
10775 /* Assume Counter flag is set to 1 in tmcd track (even though it is likely
10776 * not the case) and thus assume "frame number format" instead of QT one.
10777 * No sample with tmcd track can be found with a QT timecode at the moment,
10778 * despite what the tmcd track "suggests" (Counter flag set to 0 means QT
10779 * format). */
10780
10781 /* 60 fps content have tmcd_nb_frames set to 30 but tc_rate set to 60, so
10782 * we multiply the frame number with the quotient.
10783 * See tickets #9492, #9710. */
10784 rounded_tc_rate = (tc_rate.num + tc_rate.den / 2LL) / tc_rate.den;
10785 /* Work around files where tmcd_nb_frames is rounded down from frame rate
10786 * instead of up. See ticket #5978. */
10787 if (tmcd_nb_frames == tc_rate.num / tc_rate.den &&
10788 s->strict_std_compliance < FF_COMPLIANCE_STRICT)
10789 tmcd_nb_frames = rounded_tc_rate;
10790 value = av_rescale(value, rounded_tc_rate, tmcd_nb_frames);
10791
10793
10794 avio_seek(sc->pb, cur_pos, SEEK_SET);
10795 return 0;
10796}
10797
10799 int i;
10800 if (!index || !*index) return;
10801 for (i = 0; i < (*index)->nb_encrypted_samples; i++) {
10802 av_encryption_info_free((*index)->encrypted_samples[i]);
10803 }
10804 av_freep(&(*index)->encrypted_samples);
10805 av_freep(&(*index)->auxiliary_info_sizes);
10806 av_freep(&(*index)->auxiliary_offsets);
10807 av_freep(index);
10808}
10809
10811{
10812 MOVStreamContext *sc = st->priv_data;
10813
10814 if (!sc || --sc->refcount) {
10815 st->priv_data = NULL;
10816 return;
10817 }
10818
10819 av_freep(&sc->tts_data);
10820 for (int i = 0; i < sc->drefs_count; i++) {
10821 av_freep(&sc->drefs[i].path);
10822 av_freep(&sc->drefs[i].dir);
10823 }
10824 av_freep(&sc->drefs);
10825
10826 sc->drefs_count = 0;
10827
10828 if (!sc->pb_is_copied)
10829 ff_format_io_close(s, &sc->pb);
10830
10831 sc->pb = NULL;
10832 av_freep(&sc->chunk_offsets);
10833 av_freep(&sc->stsc_data);
10834 av_freep(&sc->sample_sizes);
10835 av_freep(&sc->keyframes);
10836 av_freep(&sc->ctts_data);
10837 av_freep(&sc->stts_data);
10838 av_freep(&sc->sdtp_data);
10839 av_freep(&sc->stps_data);
10840 av_freep(&sc->elst_data);
10841 av_freep(&sc->rap_group);
10842 av_freep(&sc->sync_group);
10843 av_freep(&sc->sgpd_sync);
10847 av_freep(&sc->index_ranges);
10848 for (int i = 0; i < sc->nb_tref_tags; i++)
10849 av_freep(&sc->tref_tags[i].id);
10850 av_freep(&sc->tref_tags);
10851
10852 if (sc->extradata)
10853 for (int i = 0; i < sc->stsd_count; i++)
10854 av_free(sc->extradata[i]);
10855 av_freep(&sc->extradata);
10857
10861
10862 av_freep(&sc->stereo3d);
10863 av_freep(&sc->spherical);
10864 av_freep(&sc->mastering);
10865 av_freep(&sc->coll);
10866 av_freep(&sc->ambient);
10867
10868#if CONFIG_IAMFDEC
10869 if (sc->iamf)
10871#endif
10872 av_freep(&sc->iamf);
10873}
10874
10876{
10877 MOVContext *mov = s->priv_data;
10878 int i, j;
10879
10880 for (i = 0; i < s->nb_streams; i++) {
10881 AVStream *st = s->streams[i];
10882
10884 }
10885
10886 av_freep(&mov->dv_demux);
10888 mov->dv_fctx = NULL;
10889
10890 if (mov->meta_keys) {
10891 for (i = 1; i < mov->meta_keys_count; i++) {
10892 av_freep(&mov->meta_keys[i]);
10893 }
10894 av_freep(&mov->meta_keys);
10895 }
10896
10897 av_freep(&mov->trex_data);
10898 av_freep(&mov->bitrates);
10899
10900 for (i = 0; i < mov->frag_index.nb_items; i++) {
10902 for (j = 0; j < mov->frag_index.item[i].nb_stream_info; j++) {
10903 mov_free_encryption_index(&frag[j].encryption_index);
10904 }
10906 }
10907 av_freep(&mov->frag_index.item);
10908
10909 av_freep(&mov->aes_decrypt);
10910 av_freep(&mov->chapter_tracks);
10911 for (i = 0; i < mov->nb_heif_item; i++) {
10912 if (!mov->heif_item[i])
10913 continue;
10914 av_freep(&mov->heif_item[i]->name);
10918 av_exif_free(&mov->heif_item[i]->ifd);
10919 av_freep(&mov->heif_item[i]);
10920 }
10921 av_freep(&mov->heif_item);
10922 for (i = 0; i < mov->nb_heif_group; i++) {
10926 }
10927 av_freep(&mov->heif_group);
10928
10929 return 0;
10930}
10931
10932static int tmcd_is_referenced(AVFormatContext *s, int tmcd_id)
10933{
10934 int i;
10935
10936 for (i = 0; i < s->nb_streams; i++) {
10937 AVStream *st = s->streams[i];
10938 MOVStreamContext *sc = st->priv_data;
10939 MovTref *tag = mov_find_tref_tag(sc, MKTAG('t','m','c','d'));
10940
10941 if (!tag)
10942 continue;
10943 if (mov_find_tref_id(tag, tmcd_id))
10944 return 1;
10945 }
10946 return 0;
10947}
10948
10949/* look for a tmcd track not referenced by any video track, and export it globally */
10951{
10952 int i;
10953
10954 for (i = 0; i < s->nb_streams; i++) {
10955 AVStream *st = s->streams[i];
10956
10957 if (st->codecpar->codec_tag == MKTAG('t','m','c','d') &&
10958 !tmcd_is_referenced(s, st->id)) {
10959 AVDictionaryEntry *tcr = av_dict_get(st->metadata, "timecode", NULL, 0);
10960 if (tcr) {
10961 av_dict_set(&s->metadata, "timecode", tcr->value, 0);
10962 break;
10963 }
10964 }
10965 }
10966}
10967
10969{
10970 int version, fieldlength, i, j;
10972 uint32_t size = avio_rb32(f);
10973 unsigned track_id, item_count;
10974
10975 if (avio_rb32(f) != MKBETAG('t', 'f', 'r', 'a')) {
10976 return 1;
10977 }
10978 av_log(mov->fc, AV_LOG_VERBOSE, "found tfra\n");
10979
10980 version = avio_r8(f);
10981 avio_rb24(f);
10982 track_id = avio_rb32(f);
10983 fieldlength = avio_rb32(f);
10984 item_count = avio_rb32(f);
10985 for (i = 0; i < item_count; i++) {
10986 int64_t time, offset;
10987 int index;
10988 MOVFragmentStreamInfo * frag_stream_info;
10989
10990 if (avio_feof(f)) {
10991 return AVERROR_INVALIDDATA;
10992 }
10993
10994 if (version == 1) {
10995 time = avio_rb64(f);
10996 offset = avio_rb64(f);
10997 } else {
10998 time = avio_rb32(f);
10999 offset = avio_rb32(f);
11000 }
11001
11002 // The first sample of each stream in a fragment is always a random
11003 // access sample. So it's entry in the tfra can be used as the
11004 // initial PTS of the fragment.
11006 frag_stream_info = get_frag_stream_info(&mov->frag_index, index, track_id);
11007 if (frag_stream_info &&
11008 frag_stream_info->first_tfra_pts == AV_NOPTS_VALUE)
11009 frag_stream_info->first_tfra_pts = time;
11010
11011 for (j = 0; j < ((fieldlength >> 4) & 3) + 1; j++)
11012 avio_r8(f);
11013 for (j = 0; j < ((fieldlength >> 2) & 3) + 1; j++)
11014 avio_r8(f);
11015 for (j = 0; j < ((fieldlength >> 0) & 3) + 1; j++)
11016 avio_r8(f);
11017 }
11018
11019 avio_seek(f, pos + size, SEEK_SET);
11020 return 0;
11021}
11022
11024{
11025 int64_t stream_size = avio_size(f);
11026 int64_t original_pos = avio_tell(f);
11027 int64_t seek_ret;
11028 int ret = -1;
11029 if ((seek_ret = avio_seek(f, stream_size - 4, SEEK_SET)) < 0) {
11030 ret = seek_ret;
11031 goto fail;
11032 }
11033 c->mfra_size = avio_rb32(f);
11034 c->have_read_mfra_size = 1;
11035 if (!c->mfra_size || c->mfra_size > stream_size) {
11036 av_log(c->fc, AV_LOG_DEBUG, "doesn't look like mfra (unreasonable size)\n");
11037 goto fail;
11038 }
11039 if ((seek_ret = avio_seek(f, -((int64_t) c->mfra_size), SEEK_CUR)) < 0) {
11040 ret = seek_ret;
11041 goto fail;
11042 }
11043 if (avio_rb32(f) != c->mfra_size) {
11044 av_log(c->fc, AV_LOG_DEBUG, "doesn't look like mfra (size mismatch)\n");
11045 goto fail;
11046 }
11047 if (avio_rb32(f) != MKBETAG('m', 'f', 'r', 'a')) {
11048 av_log(c->fc, AV_LOG_DEBUG, "doesn't look like mfra (tag mismatch)\n");
11049 goto fail;
11050 }
11051 av_log(c->fc, AV_LOG_VERBOSE, "stream has mfra\n");
11052 do {
11053 ret = read_tfra(c, f);
11054 if (ret < 0)
11055 goto fail;
11056 } while (!ret);
11057 ret = 0;
11058 c->frag_index.complete = 1;
11059fail:
11060 seek_ret = avio_seek(f, original_pos, SEEK_SET);
11061 if (seek_ret < 0) {
11062 av_log(c->fc, AV_LOG_ERROR,
11063 "failed to seek back after looking for mfra\n");
11064 ret = seek_ret;
11065 }
11066 return ret;
11067}
11068
11070 AVPacketSideData **coded_side_data, int *nb_coded_side_data,
11071 const HEIFItem *item)
11072{
11073 AVPacketSideData *sd =
11074 (AVPacketSideData *)av_packet_side_data_get(*coded_side_data,
11075 *nb_coded_side_data,
11077 const AVExifMetadata *ifd = &item->ifd;
11078 AVBufferRef *buf = NULL;
11080 int err;
11081
11082 if (sd)
11083 return 0;
11084
11085 err = av_exif_write(s, ifd, &buf, AV_EXIF_T_OFF);
11086 if (err < 0)
11087 return err;
11088
11089 offset = AV_RB32(buf->data) + 4;
11090 if (offset >= buf->size) {
11091 av_buffer_unref(&buf);
11092 return AVERROR_INVALIDDATA;
11093 }
11094 sd = av_packet_side_data_new(coded_side_data, nb_coded_side_data,
11095 AV_PKT_DATA_EXIF, buf->size - offset, 0);
11096 if (!sd) {
11097 av_buffer_unref(&buf);
11098 return AVERROR(ENOMEM);
11099 }
11100 memcpy(sd->data, buf->data + offset, buf->size - offset);
11101
11102 av_buffer_unref(&buf);
11103
11104 return 0;
11105}
11106
11107static int set_icc_profile_from_item(AVPacketSideData **coded_side_data, int *nb_coded_side_data,
11108 const HEIFItem *item)
11109{
11110 AVPacketSideData *sd =
11111 (AVPacketSideData *)av_packet_side_data_get(*coded_side_data,
11112 *nb_coded_side_data,
11114
11115 if (sd)
11116 return 0;
11117
11118 sd = av_packet_side_data_new(coded_side_data, nb_coded_side_data,
11120 item->icc_profile_size, 0);
11121 if (!sd)
11122 return AVERROR(ENOMEM);
11123
11124 memcpy(sd->data, item->icc_profile, item->icc_profile_size);
11125
11126 return 0;
11127}
11128
11129static int set_display_matrix_from_item(AVPacketSideData **coded_side_data, int *nb_coded_side_data,
11130 const HEIFItem *item)
11131{
11132 int32_t *matrix;
11133 AVPacketSideData *sd =
11134 (AVPacketSideData *)av_packet_side_data_get(*coded_side_data,
11135 *nb_coded_side_data,
11137
11138 if (sd)
11139 return 0;
11140
11141 sd = av_packet_side_data_new(coded_side_data, nb_coded_side_data,
11143 9 * sizeof(*matrix), 0);
11144 if (!sd)
11145 return AVERROR(ENOMEM);
11146
11147 matrix = (int32_t*)sd->data;
11148 /* rotation is in the counter-clockwise direction whereas
11149 * av_display_rotation_set() expects its argument to be
11150 * oriented clockwise, so we need to negate it. */
11153
11154 return 0;
11155}
11156
11158 AVStreamGroupTileGrid *tile_grid)
11159{
11160 MOVContext *c = s->priv_data;
11161 const HEIFItem *item = grid->item;
11162 int64_t coded_width = 0, coded_height = 0;
11163 int64_t offset = 0, pos = avio_tell(s->pb);
11164 int64_t x = 0, y = 0;
11165 int i = 0;
11166 int tile_rows, tile_cols;
11167 int flags, size;
11168
11169 if (!(s->pb->seekable & AVIO_SEEKABLE_NORMAL)) {
11170 av_log(c->fc, AV_LOG_INFO, "grid box with non seekable input\n");
11171 return AVERROR_PATCHWELCOME;
11172 }
11173 if (item->is_idat_relative) {
11174 if (!c->idat_offset) {
11175 av_log(c->fc, AV_LOG_ERROR, "missing idat box required by the image grid\n");
11176 return AVERROR_INVALIDDATA;
11177 }
11178 offset = c->idat_offset;
11179 }
11180
11181 if (offset > INT64_MAX - item->extent_offset)
11182 return AVERROR_INVALIDDATA;
11183
11184 avio_seek(s->pb, item->extent_offset + offset, SEEK_SET);
11185
11186 avio_r8(s->pb); /* version */
11187 flags = avio_r8(s->pb);
11188
11189 tile_rows = avio_r8(s->pb) + 1;
11190 tile_cols = avio_r8(s->pb) + 1;
11191 /* actual width and height of output image */
11192 tile_grid->width = (flags & 1) ? avio_rb32(s->pb) : avio_rb16(s->pb);
11193 tile_grid->height = (flags & 1) ? avio_rb32(s->pb) : avio_rb16(s->pb);
11194
11195 av_log(c->fc, AV_LOG_TRACE, "grid: grid_rows %d grid_cols %d output_width %d output_height %d\n",
11196 tile_rows, tile_cols, tile_grid->width, tile_grid->height);
11197
11198 avio_seek(s->pb, pos, SEEK_SET);
11199
11201 tile_grid->nb_tiles = grid->nb_items;
11202
11203 if (tile_grid->nb_tiles != size)
11204 return AVERROR_INVALIDDATA;
11205
11206 for (int i = 0; i < tile_cols; i++)
11207 coded_width += grid->item_list[i]->width;
11208 for (int i = 0; i < size; i += tile_cols)
11209 coded_height += grid->item_list[i]->height;
11210
11211 if (coded_width > INT_MAX || coded_height > INT_MAX)
11212 return AVERROR_INVALIDDATA;
11213
11214 tile_grid->coded_width = coded_width;
11215 tile_grid->coded_height = coded_height;
11216
11217 tile_grid->offsets = av_calloc(tile_grid->nb_tiles, sizeof(*tile_grid->offsets));
11218 if (!tile_grid->offsets)
11219 return AVERROR(ENOMEM);
11220
11221 while (y < tile_grid->coded_height) {
11222 int left_col = i;
11223
11224 while (x < tile_grid->coded_width) {
11225 if (i == tile_grid->nb_tiles)
11226 return AVERROR_INVALIDDATA;
11227
11228 tile_grid->offsets[i].idx = grid->item_idx_list[i];
11229 tile_grid->offsets[i].horizontal = x;
11230 tile_grid->offsets[i].vertical = y;
11231
11232 x += grid->item_list[i++]->width;
11233 }
11234
11235 if (x > tile_grid->coded_width) {
11236 av_log(c->fc, AV_LOG_ERROR, "Non uniform HEIF tiles\n");
11237 return AVERROR_INVALIDDATA;
11238 }
11239
11240 x = 0;
11241 y += grid->item_list[left_col]->height;
11242 }
11243
11244 if (y > tile_grid->coded_height || i != tile_grid->nb_tiles) {
11245 av_log(c->fc, AV_LOG_ERROR, "Non uniform HEIF tiles\n");
11246 return AVERROR_INVALIDDATA;
11247 }
11248
11249 return 0;
11250}
11251
11253 AVStreamGroupTileGrid *tile_grid)
11254{
11255 MOVContext *c = s->priv_data;
11256 const HEIFItem *item = grid->item;
11257 uint16_t canvas_fill_value[4];
11258 int64_t offset = 0, pos = avio_tell(s->pb);
11259 int ret = 0, flags;
11260
11261 if (!(s->pb->seekable & AVIO_SEEKABLE_NORMAL)) {
11262 av_log(c->fc, AV_LOG_INFO, "iovl box with non seekable input\n");
11263 return AVERROR_PATCHWELCOME;
11264 }
11265 if (item->is_idat_relative) {
11266 if (!c->idat_offset) {
11267 av_log(c->fc, AV_LOG_ERROR, "missing idat box required by the image overlay\n");
11268 return AVERROR_INVALIDDATA;
11269 }
11270 offset = c->idat_offset;
11271 }
11272
11273 if (offset > INT64_MAX - item->extent_offset)
11274 return AVERROR_INVALIDDATA;
11275
11276 avio_seek(s->pb, item->extent_offset + offset, SEEK_SET);
11277
11278 avio_r8(s->pb); /* version */
11279 flags = avio_r8(s->pb);
11280
11281 for (int i = 0; i < 4; i++)
11282 canvas_fill_value[i] = avio_rb16(s->pb);
11283 av_log(c->fc, AV_LOG_TRACE, "iovl: canvas_fill_value { %u, %u, %u, %u }\n",
11284 canvas_fill_value[0], canvas_fill_value[1],
11285 canvas_fill_value[2], canvas_fill_value[3]);
11286 for (int i = 0; i < 4; i++)
11287 tile_grid->background[i] = canvas_fill_value[i];
11288
11289 /* actual width and height of output image */
11290 tile_grid->width =
11291 tile_grid->coded_width = (flags & 1) ? avio_rb32(s->pb) : avio_rb16(s->pb);
11292 tile_grid->height =
11293 tile_grid->coded_height = (flags & 1) ? avio_rb32(s->pb) : avio_rb16(s->pb);
11294
11295 av_log(c->fc, AV_LOG_TRACE, "iovl: output_width %d, output_height %d\n",
11296 tile_grid->width, tile_grid->height);
11297
11298 tile_grid->nb_tiles = grid->nb_items;
11299 tile_grid->offsets = av_malloc_array(tile_grid->nb_tiles, sizeof(*tile_grid->offsets));
11300 if (!tile_grid->offsets) {
11301 ret = AVERROR(ENOMEM);
11302 goto fail;
11303 }
11304
11305 for (int i = 0; i < tile_grid->nb_tiles; i++) {
11306 tile_grid->offsets[i].idx = grid->item_idx_list[i];
11307 tile_grid->offsets[i].horizontal = (flags & 1) ? avio_rb32(s->pb) : avio_rb16(s->pb);
11308 tile_grid->offsets[i].vertical = (flags & 1) ? avio_rb32(s->pb) : avio_rb16(s->pb);
11309 av_log(c->fc, AV_LOG_TRACE, "iovl: stream_idx[%d] %u, "
11310 "horizontal_offset[%d] %d, vertical_offset[%d] %d\n",
11311 i, tile_grid->offsets[i].idx,
11312 i, tile_grid->offsets[i].horizontal, i, tile_grid->offsets[i].vertical);
11313 }
11314
11315fail:
11316 avio_seek(s->pb, pos, SEEK_SET);
11317
11318 return ret;
11319}
11320
11322{
11323 MOVContext *c = s->priv_data;
11324 AVExifMetadata *ifd = &item->ifd;
11325 uint8_t *buf;
11326 int64_t offset = 0, pos = avio_tell(s->pb);
11327 unsigned orientation_id = av_exif_get_tag_id("Orientation");
11328 int err;
11329
11330 if (!(s->pb->seekable & AVIO_SEEKABLE_NORMAL)) {
11331 av_log(c->fc, AV_LOG_WARNING, "Exif metadata with non seekable input\n");
11332 return AVERROR_PATCHWELCOME;
11333 }
11334 if (ref->is_idat_relative) {
11335 if (!c->idat_offset) {
11336 av_log(c->fc, AV_LOG_ERROR, "missing idat box required by the Exif metadata\n");
11337 return AVERROR_INVALIDDATA;
11338 }
11339 offset = c->idat_offset;
11340 }
11341
11342 buf = av_malloc(ref->extent_length);
11343 if (!buf)
11344 return AVERROR(ENOMEM);
11345
11346 if (offset > INT64_MAX - ref->extent_offset) {
11347 err = AVERROR(ENOMEM);
11348 goto fail;
11349 }
11350
11351 avio_seek(s->pb, ref->extent_offset + offset, SEEK_SET);
11352 err = avio_read(s->pb, buf, ref->extent_length);
11353 if (err != ref->extent_length) {
11354 if (err > 0)
11355 err = AVERROR_INVALIDDATA;
11356 goto fail;
11357 }
11358
11359 // HEIF spec states that Exif metadata is informative. The irot item property is
11360 // the normative source of rotation information. So we remove any Orientation tag
11361 // present in the Exif buffer.
11362 err = av_exif_parse_buffer(s, buf, ref->extent_length, ifd, AV_EXIF_T_OFF);
11363 if (err < 0) {
11364 av_log(s, AV_LOG_ERROR, "Unable to parse Exif metadata\n");
11365 goto fail;
11366 }
11367
11368 err = av_exif_remove_entry(s, ifd, orientation_id, 0);
11369 if (err < 0)
11370 goto fail;
11371
11372 err = 0;
11373fail:
11374 av_free(buf);
11375 if (err < 0)
11376 av_exif_free(ifd);
11377 avio_seek(s->pb, pos, SEEK_SET);
11378
11379 return err;
11380}
11381
11383 AVPacketSideData **coded_side_data,
11384 int *nb_coded_side_data)
11385{
11386 int err;
11387
11388 /* exif */
11389 if (item->ifd.count) {
11390 err = set_exif_from_item(s, coded_side_data, nb_coded_side_data, item);
11391 if (err < 0)
11392 return err;
11393 }
11394
11395 /* rotation */
11396 if (item->rotation || item->hflip || item->vflip) {
11397 err = set_display_matrix_from_item(coded_side_data, nb_coded_side_data, item);
11398 if (err < 0)
11399 return err;
11400 }
11401
11402 /* ICC profile */
11403 if (item->icc_profile_size) {
11404 err = set_icc_profile_from_item(coded_side_data, nb_coded_side_data, item);
11405 if (err < 0)
11406 return err;
11407 }
11408
11409 return 0;
11410}
11411
11413 AVPacketSideData **coded_side_data,
11414 int *nb_coded_side_data)
11415{
11416 MOVContext *mov = s->priv_data;
11417 int err;
11418
11419 for (int j = 0; j < item->nb_iref_from_list; j++) {
11421
11422 av_assert0(ref);
11423 switch(ref->type) {
11424 case MKTAG('E','x','i','f'):
11425 err = mov_parse_exif_item(s, item, ref);
11426 if (err < 0 && (s->error_recognition & AV_EF_EXPLODE))
11427 return err;
11428 break;
11429 default:
11430 break;
11431 }
11432 }
11433
11434 err = mov_apply_heif_item_references(s, item, coded_side_data, nb_coded_side_data);
11435 if (err < 0)
11436 return err;
11437
11438 return 0;
11439}
11440
11442{
11443 MOVContext *mov = s->priv_data;
11444
11445 for (int i = 0; i < mov->nb_heif_group; i++) {
11446 AVStreamGroup *stg;
11447 AVStreamGroupTileGrid *tile_grid;
11448 const HEIFGroup *grid = &mov->heif_group[i];
11449 int err;
11450
11451 if (!grid->item || (grid->item->type != MKTAG('g','r','i','d') &&
11452 grid->item->type != MKTAG('i','o','v','l')))
11453 continue;
11454
11456 if (!stg)
11457 return AVERROR(ENOMEM);
11458
11459 stg->id = grid->item->item_id;
11460 tile_grid = stg->params.tile_grid;
11461
11462 for (int j = 0; j < grid->nb_items; j++) {
11463 int tile_id = grid->item_id_list[j];
11464 HEIFItem *item = get_heif_item(mov, tile_id);
11465 AVStream *st;
11466
11467 if (!item) {
11468 av_log(s, AV_LOG_WARNING, "HEIF item id %d referenced by grid id %d doesn't "
11469 "exist\n",
11470 tile_id, grid->item->item_id);
11472 stg = NULL;
11473 break;
11474 }
11475
11476 st = item->st;
11477 if (!st) {
11478 av_log(s, AV_LOG_WARNING, "HEIF item id %d from grid id %d doesn't "
11479 "reference a stream\n",
11480 tile_id, grid->item->item_id);
11482 stg = NULL;
11483 break;
11484 }
11485
11486 grid->item_list[j] = item;
11487 grid->item_idx_list[j] = stg->nb_entries;
11488
11489 err = avformat_stream_group_add_stream(stg, st);
11490 if (err < 0) {
11491 int l;
11492 if (err != AVERROR(EEXIST))
11493 return err;
11494
11495 for (l = 0; l < stg->nb_entries; l++)
11496 if (stg->entries[l]->stream->index == st->index)
11497 break;
11498 av_assert0(l < stg->nb_entries);
11499 grid->item_idx_list[j] = l;
11500 }
11501
11502 if (item->item_id != mov->primary_item_id)
11504 }
11505 if (!stg)
11506 continue;
11507
11508 switch (grid->item->type) {
11509 case MKTAG('g','r','i','d'):
11510 err = read_image_grid(s, grid, tile_grid);
11511 break;
11512 case MKTAG('i','o','v','l'):
11513 err = read_image_iovl(s, grid, tile_grid);
11514 break;
11515 default:
11516 av_assert0(0);
11517 }
11518 if (err < 0)
11519 return err;
11520
11522 &stg->nb_coded_side_data);
11523 if (err < 0)
11524 return err;
11525
11526 if (grid->item->name)
11527 av_dict_set(&stg->metadata, "title", grid->item->name, 0);
11528 if (grid->item->item_id == mov->primary_item_id)
11530
11531 grid->item->stg = stg;
11532 }
11533
11534 return 0;
11535}
11536
11538{
11539 MOVContext *mov = s->priv_data;
11540 AVStreamGroup *stg;
11541 AVStreamGroupLayeredVideo *layered_video;
11542 AVGainMapParams *gain = NULL;
11543 uint8_t *payload = NULL;
11544 int64_t pos, offset = 0;
11545 size_t gain_size;
11546 int64_t err64;
11547 int err;
11548
11549 if (!(s->pb->seekable & AVIO_SEEKABLE_NORMAL)) {
11550 av_log(s, AV_LOG_WARNING, "tmap box with non seekable input\n");
11551 return 0;
11552 }
11553
11555 if (!stg)
11556 return AVERROR(ENOMEM);
11557
11558 stg->id = tmap->item->item_id;
11559 layered_video = stg->params.layered_video;
11560
11561 for (int j = 0; j < tmap->nb_items; j++) {
11562 int item_id = tmap->item_id_list[j];
11563 HEIFItem *item = get_heif_item(mov, item_id);
11564 AVStreamGroup *child_stg;
11565 AVStream *st;
11566
11567 if (!item) {
11568 av_log(s, AV_LOG_WARNING, "HEIF item id %d referenced by tmap id %d doesn't "
11569 "exist\n",
11570 item_id, tmap->item->item_id);
11572 return 0;
11573 }
11574
11575 st = item->st;
11576 child_stg = item->stg;
11577 if (!st && !child_stg) {
11578 av_log(s, AV_LOG_WARNING, "HEIF item id %d from tmap id %d doesn't "
11579 "reference a stream or tmap\n",
11580 item_id, tmap->item->item_id);
11582 return 0;
11583 }
11584 av_assert0(!st != !child_stg);
11585
11586 tmap->item_list[j] = item;
11587
11588 if (st)
11589 err = avformat_stream_group_add_stream(stg, st);
11590 else
11591 err = avformat_stream_group_add_stream_group(stg, child_stg);
11592 if (err < 0) {
11593 if (err == AVERROR(EEXIST))
11594 err = AVERROR_INVALIDDATA;
11595
11596 return err;
11597 }
11598
11599 if ((item->flags & MOV_INFE_FLAG_HIDDEN)) {
11600 if (st)
11602 else
11604 }
11605 }
11606
11607 layered_video->width = tmap->item->width;
11608 layered_video->height = tmap->item->height;
11609
11610 if (tmap->item->is_idat_relative) {
11611 if (!mov->idat_offset) {
11612 av_log(s, AV_LOG_ERROR, "Missing idat box required by the tmap\n");
11613 return AVERROR_INVALIDDATA;
11614 }
11615 offset = mov->idat_offset;
11616 }
11617
11618 if (offset > INT64_MAX - tmap->item->extent_offset)
11619 return AVERROR_INVALIDDATA;
11620
11621 gain = av_gain_map_params_alloc(&gain_size);
11622 if (!gain)
11623 return AVERROR(ENOMEM);
11624
11625 payload = av_malloc(tmap->item->extent_length);
11626 if (!payload) {
11627 return AVERROR(ENOMEM);
11628 goto fail;
11629 }
11630
11631 pos = avio_tell(s->pb);
11632 err64 = avio_seek(s->pb, tmap->item->extent_offset + offset, SEEK_SET);
11633 if (err64 != tmap->item->extent_offset + offset) {
11634 err64 = err64 < 0 ? err64 : AVERROR_INVALIDDATA;
11635 goto fail;
11636 }
11637 avio_r8(s->pb); /* version */
11638
11639 err = avio_read(s->pb, payload, tmap->item->extent_length);
11640 if (err == tmap->item->extent_length)
11641 err64 = avio_seek(s->pb, pos, SEEK_SET);
11642 else {
11643 err = err < 0 ? err : AVERROR_INVALIDDATA;
11644 goto fail;
11645 }
11646 if (err64 != pos) {
11647 err = err64 < 0 ? err64 : AVERROR_INVALIDDATA;
11648 goto fail;
11649 }
11650
11651 err = av_gain_map_params_from_iso21496(gain, payload, tmap->item->extent_length);
11652 av_freep(&payload);
11653 if (err < 0)
11654 goto fail;
11655
11656 for (int j = 0; j < tmap->nb_items; j++) {
11657 HEIFItem *item = tmap->item_list[j];
11658 AVPacketSideData *sd;
11659 AVPacketSideData **coded_side_data;
11660 int *nb_coded_side_data;
11661
11662 if (!(item->flags & MOV_INFE_FLAG_HIDDEN))
11663 continue;
11664
11665 layered_video->el_index = j;
11666
11667 if (item->st) {
11668 coded_side_data = &item->st->codecpar->coded_side_data;
11669 nb_coded_side_data = &item->st->codecpar->nb_coded_side_data;
11670 } else {
11671 av_assert0(item->stg);
11672 coded_side_data = &item->stg->coded_side_data;
11673 nb_coded_side_data = &item->stg->nb_coded_side_data;
11674 }
11675
11676 sd = av_packet_side_data_add(coded_side_data, nb_coded_side_data,
11678 (uint8_t *)gain, gain_size, 0);
11679 if (!sd) {
11680 av_free(gain);
11681 return AVERROR(ENOMEM);
11682 }
11683 gain = NULL;
11684
11685 for (int k = 0; k < item->nb_iref_to_list; k++) {
11686 HEIFItem *ref = get_heif_item(mov, item->iref_to_list[k].item_id);
11687
11688 av_assert0(ref);
11689 // Remove auxl reference so we don't create the same group we made with
11690 // this tmap using it. Strictly speaking, the chances for Apple style
11691 // Exif values being present on a base item referenced by a tmap item
11692 // are very low, but better safe than sorry.
11693 if (item->iref_to_list[k].type == MKTAG('a','u','x','l') &&
11694 (ref == tmap->item_list[!j])) {
11695 if (k != (item->nb_iref_to_list - 1))
11696 item->iref_to_list[k] = item->iref_to_list[item->nb_iref_to_list - 1];
11697 --item->nb_iref_to_list;
11698 break;
11699 }
11700 }
11701 break;
11702 }
11703 av_free(gain);
11704
11706 &stg->nb_coded_side_data);
11707 if (err < 0)
11708 return err;
11709
11710 if (tmap->item->name)
11711 av_dict_set(&stg->metadata, "title", tmap->item->name, 0);
11712 if (tmap->item->item_id == mov->primary_item_id)
11714
11715 tmap->item->stg = stg;
11716
11717 return 0;
11718fail:
11719 av_free(gain);
11720 av_free(payload);
11721
11722 return err;
11723}
11724
11725// Parse Apple style Gain Map metadata from Exif values
11726// See https://developer.apple.com/documentation/appkit/applying-apple-hdr-effect-to-your-photos
11728 HEIFItem *base, HEIFItem *gain_map)
11729{
11730 AVStreamGroupLayeredVideo *layered_video;
11731 AVStreamGroup *stg;
11732 AVGainMapParams *gain;
11733 AVPacketSideData **coded_side_data;
11734 int *nb_coded_side_data;
11735 AVExifEntry *entry, *maker33 = NULL, *maker48 = NULL;
11736 double maker_33 = 0.0, maker_48 = 0.0, headroom;
11737 size_t gain_size;
11738 int err;
11739
11740 if ((!gain_map->st && !gain_map->stg) ||
11741 (!base->st && !base->stg)) {
11742 av_log(s, AV_LOG_WARNING, "HEIF gain_map id %d or its base doesn't reference "
11743 "a stream or group\n",
11744 gain_map->item_id);
11745 return 0;
11746 }
11747
11748 if (!base->ifd.count)
11749 return 0;
11750
11751 err = av_exif_get_entry(s, &base->ifd, 0x8769, 0, &entry);
11752 if (err > 0)
11753 err = av_exif_get_entry(s, &entry->value.ifd, 0x927c, 0, &entry);
11754 if (err > 0) {
11755 av_exif_get_entry(s, &entry->value.ifd, 0x21, 0, &maker33);
11756 av_exif_get_entry(s, &entry->value.ifd, 0x30, 0, &maker48);
11757 }
11758 if ((!maker33 && !maker48) ||
11759 (maker33 && maker33->type != AV_TIFF_SRATIONAL) ||
11760 (maker48 && maker48->type != AV_TIFF_SRATIONAL))
11761 return 0;
11762
11763 if (maker33)
11764 maker_33 = av_q2d(*maker33->value.rat);
11765 if (maker48)
11766 maker_48 = av_q2d(*maker48->value.rat);
11767
11768 if (maker_33 < 1.0) {
11769 if (maker_48 <= 0.01) {
11770 headroom = -20.0 * maker_48 + 1.8;
11771 } else {
11772 headroom = -0.101 * maker_48 + 1.601;
11773 }
11774 } else {
11775 if (maker_48 <= 0.01) {
11776 headroom = -70.0 * maker_48 + 3.0;
11777 } else {
11778 headroom = -0.303 * maker_48 + 2.303;
11779 }
11780 }
11781 if (headroom <= 0.0)
11782 return 0;
11783
11785 if (!stg)
11786 return AVERROR(ENOMEM);
11787
11788 stg->id = gain_map->item_id;
11789 layered_video = stg->params.layered_video;
11790
11791 layered_video->width = base->width;
11792 layered_video->height = base->height;
11793 layered_video->el_index = 1;
11794
11795 av_assert0(!base->st != !base->stg);
11796 if (base->st)
11797 err = avformat_stream_group_add_stream(stg, base->st);
11798 else
11800 if (err < 0) {
11801 if (err == AVERROR(EEXIST))
11802 err = AVERROR_INVALIDDATA;
11803 return err;
11804 }
11805
11806 av_assert0(!gain_map->st != !gain_map->stg);
11807 if (gain_map->st) {
11808 coded_side_data = &gain_map->st->codecpar->coded_side_data;
11809 nb_coded_side_data = &gain_map->st->codecpar->nb_coded_side_data;
11810 err = avformat_stream_group_add_stream(stg, gain_map->st);
11811 } else {
11812 coded_side_data = &gain_map->stg->coded_side_data;
11813 nb_coded_side_data = &gain_map->stg->nb_coded_side_data;
11814 err = avformat_stream_group_add_stream_group(stg, gain_map->stg);
11815 }
11816 if (err < 0) {
11817 if (err == AVERROR(EEXIST))
11818 err = AVERROR_INVALIDDATA;
11819 return err;
11820 }
11821
11822 gain = av_gain_map_params_alloc(&gain_size);
11823 if (!gain)
11824 return AVERROR(ENOMEM);
11825
11826 gain->use_base_color_space = 1;
11827 gain->alternate_hdr_headroom = av_d2q(headroom, INT_MAX);
11828 gain->nb_channels = 1;
11829 gain->channels[0].base_offset = (AVRational) { 0, 1 };
11830 gain->channels[0].alternate_offset = (AVRational) { 0, 1 };
11832
11833 AVPacketSideData *sd = av_packet_side_data_add(coded_side_data, nb_coded_side_data,
11835 (uint8_t *)gain, gain_size, 0);
11836 if (!sd) {
11837 av_free(gain);
11838 return AVERROR(ENOMEM);
11839 }
11840
11841 // Apply all references from the base image except Exif to the Gain Map group
11842 int count = base->ifd.count;
11843 base->ifd.count = 0;
11845 &stg->nb_coded_side_data);
11846 base->ifd.count = count;
11847 if (err < 0)
11848 return err;
11849
11850 return 0;
11851}
11852
11854{
11855 MOVContext *mov = s->priv_data;
11856 int err;
11857
11858 for (int i = 0; i < mov->nb_heif_group; i++) {
11859 const HEIFGroup *tmap = &mov->heif_group[i];
11860
11861 if (!tmap->item)
11862 continue;
11863
11864 switch (tmap->item->type) {
11865 case MKTAG('t','m','a','p'):
11867 if (err < 0)
11868 return err;
11869 break;
11870 default:
11871 break;
11872 }
11873 }
11874
11875 for (int i = 0; i < mov->nb_heif_item; i++) {
11876 HEIFItem *item = mov->heif_item[i];
11877 int err;
11878
11879 if (!item)
11880 continue;
11881
11882 for (int j = 0; j < item->nb_iref_to_list; j++) {
11883 HEIFItem *ref = get_heif_item(mov, item->iref_to_list[j].item_id);
11884
11885 av_assert0(ref);
11886 switch(item->iref_to_list[j].type) {
11887 case MKTAG('a','u','x','l'):
11888 if (!item->is_gainmap)
11889 break;
11890
11892 if (err < 0)
11893 return err;
11894 break;
11895 }
11896 }
11897 }
11898
11899 return 0;
11900}
11901
11903{
11904 MOVContext *mov = s->priv_data;
11905 int err;
11906
11907 for (int i = 0; i < mov->nb_heif_item; i++) {
11908 HEIFItem *item = mov->heif_item[i];
11909 MOVStreamContext *sc;
11910 AVStream *st;
11911 int64_t offset = 0;
11912
11913 if (!item)
11914 continue;
11915 if (!item->st) {
11916 continue;
11917 }
11918 if (item->is_idat_relative) {
11919 if (!mov->idat_offset) {
11920 av_log(s, AV_LOG_ERROR, "Missing idat box for item %d\n", item->item_id);
11921 return AVERROR_INVALIDDATA;
11922 }
11923 offset = mov->idat_offset;
11924 }
11925
11926 st = item->st;
11927 sc = st->priv_data;
11928 st->codecpar->width = item->width;
11929 st->codecpar->height = item->height;
11930
11931 sc->sample_size = sc->stsz_sample_size = item->extent_length;
11932 sc->sample_count = 1;
11933
11934 err = sanity_checks(s, sc, st->index);
11935 if (err)
11936 return AVERROR_INVALIDDATA;
11937
11938 if (offset > INT64_MAX - item->extent_offset)
11939 return AVERROR_INVALIDDATA;
11940
11941 sc->chunk_offsets[0] = item->extent_offset + offset;
11942
11945 if (err < 0)
11946 return err;
11947
11948 if (item->name)
11949 av_dict_set(&st->metadata, "title", item->name, 0);
11950 if (item->item_id == mov->primary_item_id)
11952
11953 mov_build_index(mov, st);
11954 }
11955
11956 if (mov->nb_heif_group) {
11957 err = mov_parse_tiles(s);
11958 if (err < 0)
11959 return err;
11960
11962 if (err < 0)
11963 return err;
11964 }
11965
11966 return 0;
11967}
11968
11970{
11971 int err;
11972
11973 for (int i = 0; i < s->nb_streams; i++) {
11974 AVStreamGroup *stg;
11975 const AVDictionaryEntry *tcr;
11976 AVStream *st = s->streams[i];
11977
11978 if (st->codecpar->codec_tag != MKTAG('t','m','c','d'))
11979 continue;
11980
11982 if (!stg)
11983 return AVERROR(ENOMEM);
11984
11985 stg->id = st->id;
11986 tcr = av_dict_get(st->metadata, "timecode", NULL, 0);
11987
11988 for (int j = 0; j < s->nb_streams; j++) {
11989 AVStream *st2 = s->streams[j];
11990 MOVStreamContext *sc2 = st2->priv_data;
11991 MovTref *tag = mov_find_tref_tag(sc2, MKTAG('t','m','c','d'));
11992
11993 if (!tag)
11994 continue;
11995
11996 for (int k = 0; k < tag->nb_id; k++) {
11997 if (tag->id[k] != st->id)
11998 continue;
11999
12000 err = avformat_stream_group_add_stream(stg, st2);
12001 if (err < 0)
12002 return err;
12003
12004 if (tcr)
12005 av_dict_set(&st2->metadata, "timecode", tcr->value, AV_DICT_DONT_OVERWRITE);
12006 }
12007 }
12008
12009 if (!stg->nb_entries) {
12011 continue;
12012 }
12013
12014 err = avformat_stream_group_add_stream(stg, st);
12015 if (err < 0)
12016 return err;
12017
12018 stg->params.tref->metadata_index = stg->nb_entries - 1;
12019 }
12021
12022 return 0;
12023}
12024
12026 uint32_t *tref_id, int nb_tref_id, int first_index)
12027{
12028 if (!nb_tref_id)
12029 return NULL;
12030
12031 for (int i = first_index; i < s->nb_streams; i++)
12032 for (int j = 0; j < nb_tref_id; j++)
12033 if (s->streams[i]->index != st->index &&
12034 s->streams[i]->id == tref_id[j])
12035 return s->streams[i];
12036
12037 return NULL;
12038}
12039
12041{
12042 static const uint32_t tref_tags[] = {
12043 MKTAG('c','d','s','c'),
12044 MKTAG('r','n','d','r'),
12045 };
12046
12047 int err;
12048
12049 // Don't try to add a group if there's only one track
12050 if (s->nb_streams <= 1)
12051 return 0;
12052
12053 for (int i = 0; i < s->nb_streams; i++) {
12054 AVStream *st = s->streams[i];
12055 MOVStreamContext *sc = st->priv_data;
12056
12057 for (int c = 0; c < FF_ARRAY_ELEMS(tref_tags); c++) {
12058 AVStreamGroup *stg;
12059 AVStream *st_ref;
12060 MovTref *tag = mov_find_tref_tag(sc, tref_tags[c]);
12061
12062 if (!tag)
12063 continue;
12064
12065 st_ref = mov_find_reference_track(s, st, tag->id, tag->nb_id, 0);
12066 if (!st_ref) {
12067 av_log(s, AV_LOG_WARNING, "Failed to find referenced stream\n");
12068 continue;
12069 }
12070
12072 if (!stg)
12073 return AVERROR(ENOMEM);
12074
12075 stg->id = st_ref->id;
12076
12077 err = avformat_stream_group_add_stream(stg, st_ref);
12078 if (err < 0)
12079 return err;
12080
12081 err = avformat_stream_group_add_stream(stg, st);
12082 if (err < 0)
12083 return err;
12084
12085 stg->params.tref->metadata_index = stg->nb_entries - 1;
12086 }
12087 }
12088
12089 return 0;
12090}
12091
12093{
12094 int err;
12095
12096 // Don't try to add a group if there's only one track
12097 if (s->nb_streams <= 1)
12098 return 0;
12099
12100 for (int i = 0; i < s->nb_streams; i++) {
12101 AVStreamGroup *stg;
12102 AVStream *st = s->streams[i];
12103 AVStream *st_base;
12104 MOVStreamContext *sc = st->priv_data;
12105 MovTref *tag = mov_find_tref_tag(sc, MKTAG('s','b','a','s'));
12106 int j = 0;
12107
12108 /* Find an enhancement stream. */
12109 if (st->codecpar->codec_id != AV_CODEC_ID_LCEVC || !tag)
12110 continue;
12111
12113 if (!stg)
12114 return AVERROR(ENOMEM);
12115
12116 stg->id = st->id;
12119
12120 while (st_base = mov_find_reference_track(s, st, tag->id, tag->nb_id, j)) {
12121 err = avformat_stream_group_add_stream(stg, st_base);
12122 if (err < 0)
12123 return err;
12124
12125 j = st_base->index + 1;
12126 }
12127 if (!j) {
12128 int loglevel = (s->error_recognition & AV_EF_EXPLODE) ? AV_LOG_ERROR : AV_LOG_WARNING;
12129 av_log(s, loglevel, "Failed to find base stream for LCEVC stream\n");
12131 if (s->error_recognition & AV_EF_EXPLODE)
12132 return AVERROR_INVALIDDATA;
12133 continue;
12134 }
12135
12136 err = avformat_stream_group_add_stream(stg, st);
12137 if (err < 0)
12138 return err;
12139
12140 stg->params.layered_video->el_index = stg->nb_entries - 1;
12141 }
12142
12143 return 0;
12144}
12145
12147{
12148 int err;
12149
12150 if (s->nb_streams <= 1)
12151 return 0;
12152
12153 /* Identify legacy dual-track Dolby Vision profile 7 carriage per Annex
12154 * C of "Dolby Vision Streams Within the ISO Base Media File Format",
12155 * v2.7.1. The 'vdep' track reference type is shared with depth video
12156 * and multi-view dependencies. The spec-mandated DV-specific sample
12157 * entry combined with the dvcC configuration record disambiguates
12158 * those uses. */
12159 for (int i = 0; i < s->nb_streams; i++) {
12160 AVStreamGroup *stg;
12161 AVStream *st = s->streams[i];
12162 AVStream *st_base;
12163 MOVStreamContext *sc = st->priv_data;
12164 MovTref *tag = mov_find_tref_tag(sc, MKTAG('v','d','e','p'));
12165 const AVPacketSideData *sd;
12167
12168 if (st->codecpar->codec_id != AV_CODEC_ID_HEVC || !tag)
12169 continue;
12170
12171 if (st->codecpar->codec_tag != MKTAG('d','v','h','e') &&
12172 st->codecpar->codec_tag != MKTAG('d','v','h','1'))
12173 continue;
12174
12178 if (!sd)
12179 continue;
12180 dovi = (const AVDOVIDecoderConfigurationRecord *)sd->data;
12181
12182 /* EL track of a dual-track stream: rpu_present_flag = 1,
12183 * el_present_flag = 1, bl_present_flag = 0, dv_profile = 7. */
12184 if (dovi->dv_profile != 7 || !dovi->rpu_present_flag ||
12185 !dovi->el_present_flag || dovi->bl_present_flag)
12186 continue;
12187
12188 st_base = mov_find_reference_track(s, st, tag->id, tag->nb_id, 0);
12189 if (!st_base) {
12190 int loglevel = (s->error_recognition & AV_EF_EXPLODE) ? AV_LOG_ERROR : AV_LOG_WARNING;
12191 av_log(s, loglevel, "Failed to find base layer for Dolby Vision EL stream\n");
12192 if (s->error_recognition & AV_EF_EXPLODE)
12193 return AVERROR_INVALIDDATA;
12194 continue;
12195 }
12196
12198 if (!stg)
12199 return AVERROR(ENOMEM);
12200
12201 stg->id = st->id;
12202
12203 err = avformat_stream_group_add_stream(stg, st_base);
12204 if (err < 0)
12205 return err;
12206
12207 err = avformat_stream_group_add_stream(stg, st);
12208 if (err < 0)
12209 return err;
12210
12211 stg->params.layered_video->el_index = stg->nb_entries - 1;
12212 stg->params.layered_video->width = st_base->codecpar->width;
12213 stg->params.layered_video->height = st_base->codecpar->height;
12214 }
12215
12216 return 0;
12217}
12218
12220{
12221 int highest_id = 0, lowest_iamf_id = INT_MAX;
12222
12223 for (int i = 0; i < s->nb_streams; i++) {
12224 const AVStream *st = s->streams[i];
12225 const MOVStreamContext *sc = st->priv_data;
12226 if (!sc->iamf)
12227 highest_id = FFMAX(highest_id, st->id);
12228 }
12229
12230 for (int i = 0; i < s->nb_stream_groups; i++) {
12231 AVStreamGroup *stg = s->stream_groups[i];
12233 continue;
12234 for (int j = 0; j < stg->nb_entries; j++) {
12235 AVStream *st = stg->entries[j]->stream;
12236 lowest_iamf_id = FFMIN(lowest_iamf_id, st->id);
12237 }
12238 }
12239
12240 if (highest_id < lowest_iamf_id)
12241 return;
12242
12243 highest_id += !lowest_iamf_id;
12244 for (int i = 0; highest_id > 1 && i < s->nb_stream_groups; i++) {
12245 AVStreamGroup *stg = s->stream_groups[i];
12247 continue;
12248 for (int j = 0; j < stg->nb_entries; j++) {
12249 AVStream *st = stg->entries[j]->stream;
12250 MOVStreamContext *sc = st->priv_data;
12251 st->id += highest_id;
12252 sc->iamf_stream_offset = highest_id;
12253 }
12254 }
12255}
12256
12258{
12259 MOVContext *mov = s->priv_data;
12260 AVIOContext *pb = s->pb;
12261 int j, err;
12262 MOVAtom atom = { AV_RL32("root") };
12263 int i;
12264
12265 mov->fc = s;
12266 mov->trak_index = -1;
12267 mov->primary_item_id = -1;
12268 mov->cur_item_id = -1;
12269 /* .mov and .mp4 aren't streamable anyway (only progressive download if moov is before mdat) */
12271 atom.size = avio_size(pb);
12272 else
12273 atom.size = INT64_MAX;
12274
12275 /* check MOV header */
12276 do {
12277 if (mov->moov_retry)
12278 avio_seek(pb, 0, SEEK_SET);
12279 if ((err = mov_read_default(mov, pb, atom)) < 0) {
12280 av_log(s, AV_LOG_ERROR, "error reading header\n");
12281 return err;
12282 }
12283 } while ((pb->seekable & AVIO_SEEKABLE_NORMAL) &&
12284 !mov->found_moov && (!mov->found_iloc || !mov->found_iinf) && !mov->moov_retry++);
12285 if (!mov->found_moov && !mov->found_iloc && !mov->found_iinf) {
12286 av_log(s, AV_LOG_ERROR, "moov atom not found\n");
12287 return AVERROR_INVALIDDATA;
12288 }
12289 av_log(mov->fc, AV_LOG_TRACE, "on_parse_exit_offset=%"PRId64"\n", avio_tell(pb));
12290
12291 if (mov->found_iloc && mov->found_iinf) {
12292 err = mov_parse_heif_items(s);
12293 if (err < 0)
12294 return err;
12295 }
12296 // prevent iloc and iinf boxes from being parsed while reading packets.
12297 // this is needed because an iinf box may have been parsed but ignored
12298 // for having old infe boxes which create no streams.
12299 mov->found_iloc = mov->found_iinf = 1;
12300
12301 if (pb->seekable & AVIO_SEEKABLE_NORMAL) {
12302 if (mov->nb_chapter_tracks > 0 && !mov->ignore_chapters)
12304 for (i = 0; i < s->nb_streams; i++)
12305 if (s->streams[i]->codecpar->codec_tag == AV_RL32("tmcd")) {
12306 mov_read_timecode_track(s, s->streams[i]);
12307 } else if (s->streams[i]->codecpar->codec_tag == AV_RL32("rtmd")) {
12308 mov_read_rtmd_track(s, s->streams[i]);
12309 }
12310 }
12311
12312 /* Create metadata stream groups. */
12314 if (err < 0)
12315 return err;
12316
12317 /* copy timecode metadata from tmcd tracks to the related video streams */
12319 if (err < 0)
12320 return err;
12321
12322 /* Create LCEVC stream groups. */
12324 if (err < 0)
12325 return err;
12326
12327 /* Create Dolby Vision Profile 7 stream groups. */
12329 if (err < 0)
12330 return err;
12331
12332 for (i = 0; i < s->nb_streams; i++) {
12333 AVStream *st = s->streams[i];
12334 FFStream *const sti = ffstream(st);
12335 MOVStreamContext *sc = st->priv_data;
12336 uint32_t dvdsub_clut[FF_DVDCLUT_CLUT_LEN] = {0};
12337 fix_timescale(mov, sc);
12338
12339 /* Set the primary extradata based on the first Sample if it doesn't reference the first stsd entry. */
12340 if (sc->stsc_count && sc->extradata_size && !sc->iamf &&
12341 sc->stsc_data[0].id > 1 && sc->stsc_data[0].id <= sc->stsd_count) {
12342 sc->last_stsd_index = sc->stsc_data[0].id - 1;
12345 if (sc->extradata_size[sc->last_stsd_index]) {
12347 if (!st->codecpar->extradata)
12348 return AVERROR(ENOMEM);
12350 }
12351 }
12352
12356 }
12359 sc->time_scale*(int64_t)sc->nb_frames_for_fps, sc->duration_for_fps, INT_MAX);
12361 if (st->codecpar->width <= 0 || st->codecpar->height <= 0) {
12362 st->codecpar->width = sc->width;
12363 st->codecpar->height = sc->height;
12364 }
12367
12368 for (j = 0; j < FF_DVDCLUT_CLUT_LEN; j++)
12369 dvdsub_clut[j] = AV_RB32(st->codecpar->extradata + j * 4);
12370
12371 err = ff_dvdclut_yuv_to_rgb(dvdsub_clut, FF_DVDCLUT_CLUT_SIZE);
12372 if (err < 0)
12373 return err;
12374
12376 st->codecpar->extradata_size = 0;
12377
12379 st->codecpar);
12380 if (err < 0)
12381 return err;
12382 }
12383 }
12384 if (mov->handbrake_version &&
12385 mov->handbrake_version <= 1000000*0 + 1000*10 + 2 && // 0.10.2
12387 av_log(s, AV_LOG_VERBOSE, "Forcing full parsing for mp3 stream\n");
12389 }
12390 }
12391
12392 if (mov->trex_data || mov->use_mfra_for > 0) {
12393 for (i = 0; i < s->nb_streams; i++) {
12394 AVStream *st = s->streams[i];
12395 MOVStreamContext *sc = st->priv_data;
12396 if (sc->duration_for_fps > 0) {
12397 /* Akin to sc->data_size * 8 * sc->time_scale / sc->duration_for_fps but accounting for overflows. */
12399 if (st->codecpar->bit_rate == INT64_MIN) {
12400 av_log(s, AV_LOG_WARNING, "Overflow during bit rate calculation %"PRId64" * 8 * %d\n",
12401 sc->data_size, sc->time_scale);
12402 st->codecpar->bit_rate = 0;
12403 if (s->error_recognition & AV_EF_EXPLODE)
12404 return AVERROR_INVALIDDATA;
12405 }
12406 }
12407 }
12408 }
12409
12410 for (i = 0; i < mov->bitrates_count && i < s->nb_streams; i++) {
12411 if (mov->bitrates[i]) {
12412 s->streams[i]->codecpar->bit_rate = mov->bitrates[i];
12413 }
12414 }
12415
12417
12418 for (i = 0; i < s->nb_streams; i++) {
12419 AVStream *st = s->streams[i];
12420 MOVStreamContext *sc = st->priv_data;
12421
12422 switch (st->codecpar->codec_type) {
12423 case AVMEDIA_TYPE_AUDIO:
12424 err = ff_replaygain_export(st, s->metadata);
12425 if (err < 0)
12426 return err;
12427 break;
12428 case AVMEDIA_TYPE_VIDEO:
12429 if (sc->display_matrix) {
12432 (uint8_t*)sc->display_matrix, sizeof(int32_t) * 9, 0))
12433 return AVERROR(ENOMEM);
12434
12435 sc->display_matrix = NULL;
12436 }
12437 if (sc->stereo3d) {
12440 (uint8_t *)sc->stereo3d, sc->stereo3d_size, 0))
12441 return AVERROR(ENOMEM);
12442
12443 sc->stereo3d = NULL;
12444 }
12445 if (sc->spherical) {
12448 (uint8_t *)sc->spherical, sc->spherical_size, 0))
12449 return AVERROR(ENOMEM);
12450
12451 sc->spherical = NULL;
12452 }
12453 if (sc->mastering) {
12456 (uint8_t *)sc->mastering, sc->mastering_size, 0))
12457 return AVERROR(ENOMEM);
12458
12459 sc->mastering = NULL;
12460 }
12461 if (sc->coll) {
12464 (uint8_t *)sc->coll, sc->coll_size, 0))
12465 return AVERROR(ENOMEM);
12466
12467 sc->coll = NULL;
12468 }
12469 if (sc->ambient) {
12472 (uint8_t *) sc->ambient, sc->ambient_size, 0))
12473 return AVERROR(ENOMEM);
12474
12475 sc->ambient = NULL;
12476 }
12477 break;
12478 }
12479 }
12480
12482
12484
12485 for (i = 0; i < mov->frag_index.nb_items; i++)
12486 if (mov->frag_index.item[i].moof_offset <= mov->fragment.moof_offset)
12487 mov->frag_index.item[i].headers_read = 1;
12488
12489 return 0;
12490}
12491
12493{
12495 int64_t best_dts = INT64_MAX;
12496 int i;
12497 MOVContext *mov = s->priv_data;
12498 int no_interleave = !mov->interleaved_read || !(s->pb->seekable & AVIO_SEEKABLE_NORMAL);
12499 for (i = 0; i < s->nb_streams; i++) {
12500 AVStream *avst = s->streams[i];
12501 FFStream *const avsti = ffstream(avst);
12502 MOVStreamContext *msc = avst->priv_data;
12503 if (msc->pb && msc->current_sample < avsti->nb_index_entries) {
12504 AVIndexEntry *current_sample = &avsti->index_entries[msc->current_sample];
12505 int64_t dts = av_rescale(current_sample->timestamp, AV_TIME_BASE, msc->time_scale);
12506 uint64_t dtsdiff = best_dts > dts ? best_dts - (uint64_t)dts : ((uint64_t)dts - best_dts);
12507 av_log(s, AV_LOG_TRACE, "stream %d, sample %d, dts %"PRId64"\n", i, msc->current_sample, dts);
12508 if (!sample || (no_interleave && current_sample->pos < sample->pos) ||
12509 ((s->pb->seekable & AVIO_SEEKABLE_NORMAL) &&
12510 ((msc->pb != s->pb && dts < best_dts) || (msc->pb == s->pb && dts != AV_NOPTS_VALUE &&
12511 ((dtsdiff <= AV_TIME_BASE && current_sample->pos < sample->pos) ||
12512 (dtsdiff > AV_TIME_BASE && dts < best_dts && mov->interleaved_read)))))) {
12513 sample = current_sample;
12514 best_dts = dts;
12515 *st = avst;
12516 }
12517 }
12518 }
12519 return sample;
12520}
12521
12522static int should_retry(AVIOContext *pb, int error_code) {
12523 if (error_code == AVERROR_EOF || avio_feof(pb))
12524 return 0;
12525
12526 return 1;
12527}
12528
12530{
12531 int ret;
12532 MOVContext *mov = s->priv_data;
12533
12534 if (index >= 0 && index < mov->frag_index.nb_items)
12535 target = mov->frag_index.item[index].moof_offset;
12536 if (target >= 0 && avio_seek(s->pb, target, SEEK_SET) != target) {
12537 av_log(mov->fc, AV_LOG_ERROR, "root atom offset 0x%"PRIx64": partial file\n", target);
12538 return AVERROR_INVALIDDATA;
12539 }
12540
12541 mov->next_root_atom = 0;
12542 if ((index < 0 && target >= 0) || index >= mov->frag_index.nb_items)
12543 index = search_frag_moof_offset(&mov->frag_index, target);
12544 if (index >= 0 && index < mov->frag_index.nb_items &&
12545 mov->frag_index.item[index].moof_offset == target) {
12546 if (index + 1 < mov->frag_index.nb_items)
12549 return 0;
12551 }
12552
12553 mov->found_mdat = 0;
12554
12555 ret = mov_read_default(mov, s->pb, (MOVAtom){ AV_RL32("root"), INT64_MAX });
12556 if (ret < 0)
12557 return ret;
12558 if (avio_feof(s->pb))
12559 return AVERROR_EOF;
12560 av_log(s, AV_LOG_TRACE, "read fragments, offset 0x%"PRIx64"\n", avio_tell(s->pb));
12561
12562 return 1;
12563}
12564
12566{
12567 MOVStreamContext *sc = st->priv_data;
12568 uint8_t *side, *extradata;
12569 int extradata_size;
12570
12571 /* Save the current index. */
12572 sc->last_stsd_index = sc->stsc_data[sc->stsc_index].id - 1;
12573
12574 /* Notify the decoder that extradata changed. */
12575 extradata_size = sc->extradata_size[sc->last_stsd_index];
12576 extradata = sc->extradata[sc->last_stsd_index];
12577 if (st->discard != AVDISCARD_ALL && extradata_size > 0 && extradata) {
12580 extradata_size);
12581 if (!side)
12582 return AVERROR(ENOMEM);
12583 memcpy(side, extradata, extradata_size);
12584 }
12585
12586 return 0;
12587}
12588
12589static int get_eia608_packet(AVIOContext *pb, AVPacket *pkt, int src_size)
12590{
12591 /* We can't make assumptions about the structure of the payload,
12592 because it may include multiple cdat and cdt2 samples. */
12593 const uint32_t cdat = AV_RB32("cdat");
12594 const uint32_t cdt2 = AV_RB32("cdt2");
12595 int ret, out_size = 0;
12596
12597 /* a valid payload must have size, 4cc, and at least 1 byte pair: */
12598 if (src_size < 10)
12599 return AVERROR_INVALIDDATA;
12600
12601 /* avoid an int overflow: */
12602 if ((src_size - 8) / 2 >= INT_MAX / 3)
12603 return AVERROR_INVALIDDATA;
12604
12605 ret = av_new_packet(pkt, ((src_size - 8) / 2) * 3);
12606 if (ret < 0)
12607 return ret;
12608
12609 /* parse and re-format the c608 payload in one pass. */
12610 while (src_size >= 10) {
12611 const uint32_t atom_size = avio_rb32(pb);
12612 const uint32_t atom_type = avio_rb32(pb);
12613 const uint32_t data_size = atom_size - 8;
12614 const uint8_t cc_field =
12615 atom_type == cdat ? 1 :
12616 atom_type == cdt2 ? 2 :
12617 0;
12618
12619 /* account for bytes consumed for atom size and type. */
12620 src_size -= 8;
12621
12622 /* make sure the data size stays within the buffer boundaries. */
12623 if (data_size < 2 || data_size > src_size) {
12624 ret = AVERROR_INVALIDDATA;
12625 break;
12626 }
12627
12628 /* make sure the data size is consistent with N byte pairs. */
12629 if (data_size % 2 != 0) {
12630 ret = AVERROR_INVALIDDATA;
12631 break;
12632 }
12633
12634 if (!cc_field) {
12635 /* neither cdat or cdt2 ... skip it */
12636 avio_skip(pb, data_size);
12637 src_size -= data_size;
12638 continue;
12639 }
12640
12641 for (uint32_t i = 0; i < data_size; i += 2) {
12642 pkt->data[out_size] = (0x1F << 3) | (1 << 2) | (cc_field - 1);
12643 pkt->data[out_size + 1] = avio_r8(pb);
12644 pkt->data[out_size + 2] = avio_r8(pb);
12645 out_size += 3;
12646 src_size -= 2;
12647 }
12648 }
12649
12650 if (src_size > 0)
12651 /* skip any remaining unread portion of the input payload */
12652 avio_skip(pb, src_size);
12653
12655 return ret;
12656}
12657
12659 int64_t current_index, AVPacket *pkt)
12660{
12661 MOVContext *mov = s->priv_data;
12662 MOVStreamContext *sc = st->priv_data;
12663
12664 pkt->stream_index = sc->ffindex;
12665 pkt->dts = sample->timestamp;
12666 if (sample->flags & AVINDEX_DISCARD_FRAME) {
12667 pkt->flags |= AV_PKT_FLAG_DISCARD;
12668 }
12669 if (sc->stts_count && sc->tts_index < sc->tts_count)
12670 pkt->duration = sc->tts_data[sc->tts_index].duration;
12671 if (sc->ctts_count && sc->tts_index < sc->tts_count) {
12672 pkt->pts = av_sat_add64(pkt->dts, av_sat_add64(sc->dts_shift, sc->tts_data[sc->tts_index].offset));
12673 } else {
12674 if (pkt->duration == 0) {
12675 int64_t next_dts = (sc->current_sample < ffstream(st)->nb_index_entries) ?
12677 if (next_dts >= pkt->dts)
12678 pkt->duration = next_dts - pkt->dts;
12679 }
12680 pkt->pts = pkt->dts;
12681 }
12682
12684 sc->current_sample >= ffstream(st)->nb_index_entries) {
12685 int64_t pts = av_rescale_q(pkt->pts, st->time_base, (AVRational){ 1, st->codecpar->sample_rate });
12686 int64_t total = av_rescale_q(st->duration, st->time_base, (AVRational){ 1, st->codecpar->sample_rate });
12687 int64_t duration = pkt->duration;
12688
12689 if (st->duration < pkt->pts) {
12690 duration = 0;
12691 } else
12692 duration = FFMIN(duration, (uint64_t)st->duration - pkt->pts);
12693
12694 duration = av_rescale_q(duration, st->time_base, (AVRational){ 1, st->codecpar->sample_rate });
12695
12696 if (!ffstream(st)->first_discard_sample)
12698 if (!ffstream(st)->last_discard_sample)
12699 ffstream(st)->last_discard_sample = total;
12700 }
12701
12702 if (sc->tts_data && sc->tts_index < sc->tts_count) {
12703 /* update tts context */
12704 sc->tts_sample++;
12705 if (sc->tts_index < sc->tts_count &&
12706 sc->tts_data[sc->tts_index].count == sc->tts_sample) {
12707 sc->tts_index++;
12708 sc->tts_sample = 0;
12709 }
12710 }
12711
12712 if (sc->sdtp_data && sc->current_sample <= sc->sdtp_count) {
12713 uint8_t sample_flags = sc->sdtp_data[sc->current_sample - 1];
12714 uint8_t sample_is_depended_on = (sample_flags >> 2) & 0x3;
12715 pkt->flags |= sample_is_depended_on == MOV_SAMPLE_DEPENDENCY_NO ? AV_PKT_FLAG_DISPOSABLE : 0;
12716 }
12717 pkt->flags |= sample->flags & AVINDEX_KEYFRAME ? AV_PKT_FLAG_KEY : 0;
12718 pkt->pos = sample->pos;
12719
12720 /* Multiple stsd handling. */
12721 if (sc->stsc_data) {
12722 if (sc->stsc_data[sc->stsc_index].id > 0 &&
12723 sc->stsc_data[sc->stsc_index].id - 1 < sc->stsd_count &&
12724 sc->stsc_data[sc->stsc_index].id - 1 != sc->last_stsd_index) {
12725 int ret = mov_change_extradata(st, pkt);
12726 if (ret < 0)
12727 return ret;
12728 }
12729
12730 /* Update the stsc index for the next sample */
12731 sc->stsc_sample++;
12734 sc->stsc_index++;
12735 sc->stsc_sample = 0;
12736 }
12737 }
12738
12739 return 0;
12740}
12741
12743{
12744 MOVContext *mov = s->priv_data;
12745 MOVStreamContext *sc;
12747 AVStream *st = NULL;
12748 FFStream *avsti = NULL;
12749 int64_t current_index;
12750 int ret;
12751 int i;
12752 mov->fc = s;
12753 retry:
12754 if (s->pb->pos == 0) {
12755
12756 // Discard current fragment index
12757 if (mov->frag_index.allocated_size > 0) {
12758 for(int i = 0; i < mov->frag_index.nb_items; i++) {
12760 }
12761 av_freep(&mov->frag_index.item);
12762 mov->frag_index.nb_items = 0;
12763 mov->frag_index.allocated_size = 0;
12764 mov->frag_index.current = -1;
12765 mov->frag_index.complete = 0;
12766 }
12767
12768 for (i = 0; i < s->nb_streams; i++) {
12769 AVStream *avst = s->streams[i];
12770 MOVStreamContext *msc = avst->priv_data;
12771
12772 // Clear current sample
12773 mov_current_sample_set(msc, 0);
12774 msc->tts_index = 0;
12775
12776 // Discard current index entries
12777 avsti = ffstream(avst);
12778 if (avsti->index_entries_allocated_size > 0) {
12779 av_freep(&avsti->index_entries);
12781 avsti->nb_index_entries = 0;
12782 }
12783 }
12784
12785 if ((ret = mov_switch_root(s, -1, -1)) < 0)
12786 return ret;
12787 }
12789 if (!sample || (mov->next_root_atom && sample->pos > mov->next_root_atom)) {
12790 if (!mov->next_root_atom)
12791 return AVERROR_EOF;
12792 if ((ret = mov_switch_root(s, mov->next_root_atom, -1)) < 0)
12793 return ret;
12794 goto retry;
12795 }
12796 sc = st->priv_data;
12797 /* must be done just before reading, to avoid infinite loop on sample */
12798 current_index = sc->current_index;
12800
12801 if (mov->next_root_atom) {
12802 sample->pos = FFMIN(sample->pos, mov->next_root_atom);
12803 sample->size = FFMIN(sample->size, (mov->next_root_atom - sample->pos));
12804 }
12805
12806 if (st->discard != AVDISCARD_ALL || sc->iamf) {
12807 int64_t ret64 = avio_seek(sc->pb, sample->pos, SEEK_SET);
12808 if (ret64 != sample->pos) {
12809 av_log(mov->fc, AV_LOG_ERROR, "stream %d, offset 0x%"PRIx64": partial file\n",
12810 sc->ffindex, sample->pos);
12811 if (should_retry(sc->pb, ret64)) {
12813 } else if (ret64 < 0) {
12814 return (int)ret64;
12815 }
12816 return AVERROR_INVALIDDATA;
12817 }
12818
12819 if (st->discard == AVDISCARD_NONKEY && !(sample->flags & AVINDEX_KEYFRAME)) {
12820 av_log(mov->fc, AV_LOG_DEBUG, "Nonkey frame from stream %d discarded due to AVDISCARD_NONKEY\n", sc->ffindex);
12821 goto retry;
12822 }
12823
12824 if (st->codecpar->codec_id == AV_CODEC_ID_EIA_608 && sample->size > 8)
12825 ret = get_eia608_packet(sc->pb, pkt, sample->size);
12826#if CONFIG_IAMFDEC
12827 else if (sc->iamf) {
12828 int64_t pts, dts, pos, duration;
12829 int flags, size = sample->size;
12830 ret = mov_finalize_packet(s, st, sample, current_index, pkt);
12831 pts = pkt->pts; dts = pkt->dts;
12832 pos = pkt->pos; flags = pkt->flags;
12833 duration = pkt->duration;
12834 while (!ret && size > 0) {
12835 ret = ff_iamf_read_packet(s, sc->iamf, sc->pb, size, sc->iamf_stream_offset, pkt);
12836 if (ret < 0) {
12837 if (should_retry(sc->pb, ret))
12839 return ret;
12840 }
12841 size -= ret;
12842
12843 if (pkt->flags & AV_PKT_FLAG_DISCARD) {
12845 ret = 0;
12846 continue;
12847 }
12848 pkt->pts = pts; pkt->dts = dts;
12849 pkt->pos = pos; pkt->flags |= flags;
12850 pkt->duration = duration;
12851 ret = ff_buffer_packet(s, pkt);
12852 }
12853 if (!ret)
12854 return FFERROR_REDO;
12855 }
12856#endif
12857 else if (st->codecpar->codec_id == AV_CODEC_ID_APV && sample->size > 4) {
12858 uint32_t au_size = avio_rb32(sc->pb);
12859 int explode = !!(mov->fc->error_recognition & AV_EF_EXPLODE);
12860 if (au_size > sample->size - 4) {
12861 av_log(s, explode ? AV_LOG_ERROR : AV_LOG_WARNING,
12862 "APV au_size %u exceeds sample body %d\n",
12863 au_size, sample->size - 4);
12864 if (explode)
12865 return AVERROR_INVALIDDATA;
12866 au_size = sample->size - 4;
12867 }
12868 ret = av_get_packet(sc->pb, pkt, au_size);
12869 } else
12870 ret = av_get_packet(sc->pb, pkt, sample->size);
12871 if (ret < 0) {
12872 if (should_retry(sc->pb, ret)) {
12874 }
12875 return ret;
12876 }
12877#if CONFIG_DV_DEMUXER
12878 if (mov->dv_demux && sc->dv_audio_container) {
12879 ret = avpriv_dv_produce_packet(mov->dv_demux, NULL, pkt->data, pkt->size, pkt->pos);
12881 if (ret < 0)
12882 return ret;
12883 ret = avpriv_dv_get_packet(mov->dv_demux, pkt);
12884 if (ret < 0)
12885 return ret;
12886 }
12887#endif
12888 if (sc->has_palette) {
12889 uint8_t *pal;
12890
12892 if (!pal) {
12893 av_log(mov->fc, AV_LOG_ERROR, "Cannot append palette to packet\n");
12894 } else {
12895 memcpy(pal, sc->palette, AVPALETTE_SIZE);
12896 sc->has_palette = 0;
12897 }
12898 }
12899 if (st->codecpar->codec_id == AV_CODEC_ID_MP3 && !ffstream(st)->need_parsing && pkt->size > 4) {
12900 if (ff_mpa_check_header(AV_RB32(pkt->data)) < 0)
12902 }
12903 }
12904
12905 ret = mov_finalize_packet(s, st, sample, current_index, pkt);
12906 if (ret < 0)
12907 return ret;
12908
12909 if (st->discard == AVDISCARD_ALL)
12910 goto retry;
12911
12912 if (mov->aax_mode)
12913 aax_filter(pkt->data, pkt->size, mov);
12914
12915 ret = cenc_filter(mov, st, sc, pkt, current_index);
12916 if (ret < 0) {
12917 return ret;
12918 }
12919
12920 return 0;
12921}
12922
12924{
12925 MOVContext *mov = s->priv_data;
12926 int index;
12927
12928 if (!mov->frag_index.complete)
12929 return 0;
12930
12931 index = search_frag_timestamp(s, &mov->frag_index, st, timestamp);
12932 if (index < 0)
12933 index = 0;
12934 if (!mov->frag_index.item[index].headers_read)
12935 return mov_switch_root(s, -1, index);
12936 if (index + 1 < mov->frag_index.nb_items)
12938
12939 return 0;
12940}
12941
12943{
12944 // TODO: a bisect search would scale much better
12945 for (int i = 0; i < sc->open_key_samples_count; i++) {
12946 const int oks = sc->open_key_samples[i];
12947 if (oks == sample)
12948 return 1;
12949 if (oks > sample) /* list is monotically increasing so we can stop early */
12950 break;
12951 }
12952 return 0;
12953}
12954
12955/*
12956 * Some key sample may be key frames but not IDR frames, so a random access to
12957 * them may not be allowed.
12958 */
12959static int can_seek_to_key_sample(AVStream *st, int sample, int64_t requested_pts)
12960{
12961 MOVStreamContext *sc = st->priv_data;
12962 FFStream *const sti = ffstream(st);
12963 int64_t key_sample_dts, key_sample_pts;
12964
12966 return 1;
12967
12968 if (sample >= sc->sample_offsets_count)
12969 return 1;
12970
12971 av_assert0(sample >= 0);
12972 key_sample_dts = sti->index_entries[sample].timestamp;
12973 key_sample_pts = key_sample_dts + sc->sample_offsets[sample] + sc->dts_shift;
12974
12975 /*
12976 * If the sample needs to be presented before an open key sample, they may
12977 * not be decodable properly, even though they come after in decoding
12978 * order.
12979 */
12980 if (is_open_key_sample(sc, sample) && key_sample_pts > requested_pts)
12981 return 0;
12982
12983 return 1;
12984}
12985
12986static int mov_seek_stream(AVFormatContext *s, AVStream *st, int64_t timestamp, int flags)
12987{
12988 MOVStreamContext *sc = st->priv_data;
12989 FFStream *const sti = ffstream(st);
12990 int sample, time_sample, ret, requested_sample;
12991 int64_t next_ts;
12992 unsigned int i;
12993
12994 // Here we consider timestamp to be PTS, hence try to offset it so that we
12995 // can search over the DTS timeline.
12996 timestamp -= (sc->min_corrected_pts + sc->dts_shift);
12997
12998 ret = mov_seek_fragment(s, st, timestamp);
12999 if (ret < 0)
13000 return ret;
13001
13002 for (;;) {
13003 sample = av_index_search_timestamp(st, timestamp, flags);
13004 av_log(s, AV_LOG_TRACE, "stream %d, timestamp %"PRId64", sample %d\n", st->index, timestamp, sample);
13005 if (sample < 0 && sti->nb_index_entries && timestamp < sti->index_entries[0].timestamp)
13006 sample = 0;
13007 if (sample < 0) /* not sure what to do */
13008 return AVERROR_INVALIDDATA;
13009
13010 if (!sample || can_seek_to_key_sample(st, sample, timestamp))
13011 break;
13012
13013 next_ts = timestamp - FFMAX(sc->min_sample_duration, 1);
13014 requested_sample = av_index_search_timestamp(st, next_ts, flags);
13015 if (requested_sample < 0)
13016 return AVERROR_INVALIDDATA;
13017
13018 // If we've reached a different sample trying to find a good pts to
13019 // seek to, give up searching because we'll end up seeking back to
13020 // sample 0 on every seek.
13021 if (sample != requested_sample && !can_seek_to_key_sample(st, requested_sample, next_ts))
13022 break;
13023
13024 timestamp = next_ts;
13025 }
13026
13028 av_log(s, AV_LOG_TRACE, "stream %d, found sample %d\n", st->index, sc->current_sample);
13029 /* adjust time to sample index */
13030 if (sc->tts_data) {
13031 time_sample = 0;
13032 for (i = 0; i < sc->tts_count; i++) {
13033 int next = time_sample + sc->tts_data[i].count;
13034 if (next > sc->current_sample) {
13035 sc->tts_index = i;
13036 sc->tts_sample = sc->current_sample - time_sample;
13037 break;
13038 }
13039 time_sample = next;
13040 }
13041 }
13042
13043 /* adjust stsd index */
13044 if (sc->chunk_count) {
13045 time_sample = 0;
13046 for (i = 0; i < sc->stsc_count; i++) {
13047 int64_t next = time_sample + mov_get_stsc_samples(sc, i);
13048 if (next > sc->current_sample) {
13049 sc->stsc_index = i;
13050 sc->stsc_sample = sc->current_sample - time_sample;
13051 break;
13052 }
13053 av_assert0(next == (int)next);
13054 time_sample = next;
13055 }
13056 }
13057
13058 return sample;
13059}
13060
13062{
13063 FFStream *const sti = ffstream(st);
13064 int64_t first_ts = sti->index_entries[0].timestamp;
13066 int64_t off;
13067
13069 return 0;
13070
13071 /* compute skip samples according to stream initial_padding, seek ts and first ts */
13072 off = av_rescale_q(ts - first_ts, st->time_base,
13073 (AVRational){1, st->codecpar->sample_rate});
13074 return FFMAX(st->codecpar->initial_padding - off, 0);
13075}
13076
13077static int mov_read_seek(AVFormatContext *s, int stream_index, int64_t sample_time, int flags)
13078{
13079 MOVContext *mc = s->priv_data;
13080 AVStream *st;
13081 FFStream *sti;
13082 int sample;
13083 int i;
13084
13085 if (stream_index >= s->nb_streams)
13086 return AVERROR_INVALIDDATA;
13087
13088 st = s->streams[stream_index];
13089 sti = ffstream(st);
13090 sample = mov_seek_stream(s, st, sample_time, flags);
13091 if (sample < 0)
13092 return sample;
13093
13094 if (mc->seek_individually) {
13095 /* adjust seek timestamp to found sample timestamp */
13096 int64_t seek_timestamp = sti->index_entries[sample].timestamp;
13098
13099 for (i = 0; i < s->nb_streams; i++) {
13100 AVStream *const st = s->streams[i];
13101 FFStream *const sti = ffstream(st);
13102 int64_t timestamp;
13103
13104 if (stream_index == i)
13105 continue;
13106
13107 timestamp = av_rescale_q(seek_timestamp, s->streams[stream_index]->time_base, st->time_base);
13108 sample = mov_seek_stream(s, st, timestamp, flags);
13109 if (sample >= 0)
13111 }
13112 } else {
13113 for (i = 0; i < s->nb_streams; i++) {
13114 MOVStreamContext *sc;
13115 st = s->streams[i];
13116 sc = st->priv_data;
13118 }
13119 while (1) {
13120 MOVStreamContext *sc;
13122 if (!entry)
13123 return AVERROR_INVALIDDATA;
13124 sc = st->priv_data;
13125 if (sc->ffindex == stream_index && sc->current_sample == sample)
13126 break;
13128 }
13129 }
13130 return 0;
13131}
13132
13133#define OFFSET(x) offsetof(MOVContext, x)
13134#define FLAGS AV_OPT_FLAG_VIDEO_PARAM | AV_OPT_FLAG_DECODING_PARAM
13135static const AVOption mov_options[] = {
13136 {"use_absolute_path",
13137 "allow using absolute path when opening alias, this is a possible security issue",
13138 OFFSET(use_absolute_path), AV_OPT_TYPE_BOOL, {.i64 = 0},
13139 0, 1, FLAGS},
13140 {"seek_streams_individually",
13141 "Seek each stream individually to the closest point",
13142 OFFSET(seek_individually), AV_OPT_TYPE_BOOL, { .i64 = 1 },
13143 0, 1, FLAGS},
13144 {"ignore_editlist", "Ignore the edit list atom.", OFFSET(ignore_editlist), AV_OPT_TYPE_BOOL, {.i64 = 0},
13145 0, 1, FLAGS},
13146 {"advanced_editlist",
13147 "Modify the AVIndex according to the editlists. Use this option to decode in the order specified by the edits.",
13148 OFFSET(advanced_editlist), AV_OPT_TYPE_BOOL, {.i64 = 1},
13149 0, 1, FLAGS},
13150 {"ignore_chapters", "", OFFSET(ignore_chapters), AV_OPT_TYPE_BOOL, {.i64 = 0},
13151 0, 1, FLAGS},
13152 {"use_mfra_for",
13153 "use mfra for fragment timestamps",
13154 OFFSET(use_mfra_for), AV_OPT_TYPE_INT, {.i64 = FF_MOV_FLAG_MFRA_AUTO},
13156 .unit = "use_mfra_for"},
13157 {"auto", "auto", 0, AV_OPT_TYPE_CONST, {.i64 = FF_MOV_FLAG_MFRA_AUTO}, 0, 0,
13158 FLAGS, .unit = "use_mfra_for" },
13159 {"dts", "dts", 0, AV_OPT_TYPE_CONST, {.i64 = FF_MOV_FLAG_MFRA_DTS}, 0, 0,
13160 FLAGS, .unit = "use_mfra_for" },
13161 {"pts", "pts", 0, AV_OPT_TYPE_CONST, {.i64 = FF_MOV_FLAG_MFRA_PTS}, 0, 0,
13162 FLAGS, .unit = "use_mfra_for" },
13163 {"use_tfdt", "use tfdt for fragment timestamps", OFFSET(use_tfdt), AV_OPT_TYPE_BOOL, {.i64 = 1},
13164 0, 1, FLAGS},
13165 { "export_all", "Export unrecognized metadata entries", OFFSET(export_all),
13166 AV_OPT_TYPE_BOOL, { .i64 = 0 }, 0, 1, .flags = FLAGS },
13167 { "export_xmp", "Export full XMP metadata", OFFSET(export_xmp),
13168 AV_OPT_TYPE_BOOL, { .i64 = 0 }, 0, 1, .flags = FLAGS },
13169 { "activation_bytes", "Secret bytes for Audible AAX files", OFFSET(activation_bytes),
13171 { "audible_key", "AES-128 Key for Audible AAXC files", OFFSET(audible_key),
13173 { "audible_iv", "AES-128 IV for Audible AAXC files", OFFSET(audible_iv),
13175 { "audible_fixed_key", // extracted from libAAX_SDK.so and AAXSDKWin.dll files!
13176 "Fixed key used for handling Audible AAX files", OFFSET(audible_fixed_key),
13177 AV_OPT_TYPE_BINARY, {.str="77214d4b196a87cd520045fd20a51d67"},
13178 .flags = AV_OPT_FLAG_DECODING_PARAM },
13179 { "decryption_key", "The default media decryption key (hex)", OFFSET(decryption_default_key), AV_OPT_TYPE_BINARY, .flags = AV_OPT_FLAG_DECODING_PARAM },
13180 { "decryption_keys", "The media decryption keys by KID (hex)", OFFSET(decryption_keys), AV_OPT_TYPE_DICT, .flags = AV_OPT_FLAG_DECODING_PARAM },
13181 { "enable_drefs", "Enable external track support.", OFFSET(enable_drefs), AV_OPT_TYPE_BOOL,
13182 {.i64 = 0}, 0, 1, FLAGS },
13183 { "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 },
13184 { "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 },
13185
13186 { NULL },
13187};
13188
13189static const AVClass mov_class = {
13190 .class_name = "mov,mp4,m4a,3gp,3g2,mj2",
13191 .item_name = av_default_item_name,
13192 .option = mov_options,
13193 .version = LIBAVUTIL_VERSION_INT,
13194};
13195
13197 .p.name = "mov,mp4,m4a,3gp,3g2,mj2",
13198 .p.long_name = NULL_IF_CONFIG_SMALL("QuickTime / MOV"),
13199 .p.priv_class = &mov_class,
13200 .p.extensions = "mov,mp4,m4a,3gp,3g2,mj2,psp,m4v,m4b,ism,ismv,isma,f4v,avif,heic,heif",
13202 .priv_data_size = sizeof(MOVContext),
13203 .flags_internal = FF_INFMT_FLAG_INIT_CLEANUP,
13209};
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:13196
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:983
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:856
void ff_remove_stream(AVFormatContext *s, AVStream *st)
Remove a stream from its AVFormatContext and free it.
Definition avformat.c:136
void ff_remove_stream_group(AVFormatContext *s, AVStreamGroup *stg)
Remove a stream group from its AVFormatContext and free it.
Definition avformat.c:144
Main libavformat public API header.
#define AVFMT_EVENT_FLAG_METADATA_UPDATED
Definition avformat.h:1795
#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:1554
@ AV_STREAM_GROUP_PARAMS_DOLBY_VISION
Definition avformat.h:1164
@ AV_STREAM_GROUP_PARAMS_TREF
Definition avformat.h:1163
@ 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:2713
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:2711
#define AV_DISPOSITION_DEFAULT
The stream should be chosen by default among other streams of the same type, unless the user has expl...
Definition avformat.h:641
#define AV_DISPOSITION_TIMED_THUMBNAILS
The stream is sparse, and contains thumbnail images, often corresponding to chapter markers.
Definition avformat.h:699
@ AVSTREAM_PARSE_HEADERS
Only parse headers, do not repack.
Definition avformat.h:614
@ AVSTREAM_PARSE_FULL
full parsing and repack
Definition avformat.h:613
int avio_get_str16be(AVIOContext *pb, int maxlen, char *buf, int buflen)
int64_t avio_seek(AVIOContext *s, int64_t offset, int whence)
fseek() equivalent for AVIOContext.
Definition aviobuf.c:236
#define AVIO_SEEKABLE_NORMAL
Seeking works like for a local file.
Definition avio.h:41
uint64_t avio_rb64(AVIOContext *s)
#define AVIO_FLAG_READ
read-only
Definition avio.h:617
int64_t avio_size(AVIOContext *s)
Get the filesize.
Definition aviobuf.c:326
unsigned int avio_rb16(AVIOContext *s)
int avio_get_str16le(AVIOContext *pb, int maxlen, char *buf, int buflen)
Read a UTF-16 string from pb and convert it to UTF-8.
int avio_feof(AVIOContext *s)
Similar to feof() but also returns nonzero on read errors.
Definition aviobuf.c:349
static av_always_inline int64_t avio_tell(AVIOContext *s)
ftell() equivalent for AVIOContext.
Definition avio.h:494
int64_t avio_skip(AVIOContext *s, int64_t offset)
Skip given number of bytes forward.
Definition aviobuf.c:321
int avio_read(AVIOContext *s, unsigned char *buf, int size)
Read size bytes from AVIOContext into buf.
Definition aviobuf.c:615
unsigned int avio_rl32(AVIOContext *s)
int avio_get_str(AVIOContext *pb, int maxlen, char *buf, int buflen)
Read a string from pb into buf.
Definition aviobuf.c:836
unsigned int avio_rb24(AVIOContext *s)
unsigned int avio_rb32(AVIOContext *s)
int avio_r8(AVIOContext *s)
Definition aviobuf.c:606
int ffio_ensure_seekback(AVIOContext *s, int64_t buf_size)
Ensures that the requested seekback buffer size will be available.
Definition aviobuf.c:985
int64_t ff_read_string_to_bprint_overwrite(AVIOContext *s, struct AVBPrint *bp, int64_t max_len)
Read a whole null-terminated string of text from AVIOContext to an AVBPrint buffer overwriting its co...
Definition aviobuf.c:830
void ffio_init_read_context(FFIOContext *s, const uint8_t *buffer, int buffer_size)
Wrap a buffer in an AVIOContext for reading.
Definition aviobuf.c:99
int ffio_read_size(AVIOContext *s, unsigned char *buf, int size)
Read size bytes from AVIOContext into buf.
Definition aviobuf.c:665
unsigned int ffio_read_leb(AVIOContext *s)
Read a unsigned integer coded as a variable number of up to eight little-endian bytes,...
Definition aviobuf.c:889
static int read_packet(void *opaque, uint8_t *buf, int buf_size)
size_t av_strlcatf(char *dst, size_t size, const char *fmt,...)
Definition avstring.c:103
static int BS_FUNC left(const BSCTX *bc)
Return the number of the bits left in a buffer.
void av_bprint_init(AVBPrint *buf, unsigned size_init, unsigned size_max)
Definition bprint.c:68
AVBPrint public header.
#define AV_BPRINT_SIZE_UNLIMITED
#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 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:2420
int ff_rfps_add_frame(AVFormatContext *ic, AVStream *st, int64_t ts)
add frame for rfps calculation.
Definition demux.c:2359
AVChapter * avpriv_new_chapter(AVFormatContext *s, int64_t id, AVRational time_base, int64_t start, int64_t end, const char *title)
Add a new chapter.
Definition demux_utils.c:46
#define FF_INFMT_FLAG_INIT_CLEANUP
For an FFInputFormat with this flag set read_close() needs to be called by the caller upon read_heade...
Definition demux.h:35
int ff_itunes_parse_smpb(const char *value, int64_t *priming, int64_t *remainder, int64_t *samples)
Parse the gapless playback information Apple encoders store in an iTunSMPB tag.
void ff_configure_buffers_for_index(AVFormatContext *s, int64_t time_tolerance)
Definition seek.c:175
int ff_generate_avci_extradata(AVStream *st)
Generate standard extradata for AVC-Intra based on width/height and field order.
#define FFERROR_REDO
Returned by demuxers to indicate that data was consumed but discarded (ignored streams or junk data).
Definition demux.h:224
int ff_get_extradata(void *logctx, AVCodecParameters *par, AVIOContext *pb, int size)
Allocate extradata with additional AV_INPUT_BUFFER_PADDING_SIZE at end which is always set to 0 and f...
int ff_add_attached_pic(AVFormatContext *s, AVStream *st, AVIOContext *pb, AVBufferRef **buf, int size)
Add an attached pic to an AVStream.
static AVPacket * pkt
Public dictionary API.
Display matrix.
int ff_isom_parse_dvcc_dvvc(void *logctx, AVStream *st, const uint8_t *buf_ptr, uint64_t size)
Definition dovi_isom.c:32
#define ISOM_DVCC_DVVC_SIZE
Definition dovi_isom.h:29
DOVI configuration.
enum AVCodecID id
Definition dts2pts.c:607
int ff_dvdclut_yuv_to_rgb(uint32_t *clut, const size_t clut_size)
Definition dvdclut.c:50
int ff_dvdclut_palette_extradata_cat(const uint32_t *clut, const size_t clut_size, AVCodecParameters *par)
Definition dvdclut.c:28
#define FF_DVDCLUT_CLUT_SIZE
Definition dvdclut.h:29
#define FF_DVDCLUT_CLUT_LEN
Definition dvdclut.h:28
channel
Use these values when setting the channel map with ebur128_set_channel().
Definition ebur128.h:39
AVEncryptionInfo * av_encryption_info_alloc(uint32_t subsample_count, uint32_t key_id_size, uint32_t iv_size)
Allocates an AVEncryptionInfo structure and sub-pointers to hold the given number of subsamples.
AVEncryptionInfo * av_encryption_info_clone(const AVEncryptionInfo *info)
Allocates an AVEncryptionInfo structure with a copy of the given data.
AVEncryptionInitInfo * av_encryption_init_info_get_side_data(const uint8_t *side_data, size_t side_data_size)
Creates a copy of the AVEncryptionInitInfo that is contained in the given side data.
uint8_t * av_encryption_init_info_add_side_data(const AVEncryptionInitInfo *info, size_t *side_data_size)
Allocates and initializes side data that holds a copy of the given encryption init info.
uint8_t * av_encryption_info_add_side_data(const AVEncryptionInfo *info, size_t *size)
Allocates and initializes side data that holds a copy of the given encryption info.
AVEncryptionInitInfo * av_encryption_init_info_alloc(uint32_t system_id_size, uint32_t num_key_ids, uint32_t key_id_size, uint32_t data_size)
Allocates an AVEncryptionInitInfo structure and sub-pointers to hold the given sizes.
void av_encryption_init_info_free(AVEncryptionInitInfo *info)
Frees the given encryption init info object.
void av_encryption_info_free(AVEncryptionInfo *info)
Frees the given encryption info object.
double value
Definition eval.c:102
int av_exif_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_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:411
static int64_t start_time
Definition ffplay.c:410
static int read_header(FFV1Context *f, RangeCoder *c)
Definition ffv1dec.c:578
FLAC (Free Lossless Audio Codec) common stuff.
@ FLAC_METADATA_TYPE_STREAMINFO
Definition flac.h:46
static av_always_inline void flac_parse_block_header(const uint8_t *block_header, int *last, int *type, int *size)
Parse the metadata block parameters from the header.
Definition flac.h:63
#define FLAC_STREAMINFO_SIZE
Definition flac.h:32
#define sample
static av_cold void cleanup(FlashSV2Context *s)
bitstream reader API header.
static unsigned int get_bits_long(GetBitContext *s, int n)
Read 0-32 bits.
Definition get_bits.h:424
static void skip_bits_long(GetBitContext *s, int n)
Skips the specified number of bits.
Definition get_bits.h:280
static void skip_bits(GetBitContext *s, int n)
Definition get_bits.h:383
static unsigned int get_bits(GetBitContext *s, int n)
Read 1-25 bits.
Definition get_bits.h:337
static int init_get_bits(GetBitContext *s, const uint8_t *buffer, int bit_size)
Initialize GetBitContext.
Definition get_bits.h:517
#define fail
Definition test.h:479
#define AV_OPT_FLAG_DECODING_PARAM
A generic parameter which can be set by the user for demuxing or decoding.
Definition opt.h:355
@ AV_OPT_TYPE_CONST
Special option type for declaring named constants.
Definition opt.h:298
@ AV_OPT_TYPE_BINARY
Underlying C type is a uint8_t* that is either NULL or points to an array allocated with the av_mallo...
Definition opt.h:285
@ AV_OPT_TYPE_INT
Underlying C type is int.
Definition opt.h:258
@ AV_OPT_TYPE_DICT
Underlying C type is AVDictionary*.
Definition opt.h:289
@ AV_OPT_TYPE_BOOL
Underlying C type is int.
Definition opt.h:326
#define AV_CH_SIDE_LEFT
#define AV_CH_SIDE_SURROUND_RIGHT
#define AV_CH_WIDE_LEFT
#define AV_CH_WIDE_RIGHT
#define AV_CH_TOP_FRONT_LEFT
#define AV_CH_FRONT_RIGHT
#define AV_CH_SIDE_SURROUND_LEFT
#define AV_CH_TOP_BACK_CENTER
#define AV_CH_FRONT_RIGHT_OF_CENTER
#define AV_CH_BACK_CENTER
#define AV_CH_TOP_FRONT_CENTER
#define AV_CH_FRONT_LEFT_OF_CENTER
#define AV_CH_LOW_FREQUENCY_2
#define AV_CH_BACK_RIGHT
#define AV_CH_TOP_SIDE_RIGHT
#define AV_CH_FRONT_CENTER
#define AV_CH_TOP_BACK_RIGHT
#define AV_CH_TOP_CENTER
#define AV_CH_SIDE_RIGHT
#define AV_CH_BACK_LEFT
#define AV_CH_TOP_SIDE_LEFT
#define AV_CH_TOP_BACK_LEFT
#define AV_CH_LOW_FREQUENCY
#define AV_CH_TOP_FRONT_RIGHT
#define AV_CH_FRONT_LEFT
int av_get_bits_per_sample(enum AVCodecID codec_id)
Return codec bits per sample.
Definition utils.c:557
AVCodecID
Identify the syntax and semantics of the bitstream.
Definition codec_id.h:47
@ AV_CODEC_ID_PCM_F32LE
Definition codec_id.h:353
@ AV_CODEC_ID_PCM_S24BE
Definition codec_id.h:345
@ AV_CODEC_ID_VORBIS
Definition codec_id.h:462
@ AV_CODEC_ID_H261
Definition codec_id.h:53
@ AV_CODEC_ID_FLV1
Definition codec_id.h:71
@ AV_CODEC_ID_PNG
Definition codec_id.h:111
@ AV_CODEC_ID_EAC3
Definition codec_id.h:497
@ AV_CODEC_ID_PCM_U8
Definition codec_id.h:337
@ AV_CODEC_ID_APV
Definition codec_id.h:323
@ AV_CODEC_ID_LCEVC
Definition codec_id.h:613
@ AV_CODEC_ID_PCM_S16LE
Definition codec_id.h:332
@ AV_CODEC_ID_GSM
as in Berlin toast format
Definition codec_id.h:475
@ AV_CODEC_ID_DVD_SUBTITLE
Definition codec_id.h:570
@ AV_CODEC_ID_TTML
Definition codec_id.h:594
@ AV_CODEC_ID_PCM_F32BE
Definition codec_id.h:352
@ AV_CODEC_ID_SVQ3
Definition codec_id.h:73
@ AV_CODEC_ID_H264
Definition codec_id.h:77
@ AV_CODEC_ID_NONE
Definition codec_id.h:48
@ AV_CODEC_ID_JPEG2000
Definition codec_id.h:138
@ AV_CODEC_ID_PCM_S16BE
Definition codec_id.h:333
@ AV_CODEC_ID_PCM_S24LE
Definition codec_id.h:344
@ AV_CODEC_ID_PCM_S32LE
Definition codec_id.h:340
@ AV_CODEC_ID_PCM_S8
Definition codec_id.h:336
@ AV_CODEC_ID_AV1
Definition codec_id.h:275
@ AV_CODEC_ID_ADPCM_MS
Definition codec_id.h:378
@ AV_CODEC_ID_VC1
Definition codec_id.h:120
@ AV_CODEC_ID_VP8
Definition codec_id.h:190
@ AV_CODEC_ID_PCM_F64LE
Definition codec_id.h:355
@ AV_CODEC_ID_ALAC
Definition codec_id.h:473
@ AV_CODEC_ID_EIA_608
Definition codec_id.h:580
@ AV_CODEC_ID_AMR_NB
Definition codec_id.h:438
@ AV_CODEC_ID_CAVS
Definition codec_id.h:137
@ AV_CODEC_ID_PRORES_RAW
Definition codec_id.h:324
@ AV_CODEC_ID_MP2
Definition codec_id.h:457
@ AV_CODEC_ID_DVAUDIO
Definition codec_id.h:463
@ AV_CODEC_ID_ADPCM_IMA_QT
Definition codec_id.h:372
@ AV_CODEC_ID_HEVC
Definition codec_id.h:223
@ AV_CODEC_ID_BIN_DATA
Definition codec_id.h:611
@ AV_CODEC_ID_AAC
Definition codec_id.h:459
@ AV_CODEC_ID_PRORES
Definition codec_id.h:198
@ AV_CODEC_ID_BMP
Definition codec_id.h:128
@ AV_CODEC_ID_PCM_F64BE
Definition codec_id.h:354
@ AV_CODEC_ID_H263
Definition codec_id.h:54
@ AV_CODEC_ID_QCELP
Definition codec_id.h:481
@ AV_CODEC_ID_AMR_WB
Definition codec_id.h:439
@ AV_CODEC_ID_AC3
Definition codec_id.h:460
@ AV_CODEC_ID_MACE3
Definition codec_id.h:466
@ AV_CODEC_ID_MACE6
Definition codec_id.h:467
@ AV_CODEC_ID_QDM2
Definition codec_id.h:476
@ AV_CODEC_ID_PCM_S32BE
Definition codec_id.h:341
@ AV_CODEC_ID_DNXHD
Definition codec_id.h:149
@ AV_CODEC_ID_MPEG4
Definition codec_id.h:62
@ AV_CODEC_ID_MJPEG
Definition codec_id.h:57
@ AV_CODEC_ID_ADPCM_IMA_WAV
Definition codec_id.h:373
@ AV_CODEC_ID_R10K
Definition codec_id.h:195
@ AV_CODEC_ID_EVC
Definition codec_id.h:316
@ AV_CODEC_ID_SPEEX
Definition codec_id.h:492
@ AV_CODEC_ID_AVUI
Definition codec_id.h:252
@ AV_CODEC_ID_ILBC
Definition codec_id.h:516
@ AV_CODEC_ID_MP3
preferred ID for decoding MPEG audio layer 1, 2 or 3
Definition codec_id.h:458
@ AV_CODEC_ID_VP9
Definition codec_id.h:217
@ AV_CODEC_ID_MPEG1VIDEO
Definition codec_id.h:51
@ AV_CODEC_ID_QDMC
Definition codec_id.h:507
@ AV_CODEC_ID_ITUT_T35
Definition codec_id.h:615
@ AV_CODEC_ID_TARGA_Y216
Definition codec_id.h:253
#define AV_INPUT_BUFFER_PADDING_SIZE
Required number of additionally allocated bytes at the end of the input bitstream for decoding.
Definition defs.h:40
@ AVDISCARD_ALL
discard all
Definition defs.h:246
@ AVDISCARD_NONKEY
discard all frames except keyframes
Definition defs.h:245
AVPacketSideData * av_packet_side_data_new(AVPacketSideData **psd, int *pnb_sd, enum AVPacketSideDataType type, size_t size, int flags)
Allocate a new packet side data.
Definition packet.c: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:472
AVStream * avformat_new_stream(AVFormatContext *s, const struct AVCodec *c)
Add a new stream to a media file.
int avformat_stream_group_add_stream(AVStreamGroup *stg, AVStream *st)
Add an already allocated stream to a stream group.
Definition options.c:586
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:164
int avformat_stream_group_add_stream_group(AVStreamGroup *stg, AVStreamGroup *group)
Add an already allocated stream group to another stream group.
Definition options.c:628
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:241
AVRational av_add_q(AVRational b, AVRational c)
Add two rationals.
Definition rational.c:93
AVRational av_mul_q(AVRational b, AVRational c)
Multiply two rationals.
Definition rational.c:80
int av_reduce(int *dst_num, int *dst_den, int64_t num, int64_t den, int64_t max)
Reduce a fraction.
Definition rational.c:35
static AVRational av_make_q(int num, int den)
Create an AVRational.
Definition rational.h:71
AVRational av_d2q(double d, int max)
Convert a double precision floating point number to a rational.
Definition rational.c:110
static double av_q2d(AVRational a)
Convert an AVRational to a double.
Definition rational.h:104
static int av_cmp_q(AVRational a, AVRational b)
Compare two rationals.
Definition rational.h:89
AVRational av_sub_q(AVRational b, AVRational c)
Subtract one rational from another.
Definition rational.c:101
int64_t av_rescale(int64_t a, int64_t b, int64_t c)
Rescale a 64-bit integer with rounding to nearest.
int64_t av_rescale_q(int64_t a, AVRational bq, AVRational cq)
Rescale a 64-bit integer by 2 rational numbers.
void * av_dynarray2_add(void **tab_ptr, int *nb_ptr, size_t elem_size, const uint8_t *elem_data)
Add an element of size elem_size to a dynamic array.
Definition mem.c:447
void * av_fast_realloc(void *ptr, unsigned int *size, size_t min_size)
Reallocate the given buffer if it is not large enough, otherwise do nothing.
Definition mem.c:601
void * av_realloc_array(void *ptr, size_t nmemb, size_t size)
Definition mem.c:318
int av_reallocp(void *ptr, size_t size)
Allocate, reallocate, or free a block of memory through a pointer to a pointer.
Definition mem.c:289
int av_reallocp_array(void *ptr, size_t nmemb, size_t size)
Allocate, reallocate an array through a pointer to a pointer.
Definition mem.c:326
const char * av_get_media_type_string(enum AVMediaType media_type)
Return a string describing the media_type enum, NULL if media_type is unknown.
Definition utils.c:28
char * av_fourcc_make_string(char *buf, uint32_t fourcc)
Fill the provided buffer with a string containing a FourCC (four-character code) representation.
Definition utils.c:54
#define av_fourcc2str(fourcc)
Definition avutil.h:323
#define AV_FOURCC_MAX_STRING_SIZE
Definition avutil.h:321
@ AVMEDIA_TYPE_AUDIO
Definition avutil.h:201
@ AVMEDIA_TYPE_SUBTITLE
Definition avutil.h:203
@ AVMEDIA_TYPE_VIDEO
Definition avutil.h:200
@ AVMEDIA_TYPE_DATA
Opaque data information usually continuous.
Definition avutil.h:202
void av_sha_update(struct AVSHA *ctx, const uint8_t *data, size_t len)
Update hash value.
Definition sha.c:315
struct AVSHA * av_sha_alloc(void)
Allocate an AVSHA context.
Definition sha.c:46
void av_sha_final(AVSHA *ctx, uint8_t *digest)
Finish hashing and output digest value.
Definition sha.c:347
av_cold int av_sha_init(AVSHA *ctx, int bits)
Initialize SHA-1 or SHA-2 hashing.
Definition sha.c:274
size_t av_strlcat(char *dst, const char *src, size_t size)
Append the string src to the string dst, but to a total length of no more than size - 1 bytes,...
Definition avstring.c:95
char * av_stristr(const char *s1, const char *s2)
Locate the first case-independent occurrence in the string haystack of the string needle.
Definition avstring.c:58
int av_strstart(const char *str, const char *pfx, const char **ptr)
Return non-zero if pfx is a prefix of str.
Definition avstring.c:36
#define AV_NOPTS_VALUE
Undefined timestamp value.
Definition avutil.h:247
#define AV_TIME_BASE
Internal time base represented as integer.
Definition avutil.h:253
#define LIBAVUTIL_VERSION_INT
Definition version.h:85
void av_display_rotation_set(int32_t matrix[9], double angle)
Initialize a transformation matrix describing a pure clockwise rotation by the specified angle (in de...
Definition display.c:50
void av_display_matrix_flip(int32_t matrix[9], int hflip, int vflip)
Flip the input matrix horizontally and/or vertically.
Definition display.c:65
AVSphericalMapping * av_spherical_alloc(size_t *size)
Allocate a AVSphericalVideo structure and initialize its fields to default values.
Definition spherical.c:26
AVSphericalProjection
Projection of the video surface(s) on a sphere.
Definition spherical.h:47
@ AV_SPHERICAL_RECTILINEAR
Video frame displays on a flat, rectangular 2D surface.
Definition spherical.h:78
@ AV_SPHERICAL_EQUIRECTANGULAR
Video represents a sphere mapped on a flat surface using equirectangular projection.
Definition spherical.h:52
@ AV_SPHERICAL_EQUIRECTANGULAR_TILE
Video represents a portion of a sphere mapped on a flat surface using equirectangular projection.
Definition spherical.h:68
@ AV_SPHERICAL_CUBEMAP
Video frame is split into 6 faces of a cube, and arranged on a 3x2 layout.
Definition spherical.h:61
@ AV_SPHERICAL_HALF_EQUIRECTANGULAR
Video frame displays as a 180 degree equirectangular projection.
Definition spherical.h:73
@ AV_SPHERICAL_PARAMETRIC_IMMERSIVE
Parametric Immersive projection (Apple).
Definition spherical.h:90
@ AV_SPHERICAL_FISHEYE
Fisheye projection (Apple).
Definition spherical.h:84
AVStereo3DType
List of possible 3D Types.
Definition stereo3d.h:48
AVStereo3D * av_stereo3d_alloc_size(size_t *size)
Allocate an AVStereo3D structure and set its fields to default values.
Definition stereo3d.c:39
#define AV_STEREO3D_FLAG_INVERT
Inverted views, Right/Bottom represents the left view.
Definition stereo3d.h:194
AVStereo3DPrimaryEye
List of possible primary eyes.
Definition stereo3d.h:174
AVStereo3DView
List of possible view types.
Definition stereo3d.h:149
@ AV_STEREO3D_2D
Video is not stereoscopic (and metadata has to be there).
Definition stereo3d.h:52
@ AV_STEREO3D_TOPBOTTOM
Views are on top of each other.
Definition stereo3d.h:76
@ AV_STEREO3D_UNSPEC
Video is stereoscopic but the packing is unspecified.
Definition stereo3d.h:143
@ AV_STEREO3D_SIDEBYSIDE
Views are next to each other.
Definition stereo3d.h:64
@ AV_PRIMARY_EYE_NONE
Neither eye.
Definition stereo3d.h:178
@ AV_PRIMARY_EYE_LEFT
Left eye.
Definition stereo3d.h:183
@ AV_PRIMARY_EYE_RIGHT
Right eye.
Definition stereo3d.h:188
@ AV_STEREO3D_VIEW_RIGHT
Frame contains only the right view.
Definition stereo3d.h:163
@ AV_STEREO3D_VIEW_PACKED
Frame contains two packed views.
Definition stereo3d.h:153
@ AV_STEREO3D_VIEW_LEFT
Frame contains only the left view.
Definition stereo3d.h:158
@ AV_STEREO3D_VIEW_UNSPEC
Content is unspecified.
Definition stereo3d.h:168
int index
Definition gxfenc.c:90
int a
int tile_rows
#define MAX_REORDER_DELAY
const VDPAUPixFmtMap * map
int ff_iamfdec_read_descriptors(IAMFContext *c, AVIOContext *pb, int max_size, void *log_ctx)
int ff_iamf_read_packet(AVFormatContext *s, IAMFDemuxContext *c, AVIOContext *pb, int max_size, int stream_id_offset, AVPacket *pkt)
void ff_iamf_read_deinit(IAMFDemuxContext *c)
const char *const ff_id3v1_genre_str[ID3v1_GENRE_MAX+1]
ID3v1 genres.
Definition id3v1.c:26
#define ID3v1_GENRE_MAX
Definition id3v1.h:29
#define r
Definition input.c:42
#define b
Definition input.c:43
static av_always_inline float av_int2float(uint32_t i)
Reinterpret a 32-bit integer as a float.
Definition intfloat.h:40
static av_always_inline double av_int2double(uint64_t i)
Reinterpret a 64-bit integer as a double.
Definition intfloat.h:60
#define AV_WB32(p, v)
#define AV_RB8(x)
#define AV_WL32(p, v)
#define AV_RL32(p)
#define AV_RB32(p)
#define AV_RB16A(p)
#define AV_WB64(p, v)
#define AV_WL32A(p, v)
#define AV_WB8(p, d)
#define AV_RB64(p)
#define AV_WB16(p, v)
#define AV_WL16A(p, v)
#define AV_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:425
#define MOV_GRAPHICS_MODE_COPY
Definition isom.h:452
int ff_mov_read_esds(AVFormatContext *fc, AVIOContext *pb)
Definition mov_esds.c:23
#define FF_MOV_FLAG_MFRA_PTS
Definition isom.h:486
#define MOV_TRUN_SAMPLE_CTS
Definition isom.h:428
#define MOV_TKHD_FLAG_ENABLED
Definition isom.h:440
#define MOV_TFHD_DEFAULT_BASE_IS_MOOF
Definition isom.h:421
#define MOV_INFE_FLAG_HIDDEN
Definition isom.h:445
#define FF_MOV_FLAG_MFRA_DTS
Definition isom.h:485
const AVCodecTag ff_codec_movaudio_tags[]
Definition isom_tags.c:307
#define MOV_FRAG_SAMPLE_FLAG_DEPENDS_YES
Definition isom.h:438
const AVCodecTag ff_codec_movvideo_tags[]
Definition isom_tags.c:29
#define MOV_TFHD_DEFAULT_SIZE
Definition isom.h:418
#define MOV_ISMV_TTML_TAG
Definition isom.h:502
#define TAG_IS_AVCI(tag)
Definition isom.h:462
#define MOV_TRUN_FIRST_SAMPLE_FLAGS
Definition isom.h:424
#define MOV_GRAPHICS_MODE_PREMUL_BLACK_ALPHA
Definition isom.h:458
#define MOV_MP4_FPCM_TAG
Definition isom.h:504
#define MOV_FRAG_SAMPLE_FLAG_IS_NON_SYNC
Definition isom.h:431
#define MOV_TFHD_STSD_ID
Definition isom.h:416
#define MOV_GRAPHICS_MODE_DITHER_COPY
Definition isom.h:453
#define MOV_TRUN_SAMPLE_FLAGS
Definition isom.h:427
#define MOV_MP4_TTML_TAG
Definition isom.h:503
#define MOV_TFHD_DEFAULT_FLAGS
Definition isom.h:419
#define MOV_TRUN_DATA_OFFSET
Definition isom.h:423
#define MOV_TFHD_BASE_DATA_OFFSET
Definition isom.h:415
#define MOV_MP4_IPCM_TAG
Definition isom.h:505
static enum AVCodecID ff_mov_get_lpcm_codec_id(int bps, int flags)
Compute codec id for 'lpcm' tag.
Definition isom.h:492
#define MOV_TRUN_SAMPLE_SIZE
Definition isom.h:426
#define MOV_SAMPLE_DEPENDENCY_NO
Definition isom.h:449
#define MOV_GRAPHICS_MODE_STRAIGHT_ALPHA
Definition isom.h:456
#define FF_MOV_FLAG_MFRA_AUTO
Definition isom.h:484
#define MOV_TFHD_DEFAULT_DURATION
Definition isom.h:417
uint32_t type
Definition jpegmpfenc.c:80
unsigned offset
Definition libaomenc.c:763
static int mix(int c0, int c1)
Definition 4xm.c:717
enum TrimAxis axis
Definition trim.c:49
@ HEVC_NAL_CRA_NUT
Definition hevc.h:50
int avpriv_dv_produce_packet(DVDemuxContext *c, AVPacket *pkt, uint8_t *buf, int buf_size, int64_t pos)
Definition dv.c:738
int avpriv_dv_get_packet(DVDemuxContext *c, AVPacket *pkt)
Definition dv.c:733
DVDemuxContext * avpriv_dv_init_demux(AVFormatContext *s)
Definition dv.c:728
int ff_dict_set_timestamp(AVDictionary **dict, const char *key, int64_t timestamp)
Set a dictionary value to an ISO-8601 compliant timestamp string.
Definition utils.c:626
int ff_hex_to_data(uint8_t *data, const char *p)
Parse a string of hexadecimal strings.
Definition utils.c:495
static av_always_inline FFStream * ffstream(AVStream *st)
Definition internal.h:365
static av_always_inline const FFStream * cffstream(const AVStream *st)
Definition internal.h:370
char * ff_data_to_hex(char *buf, const uint8_t *src, int size, int lowercase)
Write hexadecimal string corresponding to given binary data.
Definition utils.c:473
int ff_alloc_extradata(AVCodecParameters *par, int size)
Allocate extradata with additional AV_INPUT_BUFFER_PADDING_SIZE at end which is always set to 0.
Definition utils.c:237
enum AVCodecID ff_codec_get_id(const AVCodecTag *tags, unsigned int tag)
Definition utils.c:143
Macro definitions for various function/variable attributes.
#define av_fallthrough
Definition attributes.h:67
#define av_unused
Definition attributes.h:164
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:5720
static int64_t mov_get_skip_samples(AVStream *st, int sample)
Definition mov.c:13061
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:12589
static int mov_read_iloc(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition mov.c:9461
static int mov_read_pack(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition mov.c:7134
static int read_image_grid(AVFormatContext *s, const HEIFGroup *grid, AVStreamGroupTileGrid *tile_grid)
Definition mov.c:11157
static int mov_apply_heif_item_references(AVFormatContext *s, HEIFItem *item, AVPacketSideData **coded_side_data, int *nb_coded_side_data)
Definition mov.c:11382
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:4233
static int mov_read_seek(AVFormatContext *s, int stream_index, int64_t sample_time, int flags)
Definition mov.c:13077
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:10810
static int mov_read_stsd(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition mov.c:3460
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:5882
static int mov_read_dops(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition mov.c:9016
static int set_display_matrix_from_item(AVPacketSideData **coded_side_data, int *nb_coded_side_data, const HEIFItem *item)
Definition mov.c:11129
static int mov_compare_presentation_samples(const void *a, const void *b)
Definition mov.c:5290
static int mov_switch_root(AVFormatContext *s, int64_t target, int index)
Definition mov.c:12529
static int mov_read_vexu_proj(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition mov.c:7352
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:8600
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:9455
static int mov_parse_tmcd_streams(AVFormatContext *s)
Definition mov.c:11969
static int mov_read_lhvc(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition mov.c:9151
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:4470
static int mov_finalize_stsd_entry(MOVContext *c, AVStream *st)
Definition mov.c:3338
static int mov_read_pitm(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition mov.c:9447
static int mov_seek_stream(AVFormatContext *s, AVStream *st, int64_t timestamp, int flags)
Definition mov.c:12986
static int mov_read_packet(AVFormatContext *s, AVPacket *pkt)
Definition mov.c:12742
static int mov_parse_lcevc_streams(AVFormatContext *s)
Definition mov.c:12092
static int mov_read_hvce(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition mov.c:9124
static int cbcs_scheme_decrypt(MOVContext *c, MOVStreamContext *sc, AVEncryptionInfo *sample, uint8_t *input, int size)
Definition mov.c:8833
static int mov_read_default(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition mov.c:10395
static int mov_finalize_packet(AVFormatContext *s, AVStream *st, AVIndexEntry *sample, int64_t current_index, AVPacket *pkt)
Definition mov.c:12658
static int mov_read_stss(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition mov.c:3668
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:8242
static int mov_skip_multiple_stsd(MOVContext *c, AVIOContext *pb, int codec_tag, int format, int64_t size)
Definition mov.c:3312
static int mov_read_iref_auxl(MOVContext *c, AVIOContext *pb, uint32_t type, int version, uint32_t size)
Definition mov.c:9905
#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:6833
int ff_mov_read_stsd_entries(MOVContext *c, AVIOContext *pb, int entries)
Definition mov.c:3359
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_read_eyes(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition mov.c:7425
static int cenc_scheme_decrypt(MOVContext *c, MOVStreamContext *sc, AVEncryptionInfo *sample, uint8_t *input, int size)
Definition mov.c:8637
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:9798
static int mov_read_stsz(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition mov.c:3723
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:9407
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:12257
static int mov_read_dfla(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition mov.c:8560
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:7087
static int mov_read_elst(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition mov.c:6759
static int test_same_origin(const char *src, const char *ref)
Definition mov.c:5388
static int sanity_checks(void *log_obj, MOVStreamContext *sc, int index)
Definition mov.c:5545
static void mov_current_sample_set(MOVStreamContext *sc, int current_sample)
Definition mov.c:4482
static int mov_merge_tts_data(MOVContext *mov, AVStream *st, int flags)
Definition mov.c:4906
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:7215
static int mov_read_ddts(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition mov.c:1244
static int mov_read_sdtp(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition mov.c:3936
static int mov_read_stts(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition mov.c:3816
static int cenc_filter(MOVContext *mov, AVStream *st, MOVStreamContext *sc, AVPacket *pkt, int current_index)
Definition mov.c:8946
static const AVClass mov_class
Definition mov.c:13189
static int mov_read_sample_encryption_info(MOVContext *c, AVIOContext *pb, MOVStreamContext *sc, AVEncryptionInfo **sample, int use_subsamples)
Definition mov.c:7986
static int mov_read_meta(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition mov.c:5941
static int mov_read_smdm(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition mov.c:6905
static const uint32_t mac_to_unicode[128]
Definition mov.c:154
static int mov_read_sidx(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition mov.c:6547
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:4828
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:10725
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:9069
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:8458
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:10968
static int mov_seek_fragment(AVFormatContext *s, AVStream *st, int64_t timestamp)
Definition mov.c:12923
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:11537
static int mov_parse_dovi_streams(AVFormatContext *s)
Definition mov.c:12146
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:3606
static int mov_read_hdlr(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition mov.c:800
#define MOV_MERGE_STTS
Definition mov.c:4900
static int mov_read_dvcc_dvvc(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition mov.c:9104
static int should_retry(AVIOContext *pb, int error_code)
Definition mov.c:12522
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:6166
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:7033
static int mov_read_trun(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition mov.c:6205
static void mov_update_dts_shift(MOVStreamContext *sc, int duration, void *logctx)
Definition mov.c:3974
static int mov_read_kind(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition mov.c:9202
static int mov_read_sbgp(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition mov.c:4125
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:8337
static int mov_finalize_stsd_codec(MOVContext *c, AVIOContext *pb, AVStream *st, MOVStreamContext *sc)
Definition mov.c:3208
static int mov_read_tkhd(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition mov.c:5967
static int mov_read_iprp(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition mov.c:10070
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:8762
static int read_image_iovl(AVFormatContext *s, const HEIFGroup *grid, AVStreamGroupTileGrid *tile_grid)
Definition mov.c:11252
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:11023
static int mov_read_iref_dimg_grid(MOVContext *c, AVIOContext *pb, HEIFItem *item, int version, int entries)
Definition mov.c:9756
#define MIN_DATA_ENTRY_BOX_SIZE
Definition mov.c:655
static int mov_change_extradata(AVStream *st, AVPacket *pkt)
Definition mov.c:12565
static int mov_read_mdcv(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition mov.c:6952
static int mov_read_timecode_track(AVFormatContext *s, AVStream *st)
Definition mov.c:10751
static int mov_read_imir(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition mov.c:10051
static int mov_read_stps(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition mov.c:3627
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:9426
static int mov_parse_cdsc_and_rndr_streams(AVFormatContext *s)
Definition mov.c:12040
static const MOVParseTableEntry mov_default_parse_table[]
Definition mov.c:10258
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:9953
static int mov_read_trex(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition mov.c:6140
static int mov_read_saiz(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition mov.c:8158
static int mov_read_hfov(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition mov.c:7669
static int mov_read_free(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition mov.c:7866
static int set_icc_profile_from_item(AVPacketSideData **coded_side_data, int *nb_coded_side_data, const HEIFItem *item)
Definition mov.c:11107
static int mov_read_infe(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition mov.c:9558
static int mov_parse_heif_item_references(AVFormatContext *s, HEIFItem *item, AVPacketSideData **coded_side_data, int *nb_coded_side_data)
Definition mov.c:11412
static int mov_read_stsc(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition mov.c:3526
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:3135
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:8696
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:11069
static void fix_timescale(MOVContext *c, MOVStreamContext *sc)
Definition mov.c:5489
static int mov_read_custom(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition mov.c:5781
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:7935
static int mov_read_close(AVFormatContext *s)
Definition mov.c:10875
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:5417
static MOVFragmentStreamInfo * get_frag_stream_info_from_pkt(MOVFragmentIndex *frag_index, AVPacket *pkt, int id)
Definition mov.c:8921
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:8489
static int mov_read_uuid(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition mov.c:7761
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:4836
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:4969
static void mov_update_sample_durations(MOVContext *mov, AVStream *st)
Definition mov.c:5303
static int mov_read_ctts(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition mov.c:3985
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:11853
static int mov_read_amve(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition mov.c:7062
static int mov_read_keys(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition mov.c:5729
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:5959
static int can_seek_to_key_sample(AVStream *st, int sample, int64_t requested_pts)
Definition mov.c:12959
static int mov_parse_auxiliary_info(MOVContext *c, MOVStreamContext *sc, AVIOContext *pb, MOVEncryptionIndex *encryption_index)
Definition mov.c:8096
static int64_t mov_get_stsc_samples(MOVStreamContext *sc, unsigned int index)
Definition mov.c:3612
static int mov_read_vpcc(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition mov.c:6861
static int64_t add_index_entry(AVStream *st, int64_t pos, int64_t timestamp, int size, int distance, int flags)
Add index entry with the given values, to the end of ffstream(st)->index_entries.
Definition mov.c:4320
static int mov_parse_tiles(AVFormatContext *s)
Definition mov.c:11441
static void mov_fix_index(MOVContext *mov, AVStream *st)
Fix ffstream(st)->index_entries, so that it contains only the entries (and the entries which are need...
Definition mov.c:4510
#define DDTS_SIZE
static int mov_read_iref_cdsc(MOVContext *c, AVIOContext *pb, uint32_t type, int version, uint32_t size)
Definition mov.c:9859
static int cenc_decrypt(MOVContext *c, MOVStreamContext *sc, AVEncryptionInfo *sample, uint8_t *input, int size)
Definition mov.c:8905
static int mov_read_senc(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition mov.c:8040
static int mov_parse_heif_layered_video_auxl(AVFormatContext *s, HEIFItem *base, HEIFItem *gain_map)
Definition mov.c:11727
static int mov_read_sgpd(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition mov.c:4066
static AVStream * mov_find_reference_track(AVFormatContext *s, AVStream *st, uint32_t *tref_id, int nb_tref_id, int first_index)
Definition mov.c:12025
static void fix_index_entry_timestamps(AVStream *st, int end_index, int64_t end_ts, int64_t *frame_duration_buffer, int frame_duration_buffer_size)
Rewrite timestamps of index entries in the range [end_index - frame_duration_buffer_size,...
Definition mov.c:4361
static int mov_read_trak(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition mov.c:5564
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:4373
static void mov_parse_stsd_subtitle(MOVContext *c, AVIOContext *pb, AVStream *st, MOVStreamContext *sc, int64_t size)
Definition mov.c:3119
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:9381
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:10798
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:12219
#define OFFSET(x)
Definition mov.c:13133
static AVIndexEntry * mov_find_next_sample(AVFormatContext *s, AVStream **st)
Definition mov.c:12492
static int mov_read_chap(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition mov.c:6119
#define MOV_MERGE_CTTS
Definition mov.c:4899
static int is_open_key_sample(const MOVStreamContext *sc, int sample)
Definition mov.c:12942
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:9291
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:6996
static int mov_read_frma(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition mov.c:7888
static int mov_read_ispe(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition mov.c:10003
static int mov_codec_id(AVStream *st, uint32_t format)
Definition mov.c:2894
static void export_orphan_timecode(AVFormatContext *s)
Definition mov.c:10950
static int mov_parse_heif_items(AVFormatContext *s)
Definition mov.c:11902
static void mov_estimate_video_delay(MOVContext *c, AVStream *st)
Definition mov.c:4402
static int mov_read_vmhd(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition mov.c:10187
static int mov_read_tfhd(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition mov.c:6072
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:10031
static int mov_probe(const AVProbeData *p)
Definition mov.c:10517
static int parse_timecode_in_framenum_format(AVFormatContext *s, AVStream *st, int64_t value, int flags)
Definition mov.c:10711
static int mov_parse_uuid_spherical(MOVStreamContext *sc, AVIOContext *pb, size_t len)
Definition mov.c:7698
static void mov_current_sample_inc(MOVStreamContext *sc)
Definition mov.c:4458
static int mov_read_fiel(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition mov.c:2300
static int mov_read_iref_dimg_tmap(MOVContext *c, AVIOContext *pb, HEIFItem *item, int version, int entries)
Definition mov.c:9706
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:4186
static void mov_parse_stsd_audio(MOVContext *c, AVIOContext *pb, AVStream *st, MOVStreamContext *sc)
Definition mov.c:2998
static int mov_read_wide(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition mov.c:6686
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:9636
static int mov_parse_exif_item(AVFormatContext *s, HEIFItem *item, const HEIFItem *ref)
Definition mov.c:11321
static int tmcd_is_referenced(AVFormatContext *s, int tmcd_id)
Definition mov.c:10932
static void mov_read_chapters(AVFormatContext *s)
Definition mov.c:10612
static int mov_read_mhac(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition mov.c:10220
static int mov_read_cmov(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition mov.c:6706
static void set_frag_stream(MOVFragmentIndex *frag_index, int id)
Definition mov.c:1740
static const AVOption mov_options[]
Definition mov.c:13135
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:7607
int ff_mov_read_chan(AVFormatContext *s, AVIOContext *pb, AVStream *st, int64_t size)
Read 'chan' tag from the input stream.
Definition mov_chan.c:550
int ff_mov_read_chnl(AVFormatContext *s, AVIOContext *pb, AVStream *st, int version)
Read 'chnl' tag from the input stream.
Definition mov_chan.c:768
uint32_t tag
Definition movenc.c:2128
mpeg audio layer common tables.
const uint64_t ff_mpa_cicp_channel_layout_masks[20]
MPEG Audio header decoder.
static int ff_mpa_check_header(uint32_t header)
const char data[16]
Definition mxf.c:149
int profile
Definition mxfenc.c:2299
uint16_t cid
Definition mxfenc.c:2335
static 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:525
internal header for RIFF based (de)muxers do NOT include this in end user applications
int ff_get_wav_header(AVFormatContext *s, AVIOContext *pb, AVCodecParameters *par, int size, int big_endian)
Definition riffdec.c:141
#define av_bswap32
Definition bswap.h:47
Public header for SHA-1 & SHA-256 hash function implementations.
#define FF_ARRAY_ELEMS(a)
const uint8_t * code
Definition spdifenc.c:433
unsigned int pos
Definition spdifenc.c:431
Spherical video.
AVRational ambient_illuminance
Environmental illuminance of the ambient viewing environment in lux.
AVRational ambient_light_x
Normalized x chromaticity coordinate of the environmental ambient light in the nominal viewing enviro...
AVRational ambient_light_y
Normalized y chromaticity coordinate of the environmental ambient light in the nominal viewing enviro...
A reference to a data buffer.
Definition buffer.h:82
uint8_t * data
The data buffer.
Definition buffer.h:90
size_t size
Size of data in bytes.
Definition buffer.h:94
enum AVChannel id
An AVChannelLayout holds information about the channel layout of audio data.
enum AVChannelOrder order
Channel order used in this layout.
union AVChannelLayout::@162063043056170047076125117143030261346263330336 u
Details about which channels are present in this layout.
int nb_channels
Number of channels in this layout.
AVChannelCustom * map
This member must be used when the channel order is AV_CHANNEL_ORDER_CUSTOM.
Describe the class of an AVClass context structure.
Definition log.h:76
This struct describes the properties of an encoded stream.
Definition codec_par.h:49
enum AVColorSpace color_space
Definition codec_par.h:192
int extradata_size
Size of the extradata content in bytes.
Definition codec_par.h:75
int frame_size
Audio frame size, if known.
Definition codec_par.h:227
enum AVFieldOrder field_order
The order of the fields in interlaced video.
Definition codec_par.h:182
int height
The height of the video frame in pixels.
Definition codec_par.h:150
int nb_coded_side_data
Amount of entries in coded_side_data.
Definition codec_par.h:88
int bits_per_coded_sample
The number of bits per sample in the codedwords.
Definition codec_par.h:113
AVChannelLayout ch_layout
The channel layout and number of channels.
Definition codec_par.h:207
int width
The width of the video frame in pixels.
Definition codec_par.h:143
int64_t bit_rate
The average bitrate of the encoded data (in bits per second).
Definition codec_par.h:99
int seek_preroll
Number of audio samples to skip after a discontinuity.
Definition codec_par.h:256
enum AVMediaType codec_type
General type of the encoded data.
Definition codec_par.h:53
int profile
Codec-specific bitstream restrictions that the stream conforms to.
Definition codec_par.h:135
int block_align
The number of bytes per coded audio frame, required by some formats.
Definition codec_par.h:221
int video_delay
Number of delayed frames.
Definition codec_par.h:200
uint32_t codec_tag
Additional information about the codec (corresponds to the AVI FOURCC).
Definition codec_par.h:61
uint8_t * extradata
Extra binary data needed for initializing the decoder, codec-dependent.
Definition codec_par.h:71
enum AVCodecID codec_id
Specific type of the encoded data (the codec used).
Definition codec_par.h:57
enum AVColorPrimaries color_primaries
Definition codec_par.h:190
int sample_rate
The number of audio samples per second.
Definition codec_par.h:213
enum AVColorTransferCharacteristic color_trc
Definition codec_par.h:191
enum AVAlphaMode alpha_mode
Video with alpha channel only.
Definition codec_par.h:261
int initial_padding
Number of padding audio samples at the start.
Definition codec_par.h:239
AVPacketSideData * coded_side_data
Additional data associated with the entire stream.
Definition codec_par.h:83
enum AVColorRange color_range
Additional colorspace characteristics.
Definition codec_par.h:189
unsigned MaxFALL
Max average light level per frame (cd/m^2).
unsigned MaxCLL
Max content light level (cd/m^2).
char * value
Definition dict.h:92
This describes encryption info for a packet.
uint32_t skip_byte_block
Only used for pattern encryption.
uint8_t * iv
The initialization vector.
uint32_t crypt_byte_block
Only used for pattern encryption.
uint8_t * key_id
The ID of the key used to encrypt the packet.
uint32_t scheme
The fourcc encryption scheme, in big-endian byte order.
This describes info used to initialize an encryption key system.
uint8_t * data
Key-system specific initialization data.
struct AVEncryptionInitInfo * next
An optional pointer to the next initialization info in the list.
uint8_t ** key_ids
An array of key IDs this initialization data is for.
uint8_t * system_id
A unique identifier for the key system this is for, can be NULL if it is not known.
uint32_t num_key_ids
The number of key IDs.
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:1400
AVStream ** streams
A list of all streams in the file.
Definition avformat.h:1468
int error_recognition
Error recognition; higher values will detect more errors but may misdetect some more or less valid pa...
Definition avformat.h:1675
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
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:1179
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:1285
enum AVStreamGroupParamsType type
Group type.
Definition avformat.h:1211
struct AVIAMFMixPresentation * iamf_mix_presentation
Definition avformat.h:1218
AVStreamGroupEntry ** entries
A list of streams or child groups in the group.
Definition avformat.h:1298
struct AVStreamGroupTileGrid * tile_grid
Definition avformat.h:1219
struct AVStreamGroupTREF * tref
Definition avformat.h:1228
int nb_coded_side_data
Amount of entries in coded_side_data.
Definition avformat.h:1311
AVDictionary * metadata
Metadata that applies to the whole group.
Definition avformat.h:1239
union AVStreamGroup::@313244315204024013007202273061153315146016101155 params
Group type-specific parameters.
struct AVIAMFAudioElement * iamf_audio_element
Definition avformat.h:1217
int disposition
Stream group disposition - a combination of AV_DISPOSITION_* flags.
Definition avformat.h:1277
int64_t id
Group type-specific group ID.
Definition avformat.h:1203
AVPacketSideData * coded_side_data
Additional data associated with the group.
Definition avformat.h:1306
struct AVStreamGroupLayeredVideo * layered_video
Definition avformat.h:1220
Stream structure.
Definition avformat.h:768
AVCodecParameters * codecpar
Codec parameters associated with this stream.
Definition avformat.h:791
AVRational sample_aspect_ratio
sample aspect ratio (0 if unknown)
Definition avformat.h:846
int64_t nb_frames
number of frames in this stream if known or 0
Definition avformat.h:829
enum AVDiscard discard
Selects which packets can be discarded at will and do not need to be demuxed.
Definition avformat.h:839
int64_t duration
Decoding: duration of the stream, in stream time base.
Definition avformat.h:827
AVDictionary * metadata
Definition avformat.h:848
void * priv_data
Definition avformat.h:793
int id
Format-specific stream ID.
Definition avformat.h:780
int index
stream index in AVFormatContext
Definition avformat.h:774
int64_t start_time
Decoding: pts of the first frame of the stream in presentation order, in stream time base.
Definition avformat.h:817
AVPacket attached_pic
For streams with AV_DISPOSITION_ATTACHED_PIC disposition, this packet will contain the attached pictu...
Definition avformat.h:866
AVRational avg_frame_rate
Average framerate.
Definition avformat.h:857
AVRational time_base
This is the fundamental unit of time (in seconds) in terms of which frame timestamps are represented.
Definition avformat.h:807
AVRational r_frame_rate
Real base framerate of the stream.
Definition avformat.h:902
int disposition
Stream disposition - a combination of AV_DISPOSITION_* flags.
Definition avformat.h:837
This file is part of FFmpeg.
int64_t last_discard_sample
The sample after last sample that is intended to be discarded after first_discard_sample.
Definition internal.h:239
int64_t first_discard_sample
If not 0, the first audio sample that should be discarded from the stream.
Definition internal.h:232
int skip_samples
Number of samples to skip at the start of the frame decoded from the next packet.
Definition internal.h:215
int nb_index_entries
Definition internal.h:193
AVRational display_aspect_ratio
display aspect ratio (0 if unknown)
Definition internal.h:303
AVIndexEntry * index_entries
Only used if the format does not support seeking natively.
Definition internal.h:191
enum AVStreamParseType need_parsing
Definition internal.h:321
unsigned int index_entries_allocated_size
Definition internal.h:194
int16_t * item_id_list
Definition isom.h:327
HEIFItem ** item_list
Definition isom.h:326
int nb_items
Definition isom.h:329
unsigned * item_idx_list
Definition isom.h:328
HEIFItem * item
Definition isom.h:325
int item_id
Definition isom.h:296
uint32_t type
Definition isom.h:295
int is_idat_relative
Definition isom.h:318
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:320
HEIFItemRef * iref_from_list
Definition isom.h:302
int rotation
Definition isom.h:313
int hflip
Definition isom.h:314
AVExifMetadata ifd
Definition isom.h:319
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:321
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
uint32_t type
Definition isom.h:102
int64_t size
Definition isom.h:103
int handbrake_version
Definition isom.h:352
AVDictionary * decryption_keys
Definition isom.h:399
int * bitrates
bitrates read before streams creation
Definition isom.h:364
int cur_item_id
Definition isom.h:392
int ignore_editlist
Definition isom.h:356
HEIFGroup * heif_group
Definition isom.h:395
uint8_t * decryption_default_key
Definition isom.h:384
unsigned meta_keys_count
Definition isom.h:344
char ** meta_keys
Definition isom.h:343
AVFormatContext * fc
Definition isom.h:334
unsigned int aax_mode
'aax' file has been detected
Definition isom.h:372
int found_mdat
'mdat' atom has been found
Definition isom.h:340
int found_iinf
'iinf' atom has been found
Definition isom.h:339
int bitrates_count
Definition isom.h:365
int * chapter_tracks
Definition isom.h:353
int interleaved_read
Definition isom.h:398
int64_t next_root_atom
offset of the next root atom
Definition isom.h:361
int ignore_chapters
Definition isom.h:359
DVDemuxContext * dv_demux
Definition isom.h:345
int nb_heif_item
Definition isom.h:394
unsigned int nb_chapter_tracks
Definition isom.h:354
int64_t idat_offset
Definition isom.h:397
MOVFragmentIndex frag_index
Definition isom.h:370
int nb_heif_group
Definition isom.h:396
MOVTrackExt * trex_data
Definition isom.h:349
struct AVAES * aes_decrypt
Definition isom.h:383
MOVFragment fragment
current fragment in moof atom
Definition isom.h:348
AVFormatContext * dv_fctx
Definition isom.h:346
int moov_retry
Definition isom.h:366
int time_scale
Definition isom.h:335
int advanced_editlist_autodisabled
Definition isom.h:358
int found_moov
'moov' atom has been found
Definition isom.h:337
int primary_item_id
Definition isom.h:391
int advanced_editlist
Definition isom.h:357
int found_iloc
'iloc' atom has been found
Definition isom.h:338
HEIFItem ** heif_item
Definition isom.h:393
int trak_index
Index of the current 'trak'.
Definition isom.h:342
int use_mfra_for
Definition isom.h:367
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:509
Definition isom.h:95
uint32_t * id
trackID of the referenced track
Definition isom.h:98
Definition swscale.c:71
#define av_free(p)
#define av_malloc_array(a, b)
#define av_mallocz(s)
#define ff_dlog(a,...)
#define av_realloc_f(p, o, n)
#define avpriv_request_sample(...)
#define av_freep(p)
#define av_log(a,...)
static uint8_t tmp[40]
Definition aes_ctr.c:52
static const uint8_t fixed_key[]
Definition aes_ctr.c:45
int tile_cols
Definition av1_levels.c:73
#define src
Definition vp8dsp.c:248
int num
Definition error.c:23
static int ref[MAX_W *MAX_W]
static char buffer[20]
Definition seek.c:32
#define height
Definition dsp.h:99
#define width
Definition dsp.h:99
int av_timecode_init(AVTimecode *tc, AVRational rate, int flags, int frame_start, void *log_ctx)
Init a timecode struct with the passed parameters.
Definition timecode.c:201
char * av_timecode_make_string(const AVTimecode *tc, char *buf, int framenum_arg)
Load timecode string in buf.
Definition timecode.c:104
Timecode helpers header.
#define AV_TIMECODE_STR_SIZE
Definition timecode.h:33
@ AV_TIMECODE_FLAG_ALLOWNEGATIVE
negative time values are allowed
Definition timecode.h:38
@ AV_TIMECODE_FLAG_DROPFRAME
timecode is drop frame
Definition timecode.h:36
@ AV_TIMECODE_FLAG_24HOURSMAX
timecode wraps after 24 hours
Definition timecode.h:37
static int64_t pts
static const int16_t cdt2[8]
int size
UUID parsing and serialization utilities.
static int av_uuid_equal(const AVUUID uu1, const AVUUID uu2)
Compares two UUIDs for equality.
Definition uuid.h:119
#define AV_UUID_LEN
Definition uuid.h:57
uint8_t AVUUID[AV_UUID_LEN]
Definition uuid.h:60
enum AVCodecID codec_id
#define mc
static float mean(const float *input, int size)
Definition vf_nnedi.c:861
color_range
int len
uint8_t base
Definition vp3data.h:128
static double c[64]