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