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 uint64_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 (bottom > (height - 1) ||
1442 right > (width - 1)) {
1443 err = AVERROR_INVALIDDATA;
1444 goto fail;
1445 }
1446
1447 bottom = height - 1 - bottom;
1448 right = width - 1 - right;
1449
1450 if (!(left | right | top | bottom))
1451 return 0;
1452
1453 if ((left + right) >= width ||
1454 (top + bottom) >= height) {
1455 err = AVERROR_INVALIDDATA;
1456 goto fail;
1457 }
1458
1462 sizeof(uint32_t) * 4, 0);
1463 if (!sd)
1464 return AVERROR(ENOMEM);
1465
1466 AV_WL32A(sd->data, top);
1467 AV_WL32A(sd->data + 4, bottom);
1468 AV_WL32A(sd->data + 8, left);
1469 AV_WL32A(sd->data + 12, right);
1470
1471fail:
1472 if (err < 0) {
1473 int explode = !!(c->fc->error_recognition & AV_EF_EXPLODE);
1474 av_log(c->fc, explode ? AV_LOG_ERROR : AV_LOG_WARNING, "Invalid clap box\n");
1475 if (!explode)
1476 err = 0;
1477 }
1478
1479 return err;
1480}
1481
1482/* This atom overrides any previously set aspect ratio */
1484{
1485 const int num = avio_rb32(pb);
1486 const int den = avio_rb32(pb);
1487 AVStream *st;
1488 MOVStreamContext *sc;
1489
1490 if (c->fc->nb_streams < 1)
1491 return 0;
1492 st = c->fc->streams[c->fc->nb_streams-1];
1493 sc = st->priv_data;
1494
1495 av_log(c->fc, AV_LOG_TRACE, "pasp: hSpacing %d, vSpacing %d\n", num, den);
1496
1497 if (den != 0) {
1498 sc->h_spacing = num;
1499 sc->v_spacing = den;
1500 }
1501 return 0;
1502}
1503
1504/* this atom contains actual media data */
1506{
1507 if (atom.size == 0) /* wrong one (MP4) */
1508 return 0;
1509 c->found_mdat=1;
1510 return 0; /* now go for moov */
1511}
1512
1513#define DRM_BLOB_SIZE 56
1514
1516{
1517 uint8_t intermediate_key[20];
1518 uint8_t intermediate_iv[20];
1519 uint8_t input[64];
1520 uint8_t output[64];
1521 uint8_t file_checksum[20];
1522 uint8_t calculated_checksum[20];
1523 char checksum_string[2 * sizeof(file_checksum) + 1];
1524 struct AVSHA *sha;
1525 int i;
1526 int ret = 0;
1527 uint8_t *activation_bytes = c->activation_bytes;
1528 uint8_t *fixed_key = c->audible_fixed_key;
1529
1530 c->aax_mode = 1;
1531
1532 sha = av_sha_alloc();
1533 if (!sha)
1534 return AVERROR(ENOMEM);
1535 av_free(c->aes_decrypt);
1536 c->aes_decrypt = av_aes_alloc();
1537 if (!c->aes_decrypt) {
1538 ret = AVERROR(ENOMEM);
1539 goto fail;
1540 }
1541
1542 /* drm blob processing */
1543 avio_read(pb, output, 8); // go to offset 8, absolute position 0x251
1544 avio_read(pb, input, DRM_BLOB_SIZE);
1545 avio_read(pb, output, 4); // go to offset 4, absolute position 0x28d
1546 ret = ffio_read_size(pb, file_checksum, 20);
1547 if (ret < 0)
1548 goto fail;
1549
1550 // required by external tools
1551 ff_data_to_hex(checksum_string, file_checksum, sizeof(file_checksum), 1);
1552 av_log(c->fc, AV_LOG_INFO, "[aax] file checksum == %s\n", checksum_string);
1553
1554 /* verify activation data */
1555 if (!activation_bytes) {
1556 av_log(c->fc, AV_LOG_WARNING, "[aax] activation_bytes option is missing!\n");
1557 ret = 0; /* allow ffprobe to continue working on .aax files */
1558 goto fail;
1559 }
1560 if (c->activation_bytes_size != 4) {
1561 av_log(c->fc, AV_LOG_FATAL, "[aax] activation_bytes value needs to be 4 bytes!\n");
1562 ret = AVERROR(EINVAL);
1563 goto fail;
1564 }
1565
1566 /* verify fixed key */
1567 if (c->audible_fixed_key_size != 16) {
1568 av_log(c->fc, AV_LOG_FATAL, "[aax] audible_fixed_key value needs to be 16 bytes!\n");
1569 ret = AVERROR(EINVAL);
1570 goto fail;
1571 }
1572
1573 /* AAX (and AAX+) key derivation */
1574 av_sha_init(sha, 160);
1575 av_sha_update(sha, fixed_key, 16);
1576 av_sha_update(sha, activation_bytes, 4);
1577 av_sha_final(sha, intermediate_key);
1578 av_sha_init(sha, 160);
1579 av_sha_update(sha, fixed_key, 16);
1580 av_sha_update(sha, intermediate_key, 20);
1581 av_sha_update(sha, activation_bytes, 4);
1582 av_sha_final(sha, intermediate_iv);
1583 av_sha_init(sha, 160);
1584 av_sha_update(sha, intermediate_key, 16);
1585 av_sha_update(sha, intermediate_iv, 16);
1586 av_sha_final(sha, calculated_checksum);
1587 if (memcmp(calculated_checksum, file_checksum, 20)) { // critical error
1588 av_log(c->fc, AV_LOG_ERROR, "[aax] mismatch in checksums!\n");
1589 ret = AVERROR_INVALIDDATA;
1590 goto fail;
1591 }
1592 av_aes_init(c->aes_decrypt, intermediate_key, 128, 1);
1593 av_aes_crypt(c->aes_decrypt, output, input, DRM_BLOB_SIZE >> 4, intermediate_iv, 1);
1594 for (i = 0; i < 4; i++) {
1595 // file data (in output) is stored in big-endian mode
1596 if (activation_bytes[i] != output[3 - i]) { // critical error
1597 av_log(c->fc, AV_LOG_ERROR, "[aax] error in drm blob decryption!\n");
1598 ret = AVERROR_INVALIDDATA;
1599 goto fail;
1600 }
1601 }
1602 memcpy(c->file_key, output + 8, 16);
1603 memcpy(input, output + 26, 16);
1604 av_sha_init(sha, 160);
1605 av_sha_update(sha, input, 16);
1606 av_sha_update(sha, c->file_key, 16);
1607 av_sha_update(sha, fixed_key, 16);
1608 av_sha_final(sha, c->file_iv);
1609
1610fail:
1611 av_free(sha);
1612
1613 return ret;
1614}
1615
1617{
1618 if (c->audible_key_size != 16) {
1619 av_log(c->fc, AV_LOG_FATAL, "[aaxc] audible_key value needs to be 16 bytes!\n");
1620 return AVERROR(EINVAL);
1621 }
1622
1623 if (c->audible_iv_size != 16) {
1624 av_log(c->fc, AV_LOG_FATAL, "[aaxc] audible_iv value needs to be 16 bytes!\n");
1625 return AVERROR(EINVAL);
1626 }
1627
1628 c->aes_decrypt = av_aes_alloc();
1629 if (!c->aes_decrypt) {
1630 return AVERROR(ENOMEM);
1631 }
1632
1633 memcpy(c->file_key, c->audible_key, 16);
1634 memcpy(c->file_iv, c->audible_iv, 16);
1635 c->aax_mode = 1;
1636
1637 return 0;
1638}
1639
1640// Audible AAX (and AAX+) bytestream decryption
1641static int aax_filter(uint8_t *input, int size, MOVContext *c)
1642{
1643 int blocks = 0;
1644 unsigned char iv[16];
1645
1646 memcpy(iv, c->file_iv, 16); // iv is overwritten
1647 blocks = size >> 4; // trailing bytes are not encrypted!
1648 av_aes_init(c->aes_decrypt, c->file_key, 128, 1);
1649 av_aes_crypt(c->aes_decrypt, input, input, blocks, iv, 1);
1650
1651 return 0;
1652}
1653
1654/* read major brand, minor version and compatible brands and store them as metadata */
1656{
1657 uint32_t minor_ver;
1658 int comp_brand_size;
1659 char* comp_brands_str;
1660 uint8_t type[5] = {0};
1661 int ret = ffio_read_size(pb, type, 4);
1662 if (ret < 0)
1663 return ret;
1664 if (c->fc->nb_streams) {
1665 if (c->fc->strict_std_compliance >= FF_COMPLIANCE_STRICT)
1666 return AVERROR_INVALIDDATA;
1667 av_log(c->fc, AV_LOG_DEBUG, "Ignoring duplicate FTYP\n");
1668 return 0;
1669 }
1670
1671 if (strcmp(type, "qt "))
1672 c->isom = 1;
1673 av_log(c->fc, AV_LOG_DEBUG, "ISO: File Type Major Brand: %.4s\n",(char *)&type);
1674 av_dict_set(&c->fc->metadata, "major_brand", type, 0);
1675 minor_ver = avio_rb32(pb); /* minor version */
1676 av_dict_set_int(&c->fc->metadata, "minor_version", minor_ver, 0);
1677
1678 comp_brand_size = atom.size - 8;
1679 if (comp_brand_size < 0 || comp_brand_size == INT_MAX)
1680 return AVERROR_INVALIDDATA;
1681 comp_brands_str = av_malloc(comp_brand_size + 1); /* Add null terminator */
1682 if (!comp_brands_str)
1683 return AVERROR(ENOMEM);
1684
1685 ret = ffio_read_size(pb, comp_brands_str, comp_brand_size);
1686 if (ret < 0) {
1687 av_freep(&comp_brands_str);
1688 return ret;
1689 }
1690 comp_brands_str[comp_brand_size] = 0;
1691 av_dict_set(&c->fc->metadata, "compatible_brands",
1692 comp_brands_str, AV_DICT_DONT_STRDUP_VAL);
1693
1694 // Logic for handling Audible's .aaxc files
1695 if (!strcmp(type, "aaxc")) {
1697 }
1698
1699 return 0;
1700}
1701
1702/* this atom should contain all header atoms */
1704{
1705 int ret;
1706
1707 if (c->found_moov) {
1708 av_log(c->fc, AV_LOG_WARNING, "Found duplicated MOOV Atom. Skipped it\n");
1709 avio_skip(pb, atom.size);
1710 return 0;
1711 }
1712
1713 if ((ret = mov_read_default(c, pb, atom)) < 0)
1714 return ret;
1715 /* we parsed the 'moov' atom, we can terminate the parsing as soon as we find the 'mdat' */
1716 /* so we don't parse the whole file if over a network */
1717 c->found_moov=1;
1718 return 0; /* now go for mdat */
1719}
1720
1722 MOVFragmentIndex *frag_index,
1723 int index,
1724 int id)
1725{
1726 int i;
1727 MOVFragmentIndexItem * item;
1728
1729 if (index < 0 || index >= frag_index->nb_items)
1730 return NULL;
1731 item = &frag_index->item[index];
1732 for (i = 0; i < item->nb_stream_info; i++)
1733 if (item->stream_info[i].id == id)
1734 return &item->stream_info[i];
1735
1736 // This shouldn't happen
1737 return NULL;
1738}
1739
1740static void set_frag_stream(MOVFragmentIndex *frag_index, int id)
1741{
1742 int i;
1743 MOVFragmentIndexItem * item;
1744
1745 if (frag_index->current < 0 ||
1746 frag_index->current >= frag_index->nb_items)
1747 return;
1748
1749 item = &frag_index->item[frag_index->current];
1750 for (i = 0; i < item->nb_stream_info; i++)
1751 if (item->stream_info[i].id == id) {
1752 item->current = i;
1753 return;
1754 }
1755
1756 // id not found. This shouldn't happen.
1757 item->current = -1;
1758}
1759
1761 MOVFragmentIndex *frag_index)
1762{
1764 if (frag_index->current < 0 ||
1765 frag_index->current >= frag_index->nb_items)
1766 return NULL;
1767
1768 item = &frag_index->item[frag_index->current];
1769 if (item->current >= 0 && item->current < item->nb_stream_info)
1770 return &item->stream_info[item->current];
1771
1772 // This shouldn't happen
1773 return NULL;
1774}
1775
1777{
1778 int a, b, m;
1779 int64_t moof_offset;
1780
1781 // Optimize for appending new entries
1782 if (!frag_index->nb_items ||
1783 frag_index->item[frag_index->nb_items - 1].moof_offset < offset)
1784 return frag_index->nb_items;
1785
1786 a = -1;
1787 b = frag_index->nb_items;
1788
1789 while (b - a > 1) {
1790 m = (a + b) >> 1;
1791 moof_offset = frag_index->item[m].moof_offset;
1792 if (moof_offset >= offset)
1793 b = m;
1794 if (moof_offset <= offset)
1795 a = m;
1796 }
1797 return b;
1798}
1799
1801{
1802 av_assert0(frag_stream_info);
1803 if (frag_stream_info->sidx_pts != AV_NOPTS_VALUE)
1804 return frag_stream_info->sidx_pts;
1805 if (frag_stream_info->first_tfra_pts != AV_NOPTS_VALUE)
1806 return frag_stream_info->first_tfra_pts;
1807 return frag_stream_info->tfdt_dts;
1808}
1809
1811 MOVFragmentIndex *frag_index, int index)
1812{
1813 MOVFragmentStreamInfo * frag_stream_info;
1814 MOVStreamContext *sc = dst_st->priv_data;
1815 int64_t timestamp;
1816 int i, j;
1817
1818 // If the stream is referenced by any sidx, limit the search
1819 // to fragments that referenced this stream in the sidx
1820 if (sc->has_sidx) {
1821 frag_stream_info = get_frag_stream_info(frag_index, index, sc->id);
1822 if (!frag_stream_info)
1823 return AV_NOPTS_VALUE;
1824 if (frag_stream_info->sidx_pts != AV_NOPTS_VALUE)
1825 return frag_stream_info->sidx_pts;
1826 if (frag_stream_info->first_tfra_pts != AV_NOPTS_VALUE)
1827 return frag_stream_info->first_tfra_pts;
1828 return frag_stream_info->sidx_pts;
1829 }
1830
1831 for (i = 0; i < frag_index->item[index].nb_stream_info; i++) {
1832 if (dst_st->id != frag_index->item[index].stream_info[i].id)
1833 continue;
1834 AVStream *frag_stream = NULL;
1835 frag_stream_info = &frag_index->item[index].stream_info[i];
1836 for (j = 0; j < s->nb_streams; j++) {
1837 MOVStreamContext *sc2 = s->streams[j]->priv_data;
1838 if (sc2->id == frag_stream_info->id)
1839 frag_stream = s->streams[j];
1840 }
1841 if (!frag_stream) {
1842 av_log(s, AV_LOG_WARNING, "No stream matching sidx ID found.\n");
1843 continue;
1844 }
1845 timestamp = get_stream_info_time(frag_stream_info);
1846 if (timestamp != AV_NOPTS_VALUE)
1847 return av_rescale_q(timestamp, frag_stream->time_base, dst_st->time_base);
1848 }
1849 return AV_NOPTS_VALUE;
1850}
1851
1853 AVStream *st, int64_t timestamp)
1854{
1855 int a, b, m, m0;
1856 int64_t frag_time;
1857
1858 a = -1;
1859 b = frag_index->nb_items;
1860
1861 while (b - a > 1) {
1862 m0 = m = (a + b) >> 1;
1863
1864 while (m < b &&
1865 (frag_time = get_frag_time(s, st, frag_index, m)) == AV_NOPTS_VALUE)
1866 m++;
1867
1868 if (m < b && frag_time <= timestamp)
1869 a = m;
1870 else
1871 b = m0;
1872 }
1873
1874 return a;
1875}
1876
1878{
1879 int index, i;
1880 MOVFragmentIndexItem * item;
1881 MOVFragmentStreamInfo * frag_stream_info;
1882
1883 // If moof_offset already exists in frag_index, return index to it
1884 index = search_frag_moof_offset(&c->frag_index, offset);
1885 if (index < c->frag_index.nb_items &&
1886 c->frag_index.item[index].moof_offset == offset)
1887 return index;
1888
1889 // offset is not yet in frag index.
1890 // Insert new item at index (sorted by moof offset)
1891 item = av_fast_realloc(c->frag_index.item,
1892 &c->frag_index.allocated_size,
1893 (c->frag_index.nb_items + 1) *
1894 sizeof(*c->frag_index.item));
1895 if (!item)
1896 return -1;
1897 c->frag_index.item = item;
1898
1899 frag_stream_info = av_realloc_array(NULL, c->fc->nb_streams,
1900 sizeof(*item->stream_info));
1901 if (!frag_stream_info)
1902 return -1;
1903
1904 for (i = 0; i < c->fc->nb_streams; i++) {
1905 // Avoid building frag index if streams lack track id.
1906 MOVStreamContext *sc = c->fc->streams[i]->priv_data;
1907 if (sc->id < 0) {
1908 av_free(frag_stream_info);
1909 return AVERROR_INVALIDDATA;
1910 }
1911
1912 frag_stream_info[i].id = sc->id;
1913 frag_stream_info[i].sidx_pts = AV_NOPTS_VALUE;
1914 frag_stream_info[i].tfdt_dts = AV_NOPTS_VALUE;
1915 frag_stream_info[i].next_trun_dts = AV_NOPTS_VALUE;
1916 frag_stream_info[i].first_tfra_pts = AV_NOPTS_VALUE;
1917 frag_stream_info[i].index_base = -1;
1918 frag_stream_info[i].index_entry = -1;
1919 frag_stream_info[i].encryption_index = NULL;
1920 frag_stream_info[i].stsd_id = -1;
1921 }
1922
1923 if (index < c->frag_index.nb_items)
1924 memmove(c->frag_index.item + index + 1, c->frag_index.item + index,
1925 (c->frag_index.nb_items - index) * sizeof(*c->frag_index.item));
1926 if (index <= c->frag_index.current)
1927 c->frag_index.current++;
1928
1929 item = &c->frag_index.item[index];
1930 item->headers_read = 0;
1931 item->current = 0;
1932 item->nb_stream_info = c->fc->nb_streams;
1933 item->moof_offset = offset;
1934 item->stream_info = frag_stream_info;
1935 c->frag_index.nb_items++;
1936
1937 return index;
1938}
1939
1940static void fix_frag_index_entries(MOVFragmentIndex *frag_index, int index,
1941 int id, int entries)
1942{
1943 int i;
1944 MOVFragmentStreamInfo * frag_stream_info;
1945
1946 if (index < 0)
1947 return;
1948 for (i = index; i < frag_index->nb_items; i++) {
1949 frag_stream_info = get_frag_stream_info(frag_index, i, id);
1950 if (frag_stream_info && frag_stream_info->index_entry >= 0)
1951 frag_stream_info->index_entry += entries;
1952 }
1953}
1954
1956{
1957 // Set by mov_read_tfhd(). mov_read_trun() will reject files missing tfhd.
1958 c->fragment.found_tfhd = 0;
1959
1960 if (!c->has_looked_for_mfra && c->use_mfra_for > 0) {
1961 c->has_looked_for_mfra = 1;
1962 if (pb->seekable & AVIO_SEEKABLE_NORMAL) {
1963 int ret;
1964 av_log(c->fc, AV_LOG_VERBOSE, "stream has moof boxes, will look "
1965 "for a mfra\n");
1966 if ((ret = mov_read_mfra(c, pb)) < 0) {
1967 av_log(c->fc, AV_LOG_VERBOSE, "found a moof box but failed to "
1968 "read the mfra (may be a live ismv)\n");
1969 }
1970 } else {
1971 av_log(c->fc, AV_LOG_VERBOSE, "found a moof box but stream is not "
1972 "seekable, can not look for mfra\n");
1973 }
1974 }
1975 c->fragment.moof_offset = c->fragment.implicit_offset = avio_tell(pb) - 8;
1976 av_log(c->fc, AV_LOG_TRACE, "moof offset %"PRIx64"\n", c->fragment.moof_offset);
1977 c->frag_index.current = update_frag_index(c, c->fragment.moof_offset);
1978 return mov_read_default(c, pb, atom);
1979}
1980
1982{
1983 int64_t time;
1984 if (version == 1) {
1985 time = avio_rb64(pb);
1986 avio_rb64(pb);
1987 if (time < 0) {
1988 av_log(c->fc, AV_LOG_DEBUG, "creation_time is negative\n");
1989 return;
1990 }
1991 } else {
1992 time = avio_rb32(pb);
1993 avio_rb32(pb); /* modification time */
1994 if (time > 0 && time < 2082844800) {
1995 av_log(c->fc, AV_LOG_WARNING, "Detected creation time before 1970, parsing as unix timestamp.\n");
1996 time += 2082844800;
1997 }
1998 }
1999 if (time) {
2000 time -= 2082844800; /* seconds between 1904-01-01 and Epoch */
2001
2002 if ((int64_t)(time * 1000000ULL) / 1000000 != time) {
2003 av_log(c->fc, AV_LOG_DEBUG, "creation_time is not representable\n");
2004 return;
2005 }
2006
2007 ff_dict_set_timestamp(metadata, "creation_time", time * 1000000);
2008 }
2009}
2010
2012{
2013 AVStream *st;
2014 MOVStreamContext *sc;
2015 int version;
2016 char language[4] = {0};
2017 unsigned lang;
2018
2019 if (c->fc->nb_streams < 1)
2020 return 0;
2021 st = c->fc->streams[c->fc->nb_streams-1];
2022 sc = st->priv_data;
2023
2024 if (sc->time_scale) {
2025 av_log(c->fc, AV_LOG_ERROR, "Multiple mdhd?\n");
2026 return AVERROR_INVALIDDATA;
2027 }
2028
2029 version = avio_r8(pb);
2030 if (version > 1) {
2031 avpriv_request_sample(c->fc, "Version %d", version);
2032 return AVERROR_PATCHWELCOME;
2033 }
2034 avio_rb24(pb); /* flags */
2036
2037 sc->time_scale = avio_rb32(pb);
2038 if (sc->time_scale <= 0) {
2039 av_log(c->fc, AV_LOG_ERROR, "Invalid mdhd time scale %d, defaulting to 1\n", sc->time_scale);
2040 sc->time_scale = 1;
2041 }
2042 st->duration = (version == 1) ? avio_rb64(pb) : avio_rb32(pb); /* duration */
2043
2044 if ((version == 1 && st->duration == UINT64_MAX) ||
2045 (version != 1 && st->duration == UINT32_MAX)) {
2046 st->duration = 0;
2047 }
2048
2049 lang = avio_rb16(pb); /* language */
2050 if (ff_mov_lang_to_iso639(lang, language))
2051 av_dict_set(&st->metadata, "language", language, 0);
2052 avio_rb16(pb); /* quality */
2053
2054 return 0;
2055}
2056
2058{
2059 int i;
2060 int version = avio_r8(pb); /* version */
2061 avio_rb24(pb); /* flags */
2062
2063 mov_metadata_creation_time(c, pb, &c->fc->metadata, version);
2064 c->time_scale = avio_rb32(pb); /* time scale */
2065 if (c->time_scale <= 0) {
2066 av_log(c->fc, AV_LOG_ERROR, "Invalid mvhd time scale %d, defaulting to 1\n", c->time_scale);
2067 c->time_scale = 1;
2068 }
2069 av_log(c->fc, AV_LOG_TRACE, "time scale = %i\n", c->time_scale);
2070
2071 c->duration = (version == 1) ? avio_rb64(pb) : avio_rb32(pb); /* duration */
2072 avio_rb32(pb); /* preferred scale */
2073
2074 avio_rb16(pb); /* preferred volume */
2075
2076 avio_skip(pb, 10); /* reserved */
2077
2078 /* movie display matrix, store it in main context and use it later on */
2079 for (i = 0; i < 3; i++) {
2080 c->movie_display_matrix[i][0] = avio_rb32(pb); // 16.16 fixed point
2081 c->movie_display_matrix[i][1] = avio_rb32(pb); // 16.16 fixed point
2082 c->movie_display_matrix[i][2] = avio_rb32(pb); // 2.30 fixed point
2083 }
2084
2085 avio_rb32(pb); /* preview time */
2086 avio_rb32(pb); /* preview duration */
2087 avio_rb32(pb); /* poster time */
2088 avio_rb32(pb); /* selection time */
2089 avio_rb32(pb); /* selection duration */
2090 avio_rb32(pb); /* current time */
2091 avio_rb32(pb); /* next track ID */
2092
2093 return 0;
2094}
2095
2097{
2098 AVStream *st;
2099
2100 if (fc->nb_streams < 1)
2101 return;
2102 st = fc->streams[fc->nb_streams-1];
2103
2104 switch (st->codecpar->codec_id) {
2107 break;
2110 break;
2113 break;
2116 break;
2119 break;
2120 default:
2121 break;
2122 }
2123}
2124
2126{
2127 int little_endian = avio_rb16(pb) & 0xFF;
2128 av_log(c->fc, AV_LOG_TRACE, "enda %d\n", little_endian);
2129 if (little_endian == 1)
2131 return 0;
2132}
2133
2135{
2136 int format_flags;
2137 int version, flags;
2138 int pcm_sample_size;
2139 AVFormatContext *fc = c->fc;
2140 AVStream *st;
2141 MOVStreamContext *sc;
2142
2143 if (atom.size < 6) {
2144 av_log(c->fc, AV_LOG_ERROR, "Empty pcmC box\n");
2145 return AVERROR_INVALIDDATA;
2146 }
2147
2148 version = avio_r8(pb);
2149 flags = avio_rb24(pb);
2150
2151 if (version != 0 || flags != 0) {
2152 av_log(c->fc, AV_LOG_ERROR,
2153 "Unsupported 'pcmC' box with version %d, flags: %x",
2154 version, flags);
2155 return AVERROR_INVALIDDATA;
2156 }
2157
2158 format_flags = avio_r8(pb);
2159 pcm_sample_size = avio_r8(pb);
2160
2161 if (fc->nb_streams < 1)
2162 return AVERROR_INVALIDDATA;
2163
2164 st = fc->streams[fc->nb_streams - 1];
2165 sc = st->priv_data;
2166
2167 if (sc->format == MOV_MP4_FPCM_TAG) {
2168 switch (pcm_sample_size) {
2169 case 32:
2171 break;
2172 case 64:
2174 break;
2175 default:
2176 av_log(fc, AV_LOG_ERROR, "invalid pcm_sample_size %d for %s\n",
2177 pcm_sample_size,
2178 av_fourcc2str(sc->format));
2179 return AVERROR_INVALIDDATA;
2180 }
2181 } else if (sc->format == MOV_MP4_IPCM_TAG) {
2182 switch (pcm_sample_size) {
2183 case 16:
2185 break;
2186 case 24:
2188 break;
2189 case 32:
2191 break;
2192 default:
2193 av_log(fc, AV_LOG_ERROR, "invalid pcm_sample_size %d for %s\n",
2194 pcm_sample_size,
2195 av_fourcc2str(sc->format));
2196 return AVERROR_INVALIDDATA;
2197 }
2198 } else {
2199 av_log(fc, AV_LOG_ERROR, "'pcmC' with invalid sample entry '%s'\n",
2200 av_fourcc2str(sc->format));
2201 return AVERROR_INVALIDDATA;
2202 }
2203
2204 if (format_flags & 1) // indicates little-endian format. If not present, big-endian format is used
2207
2208 return 0;
2209}
2210
2212{
2213 AVStream *st;
2214 HEIFItem *item = NULL;
2215 char color_parameter_type[5] = { 0 };
2216 uint16_t color_primaries, color_trc, color_matrix;
2217 int ret;
2218
2219 st = get_curr_st(c);
2220 if (!st) {
2221 item = get_heif_item(c, c->cur_item_id);
2222 if (!item)
2223 return 0;
2224 }
2225
2226 ret = ffio_read_size(pb, color_parameter_type, 4);
2227 if (ret < 0)
2228 return ret;
2229 if (strncmp(color_parameter_type, "nclx", 4) &&
2230 strncmp(color_parameter_type, "nclc", 4) &&
2231 strncmp(color_parameter_type, "prof", 4)) {
2232 av_log(c->fc, AV_LOG_WARNING, "unsupported color_parameter_type %s\n",
2233 color_parameter_type);
2234 return 0;
2235 }
2236
2237 if (!strncmp(color_parameter_type, "prof", 4)) {
2238 AVPacketSideData *sd;
2239 uint8_t *icc_profile;
2240 if (st) {
2244 atom.size - 4, 0);
2245 if (!sd)
2246 return AVERROR(ENOMEM);
2247 icc_profile = sd->data;
2248 } else {
2249 if (c->heif_icc_profile_items >= c->fc->max_streams) {
2250 av_log(c->fc, AV_LOG_WARNING,
2251 "HEIF ICC profile copies exceed cap %d; ignoring further items\n",
2252 c->fc->max_streams);
2253 return 0;
2254 }
2255 av_freep(&item->icc_profile);
2256 icc_profile = item->icc_profile = av_malloc(atom.size - 4);
2257 if (!icc_profile) {
2258 item->icc_profile_size = 0;
2259 return AVERROR(ENOMEM);
2260 }
2261 item->icc_profile_size = atom.size - 4;
2262 c->heif_icc_profile_items++;
2263 }
2264 ret = ffio_read_size(pb, icc_profile, atom.size - 4);
2265 if (ret < 0)
2266 return ret;
2267 } else if (st) {
2269 color_trc = avio_rb16(pb);
2270 color_matrix = avio_rb16(pb);
2271
2272 av_log(c->fc, AV_LOG_TRACE,
2273 "%s: pri %d trc %d matrix %d",
2274 color_parameter_type, color_primaries, color_trc, color_matrix);
2275
2276 if (!strncmp(color_parameter_type, "nclx", 4)) {
2277 uint8_t color_range = avio_r8(pb) >> 7;
2278 av_log(c->fc, AV_LOG_TRACE, " full %"PRIu8"", color_range);
2279 if (color_range)
2281 else
2283 }
2284
2287 if (!av_color_transfer_name(color_trc))
2288 color_trc = AVCOL_TRC_UNSPECIFIED;
2289 if (!av_color_space_name(color_matrix))
2290 color_matrix = AVCOL_SPC_UNSPECIFIED;
2291
2293 st->codecpar->color_trc = color_trc;
2294 st->codecpar->color_space = color_matrix;
2295 av_log(c->fc, AV_LOG_TRACE, "\n");
2296 }
2297 return 0;
2298}
2299
2301{
2302 AVStream *st;
2303 unsigned mov_field_order;
2304 enum AVFieldOrder decoded_field_order = AV_FIELD_UNKNOWN;
2305
2306 if (c->fc->nb_streams < 1) // will happen with jp2 files
2307 return 0;
2308 st = c->fc->streams[c->fc->nb_streams-1];
2309 if (atom.size < 2)
2310 return AVERROR_INVALIDDATA;
2311 mov_field_order = avio_rb16(pb);
2312 if ((mov_field_order & 0xFF00) == 0x0100)
2313 decoded_field_order = AV_FIELD_PROGRESSIVE;
2314 else if ((mov_field_order & 0xFF00) == 0x0200) {
2315 switch (mov_field_order & 0xFF) {
2316 case 0x01: decoded_field_order = AV_FIELD_TT;
2317 break;
2318 case 0x06: decoded_field_order = AV_FIELD_BB;
2319 break;
2320 case 0x09: decoded_field_order = AV_FIELD_TB;
2321 break;
2322 case 0x0E: decoded_field_order = AV_FIELD_BT;
2323 break;
2324 }
2325 }
2326 if (decoded_field_order == AV_FIELD_UNKNOWN && mov_field_order) {
2327 av_log(c->fc, AV_LOG_ERROR, "Unknown MOV field order 0x%04x\n", mov_field_order);
2328 }
2329 st->codecpar->field_order = decoded_field_order;
2330
2331 return 0;
2332}
2333
2335{
2336 int err = 0;
2337 uint64_t size = (uint64_t)par->extradata_size + atom.size + 8 + AV_INPUT_BUFFER_PADDING_SIZE;
2338 if (size > INT_MAX || (uint64_t)atom.size > INT_MAX)
2339 return AVERROR_INVALIDDATA;
2340 if ((err = av_reallocp(&par->extradata, size)) < 0) {
2341 par->extradata_size = 0;
2342 return err;
2343 }
2345 return 0;
2346}
2347
2348/* Read a whole atom into the extradata return the size of the atom read, possibly truncated if != atom.size */
2350 AVCodecParameters *par, uint8_t *buf)
2351{
2352 int64_t result = atom.size;
2353 int err;
2354
2355 AV_WB32(buf , atom.size + 8);
2356 AV_WL32(buf + 4, atom.type);
2357 err = ffio_read_size(pb, buf + 8, atom.size);
2358 if (err < 0) {
2359 par->extradata_size -= atom.size;
2360 return err;
2361 } else if (err < atom.size) {
2362 av_log(c->fc, AV_LOG_WARNING, "truncated extradata\n");
2363 par->extradata_size -= atom.size - err;
2364 result = err;
2365 }
2366 memset(buf + 8 + err, 0, AV_INPUT_BUFFER_PADDING_SIZE);
2367 return result;
2368}
2369
2370/* FIXME modify QDM2/SVQ3/H.264 decoders to take full atom as extradata */
2372 enum AVCodecID codec_id)
2373{
2374 AVStream *st;
2375 uint64_t original_size;
2376 int err;
2377
2378 if (c->fc->nb_streams < 1) // will happen with jp2 files
2379 return 0;
2380 st = c->fc->streams[c->fc->nb_streams-1];
2381
2382 if (st->codecpar->codec_id != codec_id)
2383 return 0; /* unexpected codec_id - don't mess with extradata */
2384
2385 original_size = st->codecpar->extradata_size;
2386 err = mov_realloc_extradata(st->codecpar, atom);
2387 if (err)
2388 return err;
2389
2390 err = mov_read_atom_into_extradata(c, pb, atom, st->codecpar, st->codecpar->extradata + original_size);
2391 if (err < 0)
2392 return err;
2393 return 0; // Note: this is the original behavior to ignore truncation.
2394}
2395
2396/* wrapper functions for reading ALAC/AVS/MJPEG/MJPEG2000 extradata atoms only for those codecs */
2398{
2399 return mov_read_extradata(c, pb, atom, AV_CODEC_ID_ALAC);
2400}
2401
2403{
2404 return mov_read_extradata(c, pb, atom, AV_CODEC_ID_CAVS);
2405}
2406
2408{
2409 return mov_read_extradata(c, pb, atom, AV_CODEC_ID_JPEG2000);
2410}
2411
2413{
2414 return mov_read_extradata(c, pb, atom, AV_CODEC_ID_R10K);
2415}
2416
2418{
2419 int ret = mov_read_extradata(c, pb, atom, AV_CODEC_ID_AVUI);
2420 if (!ret)
2421 ret = mov_read_extradata(c, pb, atom, AV_CODEC_ID_DNXHD);
2422 return ret;
2423}
2424
2426{
2427 int ret = mov_read_extradata(c, pb, atom, AV_CODEC_ID_TARGA_Y216);
2428
2429 if (!ret && c->fc->nb_streams >= 1) {
2430 AVCodecParameters *par = c->fc->streams[c->fc->nb_streams-1]->codecpar;
2431 if (par->extradata_size >= 40) {
2432 par->height = AV_RB16(&par->extradata[36]);
2433 par->width = AV_RB16(&par->extradata[38]);
2434 }
2435 }
2436 return ret;
2437}
2438
2440{
2441 if (c->fc->nb_streams >= 1) {
2442 AVStream *const st = c->fc->streams[c->fc->nb_streams - 1];
2443 FFStream *const sti = ffstream(st);
2444 AVCodecParameters *par = st->codecpar;
2445
2446 if (par->codec_tag == MKTAG('A', 'V', 'i', 'n') &&
2447 par->codec_id == AV_CODEC_ID_H264 &&
2448 atom.size > 11) {
2449 int cid;
2450 avio_skip(pb, 10);
2451 cid = avio_rb16(pb);
2452 /* For AVID AVCI50, force width of 1440 to be able to select the correct SPS and PPS */
2453 if (cid == 0xd4d || cid == 0xd4e)
2454 par->width = 1440;
2455 return 0;
2456 } else if ((par->codec_tag == MKTAG('A', 'V', 'd', '1') ||
2457 par->codec_tag == MKTAG('A', 'V', 'j', '2') ||
2458 par->codec_tag == MKTAG('A', 'V', 'd', 'n')) &&
2459 atom.size >= 24) {
2460 int num, den;
2461 avio_skip(pb, 12);
2462 num = avio_rb32(pb);
2463 den = avio_rb32(pb);
2464 if (num <= 0 || den <= 0)
2465 return 0;
2466 switch (avio_rb32(pb)) {
2467 case 2:
2468 if (den >= INT_MAX / 2)
2469 return 0;
2470 den *= 2;
2472 case 1:
2473 sti->display_aspect_ratio = (AVRational){ num, den };
2475 default:
2476 return 0;
2477 }
2478 }
2479 }
2480
2481 return mov_read_avid(c, pb, atom);
2482}
2483
2485{
2486 int ret = 0;
2487 int length = 0;
2488 uint64_t original_size;
2489 if (c->fc->nb_streams >= 1) {
2490 AVCodecParameters *par = c->fc->streams[c->fc->nb_streams-1]->codecpar;
2491 if (par->codec_id == AV_CODEC_ID_H264)
2492 return 0;
2493 if (atom.size == 16) {
2494 original_size = par->extradata_size;
2495 ret = mov_realloc_extradata(par, atom);
2496 if (!ret) {
2497 length = mov_read_atom_into_extradata(c, pb, atom, par, par->extradata + original_size);
2498 if (length == atom.size) {
2499 const uint8_t range_value = par->extradata[original_size + 19];
2500 switch (range_value) {
2501 case 1:
2503 break;
2504 case 2:
2506 break;
2507 default:
2508 av_log(c->fc, AV_LOG_WARNING, "ignored unknown aclr value (%d)\n", range_value);
2509 break;
2510 }
2511 ff_dlog(c->fc, "color_range: %d\n", par->color_range);
2512 } else {
2513 /* For some reason the whole atom was not added to the extradata */
2514 av_log(c->fc, AV_LOG_ERROR, "aclr not decoded - incomplete atom\n");
2515 }
2516 } else {
2517 av_log(c->fc, AV_LOG_ERROR, "aclr not decoded - unable to add atom to extradata\n");
2518 }
2519 } else {
2520 av_log(c->fc, AV_LOG_WARNING, "aclr not decoded - unexpected size %"PRId64"\n", atom.size);
2521 }
2522 }
2523
2524 return ret;
2525}
2526
2528{
2529 return mov_read_extradata(c, pb, atom, AV_CODEC_ID_SVQ3);
2530}
2531
2533{
2534 AVStream *st;
2535 int ret;
2536
2537 if (c->fc->nb_streams < 1)
2538 return 0;
2539 st = c->fc->streams[c->fc->nb_streams-1];
2540
2541 if ((uint64_t)atom.size > (1<<30))
2542 return AVERROR_INVALIDDATA;
2543
2544 if (st->codecpar->codec_id == AV_CODEC_ID_QDM2 ||
2547 // pass all frma atom to codec, needed at least for QDMC and QDM2
2548 ret = ff_get_extradata(c->fc, st->codecpar, pb, atom.size);
2549 if (ret < 0)
2550 return ret;
2551 } else if (atom.size > 8) { /* to read frma, esds atoms */
2552 if (st->codecpar->codec_id == AV_CODEC_ID_ALAC && atom.size >= 24) {
2553 uint64_t buffer;
2554 ret = ffio_ensure_seekback(pb, 8);
2555 if (ret < 0)
2556 return ret;
2557 buffer = avio_rb64(pb);
2558 atom.size -= 8;
2559 if ( (buffer & 0xFFFFFFFF) == MKBETAG('f','r','m','a')
2560 && buffer >> 32 <= atom.size
2561 && buffer >> 32 >= 8) {
2562 avio_skip(pb, -8);
2563 atom.size += 8;
2564 } else if (!st->codecpar->extradata_size) {
2565#define ALAC_EXTRADATA_SIZE 36
2567 if (!st->codecpar->extradata)
2568 return AVERROR(ENOMEM);
2571 AV_WB32(st->codecpar->extradata + 4, MKTAG('a','l','a','c'));
2572 AV_WB64(st->codecpar->extradata + 12, buffer);
2573 avio_read(pb, st->codecpar->extradata + 20, 16);
2574 avio_skip(pb, atom.size - 24);
2575 return 0;
2576 }
2577 }
2578 if ((ret = mov_read_default(c, pb, atom)) < 0)
2579 return ret;
2580 } else
2581 avio_skip(pb, atom.size);
2582 return 0;
2583}
2584
2585/**
2586 * This function reads atom content and puts data in extradata without tag
2587 * nor size unlike mov_read_extradata.
2588 */
2590{
2591 AVStream *st;
2592 int ret;
2593
2594 st = get_curr_st(c);
2595 if (!st)
2596 return 0;
2597
2598 if ((uint64_t)atom.size > (1<<30))
2599 return AVERROR_INVALIDDATA;
2600
2601 if (atom.type == MKTAG('v','v','c','C')) {
2602 avio_skip(pb, 4);
2603 atom.size -= 4;
2604 }
2605
2606 if (atom.size >= 10) {
2607 // Broken files created by legacy versions of libavformat will
2608 // wrap a whole fiel atom inside of a glbl atom.
2609 unsigned size = avio_rb32(pb);
2610 unsigned type = avio_rl32(pb);
2611 if (avio_feof(pb))
2612 return AVERROR_INVALIDDATA;
2613 avio_seek(pb, -8, SEEK_CUR);
2614 if (type == MKTAG('f','i','e','l') && size == atom.size)
2615 return mov_read_default(c, pb, atom);
2616 }
2617 if (st->codecpar->extradata_size > 1 && st->codecpar->extradata) {
2618 av_log(c->fc, AV_LOG_WARNING, "ignoring multiple glbl\n");
2619 return 0;
2620 }
2621 ret = ff_get_extradata(c->fc, st->codecpar, pb, atom.size);
2622 if (ret < 0)
2623 return ret;
2624 if (atom.type == MKTAG('h','v','c','C') && st->codecpar->codec_tag == MKTAG('d','v','h','1'))
2625 /* HEVC-based Dolby Vision derived from hvc1.
2626 Happens to match with an identifier
2627 previously utilized for DV. Thus, if we have
2628 the hvcC extradata box available as specified,
2629 set codec to HEVC */
2631
2632 return 0;
2633}
2634
2636{
2637 AVStream *st;
2638 uint8_t profile_level;
2639 int ret;
2640
2641 if (c->fc->nb_streams < 1)
2642 return 0;
2643 st = c->fc->streams[c->fc->nb_streams-1];
2644
2645 if (atom.size >= (1<<28) || atom.size < 7)
2646 return AVERROR_INVALIDDATA;
2647
2648 profile_level = avio_r8(pb);
2649 if ((profile_level & 0xf0) != 0xc0)
2650 return 0;
2651
2652 avio_seek(pb, 6, SEEK_CUR);
2653 ret = ff_get_extradata(c->fc, st->codecpar, pb, atom.size - 7);
2654 if (ret < 0)
2655 return ret;
2656
2657 return 0;
2658}
2659
2660static int mov_find_tref_id(const MovTref *tag, uint32_t id)
2661{
2662 for (int i = 0; i < tag->nb_id; i++) {
2663 if (tag->id[i] == id)
2664 return 1;
2665 }
2666 return 0;
2667}
2668
2669static int mov_add_tref_id(MovTref *tag, uint32_t id)
2670{
2671 int ret = mov_find_tref_id(tag, id);
2672
2673 if (!ret) {
2674 uint32_t *tmp = av_realloc_array(tag->id, tag->nb_id + 1, sizeof(*tag->id));
2675 if (!tmp)
2676 return AVERROR(ENOMEM);
2677 tag->id = tmp;
2678 tag->id[tag->nb_id++] = id;
2679 }
2680
2681 return 0;
2682}
2683
2685{
2686 for (int i = 0; i < sc->nb_tref_tags; i++) {
2687 MovTref *entry = &sc->tref_tags[i];
2688
2689 if (entry->name == name)
2690 return entry;
2691 }
2692 return NULL;
2693}
2694
2696{
2698
2699 if (!tag) {
2701 sizeof(*sc->tref_tags));
2702 if (!tmp)
2703 return NULL;
2704 sc->tref_tags = tmp;
2705 tag = &sc->tref_tags[sc->nb_tref_tags++];
2706 *tag = (MovTref){ .name = name };
2707 }
2708
2709 return tag;
2710}
2711
2713{
2714 AVStream* st;
2715 MOVStreamContext* sc;
2716
2717 if (c->fc->nb_streams < 1)
2718 return 0;
2719
2720 if (atom.size > 4) {
2721 av_log(c->fc, AV_LOG_ERROR, "Only a single tref of type cdsc/rndr is supported\n");
2722 return AVERROR_PATCHWELCOME;
2723 }
2724 if (atom.size < 4)
2725 return AVERROR_INVALIDDATA;
2726
2727 st = get_curr_st(c);
2728 if (!st)
2729 return AVERROR_INVALIDDATA;
2730 sc = st->priv_data;
2731
2732 MovTref *tag = mov_add_tref_tag(sc, atom.type);
2733 if (!tag)
2734 return AVERROR(ENOMEM);
2735
2736 int ret = mov_add_tref_id(tag, avio_rb32(pb));
2737 if (ret < 0)
2738 return ret;
2739
2740 return 0;
2741}
2742
2744{
2745 AVStream* st;
2746 MOVStreamContext* sc;
2747
2748 if (c->fc->nb_streams < 1)
2749 return 0;
2750
2751 /* For SBAS this should be fine - though beware if someone implements a
2752 * tref atom processor that doesn't drop down to default then this may
2753 * be lost. */
2754 if (atom.size > 4) {
2755 av_log(c->fc, AV_LOG_ERROR, "Only a single tref of type sbas is supported\n");
2756 return AVERROR_PATCHWELCOME;
2757 }
2758 if (atom.size < 4)
2759 return AVERROR_INVALIDDATA;
2760
2761 st = c->fc->streams[c->fc->nb_streams - 1];
2762 sc = st->priv_data;
2763
2764 MovTref *tag = mov_add_tref_tag(sc, atom.type);
2765 if (!tag)
2766 return AVERROR(ENOMEM);
2767
2768 int ret = mov_add_tref_id(tag, avio_rb32(pb));
2769 if (ret < 0)
2770 return ret;
2771
2772 return 0;
2773}
2774
2776{
2777 AVStream* st;
2778 MOVStreamContext* sc;
2779
2780 if (c->fc->nb_streams < 1)
2781 return 0;
2782
2783 if (atom.size > 4)
2784 av_log(c->fc, AV_LOG_WARNING, "More than one vdep reference is not supported.\n");
2785 if (atom.size < 4)
2786 return AVERROR_INVALIDDATA;
2787
2788 st = c->fc->streams[c->fc->nb_streams - 1];
2789 sc = st->priv_data;
2790
2791 MovTref *tag = mov_add_tref_tag(sc, atom.type);
2792 if (!tag)
2793 return AVERROR(ENOMEM);
2794
2795 int ret = mov_add_tref_id(tag, avio_rb32(pb));
2796 if (ret < 0)
2797 return ret;
2798
2799 return 0;
2800}
2801
2802/**
2803 * An strf atom is a BITMAPINFOHEADER struct. This struct is 40 bytes itself,
2804 * but can have extradata appended at the end after the 40 bytes belonging
2805 * to the struct.
2806 */
2808{
2809 AVStream *st;
2810 int ret;
2811
2812 if (c->fc->nb_streams < 1)
2813 return 0;
2814 if (atom.size <= 40)
2815 return 0;
2816 st = c->fc->streams[c->fc->nb_streams-1];
2817
2818 if ((uint64_t)atom.size > (1<<30))
2819 return AVERROR_INVALIDDATA;
2820
2821 avio_skip(pb, 40);
2822 ret = ff_get_extradata(c->fc, st->codecpar, pb, atom.size - 40);
2823 if (ret < 0)
2824 return ret;
2825
2826 return 0;
2827}
2828
2830{
2831 AVStream *st;
2832 MOVStreamContext *sc;
2833 unsigned int i, entries;
2834
2835 if (c->trak_index < 0) {
2836 av_log(c->fc, AV_LOG_WARNING, "STCO outside TRAK\n");
2837 return 0;
2838 }
2839 if (c->fc->nb_streams < 1)
2840 return 0;
2841 st = c->fc->streams[c->fc->nb_streams-1];
2842 sc = st->priv_data;
2843
2844 avio_r8(pb); /* version */
2845 avio_rb24(pb); /* flags */
2846
2847 // Clamp allocation size for `chunk_offsets` -- don't throw an error for an
2848 // invalid count since the EOF path doesn't throw either.
2849 entries = avio_rb32(pb);
2850 entries =
2851 FFMIN(entries,
2852 FFMAX(0, (atom.size - 8) /
2853 (atom.type == MKTAG('s', 't', 'c', 'o') ? 4 : 8)));
2854
2855 if (!entries)
2856 return 0;
2857
2858 if (sc->chunk_offsets) {
2859 av_log(c->fc, AV_LOG_WARNING, "Ignoring duplicated STCO atom\n");
2860 return 0;
2861 }
2862
2864 sc->chunk_count = 0;
2865 sc->chunk_offsets = av_malloc_array(entries, sizeof(*sc->chunk_offsets));
2866 if (!sc->chunk_offsets)
2867 return AVERROR(ENOMEM);
2868 sc->chunk_count = entries;
2869
2870 if (atom.type == MKTAG('s','t','c','o'))
2871 for (i = 0; i < entries && !pb->eof_reached; i++)
2872 sc->chunk_offsets[i] = avio_rb32(pb);
2873 else if (atom.type == MKTAG('c','o','6','4'))
2874 for (i = 0; i < entries && !pb->eof_reached; i++) {
2875 sc->chunk_offsets[i] = avio_rb64(pb);
2876 if (sc->chunk_offsets[i] < 0) {
2877 av_log(c->fc, AV_LOG_WARNING, "Impossible chunk_offset\n");
2878 sc->chunk_offsets[i] = 0;
2879 }
2880 }
2881 else
2882 return AVERROR_INVALIDDATA;
2883
2884 sc->chunk_count = i;
2885
2886 if (pb->eof_reached) {
2887 av_log(c->fc, AV_LOG_WARNING, "reached eof, corrupted STCO atom\n");
2888 return AVERROR_EOF;
2889 }
2890
2891 return 0;
2892}
2893
2894static int mov_codec_id(AVStream *st, uint32_t format)
2895{
2897
2898 if (id <= 0 &&
2899 ((format & 0xFFFF) == 'm' + ('s' << 8) ||
2900 (format & 0xFFFF) == 'T' + ('S' << 8)))
2902
2903 if (st->codecpar->codec_type != AVMEDIA_TYPE_VIDEO && id > 0) {
2905 } else if (st->codecpar->codec_type != AVMEDIA_TYPE_AUDIO &&
2906 /* skip old ASF MPEG-4 tag */
2907 format && format != MKTAG('m','p','4','s')) {
2909 if (id <= 0)
2911 if (id > 0)
2913 else if (st->codecpar->codec_type == AVMEDIA_TYPE_DATA ||
2917 if (id <= 0) {
2920 }
2921
2922 if (id > 0)
2924 else
2926 }
2927 }
2928
2929 st->codecpar->codec_tag = format;
2930
2931 return id;
2932}
2933
2935 AVStream *st, MOVStreamContext *sc)
2936{
2937 uint8_t codec_name[32] = { 0 };
2938 int64_t stsd_start;
2939 unsigned int len;
2940 uint32_t id = 0;
2941
2942 /* The first 16 bytes of the video sample description are already
2943 * read in ff_mov_read_stsd_entries() */
2944 stsd_start = avio_tell(pb) - 16;
2945
2946 if (c->isom) {
2947 avio_skip(pb, 2); /* pre_defined */
2948 avio_skip(pb, 2); /* reserved */
2949 avio_skip(pb, 12); /* pre_defined */
2950 } else {
2951 avio_rb16(pb); /* version */
2952 avio_rb16(pb); /* revision level */
2953 id = avio_rl32(pb); /* vendor */
2954 av_dict_set(&st->metadata, "vendor_id", av_fourcc2str(id), 0);
2955 avio_rb32(pb); /* temporal quality */
2956 avio_rb32(pb); /* spatial quality */
2957 }
2958
2959 st->codecpar->width = avio_rb16(pb); /* width */
2960 st->codecpar->height = avio_rb16(pb); /* height */
2961
2962 avio_rb32(pb); /* horiz resolution */
2963 avio_rb32(pb); /* vert resolution */
2964 avio_rb32(pb); /* data size, always 0 */
2965 avio_rb16(pb); /* frames per samples */
2966
2967 len = avio_r8(pb); /* codec name, pascal string */
2968 if (len > 31)
2969 len = 31;
2970 mov_read_mac_string(c, pb, len, codec_name, sizeof(codec_name));
2971 if (len < 31)
2972 avio_skip(pb, 31 - len);
2973
2974 if (codec_name[0])
2975 av_dict_set(&st->metadata, "encoder", codec_name, 0);
2976
2977 /* codec_tag YV12 triggers an UV swap in rawdec.c */
2978 if (!strncmp(codec_name, "Planar Y'CbCr 8-bit 4:2:0", 25)) {
2979 st->codecpar->codec_tag = MKTAG('I', '4', '2', '0');
2980 st->codecpar->width &= ~1;
2981 st->codecpar->height &= ~1;
2982 }
2983 /* Flash Media Server uses tag H.263 with Sorenson Spark */
2984 if (st->codecpar->codec_tag == MKTAG('H','2','6','3') &&
2985 !strncmp(codec_name, "Sorenson H263", 13))
2987
2988 st->codecpar->bits_per_coded_sample = avio_rb16(pb); /* depth */
2989
2990 avio_seek(pb, stsd_start, SEEK_SET);
2991
2992 if (ff_get_qtpalette(st->codecpar->codec_id, pb, sc->palette)) {
2993 st->codecpar->bits_per_coded_sample &= 0x1F;
2994 sc->has_palette = 1;
2995 }
2996}
2997
2999 AVStream *st, MOVStreamContext *sc)
3000{
3001 int bits_per_sample, flags;
3002 uint16_t version = avio_rb16(pb);
3003 uint32_t id = 0;
3004 AVDictionaryEntry *compatible_brands = av_dict_get(c->fc->metadata, "compatible_brands", NULL, AV_DICT_MATCH_CASE);
3005 int channel_count;
3006
3007 if (c->isom)
3008 avio_skip(pb, 6); /* reserved */
3009 else {
3010 avio_rb16(pb); /* revision level */
3011 id = avio_rl32(pb); /* vendor */
3012 av_dict_set(&st->metadata, "vendor_id", av_fourcc2str(id), 0);
3013 }
3014
3015 channel_count = avio_rb16(pb);
3016
3018 st->codecpar->ch_layout.nb_channels = channel_count;
3019 st->codecpar->bits_per_coded_sample = avio_rb16(pb); /* sample size */
3020 av_log(c->fc, AV_LOG_TRACE, "audio channels %d\n", channel_count);
3021
3022 sc->audio_cid = avio_rb16(pb);
3023 avio_rb16(pb); /* packet size = 0 */
3024
3025 st->codecpar->sample_rate = ((avio_rb32(pb) >> 16));
3026
3027 // Read QT version 1 fields. In version 0 these do not exist.
3028 av_log(c->fc, AV_LOG_TRACE, "version =%d, isom =%d\n", version, c->isom);
3029 if (!c->isom ||
3030 (compatible_brands && strstr(compatible_brands->value, "qt ")) ||
3031 (sc->stsd_version == 0 && version > 0)) {
3032 if (version == 1) {
3033 sc->samples_per_frame = avio_rb32(pb);
3034 avio_rb32(pb); /* bytes per packet */
3035 sc->bytes_per_frame = avio_rb32(pb);
3036 avio_rb32(pb); /* bytes per sample */
3037 } else if (version == 2) {
3038 avio_rb32(pb); /* sizeof struct only */
3040 channel_count = avio_rb32(pb);
3042 st->codecpar->ch_layout.nb_channels = channel_count;
3043 avio_rb32(pb); /* always 0x7F000000 */
3045
3046 flags = avio_rb32(pb); /* lpcm format specific flag */
3047 sc->bytes_per_frame = avio_rb32(pb);
3048 sc->samples_per_frame = avio_rb32(pb);
3049 if (st->codecpar->codec_tag == MKTAG('l','p','c','m'))
3050 st->codecpar->codec_id =
3052 flags);
3053 }
3054 if (version == 0 || (version == 1 && sc->audio_cid != -2)) {
3055 /* can't correctly handle variable sized packet as audio unit */
3056 switch (st->codecpar->codec_id) {
3057 case AV_CODEC_ID_MP2:
3058 case AV_CODEC_ID_MP3:
3060 break;
3061 }
3062 }
3063 }
3064
3065 if (sc->format == 0) {
3066 if (st->codecpar->bits_per_coded_sample == 8)
3067 st->codecpar->codec_id = mov_codec_id(st, MKTAG('r','a','w',' '));
3068 else if (st->codecpar->bits_per_coded_sample == 16)
3069 st->codecpar->codec_id = mov_codec_id(st, MKTAG('t','w','o','s'));
3070 }
3071
3072 switch (st->codecpar->codec_id) {
3073 case AV_CODEC_ID_PCM_S8:
3074 case AV_CODEC_ID_PCM_U8:
3075 if (st->codecpar->bits_per_coded_sample == 16)
3077 break;
3080 if (st->codecpar->bits_per_coded_sample == 8)
3082 else if (st->codecpar->bits_per_coded_sample == 24)
3083 st->codecpar->codec_id =
3086 else if (st->codecpar->bits_per_coded_sample == 32)
3087 st->codecpar->codec_id =
3090 break;
3091 /* set values for old format before stsd version 1 appeared */
3092 case AV_CODEC_ID_MACE3:
3093 sc->samples_per_frame = 6;
3095 break;
3096 case AV_CODEC_ID_MACE6:
3097 sc->samples_per_frame = 6;
3099 break;
3101 sc->samples_per_frame = 64;
3103 break;
3104 case AV_CODEC_ID_GSM:
3105 sc->samples_per_frame = 160;
3106 sc->bytes_per_frame = 33;
3107 break;
3108 default:
3109 break;
3110 }
3111
3112 bits_per_sample = av_get_bits_per_sample(st->codecpar->codec_id);
3113 if (bits_per_sample && (bits_per_sample >> 3) * (uint64_t)st->codecpar->ch_layout.nb_channels <= INT_MAX) {
3114 st->codecpar->bits_per_coded_sample = bits_per_sample;
3115 sc->sample_size = (bits_per_sample >> 3) * st->codecpar->ch_layout.nb_channels;
3116 }
3117}
3118
3120 AVStream *st, MOVStreamContext *sc,
3121 int64_t size)
3122{
3123 // ttxt stsd contains display flags, justification, background
3124 // color, fonts, and default styles, so fake an atom to read it
3125 MOVAtom fake_atom = { .size = size };
3126 // mp4s contains a regular esds atom, dfxp ISMV TTML has no content
3127 // in extradata unlike stpp MP4 TTML.
3128 if (st->codecpar->codec_tag != AV_RL32("mp4s") &&
3130 mov_read_glbl(c, pb, fake_atom);
3131 st->codecpar->width = sc->width;
3132 st->codecpar->height = sc->height;
3133}
3134
3136 AVStream *st, MOVStreamContext *sc,
3137 int64_t size)
3138{
3139 int ret;
3140
3141 if (st->codecpar->codec_tag == MKTAG('t','m','c','d')) {
3142 if ((int)size != size)
3143 return AVERROR(ENOMEM);
3144
3145 ret = ff_get_extradata(c->fc, st->codecpar, pb, size);
3146 if (ret < 0)
3147 return ret;
3148 if (size > 16) {
3149 MOVStreamContext *tmcd_ctx = st->priv_data;
3150 int val;
3151 val = AV_RB32(st->codecpar->extradata + 4);
3152 tmcd_ctx->tmcd_flags = val;
3153 st->avg_frame_rate.num = AV_RB32(st->codecpar->extradata + 8); /* timescale */
3154 st->avg_frame_rate.den = AV_RB32(st->codecpar->extradata + 12); /* frameDuration */
3155 tmcd_ctx->tmcd_nb_frames = st->codecpar->extradata[16]; /* number of frames */
3156 if (size > 30) {
3157 uint32_t len = AV_RB32(st->codecpar->extradata + 18); /* name atom length */
3158 uint32_t format = AV_RB32(st->codecpar->extradata + 22);
3159 if (format == AV_RB32("name") && (int64_t)size >= (int64_t)len + 18) {
3160 uint16_t str_size = AV_RB16(st->codecpar->extradata + 26); /* string length */
3161 if (str_size > 0 && size >= (int)str_size + 30 &&
3162 st->codecpar->extradata[30] /* Don't add empty string */) {
3163 char *reel_name = av_malloc(str_size + 1);
3164 if (!reel_name)
3165 return AVERROR(ENOMEM);
3166 memcpy(reel_name, st->codecpar->extradata + 30, str_size);
3167 reel_name[str_size] = 0; /* Add null terminator */
3168 av_dict_set(&st->metadata, "reel_name", reel_name,
3170 }
3171 }
3172 }
3173 }
3174 } else if (st->codecpar->codec_id == AV_CODEC_ID_ITUT_T35) {
3175 int t35_identifier_length = avio_r8(pb);
3176
3177 if (t35_identifier_length <= 0 || t35_identifier_length >= size)
3178 return AVERROR_INVALIDDATA;
3179
3180 ret = ff_get_extradata(c->fc, st->codecpar, pb, t35_identifier_length);
3181 if (ret < 0)
3182 return ret;
3183
3184 int hrsd_len = size - t35_identifier_length - 1;
3185 if (hrsd_len > 0) {
3186 uint8_t *hrsd_str = av_malloc(hrsd_len + 1);
3187 if (!hrsd_str)
3188 return AVERROR(ENOMEM);
3189
3190 ret = ffio_read_size(pb, hrsd_str, hrsd_len);
3191 if (ret < 0) {
3192 av_free(hrsd_str);
3193 return ret;
3194 }
3195 if (hrsd_str[0]) {
3196 hrsd_str[hrsd_len] = 0;
3197 ret = av_dict_set(&st->metadata, "description", hrsd_str, AV_DICT_DONT_OVERWRITE);
3198 }
3199 av_free(hrsd_str);
3200 }
3201 } else {
3202 /* other codec type, just skip (rtp, mp4s ...) */
3203 avio_skip(pb, size);
3204 }
3205 return 0;
3206}
3207
3209 AVStream *st, MOVStreamContext *sc)
3210{
3211 FFStream *const sti = ffstream(st);
3212
3214 !st->codecpar->sample_rate && sc->time_scale > 1)
3215 st->codecpar->sample_rate = sc->time_scale;
3216
3217 /* special codec parameters handling */
3218 switch (st->codecpar->codec_id) {
3219#if CONFIG_DV_DEMUXER
3221 if (c->dv_fctx) {
3222 avpriv_request_sample(c->fc, "multiple DV audio streams");
3223 return AVERROR(ENOSYS);
3224 }
3225
3226 c->dv_fctx = avformat_alloc_context();
3227 if (!c->dv_fctx) {
3228 av_log(c->fc, AV_LOG_ERROR, "dv demux context alloc error\n");
3229 return AVERROR(ENOMEM);
3230 }
3231 c->dv_demux = avpriv_dv_init_demux(c->dv_fctx);
3232 if (!c->dv_demux) {
3233 av_log(c->fc, AV_LOG_ERROR, "dv demux context init error\n");
3234 return AVERROR(ENOMEM);
3235 }
3236 sc->dv_audio_container = 1;
3238 break;
3239#endif
3240 /* no ifdef since parameters are always those */
3241 case AV_CODEC_ID_QCELP:
3244 // force sample rate for qcelp when not stored in mov
3245 if (st->codecpar->codec_tag != MKTAG('Q','c','l','p'))
3246 st->codecpar->sample_rate = 8000;
3247 // FIXME: Why is the following needed for some files?
3248 sc->samples_per_frame = 160;
3249 if (!sc->bytes_per_frame)
3250 sc->bytes_per_frame = 35;
3251 break;
3252 case AV_CODEC_ID_AMR_NB:
3255 /* force sample rate for amr, stsd in 3gp does not store sample rate */
3256 st->codecpar->sample_rate = 8000;
3257 break;
3258 case AV_CODEC_ID_AMR_WB:
3261 st->codecpar->sample_rate = 16000;
3262 break;
3263 case AV_CODEC_ID_MP2:
3264 case AV_CODEC_ID_MP3:
3265 /* force type after stsd for m1a hdlr */
3267 break;
3268 case AV_CODEC_ID_GSM:
3271 case AV_CODEC_ID_ILBC:
3272 case AV_CODEC_ID_MACE3:
3273 case AV_CODEC_ID_MACE6:
3274 case AV_CODEC_ID_QDM2:
3276 break;
3277 case AV_CODEC_ID_ALAC:
3278 if (st->codecpar->extradata_size == 36) {
3279 int channel_count = AV_RB8(st->codecpar->extradata + 21);
3280 if (st->codecpar->ch_layout.nb_channels != channel_count) {
3283 st->codecpar->ch_layout.nb_channels = channel_count;
3284 }
3285 st->codecpar->sample_rate = AV_RB32(st->codecpar->extradata + 32);
3286 }
3287 break;
3288 case AV_CODEC_ID_AC3:
3289 case AV_CODEC_ID_EAC3:
3291 case AV_CODEC_ID_VC1:
3292 case AV_CODEC_ID_VP8:
3293 case AV_CODEC_ID_VP9:
3295 break;
3297 case AV_CODEC_ID_PRORES:
3298 case AV_CODEC_ID_APV:
3299 case AV_CODEC_ID_EVC:
3300 case AV_CODEC_ID_LCEVC:
3301 case AV_CODEC_ID_AV1:
3302 /* field_order detection of H264 requires parsing */
3303 case AV_CODEC_ID_H264:
3305 break;
3306 default:
3307 break;
3308 }
3309 return 0;
3310}
3311
3313 int codec_tag, int format,
3314 int64_t size)
3315{
3316 if (codec_tag &&
3317 (codec_tag != format &&
3318 // AVID 1:1 samples with differing data format and codec tag exist
3319 (codec_tag != AV_RL32("AV1x") || format != AV_RL32("AVup")) &&
3320 // prores is allowed to have differing data format and codec tag
3321 codec_tag != AV_RL32("apcn") && codec_tag != AV_RL32("apch") &&
3322 // so is dv (sigh)
3323 codec_tag != AV_RL32("dvpp") && codec_tag != AV_RL32("dvcp") &&
3324 (c->fc->video_codec_id ? ff_codec_get_id(ff_codec_movvideo_tags, format) != c->fc->video_codec_id
3325 : codec_tag != MKTAG('j','p','e','g')))) {
3326 /* Multiple fourcc, we skip JPEG. This is not correct, we should
3327 * export it as a separate AVStream but this needs a few changes
3328 * in the MOV demuxer, patch welcome. */
3329
3330 av_log(c->fc, AV_LOG_WARNING, "multiple fourcc not supported\n");
3331 avio_skip(pb, size);
3332 return 1;
3333 }
3334
3335 return 0;
3336}
3337
3339{
3340 int ret;
3341
3342 /* special codec parameters handling */
3343 switch (st->codecpar->codec_id) {
3344 case AV_CODEC_ID_H264:
3345 // done for ai5q, ai52, ai55, ai1q, ai12 and ai15.
3348 if (ret < 0)
3349 return ret;
3350 }
3351 break;
3352 default:
3353 break;
3354 }
3355
3356 return 0;
3357}
3358
3360{
3361 AVStream *st;
3362 MOVStreamContext *sc;
3363 int pseudo_stream_id;
3364
3365 av_assert0 (c->fc->nb_streams >= 1);
3366 st = c->fc->streams[c->fc->nb_streams-1];
3367 sc = st->priv_data;
3368
3369 for (pseudo_stream_id = 0;
3370 pseudo_stream_id < entries && !pb->eof_reached;
3371 pseudo_stream_id++) {
3372 //Parsing Sample description table
3373 enum AVCodecID id;
3374 int ret, dref_id = 1;
3375 MOVAtom a = { AV_RL32("stsd") };
3376 int64_t start_pos = avio_tell(pb);
3377 int64_t size = avio_rb32(pb); /* size */
3378 uint32_t format = avio_rl32(pb); /* data format */
3379
3380 if (size >= 16) {
3381 avio_rb32(pb); /* reserved */
3382 avio_rb16(pb); /* reserved */
3383 dref_id = avio_rb16(pb);
3384 } else if (size <= 7) {
3385 av_log(c->fc, AV_LOG_ERROR,
3386 "invalid size %"PRId64" in stsd\n", size);
3387 return AVERROR_INVALIDDATA;
3388 }
3389
3391 size - (avio_tell(pb) - start_pos))) {
3392 sc->stsd_count++;
3393 continue;
3394 }
3395
3396 sc->pseudo_stream_id = st->codecpar->codec_tag ? -1 : pseudo_stream_id;
3397 sc->dref_id= dref_id;
3398 sc->format = format;
3399
3400 id = mov_codec_id(st, format);
3401
3402 av_log(c->fc, AV_LOG_TRACE,
3403 "size=%"PRId64" 4CC=%s codec_type=%d\n", size,
3405
3406 st->codecpar->codec_id = id;
3408 mov_parse_stsd_video(c, pb, st, sc);
3409 } else if (st->codecpar->codec_type==AVMEDIA_TYPE_AUDIO) {
3410 mov_parse_stsd_audio(c, pb, st, sc);
3411 if (st->codecpar->sample_rate < 0) {
3412 av_log(c->fc, AV_LOG_ERROR, "Invalid sample rate %d\n", st->codecpar->sample_rate);
3413 return AVERROR_INVALIDDATA;
3414 }
3415 if (st->codecpar->ch_layout.nb_channels < 0) {
3416 av_log(c->fc, AV_LOG_ERROR, "Invalid channels %d\n", st->codecpar->ch_layout.nb_channels);
3417 return AVERROR_INVALIDDATA;
3418 }
3419 } else if (st->codecpar->codec_type==AVMEDIA_TYPE_SUBTITLE){
3420 mov_parse_stsd_subtitle(c, pb, st, sc,
3421 size - (avio_tell(pb) - start_pos));
3422 } else {
3423 ret = mov_parse_stsd_data(c, pb, st, sc,
3424 size - (avio_tell(pb) - start_pos));
3425 if (ret < 0)
3426 return ret;
3427 }
3428 /* this will read extra atoms at the end (wave, alac, damr, avcC, hvcC, SMI ...) */
3429 a.size = size - (avio_tell(pb) - start_pos);
3430 if (a.size > 8) {
3431 if ((ret = mov_read_default(c, pb, a)) < 0)
3432 return ret;
3433 } else if (a.size > 0)
3434 avio_skip(pb, a.size);
3435
3436 ret = mov_finalize_stsd_entry(c, st);
3437 if (ret < 0)
3438 return ret;
3439
3440 if (sc->extradata && st->codecpar->extradata) {
3441 int extra_size = st->codecpar->extradata_size;
3442
3443 /* Move the current stream extradata to the stream context one. */
3444 sc->extradata_size[pseudo_stream_id] = extra_size;
3445 sc->extradata[pseudo_stream_id] = st->codecpar->extradata;
3446 st->codecpar->extradata = NULL;
3447 st->codecpar->extradata_size = 0;
3448 }
3449 sc->stsd_count++;
3450 }
3451
3452 if (pb->eof_reached) {
3453 av_log(c->fc, AV_LOG_WARNING, "reached eof, corrupted STSD atom\n");
3454 return AVERROR_EOF;
3455 }
3456
3457 return 0;
3458}
3459
3461{
3462 AVStream *st;
3463 MOVStreamContext *sc;
3464 int ret, entries;
3465
3466 if (c->fc->nb_streams < 1)
3467 return 0;
3468 st = c->fc->streams[c->fc->nb_streams - 1];
3469 sc = st->priv_data;
3470
3471 if (sc->extradata) {
3472 av_log(c->fc, AV_LOG_ERROR,
3473 "Duplicate stsd found in this track.\n");
3474 return AVERROR_INVALIDDATA;
3475 }
3476
3477 sc->stsd_version = avio_r8(pb);
3478 avio_rb24(pb); /* flags */
3479 entries = avio_rb32(pb);
3480
3481 /* Each entry contains a size (4 bytes) and format (4 bytes). */
3482 if (entries <= 0 || entries > atom.size / 8 || entries > 1024) {
3483 av_log(c->fc, AV_LOG_ERROR, "invalid STSD entries %d\n", entries);
3484 return AVERROR_INVALIDDATA;
3485 }
3486
3487 /* Prepare space for hosting multiple extradata. */
3488 sc->extradata = av_calloc(entries, sizeof(*sc->extradata));
3489 if (!sc->extradata)
3490 return AVERROR(ENOMEM);
3491
3492 sc->extradata_size = av_calloc(entries, sizeof(*sc->extradata_size));
3493 if (!sc->extradata_size) {
3494 ret = AVERROR(ENOMEM);
3495 goto fail;
3496 }
3497
3498 ret = ff_mov_read_stsd_entries(c, pb, entries);
3499 if (ret < 0)
3500 goto fail;
3501
3502 /* Restore back the primary extradata. */
3505 if (sc->extradata_size[0]) {
3507 if (!st->codecpar->extradata)
3508 return AVERROR(ENOMEM);
3509 memcpy(st->codecpar->extradata, sc->extradata[0], sc->extradata_size[0]);
3510 }
3511
3512 return mov_finalize_stsd_codec(c, pb, st, sc);
3513fail:
3514 if (sc->extradata) {
3515 int j;
3516 for (j = 0; j < sc->stsd_count; j++)
3517 av_freep(&sc->extradata[j]);
3518 }
3519
3520 sc->stsd_count = 0;
3521 av_freep(&sc->extradata);
3523 return ret;
3524}
3525
3527{
3528 AVStream *st;
3529 MOVStreamContext *sc;
3530 unsigned int i, entries;
3531
3532 if (c->trak_index < 0) {
3533 av_log(c->fc, AV_LOG_WARNING, "STSC outside TRAK\n");
3534 return 0;
3535 }
3536
3537 if (c->fc->nb_streams < 1)
3538 return 0;
3539 st = c->fc->streams[c->fc->nb_streams-1];
3540 sc = st->priv_data;
3541
3542 avio_r8(pb); /* version */
3543 avio_rb24(pb); /* flags */
3544
3545 entries = avio_rb32(pb);
3546 if ((uint64_t)entries * 12 + 4 > atom.size)
3547 return AVERROR_INVALIDDATA;
3548
3549 av_log(c->fc, AV_LOG_TRACE, "track[%u].stsc.entries = %u\n", c->fc->nb_streams - 1, entries);
3550
3551 if (!entries)
3552 return 0;
3553 if (sc->stsc_data) {
3554 av_log(c->fc, AV_LOG_WARNING, "Ignoring duplicated STSC atom\n");
3555 return 0;
3556 }
3557 av_free(sc->stsc_data);
3558 sc->stsc_count = 0;
3559 sc->stsc_data = av_malloc_array(entries, sizeof(*sc->stsc_data));
3560 if (!sc->stsc_data)
3561 return AVERROR(ENOMEM);
3562
3563 for (i = 0; i < entries && !pb->eof_reached; i++) {
3564 sc->stsc_data[i].first = avio_rb32(pb);
3565 sc->stsc_data[i].count = avio_rb32(pb);
3566 sc->stsc_data[i].id = avio_rb32(pb);
3567 }
3568
3569 sc->stsc_count = i;
3570 for (i = sc->stsc_count - 1; i < UINT_MAX; i--) {
3571 int64_t first_min = i + 1;
3572 if ((i+1 < sc->stsc_count && sc->stsc_data[i].first >= sc->stsc_data[i+1].first) ||
3573 (i > 0 && sc->stsc_data[i].first <= sc->stsc_data[i-1].first) ||
3574 sc->stsc_data[i].first < first_min ||
3575 sc->stsc_data[i].count < 1 ||
3576 sc->stsc_data[i].id < 1) {
3577 av_log(c->fc, AV_LOG_WARNING, "STSC entry %d is invalid (first=%d count=%d id=%d)\n", i, sc->stsc_data[i].first, sc->stsc_data[i].count, sc->stsc_data[i].id);
3578 if (i+1 >= sc->stsc_count) {
3579 if (sc->stsc_data[i].count == 0 && i > 0) {
3580 sc->stsc_count --;
3581 continue;
3582 }
3583 sc->stsc_data[i].first = FFMAX(sc->stsc_data[i].first, first_min);
3584 if (i > 0 && sc->stsc_data[i].first <= sc->stsc_data[i-1].first)
3585 sc->stsc_data[i].first = FFMIN(sc->stsc_data[i-1].first + 1LL, INT_MAX);
3586 sc->stsc_data[i].count = FFMAX(sc->stsc_data[i].count, 1);
3587 sc->stsc_data[i].id = FFMAX(sc->stsc_data[i].id, 1);
3588 continue;
3589 }
3590 av_assert0(sc->stsc_data[i+1].first >= 2);
3591 // We replace this entry by the next valid
3592 sc->stsc_data[i].first = sc->stsc_data[i+1].first - 1;
3593 sc->stsc_data[i].count = sc->stsc_data[i+1].count;
3594 sc->stsc_data[i].id = sc->stsc_data[i+1].id;
3595 }
3596 }
3597
3598 if (pb->eof_reached) {
3599 av_log(c->fc, AV_LOG_WARNING, "reached eof, corrupted STSC atom\n");
3600 return AVERROR_EOF;
3601 }
3602
3603 return 0;
3604}
3605
3606static inline int mov_stsc_index_valid(unsigned int index, unsigned int count)
3607{
3608 return index < count - 1;
3609}
3610
3611/* Compute the samples value for the stsc entry at the given index. */
3612static inline int64_t mov_get_stsc_samples(MOVStreamContext *sc, unsigned int index)
3613{
3614 int chunk_count;
3615
3617 chunk_count = sc->stsc_data[index + 1].first - sc->stsc_data[index].first;
3618 else {
3619 // Validation for stsc / stco happens earlier in mov_read_stsc + mov_read_trak.
3621 chunk_count = sc->chunk_count - (sc->stsc_data[index].first - 1);
3622 }
3623
3624 return sc->stsc_data[index].count * (int64_t)chunk_count;
3625}
3626
3628{
3629 AVStream *st;
3630 MOVStreamContext *sc;
3631 unsigned i, entries;
3632
3633 if (c->trak_index < 0) {
3634 av_log(c->fc, AV_LOG_WARNING, "STPS outside TRAK\n");
3635 return 0;
3636 }
3637
3638 if (c->fc->nb_streams < 1)
3639 return 0;
3640 st = c->fc->streams[c->fc->nb_streams-1];
3641 sc = st->priv_data;
3642
3643 avio_rb32(pb); // version + flags
3644
3645 entries = avio_rb32(pb);
3646 if (sc->stps_data)
3647 av_log(c->fc, AV_LOG_WARNING, "Duplicated STPS atom\n");
3648 av_free(sc->stps_data);
3649 sc->stps_count = 0;
3650 sc->stps_data = av_malloc_array(entries, sizeof(*sc->stps_data));
3651 if (!sc->stps_data)
3652 return AVERROR(ENOMEM);
3653
3654 for (i = 0; i < entries && !pb->eof_reached; i++) {
3655 sc->stps_data[i] = avio_rb32(pb);
3656 }
3657
3658 sc->stps_count = i;
3659
3660 if (pb->eof_reached) {
3661 av_log(c->fc, AV_LOG_WARNING, "reached eof, corrupted STPS atom\n");
3662 return AVERROR_EOF;
3663 }
3664
3665 return 0;
3666}
3667
3669{
3670 AVStream *st;
3671 FFStream *sti;
3672 MOVStreamContext *sc;
3673 unsigned int i, entries;
3674
3675 if (c->trak_index < 0) {
3676 av_log(c->fc, AV_LOG_WARNING, "STSS outside TRAK\n");
3677 return 0;
3678 }
3679
3680 if (c->fc->nb_streams < 1)
3681 return 0;
3682 st = c->fc->streams[c->fc->nb_streams-1];
3683 sti = ffstream(st);
3684 sc = st->priv_data;
3685
3686 avio_r8(pb); /* version */
3687 avio_rb24(pb); /* flags */
3688
3689 entries = avio_rb32(pb);
3690
3691 av_log(c->fc, AV_LOG_TRACE, "keyframe_count = %u\n", entries);
3692
3693 if (!entries) {
3694 sc->keyframe_absent = 1;
3697 return 0;
3698 }
3699 if (sc->keyframes)
3700 av_log(c->fc, AV_LOG_WARNING, "Duplicated STSS atom\n");
3701 if (entries >= UINT_MAX / sizeof(int))
3702 return AVERROR_INVALIDDATA;
3703 av_freep(&sc->keyframes);
3704 sc->keyframe_count = 0;
3705 sc->keyframes = av_malloc_array(entries, sizeof(*sc->keyframes));
3706 if (!sc->keyframes)
3707 return AVERROR(ENOMEM);
3708
3709 for (i = 0; i < entries && !pb->eof_reached; i++) {
3710 sc->keyframes[i] = avio_rb32(pb);
3711 }
3712
3713 sc->keyframe_count = i;
3714
3715 if (pb->eof_reached) {
3716 av_log(c->fc, AV_LOG_WARNING, "reached eof, corrupted STSS atom\n");
3717 return AVERROR_EOF;
3718 }
3719
3720 return 0;
3721}
3722
3724{
3725 AVStream *st;
3726 MOVStreamContext *sc;
3727 unsigned int i, entries, sample_size, field_size, num_bytes;
3728 GetBitContext gb;
3729 unsigned char* buf;
3730 int ret;
3731
3732 if (c->trak_index < 0) {
3733 av_log(c->fc, AV_LOG_WARNING, "STSZ outside TRAK\n");
3734 return 0;
3735 }
3736
3737 if (c->fc->nb_streams < 1)
3738 return 0;
3739 st = c->fc->streams[c->fc->nb_streams-1];
3740 sc = st->priv_data;
3741
3742 avio_r8(pb); /* version */
3743 avio_rb24(pb); /* flags */
3744
3745 if (atom.type == MKTAG('s','t','s','z')) {
3746 sample_size = avio_rb32(pb);
3747 if (!sc->sample_size) /* do not overwrite value computed in stsd */
3748 sc->sample_size = sample_size;
3749 sc->stsz_sample_size = sample_size;
3750 field_size = 32;
3751 } else {
3752 sample_size = 0;
3753 avio_rb24(pb); /* reserved */
3754 field_size = avio_r8(pb);
3755 }
3756 entries = avio_rb32(pb);
3757
3758 av_log(c->fc, AV_LOG_TRACE, "sample_size = %u sample_count = %u\n", sc->sample_size, entries);
3759
3760 sc->sample_count = entries;
3761 if (sample_size)
3762 return 0;
3763
3764 if (field_size != 4 && field_size != 8 && field_size != 16 && field_size != 32) {
3765 av_log(c->fc, AV_LOG_ERROR, "Invalid sample field size %u\n", field_size);
3766 return AVERROR_INVALIDDATA;
3767 }
3768
3769 if (!entries)
3770 return 0;
3771 if (entries >= (INT_MAX - 4 - 8 * AV_INPUT_BUFFER_PADDING_SIZE) / field_size)
3772 return AVERROR_INVALIDDATA;
3773 if (sc->sample_sizes)
3774 av_log(c->fc, AV_LOG_WARNING, "Duplicated STSZ atom\n");
3775 av_free(sc->sample_sizes);
3776 sc->sample_count = 0;
3777 sc->sample_sizes = av_malloc_array(entries, sizeof(*sc->sample_sizes));
3778 if (!sc->sample_sizes)
3779 return AVERROR(ENOMEM);
3780
3781 num_bytes = (entries*field_size+4)>>3;
3782
3783 buf = av_malloc(num_bytes+AV_INPUT_BUFFER_PADDING_SIZE);
3784 if (!buf) {
3785 av_freep(&sc->sample_sizes);
3786 return AVERROR(ENOMEM);
3787 }
3788
3789 ret = ffio_read_size(pb, buf, num_bytes);
3790 if (ret < 0) {
3791 av_freep(&sc->sample_sizes);
3792 av_free(buf);
3793 av_log(c->fc, AV_LOG_WARNING, "STSZ atom truncated\n");
3794 return 0;
3795 }
3796
3797 init_get_bits(&gb, buf, 8*num_bytes);
3798
3799 for (i = 0; i < entries; i++) {
3800 sc->sample_sizes[i] = get_bits_long(&gb, field_size);
3801 if (sc->sample_sizes[i] > INT64_MAX - sc->data_size) {
3802 av_free(buf);
3803 av_log(c->fc, AV_LOG_ERROR, "Sample size overflow in STSZ\n");
3804 return AVERROR_INVALIDDATA;
3805 }
3806 sc->data_size += sc->sample_sizes[i];
3807 }
3808
3809 sc->sample_count = i;
3810
3811 av_free(buf);
3812
3813 return 0;
3814}
3815
3817{
3818 AVStream *st;
3819 MOVStreamContext *sc;
3820 unsigned int i, entries;
3821 int64_t duration = 0;
3822 int64_t total_sample_count = 0;
3823 int64_t current_dts = 0;
3824 int64_t corrected_dts = 0;
3825
3826 if (c->trak_index < 0) {
3827 av_log(c->fc, AV_LOG_WARNING, "STTS outside TRAK\n");
3828 return 0;
3829 }
3830
3831 if (c->fc->nb_streams < 1)
3832 return 0;
3833 st = c->fc->streams[c->fc->nb_streams-1];
3834 sc = st->priv_data;
3835
3836 avio_r8(pb); /* version */
3837 avio_rb24(pb); /* flags */
3838 entries = avio_rb32(pb);
3839
3840 av_log(c->fc, AV_LOG_TRACE, "track[%u].stts.entries = %u\n",
3841 c->fc->nb_streams-1, entries);
3842
3843 if (sc->stts_data)
3844 av_log(c->fc, AV_LOG_WARNING, "Duplicated STTS atom\n");
3845 av_freep(&sc->stts_data);
3846 sc->stts_count = 0;
3847 if (entries >= INT_MAX / sizeof(*sc->stts_data))
3848 return AVERROR(ENOMEM);
3849
3850 for (i = 0; i < entries && !pb->eof_reached; i++) {
3851 unsigned int sample_duration;
3852 unsigned int sample_count;
3853 unsigned int min_entries = FFMIN(FFMAX(i + 1, 1024 * 1024), entries);
3855 min_entries * sizeof(*sc->stts_data));
3856 if (!stts_data) {
3857 av_freep(&sc->stts_data);
3858 sc->stts_count = 0;
3859 return AVERROR(ENOMEM);
3860 }
3861 sc->stts_count = min_entries;
3862 sc->stts_data = stts_data;
3863
3864 sample_count = avio_rb32(pb);
3865 sample_duration = avio_rb32(pb);
3866
3867 sc->stts_data[i].count= sample_count;
3868 sc->stts_data[i].duration= sample_duration;
3869
3870 av_log(c->fc, AV_LOG_TRACE, "sample_count=%u, sample_duration=%u\n",
3871 sample_count, sample_duration);
3872
3873 /* STTS sample offsets are uint32 but some files store it as int32
3874 * with negative values used to correct DTS delays.
3875 There may be abnormally large values as well. */
3876 if (sample_duration > c->max_stts_delta) {
3877 // assume high delta is a correction if negative when cast as int32
3878 int32_t delta_magnitude = (int32_t)sample_duration;
3879 av_log(c->fc, AV_LOG_WARNING, "Too large sample offset %u in stts entry %u with count %u in st:%d. Clipping to 1.\n",
3880 sample_duration, i, sample_count, st->index);
3881 sc->stts_data[i].duration = 1;
3882 corrected_dts = av_sat_add64(corrected_dts, (delta_magnitude < 0 ? (int64_t)delta_magnitude : 1) * sample_count);
3883 } else {
3884 corrected_dts += sample_duration * (uint64_t)sample_count;
3885 }
3886
3887 current_dts += sc->stts_data[i].duration * (uint64_t)sample_count;
3888
3889 if (current_dts > corrected_dts) {
3890 int64_t drift = av_sat_sub64(current_dts, corrected_dts) / FFMAX(sample_count, 1);
3891 uint32_t correction = (sc->stts_data[i].duration > drift) ? drift : sc->stts_data[i].duration - 1;
3892 current_dts -= correction * (uint64_t)sample_count;
3893 sc->stts_data[i].duration -= correction;
3894 }
3895
3896 duration+=(int64_t)sc->stts_data[i].duration*(uint64_t)sc->stts_data[i].count;
3897 total_sample_count+=sc->stts_data[i].count;
3898 }
3899
3900 sc->stts_count = i;
3901
3902 if (duration > 0 &&
3903 duration <= INT64_MAX - sc->duration_for_fps &&
3904 total_sample_count <= INT_MAX - sc->nb_frames_for_fps) {
3906 sc->nb_frames_for_fps += total_sample_count;
3907 }
3908
3909 if (pb->eof_reached) {
3910 av_log(c->fc, AV_LOG_WARNING, "reached eof, corrupted STTS atom\n");
3911 return AVERROR_EOF;
3912 }
3913
3914 st->nb_frames= total_sample_count;
3915 if (duration)
3916 st->duration= FFMIN(st->duration, duration);
3917
3918 // All samples have zero duration. They have higher chance be chose by
3919 // mov_find_next_sample, which leads to seek again and again.
3920 //
3921 // It's AVERROR_INVALIDDATA actually, but such files exist in the wild.
3922 // So only mark data stream as discarded for safety.
3923 if (!duration && sc->stts_count &&
3925 av_log(c->fc, AV_LOG_WARNING,
3926 "All samples in data stream index:id [%d:%d] have zero "
3927 "duration, stream set to be discarded by default. Override "
3928 "using AVStream->discard or -discard for ffmpeg command.\n",
3929 st->index, sc->id);
3930 st->discard = AVDISCARD_ALL;
3931 }
3932 sc->track_end = duration;
3933 return 0;
3934}
3935
3937{
3938 AVStream *st;
3939 MOVStreamContext *sc;
3940 unsigned int i;
3941 int64_t entries;
3942
3943 if (c->fc->nb_streams < 1)
3944 return 0;
3945 st = c->fc->streams[c->fc->nb_streams - 1];
3946 sc = st->priv_data;
3947
3948 avio_r8(pb); /* version */
3949 avio_rb24(pb); /* flags */
3950 entries = atom.size - 4;
3951
3952 av_log(c->fc, AV_LOG_TRACE, "track[%u].sdtp.entries = %" PRId64 "\n",
3953 c->fc->nb_streams - 1, entries);
3954
3955 if (sc->sdtp_data)
3956 av_log(c->fc, AV_LOG_WARNING, "Duplicated SDTP atom\n");
3957 av_freep(&sc->sdtp_data);
3958 sc->sdtp_count = 0;
3959
3960 if (entries < 0 || entries > UINT_MAX)
3961 return AVERROR(ERANGE);
3962
3963 sc->sdtp_data = av_malloc(entries);
3964 if (!sc->sdtp_data)
3965 return AVERROR(ENOMEM);
3966
3967 for (i = 0; i < entries && !pb->eof_reached; i++)
3968 sc->sdtp_data[i] = avio_r8(pb);
3969 sc->sdtp_count = i;
3970
3971 return 0;
3972}
3973
3974static void mov_update_dts_shift(MOVStreamContext *sc, int duration, void *logctx)
3975{
3976 if (duration < 0) {
3977 if (duration == INT_MIN) {
3978 av_log(logctx, AV_LOG_WARNING, "mov_update_dts_shift(): dts_shift set to %d\n", INT_MAX);
3979 duration++;
3980 }
3981 sc->dts_shift = FFMAX(sc->dts_shift, -duration);
3982 }
3983}
3984
3986{
3987 AVStream *st;
3988 MOVStreamContext *sc;
3989 unsigned int i, entries, ctts_count = 0;
3990
3991 if (c->trak_index < 0) {
3992 av_log(c->fc, AV_LOG_WARNING, "CTTS outside TRAK\n");
3993 return 0;
3994 }
3995
3996 if (c->fc->nb_streams < 1)
3997 return 0;
3998 st = c->fc->streams[c->fc->nb_streams-1];
3999 sc = st->priv_data;
4000
4001 avio_r8(pb); /* version */
4002 avio_rb24(pb); /* flags */
4003 entries = avio_rb32(pb);
4004
4005 av_log(c->fc, AV_LOG_TRACE, "track[%u].ctts.entries = %u\n", c->fc->nb_streams - 1, entries);
4006
4007 if (!entries)
4008 return 0;
4009 if (entries >= UINT_MAX / sizeof(*sc->ctts_data))
4010 return AVERROR_INVALIDDATA;
4011 av_freep(&sc->ctts_data);
4012 sc->ctts_data = av_fast_realloc(NULL, &sc->ctts_allocated_size, entries * sizeof(*sc->ctts_data));
4013 if (!sc->ctts_data)
4014 return AVERROR(ENOMEM);
4015
4016 for (i = 0; i < entries && !pb->eof_reached; i++) {
4017 MOVCtts *ctts_data;
4018 const size_t min_size_needed = (ctts_count + 1) * sizeof(MOVCtts);
4019 const size_t requested_size =
4020 min_size_needed > sc->ctts_allocated_size ?
4021 FFMAX(min_size_needed, 2 * sc->ctts_allocated_size) :
4022 min_size_needed;
4023 int count = avio_rb32(pb);
4024 int duration = avio_rb32(pb);
4025
4026 if (count <= 0) {
4027 av_log(c->fc, AV_LOG_TRACE,
4028 "ignoring CTTS entry with count=%d duration=%d\n",
4029 count, duration);
4030 continue;
4031 }
4032
4033 if (ctts_count >= UINT_MAX / sizeof(MOVCtts) - 1)
4034 return AVERROR(ENOMEM);
4035
4036 ctts_data = av_fast_realloc(sc->ctts_data, &sc->ctts_allocated_size, requested_size);
4037
4038 if (!ctts_data)
4039 return AVERROR(ENOMEM);
4040
4041 sc->ctts_data = ctts_data;
4042
4043 ctts_data[ctts_count].count = count;
4044 ctts_data[ctts_count].offset = duration;
4045 ctts_count++;
4046
4047 av_log(c->fc, AV_LOG_TRACE, "count=%d, duration=%d\n",
4048 count, duration);
4049
4050 if (i+2<entries)
4052 }
4053
4054 sc->ctts_count = ctts_count;
4055
4056 if (pb->eof_reached) {
4057 av_log(c->fc, AV_LOG_WARNING, "reached eof, corrupted CTTS atom\n");
4058 return AVERROR_EOF;
4059 }
4060
4061 av_log(c->fc, AV_LOG_TRACE, "dts shift %d\n", sc->dts_shift);
4062
4063 return 0;
4064}
4065
4067{
4068 AVStream *st;
4069 MOVStreamContext *sc;
4070 uint8_t version;
4071 uint32_t grouping_type;
4072 uint32_t default_length;
4073 av_unused uint32_t default_group_description_index;
4074 uint32_t entry_count;
4075
4076 if (c->fc->nb_streams < 1)
4077 return 0;
4078 st = c->fc->streams[c->fc->nb_streams - 1];
4079 sc = st->priv_data;
4080
4081 version = avio_r8(pb); /* version */
4082 avio_rb24(pb); /* flags */
4083 grouping_type = avio_rl32(pb);
4084
4085 /*
4086 * This function only supports "sync" boxes, but the code is able to parse
4087 * other boxes (such as "tscl", "tsas" and "stsa")
4088 */
4089 if (grouping_type != MKTAG('s','y','n','c'))
4090 return 0;
4091
4092 default_length = version >= 1 ? avio_rb32(pb) : 0;
4093 default_group_description_index = version >= 2 ? avio_rb32(pb) : 0;
4094 entry_count = avio_rb32(pb);
4095
4096 if (entry_count > atom.size)
4097 return AVERROR_INVALIDDATA;
4098
4099 av_freep(&sc->sgpd_sync);
4100 sc->sgpd_sync_count = entry_count;
4101 sc->sgpd_sync = av_calloc(entry_count, sizeof(*sc->sgpd_sync));
4102 if (!sc->sgpd_sync)
4103 return AVERROR(ENOMEM);
4104
4105 for (uint32_t i = 0; i < entry_count && !pb->eof_reached; i++) {
4106 uint32_t description_length = default_length;
4107 if (version >= 1 && default_length == 0)
4108 description_length = avio_rb32(pb);
4109 if (grouping_type == MKTAG('s','y','n','c')) {
4110 const uint8_t nal_unit_type = avio_r8(pb) & 0x3f;
4111 sc->sgpd_sync[i] = nal_unit_type;
4112 description_length -= 1;
4113 }
4114 avio_skip(pb, description_length);
4115 }
4116
4117 if (pb->eof_reached) {
4118 av_log(c->fc, AV_LOG_WARNING, "reached eof, corrupted SGPD atom\n");
4119 return AVERROR_EOF;
4120 }
4121
4122 return 0;
4123}
4124
4126{
4127 AVStream *st;
4128 MOVStreamContext *sc;
4129 unsigned int i, entries;
4130 uint8_t version;
4131 uint32_t grouping_type;
4132 MOVSbgp *table, **tablep;
4133 int *table_count;
4134
4135 if (c->fc->nb_streams < 1)
4136 return 0;
4137 st = c->fc->streams[c->fc->nb_streams-1];
4138 sc = st->priv_data;
4139
4140 version = avio_r8(pb); /* version */
4141 avio_rb24(pb); /* flags */
4142 grouping_type = avio_rl32(pb);
4143
4144 if (grouping_type == MKTAG('r','a','p',' ')) {
4145 tablep = &sc->rap_group;
4146 table_count = &sc->rap_group_count;
4147 } else if (grouping_type == MKTAG('s','y','n','c')) {
4148 tablep = &sc->sync_group;
4149 table_count = &sc->sync_group_count;
4150 } else {
4151 return 0;
4152 }
4153
4154 if (version == 1)
4155 avio_rb32(pb); /* grouping_type_parameter */
4156
4157 entries = avio_rb32(pb);
4158 if (!entries)
4159 return 0;
4160 if (*tablep)
4161 av_log(c->fc, AV_LOG_WARNING, "Duplicated SBGP %s atom\n", av_fourcc2str(grouping_type));
4162 av_freep(tablep);
4163 table = av_malloc_array(entries, sizeof(*table));
4164 if (!table)
4165 return AVERROR(ENOMEM);
4166 *tablep = table;
4167
4168 for (i = 0; i < entries && !pb->eof_reached; i++) {
4169 table[i].count = avio_rb32(pb); /* sample_count */
4170 table[i].index = avio_rb32(pb); /* group_description_index */
4171 }
4172
4173 *table_count = i;
4174
4175 if (pb->eof_reached) {
4176 av_log(c->fc, AV_LOG_WARNING, "reached eof, corrupted SBGP atom\n");
4177 return AVERROR_EOF;
4178 }
4179
4180 return 0;
4181}
4182
4183/**
4184 * Get ith edit list entry (media time, duration).
4185 */
4187 const MOVStreamContext *msc,
4188 unsigned int edit_list_index,
4189 int64_t *edit_list_media_time,
4190 int64_t *edit_list_duration,
4191 int64_t global_timescale)
4192{
4193 if (edit_list_index == msc->elst_count) {
4194 return 0;
4195 }
4196 *edit_list_media_time = msc->elst_data[edit_list_index].time;
4197 *edit_list_duration = msc->elst_data[edit_list_index].duration;
4198
4199 /* duration is in global timescale units;convert to msc timescale */
4200 if (global_timescale == 0) {
4201 avpriv_request_sample(mov->fc, "Support for mvhd.timescale = 0 with editlists");
4202 return 0;
4203 }
4204 *edit_list_duration = av_rescale(*edit_list_duration, msc->time_scale,
4205 global_timescale);
4206
4207 if (*edit_list_duration + (uint64_t)*edit_list_media_time > INT64_MAX)
4208 *edit_list_duration = 0;
4209
4210 return 1;
4211}
4212
4213/**
4214 * Find the closest previous frame to the timestamp_pts, in e_old index
4215 * entries. Searching for just any frame / just key frames can be controlled by
4216 * last argument 'flag'.
4217 * Note that if ctts_data is not NULL, we will always search for a key frame
4218 * irrespective of the value of 'flag'. If we don't find any keyframe, we will
4219 * return the first frame of the video.
4220 *
4221 * Here the timestamp_pts is considered to be a presentation timestamp and
4222 * the timestamp of index entries are considered to be decoding timestamps.
4223 *
4224 * Returns 0 if successful in finding a frame, else returns -1.
4225 * Places the found index corresponding output arg.
4226 *
4227 * If ctts_old is not NULL, then refines the searched entry by searching
4228 * backwards from the found timestamp, to find the frame with correct PTS.
4229 *
4230 * Places the found ctts_index and ctts_sample in corresponding output args.
4231 */
4233 AVIndexEntry *e_old,
4234 int nb_old,
4235 MOVTimeToSample *tts_data,
4236 int64_t tts_count,
4237 int64_t timestamp_pts,
4238 int flag,
4239 int64_t* index,
4240 int64_t* tts_index,
4241 int64_t* tts_sample)
4242{
4243 MOVStreamContext *msc = st->priv_data;
4244 FFStream *const sti = ffstream(st);
4245 AVIndexEntry *e_keep = sti->index_entries;
4246 int nb_keep = sti->nb_index_entries;
4247 int64_t i = 0;
4248
4250
4251 // If dts_shift > 0, then all the index timestamps will have to be offset by
4252 // at least dts_shift amount to obtain PTS.
4253 // Hence we decrement the searched timestamp_pts by dts_shift to find the closest index element.
4254 if (msc->dts_shift > 0) {
4255 timestamp_pts -= msc->dts_shift;
4256 }
4257
4258 sti->index_entries = e_old;
4259 sti->nb_index_entries = nb_old;
4261
4262 // Keep going backwards in the index entries until the timestamp is the same.
4263 if (*index >= 0) {
4264 for (i = *index; i > 0 && e_old[i].timestamp == e_old[i - 1].timestamp;
4265 i--) {
4266 if ((flag & AVSEEK_FLAG_ANY) ||
4267 (e_old[i - 1].flags & AVINDEX_KEYFRAME)) {
4268 *index = i - 1;
4269 }
4270 }
4271 }
4272
4273 // If we have CTTS then refine the search, by searching backwards over PTS
4274 // computed by adding corresponding CTTS durations to index timestamps.
4275 if (msc->ctts_count && *index >= 0) {
4276 av_assert0(tts_index);
4277 av_assert0(tts_sample);
4278 // Find out the ctts_index for the found frame.
4279 *tts_index = 0;
4280 *tts_sample = 0;
4281 for (int64_t index_tts_count = 0; index_tts_count < *index; index_tts_count++) {
4282 if (*tts_index < tts_count) {
4283 (*tts_sample)++;
4284 if (tts_data[*tts_index].count == *tts_sample) {
4285 (*tts_index)++;
4286 *tts_sample = 0;
4287 }
4288 }
4289 }
4290
4291 while (*index >= 0 && (*tts_index) >= 0 && (*tts_index) < tts_count) {
4292 // Find a "key frame" with PTS <= timestamp_pts (So that we can decode B-frames correctly).
4293 // No need to add dts_shift to the timestamp here because timestamp_pts has already been
4294 // compensated by dts_shift above.
4295 if ((e_old[*index].timestamp + tts_data[*tts_index].offset) <= timestamp_pts &&
4296 (e_old[*index].flags & AVINDEX_KEYFRAME)) {
4297 break;
4298 }
4299
4300 (*index)--;
4301 if (*tts_sample == 0) {
4302 (*tts_index)--;
4303 if (*tts_index >= 0)
4304 *tts_sample = tts_data[*tts_index].count - 1;
4305 } else {
4306 (*tts_sample)--;
4307 }
4308 }
4309 }
4310
4311 /* restore AVStream state*/
4312 sti->index_entries = e_keep;
4313 sti->nb_index_entries = nb_keep;
4314 return *index >= 0 ? 0 : -1;
4315}
4316
4317/**
4318 * Add index entry with the given values, to the end of ffstream(st)->index_entries.
4319 * Returns the new size ffstream(st)->index_entries if successful, else returns -1.
4320 *
4321 * This function is similar to ff_add_index_entry in libavformat/utils.c
4322 * except that here we are always unconditionally adding an index entry to
4323 * the end, instead of searching the entries list and skipping the add if
4324 * there is an existing entry with the same timestamp.
4325 * This is needed because the mov_fix_index calls this func with the same
4326 * unincremented timestamp for successive discarded frames.
4327 */
4329 int size, int distance, int flags)
4330{
4331 FFStream *const sti = ffstream(st);
4332 AVIndexEntry *entries, *ie;
4333 int64_t index = -1;
4334 const size_t min_size_needed = (sti->nb_index_entries + 1) * sizeof(AVIndexEntry);
4335
4336 // Double the allocation each time, to lower memory fragmentation.
4337 // Another difference from ff_add_index_entry function.
4338 const size_t requested_size =
4339 min_size_needed > sti->index_entries_allocated_size ?
4340 FFMAX(min_size_needed, 2 * sti->index_entries_allocated_size) :
4341 min_size_needed;
4342
4343 if (sti->nb_index_entries + 1U >= UINT_MAX / sizeof(AVIndexEntry))
4344 return -1;
4345
4346 entries = av_fast_realloc(sti->index_entries,
4348 requested_size);
4349 if (!entries)
4350 return -1;
4351
4352 sti->index_entries = entries;
4353
4354 index = sti->nb_index_entries++;
4355 ie= &entries[index];
4356
4357 ie->pos = pos;
4358 ie->timestamp = timestamp;
4360 ie->size= size;
4361 ie->flags = flags;
4362 return index;
4363}
4364
4365/**
4366 * Rewrite timestamps of index entries in the range [end_index - frame_duration_buffer_size, end_index)
4367 * by subtracting end_ts successively by the amounts given in frame_duration_buffer.
4368 */
4369static void fix_index_entry_timestamps(AVStream* st, int end_index, int64_t end_ts,
4370 int64_t* frame_duration_buffer,
4371 int frame_duration_buffer_size) {
4372 FFStream *const sti = ffstream(st);
4373 int i = 0;
4374 av_assert0(end_index >= 0 && end_index <= sti->nb_index_entries);
4375 for (i = 0; i < frame_duration_buffer_size; i++) {
4376 end_ts -= frame_duration_buffer[frame_duration_buffer_size - 1 - i];
4377 sti->index_entries[end_index - 1 - i].timestamp = end_ts;
4378 }
4379}
4380
4381static int add_tts_entry(MOVTimeToSample **tts_data, unsigned int *tts_count, unsigned int *allocated_size,
4382 int count, int offset, unsigned int duration)
4383{
4384 MOVTimeToSample *tts_buf_new;
4385 const size_t min_size_needed = (*tts_count + 1) * sizeof(MOVTimeToSample);
4386 const size_t requested_size =
4387 min_size_needed > *allocated_size ?
4388 FFMAX(min_size_needed, 2 * (*allocated_size)) :
4389 min_size_needed;
4390
4391 if ((unsigned)(*tts_count) >= UINT_MAX / sizeof(MOVTimeToSample) - 1)
4392 return -1;
4393
4394 tts_buf_new = av_fast_realloc(*tts_data, allocated_size, requested_size);
4395
4396 if (!tts_buf_new)
4397 return -1;
4398
4399 *tts_data = tts_buf_new;
4400
4401 tts_buf_new[*tts_count].count = count;
4402 tts_buf_new[*tts_count].offset = offset;
4403 tts_buf_new[*tts_count].duration = duration;
4404
4405 *tts_count = (*tts_count) + 1;
4406 return 0;
4407}
4408
4409#define MAX_REORDER_DELAY 16
4411{
4412 MOVStreamContext *msc = st->priv_data;
4413 FFStream *const sti = ffstream(st);
4414 int ctts_ind = 0;
4415 int ctts_sample = 0;
4416 int64_t pts_buf[MAX_REORDER_DELAY + 1]; // Circular buffer to sort pts.
4417 int buf_start = 0;
4418 int j, r, num_swaps;
4419
4420 for (j = 0; j < MAX_REORDER_DELAY + 1; j++)
4421 pts_buf[j] = INT64_MIN;
4422
4423 if (st->codecpar->video_delay <= 0 && msc->ctts_count &&
4425 st->codecpar->video_delay = 0;
4426 for (int ind = 0; ind < sti->nb_index_entries && ctts_ind < msc->tts_count; ++ind) {
4427 // Point j to the last elem of the buffer and insert the current pts there.
4428 j = buf_start;
4429 buf_start = (buf_start + 1);
4430 if (buf_start == MAX_REORDER_DELAY + 1)
4431 buf_start = 0;
4432
4433 pts_buf[j] = sti->index_entries[ind].timestamp + msc->tts_data[ctts_ind].offset;
4434
4435 // The timestamps that are already in the sorted buffer, and are greater than the
4436 // current pts, are exactly the timestamps that need to be buffered to output PTS
4437 // in correct sorted order.
4438 // Hence the video delay (which is the buffer size used to sort DTS and output PTS),
4439 // can be computed as the maximum no. of swaps any particular timestamp needs to
4440 // go through, to keep this buffer in sorted order.
4441 num_swaps = 0;
4442 while (j != buf_start) {
4443 r = j - 1;
4444 if (r < 0) r = MAX_REORDER_DELAY;
4445 if (pts_buf[j] < pts_buf[r]) {
4446 FFSWAP(int64_t, pts_buf[j], pts_buf[r]);
4447 ++num_swaps;
4448 } else {
4449 break;
4450 }
4451 j = r;
4452 }
4453 st->codecpar->video_delay = FFMAX(st->codecpar->video_delay, num_swaps);
4454
4455 ctts_sample++;
4456 if (ctts_sample == msc->tts_data[ctts_ind].count) {
4457 ctts_ind++;
4458 ctts_sample = 0;
4459 }
4460 }
4461 av_log(c->fc, AV_LOG_DEBUG, "Setting codecpar->delay to %d for stream st: %d\n",
4462 st->codecpar->video_delay, st->index);
4463 }
4464}
4465
4467{
4468 sc->current_sample++;
4469 sc->current_index++;
4470 if (sc->index_ranges &&
4472 sc->current_index_range->end) {
4473 sc->current_index_range++;
4475 }
4476}
4477
4479{
4480 sc->current_sample--;
4481 sc->current_index--;
4482 if (sc->index_ranges &&
4485 sc->current_index_range--;
4486 sc->current_index = sc->current_index_range->end - 1;
4487 }
4488}
4489
4490static void mov_current_sample_set(MOVStreamContext *sc, int current_sample)
4491{
4492 int64_t range_size;
4493
4494 sc->current_sample = current_sample;
4495 sc->current_index = current_sample;
4496 if (!sc->index_ranges) {
4497 return;
4498 }
4499
4500 for (sc->current_index_range = sc->index_ranges;
4502 sc->current_index_range++) {
4503 range_size = sc->current_index_range->end - sc->current_index_range->start;
4504 if (range_size > current_sample) {
4505 sc->current_index = sc->current_index_range->start + current_sample;
4506 break;
4507 }
4508 current_sample -= range_size;
4509 }
4510}
4511
4512/**
4513 * Fix ffstream(st)->index_entries, so that it contains only the entries (and the entries
4514 * which are needed to decode them) that fall in the edit list time ranges.
4515 * Also fixes the timestamps of the index entries to match the timeline
4516 * specified the edit lists.
4517 */
4518static void mov_fix_index(MOVContext *mov, AVStream *st)
4519{
4520 MOVStreamContext *msc = st->priv_data;
4521 FFStream *const sti = ffstream(st);
4522 AVIndexEntry *e_old = sti->index_entries;
4523 int nb_old = sti->nb_index_entries;
4524 const AVIndexEntry *e_old_end = e_old + nb_old;
4525 const AVIndexEntry *current = NULL;
4526 MOVTimeToSample *tts_data_old = msc->tts_data;
4527 int64_t tts_index_old = 0;
4528 int64_t tts_sample_old = 0;
4529 int64_t tts_count_old = msc->tts_count;
4530 int64_t edit_list_media_time = 0;
4531 int64_t edit_list_duration = 0;
4532 int64_t frame_duration = 0;
4533 int64_t edit_list_dts_counter = 0;
4534 int64_t edit_list_dts_entry_end = 0;
4535 int64_t edit_list_start_tts_sample = 0;
4536 int64_t curr_cts;
4537 int64_t curr_ctts = 0;
4538 int64_t empty_edits_sum_duration = 0;
4539 int64_t edit_list_index = 0;
4540 int64_t index;
4541 int flags;
4542 int64_t start_dts = 0;
4543 int64_t edit_list_start_encountered = 0;
4544 int64_t search_timestamp = 0;
4545 int64_t* frame_duration_buffer = NULL;
4546 int num_discarded_begin = 0;
4547 int first_non_zero_audio_edit = -1;
4548 int packet_skip_samples = 0;
4549 MOVIndexRange *current_index_range = NULL;
4550 int found_keyframe_after_edit = 0;
4551 int found_non_empty_edit = 0;
4552
4553 if (!msc->elst_data || msc->elst_count <= 0 || nb_old <= 0) {
4554 return;
4555 }
4556
4557 // allocate the index ranges array
4558 msc->index_ranges = av_malloc_array(msc->elst_count + 1,
4559 sizeof(msc->index_ranges[0]));
4560 if (!msc->index_ranges) {
4561 av_log(mov->fc, AV_LOG_ERROR, "Cannot allocate index ranges buffer\n");
4562 return;
4563 }
4565
4566 // Clean AVStream from traces of old index
4567 sti->index_entries = NULL;
4569 sti->nb_index_entries = 0;
4570
4571 // Clean time to sample fields of MOVStreamContext
4572 msc->tts_data = NULL;
4573 msc->tts_count = 0;
4574 msc->tts_index = 0;
4575 msc->tts_sample = 0;
4576 msc->tts_allocated_size = 0;
4577
4578 // Reinitialize min_corrected_pts so that it can be computed again.
4579 msc->min_corrected_pts = -1;
4580
4581 // If the dts_shift is positive (in case of negative ctts values in mov),
4582 // then negate the DTS by dts_shift
4583 if (msc->dts_shift > 0) {
4584 edit_list_dts_entry_end -= msc->dts_shift;
4585 av_log(mov->fc, AV_LOG_DEBUG, "Shifting DTS by %d because of negative CTTS.\n", msc->dts_shift);
4586 }
4587
4588 start_dts = edit_list_dts_entry_end;
4589
4590 while (get_edit_list_entry(mov, msc, edit_list_index, &edit_list_media_time,
4591 &edit_list_duration, mov->time_scale)) {
4592 av_log(mov->fc, AV_LOG_DEBUG, "Processing st: %d, edit list %"PRId64" - media time: %"PRId64", duration: %"PRId64"\n",
4593 st->index, edit_list_index, edit_list_media_time, edit_list_duration);
4594 edit_list_index++;
4595 edit_list_dts_counter = edit_list_dts_entry_end;
4596 edit_list_dts_entry_end = av_sat_add64(edit_list_dts_entry_end, edit_list_duration);
4597 if (edit_list_dts_entry_end == INT64_MAX) {
4598 av_log(mov->fc, AV_LOG_ERROR, "Cannot calculate dts entry length with duration %"PRId64"\n",
4599 edit_list_duration);
4600 break;
4601 }
4602 num_discarded_begin = 0;
4603 if (!found_non_empty_edit && edit_list_media_time == -1) {
4604 empty_edits_sum_duration += edit_list_duration;
4605 continue;
4606 }
4607 found_non_empty_edit = 1;
4608
4609 // If we encounter a non-negative edit list reset the skip_samples/initial_padding fields and set them
4610 // according to the edit list below.
4612 if (first_non_zero_audio_edit < 0) {
4613 first_non_zero_audio_edit = 1;
4614 } else {
4615 first_non_zero_audio_edit = 0;
4616 }
4617
4618 if (first_non_zero_audio_edit > 0)
4619 sti->skip_samples = st->codecpar->initial_padding = 0;
4620 }
4621
4622 // While reordering frame index according to edit list we must handle properly
4623 // the scenario when edit list entry starts from none key frame.
4624 // We find closest previous key frame and preserve it and consequent frames in index.
4625 // All frames which are outside edit list entry time boundaries will be dropped after decoding.
4626 search_timestamp = edit_list_media_time;
4628 // Audio decoders like AAC need need a decoder delay samples previous to the current sample,
4629 // to correctly decode this frame. Hence for audio we seek to a frame 1 sec. before the
4630 // edit_list_media_time to cover the decoder delay.
4631 search_timestamp = FFMAX(search_timestamp - msc->time_scale, e_old[0].timestamp);
4632 }
4633
4634 if (find_prev_closest_index(st, e_old, nb_old, tts_data_old, tts_count_old, search_timestamp, 0,
4635 &index, &tts_index_old, &tts_sample_old) < 0) {
4636 av_log(mov->fc, AV_LOG_WARNING,
4637 "st: %d edit list: %"PRId64" Missing key frame while searching for timestamp: %"PRId64"\n",
4638 st->index, edit_list_index, search_timestamp);
4639 if (find_prev_closest_index(st, e_old, nb_old, tts_data_old, tts_count_old, search_timestamp, AVSEEK_FLAG_ANY,
4640 &index, &tts_index_old, &tts_sample_old) < 0) {
4641 av_log(mov->fc, AV_LOG_WARNING,
4642 "st: %d edit list %"PRId64" Cannot find an index entry before timestamp: %"PRId64".\n",
4643 st->index, edit_list_index, search_timestamp);
4644 index = 0;
4645 tts_index_old = 0;
4646 tts_sample_old = 0;
4647 }
4648 }
4649 current = e_old + index;
4650 edit_list_start_tts_sample = tts_sample_old;
4651
4652 // Iterate over index and arrange it according to edit list
4653 edit_list_start_encountered = 0;
4654 found_keyframe_after_edit = 0;
4655 for (; current < e_old_end; current++, index++) {
4656 // check if frame outside edit list mark it for discard
4657 frame_duration = (current + 1 < e_old_end) ?
4658 ((current + 1)->timestamp - current->timestamp) : edit_list_duration;
4659
4660 flags = current->flags;
4661
4662 // frames (pts) before or after edit list
4663 curr_cts = current->timestamp + msc->dts_shift;
4664 curr_ctts = 0;
4665
4666 if (tts_data_old && tts_index_old < tts_count_old) {
4667 curr_ctts = tts_data_old[tts_index_old].offset;
4668 av_log(mov->fc, AV_LOG_TRACE, "stts: %"PRId64" ctts: %"PRId64", tts_index: %"PRId64", tts_count: %"PRId64"\n",
4669 curr_cts, curr_ctts, tts_index_old, tts_count_old);
4670 curr_cts += curr_ctts;
4671 tts_sample_old++;
4672 if (tts_sample_old == tts_data_old[tts_index_old].count) {
4673 if (add_tts_entry(&msc->tts_data, &msc->tts_count,
4674 &msc->tts_allocated_size,
4675 tts_data_old[tts_index_old].count - edit_list_start_tts_sample,
4676 tts_data_old[tts_index_old].offset, tts_data_old[tts_index_old].duration) == -1) {
4677 av_log(mov->fc, AV_LOG_ERROR, "Cannot add Time To Sample entry %"PRId64" - {%"PRId64", %d}\n",
4678 tts_index_old,
4679 tts_data_old[tts_index_old].count - edit_list_start_tts_sample,
4680 tts_data_old[tts_index_old].offset);
4681 break;
4682 }
4683 tts_index_old++;
4684 tts_sample_old = 0;
4685 edit_list_start_tts_sample = 0;
4686 }
4687 }
4688
4689 if (curr_cts < edit_list_media_time || curr_cts >= (edit_list_duration + edit_list_media_time)) {
4691 curr_cts < edit_list_media_time && curr_cts + frame_duration > edit_list_media_time &&
4692 first_non_zero_audio_edit > 0) {
4693 packet_skip_samples = edit_list_media_time - curr_cts;
4694 sti->skip_samples += packet_skip_samples;
4695
4696 // Shift the index entry timestamp by packet_skip_samples to be correct.
4697 edit_list_dts_counter -= packet_skip_samples;
4698 if (edit_list_start_encountered == 0) {
4699 edit_list_start_encountered = 1;
4700 // Make timestamps strictly monotonically increasing for audio, by rewriting timestamps for
4701 // discarded packets.
4702 if (frame_duration_buffer) {
4703 fix_index_entry_timestamps(st, sti->nb_index_entries, edit_list_dts_counter,
4704 frame_duration_buffer, num_discarded_begin);
4705 av_freep(&frame_duration_buffer);
4706 }
4707 }
4708
4709 av_log(mov->fc, AV_LOG_DEBUG, "skip %d audio samples from curr_cts: %"PRId64"\n", packet_skip_samples, curr_cts);
4710 } else {
4712 av_log(mov->fc, AV_LOG_DEBUG, "drop a frame at curr_cts: %"PRId64" @ %"PRId64"\n", curr_cts, index);
4713
4714 if (edit_list_start_encountered == 0) {
4715 num_discarded_begin++;
4716 if (av_reallocp_array(&frame_duration_buffer, num_discarded_begin,
4717 sizeof(*frame_duration_buffer)) < 0) {
4718 av_log(mov->fc, AV_LOG_ERROR, "Cannot reallocate frame duration buffer\n");
4719 break;
4720 }
4721 frame_duration_buffer[num_discarded_begin - 1] = frame_duration;
4722
4723 // Increment skip_samples for the first non-zero audio edit list
4725 first_non_zero_audio_edit > 0 && st->codecpar->codec_id != AV_CODEC_ID_VORBIS) {
4726 sti->skip_samples += frame_duration;
4727 }
4728 }
4729 }
4730 } else {
4731 if (msc->min_corrected_pts < 0) {
4732 msc->min_corrected_pts = edit_list_dts_counter + curr_ctts + msc->dts_shift;
4733 } else {
4734 msc->min_corrected_pts = FFMIN(msc->min_corrected_pts, edit_list_dts_counter + curr_ctts + msc->dts_shift);
4735 }
4736 if (edit_list_start_encountered == 0) {
4737 edit_list_start_encountered = 1;
4738 // Make timestamps strictly monotonically increasing by rewriting timestamps for
4739 // discarded packets.
4740 if (frame_duration_buffer) {
4741 fix_index_entry_timestamps(st, sti->nb_index_entries, edit_list_dts_counter,
4742 frame_duration_buffer, num_discarded_begin);
4743 av_freep(&frame_duration_buffer);
4744 }
4745 }
4746 }
4747
4748 if (add_index_entry(st, current->pos, edit_list_dts_counter, current->size,
4749 current->min_distance, flags) == -1) {
4750 av_log(mov->fc, AV_LOG_ERROR, "Cannot add index entry\n");
4751 break;
4752 }
4753
4754 // Update the index ranges array
4755 if (!current_index_range || index != current_index_range->end) {
4756 current_index_range = current_index_range ? current_index_range + 1
4757 : msc->index_ranges;
4758 current_index_range->start = index;
4759 }
4760 current_index_range->end = index + 1;
4761
4762 // Only start incrementing DTS in frame_duration amounts, when we encounter a frame in edit list.
4763 if (edit_list_start_encountered > 0) {
4764 edit_list_dts_counter = edit_list_dts_counter + frame_duration;
4765 }
4766
4767 // Break when found first key frame after edit entry completion
4768 if ((curr_cts + frame_duration >= (edit_list_duration + edit_list_media_time)) &&
4770 if (msc->ctts_count) {
4771 // If we have CTTS and this is the first keyframe after edit elist,
4772 // wait for one more, because there might be trailing B-frames after this I-frame
4773 // that do belong to the edit.
4774 if (st->codecpar->codec_type != AVMEDIA_TYPE_AUDIO && found_keyframe_after_edit == 0) {
4775 found_keyframe_after_edit = 1;
4776 continue;
4777 }
4778 if (tts_sample_old != 0) {
4779 if (add_tts_entry(&msc->tts_data, &msc->tts_count,
4780 &msc->tts_allocated_size,
4781 tts_sample_old - edit_list_start_tts_sample,
4782 tts_data_old[tts_index_old].offset, tts_data_old[tts_index_old].duration) == -1) {
4783 av_log(mov->fc, AV_LOG_ERROR, "Cannot add Time To Sample entry %"PRId64" - {%"PRId64", %d}\n",
4784 tts_index_old, tts_sample_old - edit_list_start_tts_sample,
4785 tts_data_old[tts_index_old].offset);
4786 break;
4787 }
4788 }
4789 }
4790 break;
4791 }
4792 }
4793 }
4794 // If there are empty edits, then msc->min_corrected_pts might be positive
4795 // intentionally. So we subtract the sum duration of empty edits here.
4796 msc->min_corrected_pts -= empty_edits_sum_duration;
4797
4798 // If the minimum pts turns out to be greater than zero after fixing the index, then we subtract the
4799 // dts by that amount to make the first pts zero.
4801 if (msc->min_corrected_pts > 0) {
4802 av_log(mov->fc, AV_LOG_DEBUG, "Offset DTS by %"PRId64" to make first pts zero.\n", msc->min_corrected_pts);
4803 for (int i = 0; i < sti->nb_index_entries; ++i)
4805 }
4806 }
4807 // Start time should be equal to zero or the duration of any empty edits.
4808 st->start_time = empty_edits_sum_duration;
4809
4810 // Update av stream length, if it ends up shorter than the track's media duration
4811 st->duration = FFMIN(st->duration, edit_list_dts_entry_end - start_dts);
4813
4814 // Free the old index and the old CTTS structures
4815 av_free(e_old);
4816 av_free(tts_data_old);
4817 av_freep(&frame_duration_buffer);
4818
4819 // Null terminate the index ranges array
4820 current_index_range = current_index_range ? current_index_range + 1
4821 : msc->index_ranges;
4822 current_index_range->start = 0;
4823 current_index_range->end = 0;
4824 msc->current_index = msc->index_ranges[0].start;
4825}
4826
4827static uint32_t get_sgpd_sync_index(const MOVStreamContext *sc, int nal_unit_type)
4828{
4829 for (uint32_t i = 0; i < sc->sgpd_sync_count; i++)
4830 if (sc->sgpd_sync[i] == nal_unit_type)
4831 return i + 1;
4832 return 0;
4833}
4834
4836{
4837 int k;
4838 int sample_id = 0;
4839 uint32_t cra_index;
4840 MOVStreamContext *sc = st->priv_data;
4841
4843 return 0;
4844
4845 /* Build an unrolled index of the samples */
4846 sc->sample_offsets_count = 0;
4847 for (uint32_t i = 0; i < sc->ctts_count; i++) {
4848 if (sc->ctts_data[i].count > INT_MAX - sc->sample_offsets_count)
4849 return AVERROR(ENOMEM);
4851 }
4854 if (!sc->sample_offsets)
4855 return AVERROR(ENOMEM);
4856 k = 0;
4857 for (uint32_t i = 0; i < sc->ctts_count; i++)
4858 for (int j = 0; j < sc->ctts_data[i].count; j++)
4859 sc->sample_offsets[k++] = sc->ctts_data[i].offset;
4860
4861 /* The following HEVC NAL type reveal the use of open GOP sync points
4862 * (TODO: BLA types may also be concerned) */
4863 cra_index = get_sgpd_sync_index(sc, HEVC_NAL_CRA_NUT); /* Clean Random Access */
4864 if (!cra_index)
4865 return 0;
4866
4867 /* Build a list of open-GOP key samples */
4868 sc->open_key_samples_count = 0;
4869 for (uint32_t i = 0; i < sc->sync_group_count; i++)
4870 if (sc->sync_group[i].index == cra_index) {
4871 if (sc->sync_group[i].count > INT_MAX - sc->open_key_samples_count)
4872 return AVERROR(ENOMEM);
4874 }
4877 if (!sc->open_key_samples)
4878 return AVERROR(ENOMEM);
4879 k = 0;
4880 for (uint32_t i = 0; i < sc->sync_group_count; i++) {
4881 const MOVSbgp *sg = &sc->sync_group[i];
4882 if (sg->index == cra_index)
4883 for (uint32_t j = 0; j < sg->count; j++)
4884 sc->open_key_samples[k++] = sample_id;
4885 if (sg->count > INT_MAX - sample_id)
4886 return AVERROR_PATCHWELCOME;
4887 sample_id += sg->count;
4888 }
4889
4890 /* Identify the minimal time step between samples */
4891 sc->min_sample_duration = UINT_MAX;
4892 for (uint32_t i = 0; i < sc->stts_count; i++)
4894
4895 return 0;
4896}
4897
4898#define MOV_MERGE_CTTS 1
4899#define MOV_MERGE_STTS 2
4900/*
4901 * Merge stts and ctts arrays into a new combined array.
4902 * stts_count and ctts_count may be left untouched as they will be
4903 * used to check for the presence of either of them.
4904 */
4906{
4907 MOVStreamContext *sc = st->priv_data;
4908 int ctts = sc->ctts_data && (flags & MOV_MERGE_CTTS);
4909 int stts = sc->stts_data && (flags & MOV_MERGE_STTS);
4910 int idx = 0;
4911
4912 if (!sc->ctts_data && !sc->stts_data)
4913 return 0;
4914 // Expand time to sample entries such that we have a 1-1 mapping with samples
4915 if (!sc->sample_count || sc->sample_count >= UINT_MAX / sizeof(*sc->tts_data))
4916 return -1;
4917
4918 if (ctts) {
4920 sc->sample_count * sizeof(*sc->tts_data));
4921 if (!sc->tts_data)
4922 return -1;
4923
4924 memset(sc->tts_data, 0, sc->tts_allocated_size);
4925
4926 for (int i = 0; i < sc->ctts_count &&
4927 idx < sc->sample_count; i++)
4928 for (int j = 0; j < sc->ctts_data[i].count &&
4929 idx < sc->sample_count; j++) {
4930 sc->tts_data[idx].offset = sc->ctts_data[i].offset;
4931 sc->tts_data[idx++].count = 1;
4932 }
4933
4934 sc->tts_count = idx;
4935 } else
4936 sc->ctts_count = 0;
4937 av_freep(&sc->ctts_data);
4938 sc->ctts_allocated_size = 0;
4939
4940 idx = 0;
4941 if (stts) {
4943 sc->sample_count * sizeof(*sc->tts_data));
4944 if (!tts_data)
4945 return -1;
4946
4947 if (!sc->tts_data)
4948 memset(tts_data, 0, sc->tts_allocated_size);
4949 sc->tts_data = tts_data;
4950
4951 for (int i = 0; i < sc->stts_count &&
4952 idx < sc->sample_count; i++)
4953 for (int j = 0; j < sc->stts_data[i].count &&
4954 idx < sc->sample_count; j++) {
4955 sc->tts_data[idx].duration = sc->stts_data[i].duration;
4956 sc->tts_data[idx++].count = 1;
4957 }
4958
4959 sc->tts_count = FFMAX(sc->tts_count, idx);
4960 } else
4961 sc->stts_count = 0;
4962 av_freep(&sc->stts_data);
4963 sc->stts_allocated_size = 0;
4964
4965 return 0;
4966}
4967
4969{
4970 MOVStreamContext *sc = st->priv_data;
4971 FFStream *const sti = ffstream(st);
4972 int64_t current_offset;
4973 int64_t current_dts = 0;
4974 unsigned int stts_index = 0;
4975 unsigned int stsc_index = 0;
4976 unsigned int stss_index = 0;
4977 unsigned int stps_index = 0;
4978 unsigned int i, j;
4979 uint64_t stream_size = 0;
4980
4981 int ret = build_open_gop_key_points(st);
4982 if (ret < 0)
4983 return;
4984
4985 if (sc->elst_count) {
4986 int i, edit_start_index = 0, multiple_edits = 0;
4987 int64_t empty_duration = 0; // empty duration of the first edit list entry
4988 int64_t start_time = 0; // start time of the media
4989
4990 for (i = 0; i < sc->elst_count; i++) {
4991 const MOVElst *e = &sc->elst_data[i];
4992 if (i == 0 && e->time == -1) {
4993 /* if empty, the first entry is the start time of the stream
4994 * relative to the presentation itself */
4995 empty_duration = e->duration;
4996 edit_start_index = 1;
4997 } else if (i == edit_start_index && e->time >= 0) {
4998 start_time = e->time;
4999 } else {
5000 multiple_edits = 1;
5001 }
5002 }
5003
5004 if (multiple_edits && !mov->advanced_editlist) {
5006 av_log(mov->fc, AV_LOG_WARNING, "multiple edit list entries, "
5007 "not supported in fragmented MP4 files\n");
5008 else
5009 av_log(mov->fc, AV_LOG_WARNING, "multiple edit list entries, "
5010 "Use -advanced_editlist to correctly decode otherwise "
5011 "a/v desync might occur\n");
5012 }
5013
5014 /* adjust first dts according to edit list */
5015 if ((empty_duration || start_time) && mov->time_scale > 0) {
5016 if (empty_duration)
5017 empty_duration = av_rescale(empty_duration, sc->time_scale, mov->time_scale);
5018
5019 if (av_sat_sub64(start_time, empty_duration) != start_time - (uint64_t)empty_duration)
5020 av_log(mov->fc, AV_LOG_WARNING, "start_time - empty_duration is not representable\n");
5021
5022 sc->time_offset = start_time - (uint64_t)empty_duration;
5024 if (!mov->advanced_editlist)
5025 current_dts = -av_clip64(sc->time_offset, -INT64_MAX, INT64_MAX);
5026 }
5027
5028 if (!multiple_edits && !mov->advanced_editlist &&
5031 (AVRational){1, st->codecpar->sample_rate});
5032 }
5033
5034 /* only use old uncompressed audio chunk demuxing when stts specifies it */
5035 if (!(st->codecpar->codec_type == AVMEDIA_TYPE_AUDIO &&
5036 sc->stts_count == 1 && sc->stts_data && sc->stts_data[0].duration == 1)) {
5037 unsigned int current_sample = 0;
5038 unsigned int stts_sample = 0;
5039 unsigned int sample_size;
5040 unsigned int distance = 0;
5041 unsigned int rap_group_index = 0;
5042 unsigned int rap_group_sample = 0;
5043 int rap_group_present = sc->rap_group_count && sc->rap_group;
5044 int key_off = (sc->keyframe_count && sc->keyframes[0] > 0) || (sc->stps_count && sc->stps_data[0] > 0);
5045
5046 av_assert0(sc->dts_shift >= 0);
5047 if (current_dts < INT64_MIN + sc->dts_shift)
5048 return;
5049 current_dts -= sc->dts_shift;
5050 if (!sc->sample_count || sti->nb_index_entries || sc->tts_count)
5051 return;
5052 if (sc->sample_count >= UINT_MAX / sizeof(*sti->index_entries) - sti->nb_index_entries)
5053 return;
5055 sti->nb_index_entries + sc->sample_count,
5056 sizeof(*sti->index_entries)) < 0) {
5057 sti->nb_index_entries = 0;
5058 return;
5059 }
5060 sti->index_entries_allocated_size = (sti->nb_index_entries + sc->sample_count) * sizeof(*sti->index_entries);
5061
5063 if (ret < 0)
5064 return;
5065
5066 for (i = 0; i < sc->chunk_count; i++) {
5067 int64_t next_offset = i+1 < sc->chunk_count ? sc->chunk_offsets[i+1] : INT64_MAX;
5068 current_offset = sc->chunk_offsets[i];
5069 while (mov_stsc_index_valid(stsc_index, sc->stsc_count) &&
5070 i + 1 == sc->stsc_data[stsc_index + 1].first)
5071 stsc_index++;
5072
5073 if (next_offset > current_offset && sc->sample_size>0 && sc->sample_size < sc->stsz_sample_size &&
5074 sc->stsc_data[stsc_index].count * (int64_t)sc->stsz_sample_size > next_offset - current_offset) {
5075 av_log(mov->fc, AV_LOG_WARNING, "STSZ sample size %d invalid (too large), ignoring\n", sc->stsz_sample_size);
5076 sc->stsz_sample_size = sc->sample_size;
5077 }
5078 if (sc->stsz_sample_size>0 && sc->stsz_sample_size < sc->sample_size) {
5079 av_log(mov->fc, AV_LOG_WARNING, "STSZ sample size %d invalid (too small), ignoring\n", sc->stsz_sample_size);
5080 sc->stsz_sample_size = sc->sample_size;
5081 }
5082
5083 for (j = 0; j < sc->stsc_data[stsc_index].count; j++) {
5084 int keyframe = 0;
5085 if (current_sample >= sc->sample_count) {
5086 av_log(mov->fc, AV_LOG_ERROR, "wrong sample count\n");
5087 return;
5088 }
5089
5090 if (!sc->keyframe_absent && (!sc->keyframe_count || current_sample+key_off == sc->keyframes[stss_index])) {
5091 keyframe = 1;
5092 if (stss_index + 1 < sc->keyframe_count)
5093 stss_index++;
5094 } else if (sc->stps_count && current_sample+key_off == sc->stps_data[stps_index]) {
5095 keyframe = 1;
5096 if (stps_index + 1 < sc->stps_count)
5097 stps_index++;
5098 }
5099 if (rap_group_present && rap_group_index < sc->rap_group_count) {
5100 if (sc->rap_group[rap_group_index].index > 0)
5101 keyframe = 1;
5102 if (++rap_group_sample == sc->rap_group[rap_group_index].count) {
5103 rap_group_sample = 0;
5104 rap_group_index++;
5105 }
5106 }
5107 if (sc->keyframe_absent
5108 && !sc->stps_count
5109 && !rap_group_present
5110 && (st->codecpar->codec_type == AVMEDIA_TYPE_AUDIO || (i==0 && j==0)))
5111 keyframe = 1;
5112 if (keyframe)
5113 distance = 0;
5114 sample_size = sc->stsz_sample_size > 0 ? sc->stsz_sample_size : sc->sample_sizes[current_sample];
5115 if (current_offset > INT64_MAX - sample_size) {
5116 av_log(mov->fc, AV_LOG_ERROR, "Current offset %"PRId64" or sample size %u is too large\n",
5117 current_offset,
5118 sample_size);
5119 return;
5120 }
5121
5122 if (sc->pseudo_stream_id == -1 ||
5123 sc->stsc_data[stsc_index].id - 1 == sc->pseudo_stream_id) {
5124 AVIndexEntry *e;
5125 if (sample_size > 0x3FFFFFFF) {
5126 av_log(mov->fc, AV_LOG_ERROR, "Sample size %u is too large\n", sample_size);
5127 return;
5128 }
5129 e = &sti->index_entries[sti->nb_index_entries++];
5130 e->pos = current_offset;
5131 e->timestamp = current_dts;
5132 e->size = sample_size;
5134 e->flags = keyframe ? AVINDEX_KEYFRAME : 0;
5135 av_log(mov->fc, AV_LOG_TRACE, "AVIndex stream %d, sample %u, offset %"PRIx64", dts %"PRId64", "
5136 "size %u, distance %u, keyframe %d\n", st->index, current_sample,
5137 current_offset, current_dts, sample_size, distance, keyframe);
5138 if (st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO && sti->nb_index_entries < 100)
5139 ff_rfps_add_frame(mov->fc, st, current_dts);
5140 }
5141
5142 current_offset += sample_size;
5143 stream_size += sample_size;
5144
5145 if (current_dts > INT64_MAX - sc->tts_data[stts_index].duration)
5146 return;
5147 current_dts += sc->tts_data[stts_index].duration;
5148
5149 distance++;
5150 stts_sample++;
5151 current_sample++;
5152 if (stts_index + 1 < sc->tts_count && stts_sample == sc->tts_data[stts_index].count) {
5153 stts_sample = 0;
5154 stts_index++;
5155 }
5156 }
5157 }
5158 if (st->duration > 0)
5159 st->codecpar->bit_rate = stream_size*8*sc->time_scale/st->duration;
5160 } else {
5161 unsigned chunk_samples, total = 0;
5162
5163 if (!sc->chunk_count || sc->tts_count)
5164 return;
5165
5166 // compute total chunk count
5167 for (i = 0; i < sc->stsc_count; i++) {
5168 unsigned count, chunk_count;
5169
5170 chunk_samples = sc->stsc_data[i].count;
5171 if (i != sc->stsc_count - 1 &&
5172 sc->samples_per_frame && chunk_samples % sc->samples_per_frame) {
5173 av_log(mov->fc, AV_LOG_ERROR, "error unaligned chunk\n");
5174 return;
5175 }
5176
5177 if (sc->samples_per_frame >= 160) { // gsm
5178 count = chunk_samples / sc->samples_per_frame;
5179 } else if (sc->samples_per_frame > 1) {
5180 unsigned samples = (1024/sc->samples_per_frame)*sc->samples_per_frame;
5181 count = (chunk_samples+samples-1) / samples;
5182 } else {
5183 count = (chunk_samples+1023) / 1024;
5184 }
5185
5187 chunk_count = sc->stsc_data[i+1].first - sc->stsc_data[i].first;
5188 else
5189 chunk_count = sc->chunk_count - (sc->stsc_data[i].first - 1);
5190 total += chunk_count * count;
5191 }
5192
5193 av_log(mov->fc, AV_LOG_TRACE, "chunk count %u\n", total);
5194 if (total >= UINT_MAX / sizeof(*sti->index_entries) - sti->nb_index_entries)
5195 return;
5197 sti->nb_index_entries + total,
5198 sizeof(*sti->index_entries)) < 0) {
5199 sti->nb_index_entries = 0;
5200 return;
5201 }
5202 sti->index_entries_allocated_size = (sti->nb_index_entries + total) * sizeof(*sti->index_entries);
5203
5204 // populate index
5205 for (i = 0; i < sc->chunk_count; i++) {
5206 current_offset = sc->chunk_offsets[i];
5207 if (mov_stsc_index_valid(stsc_index, sc->stsc_count) &&
5208 i + 1 == sc->stsc_data[stsc_index + 1].first)
5209 stsc_index++;
5210 chunk_samples = sc->stsc_data[stsc_index].count;
5211
5212 while (chunk_samples > 0) {
5213 AVIndexEntry *e;
5214 unsigned size, samples;
5215
5216 if (sc->samples_per_frame > 1 && !sc->bytes_per_frame) {
5218 "Zero bytes per frame, but %d samples per frame",
5219 sc->samples_per_frame);
5220 return;
5221 }
5222
5223 if (sc->samples_per_frame >= 160) { // gsm
5224 samples = sc->samples_per_frame;
5225 size = sc->bytes_per_frame;
5226 } else {
5227 if (sc->samples_per_frame > 1) {
5228 samples = FFMIN((1024 / sc->samples_per_frame)*
5229 sc->samples_per_frame, chunk_samples);
5230 size = (samples / sc->samples_per_frame) * sc->bytes_per_frame;
5231 } else {
5232 samples = FFMIN(1024, chunk_samples);
5233 size = samples * sc->sample_size;
5234 }
5235 }
5236
5237 if (sti->nb_index_entries >= total) {
5238 av_log(mov->fc, AV_LOG_ERROR, "wrong chunk count %u\n", total);
5239 return;
5240 }
5241 if (size > 0x3FFFFFFF) {
5242 av_log(mov->fc, AV_LOG_ERROR, "Sample size %u is too large\n", size);
5243 return;
5244 }
5245 e = &sti->index_entries[sti->nb_index_entries++];
5246 e->pos = current_offset;
5247 e->timestamp = current_dts;
5248 e->size = size;
5249 e->min_distance = 0;
5251 av_log(mov->fc, AV_LOG_TRACE, "AVIndex stream %d, chunk %u, offset %"PRIx64", dts %"PRId64", "
5252 "size %u, duration %u\n", st->index, i, current_offset, current_dts,
5253 size, samples);
5254
5255 current_offset += size;
5256 if (current_dts > INT64_MAX - samples)
5257 return;
5258 current_dts += samples;
5259 chunk_samples -= samples;
5260 }
5261 }
5262
5263 ret = mov_merge_tts_data(mov, st, MOV_MERGE_CTTS);
5264 if (ret < 0)
5265 return;
5266 }
5267
5268 if (!mov->ignore_editlist && mov->advanced_editlist) {
5269 // Fix index according to edit lists.
5270 mov_fix_index(mov, st);
5271 }
5272
5273 // Update start time of the stream.
5276 if (sc->tts_data) {
5278 }
5279 }
5280
5281 mov_estimate_video_delay(mov, st);
5282}
5283
5288
5289static int mov_compare_presentation_samples(const void *a, const void *b)
5290{
5291 const MOVPresentationSample *sa = a;
5292 const MOVPresentationSample *sb = b;
5293
5294 if (sa->pts != sb->pts)
5295 return (sa->pts > sb->pts) - (sa->pts < sb->pts);
5296 return (sa->index > sb->index) - (sa->index < sb->index);
5297}
5298
5299/*
5300 * Set sample durations from adjacent presentation timestamps.
5301 */
5303{
5304 MOVStreamContext *sc = st->priv_data;
5305 FFStream *const sti = ffstream(st);
5306 MOVPresentationSample *samples = NULL;
5307 MOVTimeToSample *tts_data = NULL;
5308 unsigned int tts_index = 0, tts_sample = 0;
5309 int count = sti->nb_index_entries;
5310
5311 /* A single STTS entry describes a fixed sample delta. */
5313 !sc->ctts_count || sc->stts_count < 2 ||
5314 !sc->tts_data || count < 2 ||
5315 count >= UINT_MAX / sizeof(*tts_data))
5316 return;
5317
5318 samples = av_malloc_array(count, sizeof(*samples));
5319 tts_data = av_malloc_array(count, sizeof(*tts_data));
5320 if (!samples || !tts_data)
5321 goto fail;
5322
5323 for (int i = 0; i < count; i++) {
5324 int64_t dts, offset;
5325
5326 if (tts_index >= sc->tts_count || !sc->tts_data[tts_index].count)
5327 goto fail;
5328
5329 tts_data[i] = sc->tts_data[tts_index];
5330 tts_data[i].count = 1;
5331
5332 dts = sti->index_entries[i].timestamp;
5333 offset = (int64_t)sc->dts_shift + tts_data[i].offset;
5334 if (dts == AV_NOPTS_VALUE ||
5335 (offset > 0 && dts > INT64_MAX - offset) ||
5336 (offset < 0 && dts < INT64_MIN - offset))
5337 goto fail;
5338
5339 samples[i].index = i;
5340 samples[i].pts = dts + offset;
5341
5342 if (++tts_sample == sc->tts_data[tts_index].count) {
5343 tts_index++;
5344 tts_sample = 0;
5345 }
5346 }
5347 if (tts_index != sc->tts_count || tts_sample)
5348 goto fail;
5349
5350 qsort(samples, count, sizeof(*samples), mov_compare_presentation_samples);
5351
5352 for (int i = 0; i + 1 < count; i++) {
5353 uint64_t duration;
5354
5355 if (samples[i].pts >= samples[i + 1].pts)
5356 goto fail;
5357
5358 /*
5359 * In VFR streams with reordered frames, STTS deltas follow decode
5360 * order while AVPacket.duration follows presentation order. CTTS
5361 * may produce presentation intervals that cannot be obtained by
5362 * merely permuting the STTS deltas, so derive each known duration
5363 * from adjacent PTS.
5364 */
5365 duration = (uint64_t)samples[i + 1].pts - samples[i].pts;
5366 if (!duration || duration > UINT_MAX)
5367 goto fail;
5368
5369 tts_data[samples[i].index].duration = (unsigned int)duration;
5370 }
5371
5372 av_log(mov->fc, AV_LOG_DEBUG,
5373 "Updated sample durations in presentation order for stream %d\n",
5374 st->index);
5375
5376 av_freep(&sc->tts_data);
5377 sc->tts_data = tts_data;
5378 sc->tts_count = count;
5379 sc->tts_allocated_size = count * sizeof(*tts_data);
5380 tts_data = NULL;
5381
5382fail:
5383 av_free(samples);
5384 av_free(tts_data);
5385}
5386
5387static int test_same_origin(const char *src, const char *ref) {
5388 char src_proto[64];
5389 char ref_proto[64];
5390 char src_auth[256];
5391 char ref_auth[256];
5392 char src_host[256];
5393 char ref_host[256];
5394 int src_port=-1;
5395 int ref_port=-1;
5396
5397 av_url_split(src_proto, sizeof(src_proto), src_auth, sizeof(src_auth), src_host, sizeof(src_host), &src_port, NULL, 0, src);
5398 av_url_split(ref_proto, sizeof(ref_proto), ref_auth, sizeof(ref_auth), ref_host, sizeof(ref_host), &ref_port, NULL, 0, ref);
5399
5400 if (strlen(src) == 0) {
5401 return -1;
5402 } else if (strlen(src_auth) + 1 >= sizeof(src_auth) ||
5403 strlen(ref_auth) + 1 >= sizeof(ref_auth) ||
5404 strlen(src_host) + 1 >= sizeof(src_host) ||
5405 strlen(ref_host) + 1 >= sizeof(ref_host)) {
5406 return 0;
5407 } else if (strcmp(src_proto, ref_proto) ||
5408 strcmp(src_auth, ref_auth) ||
5409 strcmp(src_host, ref_host) ||
5410 src_port != ref_port) {
5411 return 0;
5412 } else
5413 return 1;
5414}
5415
5416static int mov_open_dref(MOVContext *c, AVIOContext **pb, const char *src, MOVDref *ref)
5417{
5418 /* try relative path, we do not try the absolute because it can leak information about our
5419 system to an attacker */
5420 if (ref->nlvl_to > 0 && ref->nlvl_from > 0) {
5421 char filename[1025];
5422 const char *src_path;
5423 int i, l;
5424
5425 /* find a source dir */
5426 src_path = strrchr(src, '/');
5427 if (src_path)
5428 src_path++;
5429 else
5430 src_path = src;
5431
5432 /* find a next level down to target */
5433 for (i = 0, l = strlen(ref->path) - 1; l >= 0; l--)
5434 if (ref->path[l] == '/') {
5435 if (i == ref->nlvl_to - 1)
5436 break;
5437 else
5438 i++;
5439 }
5440
5441 /* compose filename if next level down to target was found */
5442 if (i == ref->nlvl_to - 1 && src_path - src < sizeof(filename)) {
5443 memcpy(filename, src, src_path - src);
5444 filename[src_path - src] = 0;
5445
5446 for (i = 1; i < ref->nlvl_from; i++)
5447 av_strlcat(filename, "../", sizeof(filename));
5448
5449 av_strlcat(filename, ref->path + l + 1, sizeof(filename));
5450 if (!c->use_absolute_path) {
5451 int same_origin = test_same_origin(src, filename);
5452
5453 if (!same_origin) {
5454 av_log(c->fc, AV_LOG_ERROR,
5455 "Reference with mismatching origin, %s not tried for security reasons, "
5456 "set demuxer option use_absolute_path to allow it anyway\n",
5457 ref->path);
5458 return AVERROR(ENOENT);
5459 }
5460
5461 if (strstr(ref->path + l + 1, "..") ||
5462 strstr(ref->path + l + 1, ":") ||
5463 (ref->nlvl_from > 1 && same_origin < 0) ||
5464 (filename[0] == '/' && src_path == src))
5465 return AVERROR(ENOENT);
5466 }
5467
5468 if (strlen(filename) + 1 == sizeof(filename))
5469 return AVERROR(ENOENT);
5470 if (!c->fc->io_open(c->fc, pb, filename, AVIO_FLAG_READ, NULL))
5471 return 0;
5472 }
5473 } else if (c->use_absolute_path) {
5474 av_log(c->fc, AV_LOG_WARNING, "Using absolute path on user request, "
5475 "this is a possible security issue\n");
5476 if (!c->fc->io_open(c->fc, pb, ref->path, AVIO_FLAG_READ, NULL))
5477 return 0;
5478 } else {
5479 av_log(c->fc, AV_LOG_ERROR,
5480 "Absolute path %s not tried for security reasons, "
5481 "set demuxer option use_absolute_path to allow absolute paths\n",
5482 ref->path);
5483 }
5484
5485 return AVERROR(ENOENT);
5486}
5487
5489{
5490 if (sc->time_scale <= 0) {
5491 av_log(c->fc, AV_LOG_WARNING, "stream %d, timescale not set\n", sc->ffindex);
5492 sc->time_scale = c->time_scale;
5493 if (sc->time_scale <= 0)
5494 sc->time_scale = 1;
5495 }
5496}
5497
5498#if CONFIG_IAMFDEC
5499static int mov_update_iamf_streams(MOVContext *c, const AVStream *st)
5500{
5501 const MOVStreamContext *sc = st->priv_data;
5502 const IAMFContext *iamf = &sc->iamf->iamf;
5503
5504 for (int i = 0; i < iamf->nb_audio_elements; i++) {
5505 const AVStreamGroup *stg = NULL;
5506
5507 for (int j = 0; j < c->fc->nb_stream_groups; j++)
5508 if (c->fc->stream_groups[j]->id == iamf->audio_elements[i]->audio_element_id)
5509 stg = c->fc->stream_groups[j];
5510 av_assert0(stg);
5511
5512 for (int j = 0; j < stg->nb_entries; j++) {
5513 const FFStream *sti = cffstream(st);
5514 AVStream *out = stg->entries[j]->stream;
5515 FFStream *out_sti = ffstream(stg->entries[j]->stream);
5516
5517 out->codecpar->bit_rate = 0;
5518
5519 if (out == st)
5520 continue;
5521
5522 out->time_base = st->time_base;
5523 out->start_time = st->start_time;
5524 out->duration = st->duration;
5525 out->nb_frames = st->nb_frames;
5526 out->discard = st->discard;
5527
5528 av_assert0(!out_sti->index_entries);
5530 if (!out_sti->index_entries)
5531 return AVERROR(ENOMEM);
5532
5534 out_sti->nb_index_entries = sti->nb_index_entries;
5535 out_sti->skip_samples = sti->skip_samples;
5536 memcpy(out_sti->index_entries, sti->index_entries, sti->index_entries_allocated_size);
5537 }
5538 }
5539
5540 return 0;
5541}
5542#endif
5543
5544static int sanity_checks(void *log_obj, MOVStreamContext *sc, int index)
5545{
5546 if ((sc->chunk_count && (!sc->stts_count || !sc->stsc_count ||
5547 (!sc->sample_size && !sc->sample_count))) ||
5548 (sc->sample_count && (!sc->chunk_count ||
5549 (!sc->sample_size && !sc->sample_sizes)))) {
5550 av_log(log_obj, AV_LOG_ERROR, "stream %d, missing mandatory atoms, broken header\n",
5551 index);
5552 return 1;
5553 }
5554
5555 if (sc->stsc_count && sc->stsc_data[ sc->stsc_count - 1 ].first > sc->chunk_count) {
5556 av_log(log_obj, AV_LOG_ERROR, "stream %d, contradictionary STSC and STCO\n",
5557 index);
5558 return 2;
5559 }
5560 return 0;
5561}
5562
5564{
5565 AVStream *st;
5566 MOVStreamContext *sc;
5567 int ret;
5568
5569 st = avformat_new_stream(c->fc, NULL);
5570 if (!st) return AVERROR(ENOMEM);
5571 st->id = -1;
5572 sc = av_mallocz(sizeof(MOVStreamContext));
5573 if (!sc) return AVERROR(ENOMEM);
5574
5575 st->priv_data = sc;
5577 sc->ffindex = st->index;
5578 c->trak_index = st->index;
5579 sc->refcount = 1;
5580
5581 if ((ret = mov_read_default(c, pb, atom)) < 0)
5582 return ret;
5583
5584 c->trak_index = -1;
5585
5586 // Here stsc refers to a chunk not described in stco. This is technically invalid,
5587 // but we can overlook it (clearing stsc) whenever stts_count == 0 (indicating no samples).
5588 if (!sc->chunk_count && !sc->stts_count && sc->stsc_count) {
5589 sc->stsc_count = 0;
5590 av_freep(&sc->stsc_data);
5591 }
5592
5593 ret = sanity_checks(c->fc, sc, st->index);
5594 if (ret)
5595 return ret > 1 ? AVERROR_INVALIDDATA : 0;
5596
5597 fix_timescale(c, sc);
5598
5599 avpriv_set_pts_info(st, 64, 1, sc->time_scale);
5600
5601 /*
5602 * Advanced edit list support does not work with fragemented MP4s, which
5603 * have stsc, stsz, stco, and stts with zero entries in the moov atom.
5604 * In these files, trun atoms may be streamed in.
5605 */
5606 if (!sc->stts_count && c->advanced_editlist) {
5607
5608 av_log(c->fc, AV_LOG_VERBOSE, "advanced_editlist does not work with fragmented "
5609 "MP4. disabling.\n");
5610 c->advanced_editlist = 0;
5611 c->advanced_editlist_autodisabled = 1;
5612 }
5613
5614 mov_build_index(c, st);
5615 /*
5616 * Fragment samples are appended later by mov_read_trun() and are not
5617 * covered by this non-fragmented track update.
5618 */
5620
5621#if CONFIG_IAMFDEC
5622 if (sc->iamf) {
5623 ret = mov_update_iamf_streams(c, st);
5624 if (ret < 0)
5625 return ret;
5626 }
5627#endif
5628
5629 if (sc->dref_id-1 < sc->drefs_count && sc->drefs[sc->dref_id-1].path) {
5630 MOVDref *dref = &sc->drefs[sc->dref_id - 1];
5631 if (c->enable_drefs) {
5632 if (mov_open_dref(c, &sc->pb, c->fc->url, dref) < 0)
5633 av_log(c->fc, AV_LOG_ERROR,
5634 "stream %d, error opening alias: path='%s', dir='%s', "
5635 "filename='%s', volume='%s', nlvl_from=%d, nlvl_to=%d\n",
5636 st->index, dref->path, dref->dir, dref->filename,
5637 dref->volume, dref->nlvl_from, dref->nlvl_to);
5638 } else {
5639 av_log(c->fc, AV_LOG_WARNING,
5640 "Skipped opening external track: "
5641 "stream %d, alias: path='%s', dir='%s', "
5642 "filename='%s', volume='%s', nlvl_from=%d, nlvl_to=%d."
5643 "Set enable_drefs to allow this.\n",
5644 st->index, dref->path, dref->dir, dref->filename,
5645 dref->volume, dref->nlvl_from, dref->nlvl_to);
5646 }
5647 } else {
5648 sc->pb = c->fc->pb;
5649 sc->pb_is_copied = 1;
5650 }
5651
5653 int stts_constant = sc->stts_count && sc->tts_count;
5654 if (sc->h_spacing && sc->v_spacing)
5656 sc->h_spacing, sc->v_spacing, INT_MAX);
5657 if (!st->sample_aspect_ratio.num && st->codecpar->width && st->codecpar->height &&
5658 sc->height && sc->width &&
5659 (st->codecpar->width != sc->width || st->codecpar->height != sc->height)) {
5661 (int64_t)st->codecpar->height * sc->width,
5662 (int64_t)st->codecpar->width * sc->height, INT_MAX);
5663 }
5664
5665#if FF_API_R_FRAME_RATE
5666 for (unsigned int i = 1; sc->stts_count && i + 1 < sc->tts_count; i++) {
5667 if (sc->tts_data[i].duration == sc->tts_data[0].duration)
5668 continue;
5669 stts_constant = 0;
5670 }
5671 if (stts_constant)
5673 sc->time_scale, sc->tts_data[0].duration, INT_MAX);
5674#endif
5675 }
5676
5677#if CONFIG_H261_DECODER || CONFIG_H263_DECODER || CONFIG_MPEG4_DECODER
5678 switch (st->codecpar->codec_id) {
5679#if CONFIG_H261_DECODER
5680 case AV_CODEC_ID_H261:
5681#endif
5682#if CONFIG_H263_DECODER
5683 case AV_CODEC_ID_H263:
5684#endif
5685#if CONFIG_MPEG4_DECODER
5686 case AV_CODEC_ID_MPEG4:
5687#endif
5688 st->codecpar->width = 0; /* let decoder init width/height */
5689 st->codecpar->height= 0;
5690 break;
5691 }
5692#endif
5693
5694 // If the duration of the mp3 packets is not constant, then they could need a parser
5696 && sc->time_scale == st->codecpar->sample_rate) {
5697 int stts_constant = 1;
5698 for (int i = 1; sc->stts_count && i < sc->tts_count; i++) {
5699 if (sc->tts_data[i].duration == sc->tts_data[0].duration)
5700 continue;
5701 stts_constant = 0;
5702 }
5703 if (!stts_constant)
5705 }
5706 /* Do not need those anymore. */
5707 av_freep(&sc->chunk_offsets);
5708 av_freep(&sc->sample_sizes);
5709 av_freep(&sc->keyframes);
5710 av_freep(&sc->stps_data);
5711 av_freep(&sc->elst_data);
5712 av_freep(&sc->rap_group);
5713 av_freep(&sc->sync_group);
5714 av_freep(&sc->sgpd_sync);
5715
5716 return 0;
5717}
5718
5720{
5721 int ret;
5722 c->itunes_metadata = 1;
5723 ret = mov_read_default(c, pb, atom);
5724 c->itunes_metadata = 0;
5725 return ret;
5726}
5727
5729{
5730 uint32_t count;
5731 uint32_t i;
5732
5733 if (atom.size < 8)
5734 return 0;
5735
5736 avio_skip(pb, 4);
5737 count = avio_rb32(pb);
5738 atom.size -= 8;
5739 if (count > atom.size / 8 || count >= UINT_MAX / sizeof(*c->meta_keys)) {
5740 av_log(c->fc, AV_LOG_ERROR,
5741 "The 'keys' atom with the invalid key count: %"PRIu32"\n", count);
5742 return AVERROR_INVALIDDATA;
5743 }
5744
5745 c->meta_keys = av_malloc_array(count + 1, sizeof(*c->meta_keys));
5746 if (!c->meta_keys)
5747 return AVERROR(ENOMEM);
5748
5749 c->meta_keys[0] = NULL;
5750 c->meta_keys_count = 1;
5751 for (i = 1; i <= count; ++i) {
5752 uint32_t key_size = avio_rb32(pb);
5753 uint32_t type = avio_rl32(pb);
5754 c->meta_keys[i] = NULL;
5755 c->meta_keys_count = i + 1;
5756 if (key_size < 8 || key_size > atom.size) {
5757 av_log(c->fc, AV_LOG_ERROR,
5758 "The key# %"PRIu32" in meta has invalid size:"
5759 "%"PRIu32"\n", i, key_size);
5760 return AVERROR_INVALIDDATA;
5761 }
5762 atom.size -= key_size;
5763 key_size -= 8;
5764 if (type != MKTAG('m','d','t','a')) {
5765 avio_skip(pb, key_size);
5766 continue;
5767 }
5768 c->meta_keys[i] = av_malloc(key_size + 1);
5769 if (!c->meta_keys[i])
5770 return AVERROR(ENOMEM);
5771 int ret = ffio_read_size(pb, c->meta_keys[i], key_size);
5772 if (ret < 0)
5773 return ret;
5774 c->meta_keys[i][key_size] = 0;
5775 }
5776
5777 return 0;
5778}
5779
5781{
5782 int64_t end = av_sat_add64(avio_tell(pb), atom.size);
5783 uint8_t *key = NULL, *val = NULL, *mean = NULL;
5784 int i;
5785 int ret = 0;
5786 AVStream *st;
5787
5788 if (c->fc->nb_streams < 1)
5789 return 0;
5790 st = c->fc->streams[c->fc->nb_streams-1];
5791
5792 for (i = 0; i < 3; i++) {
5793 uint8_t **p;
5794 uint32_t len, tag;
5795
5796 if (end - avio_tell(pb) <= 12)
5797 break;
5798
5799 len = avio_rb32(pb);
5800 tag = avio_rl32(pb);
5801 avio_skip(pb, 4); // flags
5802
5803 if (len < 12 || len - 12 > end - avio_tell(pb))
5804 break;
5805 len -= 12;
5806
5807 if (tag == MKTAG('m', 'e', 'a', 'n'))
5808 p = &mean;
5809 else if (tag == MKTAG('n', 'a', 'm', 'e'))
5810 p = &key;
5811 else if (tag == MKTAG('d', 'a', 't', 'a') && len > 4) {
5812 avio_skip(pb, 4);
5813 len -= 4;
5814 p = &val;
5815 } else
5816 break;
5817
5818 if (*p)
5819 break;
5820
5821 *p = av_malloc(len + 1);
5822 if (!*p) {
5823 ret = AVERROR(ENOMEM);
5824 break;
5825 }
5826 ret = ffio_read_size(pb, *p, len);
5827 if (ret < 0) {
5828 av_freep(p);
5829 break;
5830 }
5831 (*p)[len] = 0;
5832 }
5833
5834 if (mean && key && val) {
5835 if (strcmp(key, "iTunSMPB") == 0) {
5836 int64_t priming, remainder, samples;
5837 if (ff_itunes_parse_smpb(val, &priming, &remainder, &samples) >= 0) {
5838 if(priming>0 && priming<16384)
5839 st->codecpar->initial_padding = priming = av_rescale_q(priming, st->time_base,
5840 (AVRational){ 1, st->codecpar->sample_rate });
5841 if (remainder > 0) {
5843 (AVRational){ 1, st->codecpar->sample_rate });
5844 remainder = av_rescale_q(remainder, st->time_base,
5845 (AVRational){ 1, st->codecpar->sample_rate });
5846 samples = av_rescale_q(samples, st->time_base,
5847 (AVRational){ 1, st->codecpar->sample_rate });
5848 if (duration > remainder && duration > samples) {
5849 ffstream(st)->first_discard_sample = duration - remainder;
5851 }
5852 }
5853 av_log(c->fc, AV_LOG_DEBUG, "Parsed iTunSMPB: priming %"PRId64", "
5854 "remainder %"PRId64" samples %"PRId64"\n",
5855 priming, remainder, samples);
5856 }
5857 }
5858 if (strcmp(mean, "com.apple.iTunes") == 0 &&
5859 strcmp(key, "DISCSUBTITLE") == 0) {
5860 av_dict_set(&c->fc->metadata, "disc_subtitle", val,
5862 val = NULL;
5863 }
5864 if (strcmp(key, "cdec") != 0) {
5865 av_dict_set(&c->fc->metadata, key, val,
5867 key = val = NULL;
5868 }
5869 } else {
5870 av_log(c->fc, AV_LOG_VERBOSE,
5871 "Unhandled or malformed custom metadata of size %"PRId64"\n", atom.size);
5872 }
5873
5874 avio_seek(pb, end, SEEK_SET);
5875 av_freep(&key);
5876 av_freep(&val);
5877 av_freep(&mean);
5878 return ret;
5879}
5880
5882{
5883 MOVStreamContext *sc;
5884 AVStream *st;
5885
5886 st = avformat_new_stream(c->fc, NULL);
5887 if (!st)
5888 return AVERROR(ENOMEM);
5889 sc = av_mallocz(sizeof(MOVStreamContext));
5890 if (!sc)
5891 goto fail;
5892
5893 item->st = st;
5894 st->id = item->item_id;
5895 st->priv_data = sc;
5897 st->codecpar->codec_id = mov_codec_id(st, item->type);
5898 sc->id = st->id;
5899 sc->ffindex = st->index;
5900 st->avg_frame_rate.num = st->avg_frame_rate.den = 1;
5901 st->time_base.num = st->time_base.den = 1;
5902 st->nb_frames = 1;
5903 sc->time_scale = 1;
5904 sc->pb = c->fc->pb;
5905 sc->pb_is_copied = 1;
5906 sc->refcount = 1;
5907
5908 if (item->name)
5909 av_dict_set(&st->metadata, "title", item->name, 0);
5910
5911 // Populate the necessary fields used by mov_build_index.
5912 sc->stsc_data = av_malloc_array(1, sizeof(*sc->stsc_data));
5913 if (!sc->stsc_data)
5914 goto fail;
5915 sc->stsc_count = 1;
5916 sc->stsc_data[0].first = 1;
5917 sc->stsc_data[0].count = 1;
5918 sc->stsc_data[0].id = 1;
5919 sc->chunk_offsets = av_malloc_array(1, sizeof(*sc->chunk_offsets));
5920 if (!sc->chunk_offsets)
5921 goto fail;
5922 sc->chunk_count = 1;
5923 sc->stts_data = av_malloc_array(1, sizeof(*sc->stts_data));
5924 if (!sc->stts_data)
5925 goto fail;
5926 sc->stts_count = 1;
5927 sc->stts_data[0].count = 1;
5928 // Not used for still images. But needed by mov_build_index.
5929 sc->stts_data[0].duration = 0;
5930
5931 return 0;
5932fail:
5933 mov_free_stream_context(c->fc, st);
5934 ff_remove_stream(c->fc, st);
5935 item->st = NULL;
5936
5937 return AVERROR(ENOMEM);
5938}
5939
5941{
5942 while (atom.size > 8) {
5943 uint32_t tag;
5944 if (avio_feof(pb))
5945 return AVERROR_EOF;
5946 tag = avio_rl32(pb);
5947 atom.size -= 4;
5948 if (tag == MKTAG('h','d','l','r')) {
5949 avio_seek(pb, -8, SEEK_CUR);
5950 atom.size += 8;
5951 return mov_read_default(c, pb, atom);
5952 }
5953 }
5954 return 0;
5955}
5956
5957// return 1 when matrix is identity, 0 otherwise
5958#define IS_MATRIX_IDENT(matrix) \
5959 ( (matrix)[0][0] == (1 << 16) && \
5960 (matrix)[1][1] == (1 << 16) && \
5961 (matrix)[2][2] == (1 << 30) && \
5962 !(matrix)[0][1] && !(matrix)[0][2] && \
5963 !(matrix)[1][0] && !(matrix)[1][2] && \
5964 !(matrix)[2][0] && !(matrix)[2][1])
5965
5967{
5968 int i, j, e;
5969 int width;
5970 int height;
5971 int display_matrix[3][3];
5972 int res_display_matrix[3][3] = { { 0 } };
5973 AVStream *st;
5974 MOVStreamContext *sc;
5975 int version;
5976 int flags;
5977
5978 if (c->fc->nb_streams < 1)
5979 return 0;
5980 st = c->fc->streams[c->fc->nb_streams-1];
5981 sc = st->priv_data;
5982
5983 // Each stream (trak) should have exactly 1 tkhd. This catches bad files and
5984 // avoids corrupting AVStreams mapped to an earlier tkhd.
5985 if (st->id != -1)
5986 return AVERROR_INVALIDDATA;
5987
5988 version = avio_r8(pb);
5989 flags = avio_rb24(pb);
5991
5992 if (version == 1) {
5993 avio_rb64(pb);
5994 avio_rb64(pb);
5995 } else {
5996 avio_rb32(pb); /* creation time */
5997 avio_rb32(pb); /* modification time */
5998 }
5999 st->id = (int)avio_rb32(pb); /* track id (NOT 0 !)*/
6000 sc->id = st->id;
6001 avio_rb32(pb); /* reserved */
6002
6003 /* highlevel (considering edits) duration in movie timebase */
6004 (version == 1) ? avio_rb64(pb) : avio_rb32(pb);
6005 avio_rb32(pb); /* reserved */
6006 avio_rb32(pb); /* reserved */
6007
6008 avio_rb16(pb); /* layer */
6009 avio_rb16(pb); /* alternate group */
6010 avio_rb16(pb); /* volume */
6011 avio_rb16(pb); /* reserved */
6012
6013 //read in the display matrix (outlined in ISO 14496-12, Section 6.2.2)
6014 // they're kept in fixed point format through all calculations
6015 // save u,v,z to store the whole matrix in the AV_PKT_DATA_DISPLAYMATRIX
6016 // side data, but the scale factor is not needed to calculate aspect ratio
6017 for (i = 0; i < 3; i++) {
6018 display_matrix[i][0] = avio_rb32(pb); // 16.16 fixed point
6019 display_matrix[i][1] = avio_rb32(pb); // 16.16 fixed point
6020 display_matrix[i][2] = avio_rb32(pb); // 2.30 fixed point
6021 }
6022
6023 width = avio_rb32(pb); // 16.16 fixed point track width
6024 height = avio_rb32(pb); // 16.16 fixed point track height
6025 sc->width = width >> 16;
6026 sc->height = height >> 16;
6027
6028 // apply the moov display matrix (after the tkhd one)
6029 for (i = 0; i < 3; i++) {
6030 const int sh[3] = { 16, 16, 30 };
6031 for (j = 0; j < 3; j++) {
6032 for (e = 0; e < 3; e++) {
6033 res_display_matrix[i][j] +=
6034 ((int64_t) display_matrix[i][e] *
6035 c->movie_display_matrix[e][j]) >> sh[e];
6036 }
6037 }
6038 }
6039
6040 // save the matrix when it is not the default identity
6041 if (!IS_MATRIX_IDENT(res_display_matrix)) {
6043 sc->display_matrix = av_malloc(sizeof(int32_t) * 9);
6044 if (!sc->display_matrix)
6045 return AVERROR(ENOMEM);
6046
6047 for (i = 0; i < 3; i++)
6048 for (j = 0; j < 3; j++)
6049 sc->display_matrix[i * 3 + j] = res_display_matrix[i][j];
6050 }
6051
6052 // transform the display width/height according to the matrix
6053 // to keep the same scale, use [width height 1<<16]
6054 if (width && height && sc->display_matrix) {
6055 double disp_transform[2];
6056
6057 for (i = 0; i < 2; i++)
6058 disp_transform[i] = hypot(sc->display_matrix[0 + i],
6059 sc->display_matrix[3 + i]);
6060
6061 if (disp_transform[0] > 1 && disp_transform[1] > 1 &&
6062 disp_transform[0] < (1<<24) && disp_transform[1] < (1<<24) &&
6063 fabs((disp_transform[0] / disp_transform[1]) - 1.0) > 0.01)
6065 disp_transform[0] / disp_transform[1],
6066 INT_MAX);
6067 }
6068 return 0;
6069}
6070
6072{
6073 MOVFragment *frag = &c->fragment;
6074 MOVTrackExt *trex = NULL;
6075 int flags, track_id, i;
6076 MOVFragmentStreamInfo * frag_stream_info;
6077
6078 avio_r8(pb); /* version */
6079 flags = avio_rb24(pb);
6080
6081 track_id = avio_rb32(pb);
6082 if (!track_id)
6083 return AVERROR_INVALIDDATA;
6084 for (i = 0; i < c->trex_count; i++)
6085 if (c->trex_data[i].track_id == track_id) {
6086 trex = &c->trex_data[i];
6087 break;
6088 }
6089 if (!trex) {
6090 av_log(c->fc, AV_LOG_WARNING, "could not find corresponding trex (id %u)\n", track_id);
6091 return 0;
6092 }
6093 c->fragment.found_tfhd = 1;
6094 frag->track_id = track_id;
6095 set_frag_stream(&c->frag_index, track_id);
6096
6099 frag->moof_offset : frag->implicit_offset;
6100 frag->stsd_id = flags & MOV_TFHD_STSD_ID ? avio_rb32(pb) : trex->stsd_id;
6101
6103 avio_rb32(pb) : trex->duration;
6104 frag->size = flags & MOV_TFHD_DEFAULT_SIZE ?
6105 avio_rb32(pb) : trex->size;
6107 avio_rb32(pb) : trex->flags;
6108 av_log(c->fc, AV_LOG_TRACE, "frag flags 0x%x\n", frag->flags);
6109
6110 frag_stream_info = get_current_frag_stream_info(&c->frag_index);
6111 if (frag_stream_info) {
6112 frag_stream_info->next_trun_dts = AV_NOPTS_VALUE;
6113 frag_stream_info->stsd_id = frag->stsd_id;
6114 }
6115 return 0;
6116}
6117
6119{
6120 unsigned i, num;
6121 void *new_tracks;
6122
6123 num = atom.size / 4;
6124 if (!(new_tracks = av_malloc_array(num, sizeof(int))))
6125 return AVERROR(ENOMEM);
6126
6127 av_free(c->chapter_tracks);
6128 c->chapter_tracks = new_tracks;
6129 c->nb_chapter_tracks = num;
6130
6131 for (i = 0; i < num && !pb->eof_reached; i++)
6132 c->chapter_tracks[i] = avio_rb32(pb);
6133
6134 c->nb_chapter_tracks = i;
6135
6136 return 0;
6137}
6138
6140{
6141 MOVTrackExt *trex;
6142 int err;
6143
6144 if ((uint64_t)c->trex_count+1 >= UINT_MAX / sizeof(*c->trex_data))
6145 return AVERROR_INVALIDDATA;
6146 if ((err = av_reallocp_array(&c->trex_data, c->trex_count + 1,
6147 sizeof(*c->trex_data))) < 0) {
6148 c->trex_count = 0;
6149 return err;
6150 }
6151
6152 c->fc->duration = AV_NOPTS_VALUE; // the duration from mvhd is not representing the whole file when fragments are used.
6153
6154 trex = &c->trex_data[c->trex_count++];
6155 avio_r8(pb); /* version */
6156 avio_rb24(pb); /* flags */
6157 trex->track_id = avio_rb32(pb);
6158 trex->stsd_id = avio_rb32(pb);
6159 trex->duration = avio_rb32(pb);
6160 trex->size = avio_rb32(pb);
6161 trex->flags = avio_rb32(pb);
6162 return 0;
6163}
6164
6166{
6167 MOVFragment *frag = &c->fragment;
6168 AVStream *st = NULL;
6169 MOVStreamContext *sc;
6170 int version, i;
6171 MOVFragmentStreamInfo * frag_stream_info;
6172 int64_t base_media_decode_time;
6173
6174 for (i = 0; i < c->fc->nb_streams; i++) {
6175 sc = c->fc->streams[i]->priv_data;
6176 if (sc->id == frag->track_id) {
6177 st = c->fc->streams[i];
6178 break;
6179 }
6180 }
6181 if (!st) {
6182 av_log(c->fc, AV_LOG_WARNING, "could not find corresponding track id %u\n", frag->track_id);
6183 return 0;
6184 }
6185 sc = st->priv_data;
6186 if (sc->pseudo_stream_id + 1 != frag->stsd_id && sc->pseudo_stream_id != -1)
6187 return 0;
6188 version = avio_r8(pb);
6189 avio_rb24(pb); /* flags */
6190 if (version) {
6191 base_media_decode_time = avio_rb64(pb);
6192 } else {
6193 base_media_decode_time = avio_rb32(pb);
6194 }
6195
6196 frag_stream_info = get_current_frag_stream_info(&c->frag_index);
6197 if (frag_stream_info)
6198 frag_stream_info->tfdt_dts = base_media_decode_time;
6199 sc->track_end = base_media_decode_time;
6200
6201 return 0;
6202}
6203
6205{
6206 MOVFragment *frag = &c->fragment;
6207 AVStream *st = NULL;
6208 FFStream *sti = NULL;
6209 MOVStreamContext *sc;
6210 MOVTimeToSample *tts_data;
6211 uint64_t offset;
6212 int64_t dts, pts = AV_NOPTS_VALUE;
6213 int data_offset = 0;
6214 unsigned entries, first_sample_flags = frag->flags;
6215 int flags, distance, i;
6216 int64_t prev_dts = AV_NOPTS_VALUE;
6217 int next_frag_index = -1, index_entry_pos;
6218 size_t requested_size;
6219 AVIndexEntry *new_entries;
6220 MOVFragmentStreamInfo * frag_stream_info;
6221
6222 if (!frag->found_tfhd) {
6223 av_log(c->fc, AV_LOG_ERROR, "trun track id unknown, no tfhd was found\n");
6224 return AVERROR_INVALIDDATA;
6225 }
6226
6227 for (i = 0; i < c->fc->nb_streams; i++) {
6228 sc = c->fc->streams[i]->priv_data;
6229 if (sc->id == frag->track_id) {
6230 st = c->fc->streams[i];
6231 sti = ffstream(st);
6232 break;
6233 }
6234 }
6235 if (!st) {
6236 av_log(c->fc, AV_LOG_WARNING, "could not find corresponding track id %u\n", frag->track_id);
6237 return 0;
6238 }
6239 sc = st->priv_data;
6240 if (sc->pseudo_stream_id+1 != frag->stsd_id && sc->pseudo_stream_id != -1)
6241 return 0;
6242
6243 // Find the next frag_index index that has a valid index_entry for
6244 // the current track_id.
6245 //
6246 // A valid index_entry means the trun for the fragment was read
6247 // and it's samples are in index_entries at the given position.
6248 // New index entries will be inserted before the index_entry found.
6249 index_entry_pos = sti->nb_index_entries;
6250 for (i = c->frag_index.current + 1; i < c->frag_index.nb_items; i++) {
6251 frag_stream_info = get_frag_stream_info(&c->frag_index, i, frag->track_id);
6252 if (frag_stream_info && frag_stream_info->index_entry >= 0) {
6253 next_frag_index = i;
6254 index_entry_pos = frag_stream_info->index_entry;
6255 break;
6256 }
6257 }
6258 av_assert0(index_entry_pos <= sti->nb_index_entries);
6259
6260 avio_r8(pb); /* version */
6261 flags = avio_rb24(pb);
6262 entries = avio_rb32(pb);
6263 av_log(c->fc, AV_LOG_TRACE, "flags 0x%x entries %u\n", flags, entries);
6264
6265 /* Explicit zero sizes are bounded by the trun payload. Reject a zero
6266 * default size before allocating or updating the sample index. */
6267 if (entries && !frag->size && !(flags & MOV_TRUN_SAMPLE_SIZE))
6268 return AVERROR_INVALIDDATA;
6269
6270 if ((uint64_t)entries+sc->tts_count >= UINT_MAX/sizeof(*sc->tts_data))
6271 return AVERROR_INVALIDDATA;
6272 if (flags & MOV_TRUN_DATA_OFFSET) data_offset = avio_rb32(pb);
6273 if (flags & MOV_TRUN_FIRST_SAMPLE_FLAGS) first_sample_flags = avio_rb32(pb);
6274
6275 int entry_size = !!(flags & MOV_TRUN_SAMPLE_DURATION) * 4
6276 + !!(flags & MOV_TRUN_SAMPLE_SIZE) * 4
6277 + !!(flags & MOV_TRUN_SAMPLE_FLAGS) * 4
6278 + !!(flags & MOV_TRUN_SAMPLE_CTS) * 4;
6279 int64_t sample_data_size = avio_size(sc->pb);
6280 int64_t max_entries = INT64_MAX;
6281
6282 if (sample_data_size > 0)
6283 max_entries = sample_data_size - sti->nb_index_entries;
6284 if (entry_size) {
6285 int64_t size = sc->pb == pb ? sample_data_size : avio_size(pb);
6286 int64_t pos = avio_tell(pb);
6287 int64_t left = atom.size - 8 - !!(flags & MOV_TRUN_DATA_OFFSET) * 4
6289
6290 if (pos >= 0 && size >= pos)
6291 left = FFMIN(left, size - pos);
6292 max_entries = FFMIN(max_entries, left / entry_size);
6293 }
6294 if (entries > max_entries) {
6295 av_log(c->fc, AV_LOG_ERROR, "trun sample count %u exceeds the %"PRId64" "
6296 "samples the input can hold\n", entries, max_entries);
6297 return AVERROR_INVALIDDATA;
6298 }
6299
6300 frag_stream_info = get_current_frag_stream_info(&c->frag_index);
6301 if (frag_stream_info) {
6302 if (frag_stream_info->next_trun_dts != AV_NOPTS_VALUE) {
6303 dts = frag_stream_info->next_trun_dts - sc->time_offset;
6304 } else if (frag_stream_info->first_tfra_pts != AV_NOPTS_VALUE &&
6305 c->use_mfra_for == FF_MOV_FLAG_MFRA_PTS) {
6306 pts = frag_stream_info->first_tfra_pts;
6307 av_log(c->fc, AV_LOG_DEBUG, "found mfra time %"PRId64
6308 ", using it for pts\n", pts);
6309 } else if (frag_stream_info->first_tfra_pts != AV_NOPTS_VALUE &&
6310 c->use_mfra_for == FF_MOV_FLAG_MFRA_DTS) {
6311 dts = frag_stream_info->first_tfra_pts;
6312 av_log(c->fc, AV_LOG_DEBUG, "found mfra time %"PRId64
6313 ", using it for dts\n", pts);
6314 } else {
6315 int has_tfdt = frag_stream_info->tfdt_dts != AV_NOPTS_VALUE;
6316 int has_sidx = frag_stream_info->sidx_pts != AV_NOPTS_VALUE;
6317 int fallback_tfdt = !c->use_tfdt && !has_sidx && has_tfdt;
6318 int fallback_sidx = c->use_tfdt && !has_tfdt && has_sidx;
6319
6320 if (fallback_sidx) {
6321 av_log(c->fc, AV_LOG_DEBUG, "use_tfdt set but no tfdt found, using sidx instead\n");
6322 }
6323 if (fallback_tfdt) {
6324 av_log(c->fc, AV_LOG_DEBUG, "use_tfdt not set but no sidx found, using tfdt instead\n");
6325 }
6326
6327 if (has_tfdt && c->use_tfdt || fallback_tfdt) {
6328 dts = frag_stream_info->tfdt_dts - sc->time_offset;
6329 av_log(c->fc, AV_LOG_DEBUG, "found tfdt time %"PRId64
6330 ", using it for dts\n", dts);
6331 } else if (has_sidx && !c->use_tfdt || fallback_sidx) {
6332 // FIXME: sidx earliest_presentation_time is *PTS*, s.b.
6333 // pts = frag_stream_info->sidx_pts;
6334 dts = frag_stream_info->sidx_pts;
6335 av_log(c->fc, AV_LOG_DEBUG, "found sidx time %"PRId64
6336 ", using it for dts\n", frag_stream_info->sidx_pts);
6337 } else {
6338 dts = sc->track_end - sc->time_offset;
6339 av_log(c->fc, AV_LOG_DEBUG, "found track end time %"PRId64
6340 ", using it for dts\n", dts);
6341 }
6342 }
6343 } else {
6344 dts = sc->track_end - sc->time_offset;
6345 av_log(c->fc, AV_LOG_DEBUG, "found track end time %"PRId64
6346 ", using it for dts\n", dts);
6347 }
6348 offset = frag->base_data_offset + data_offset;
6349 distance = 0;
6350 av_log(c->fc, AV_LOG_TRACE, "first sample flags 0x%x\n", first_sample_flags);
6351
6352 // realloc space for new index entries
6353 if ((uint64_t)sti->nb_index_entries + entries >= UINT_MAX / sizeof(AVIndexEntry)) {
6354 entries = UINT_MAX / sizeof(AVIndexEntry) - sti->nb_index_entries;
6355 av_log(c->fc, AV_LOG_ERROR, "Failed to add index entry\n");
6356 }
6357 if (entries == 0)
6358 return 0;
6359
6360 requested_size = (sti->nb_index_entries + entries) * sizeof(AVIndexEntry);
6361 new_entries = av_fast_realloc(sti->index_entries,
6363 requested_size);
6364 if (!new_entries)
6365 return AVERROR(ENOMEM);
6366 sti->index_entries= new_entries;
6367
6368 requested_size = (sti->nb_index_entries + entries) * sizeof(*sc->tts_data);
6369 tts_data = av_fast_realloc(sc->tts_data, &sc->tts_allocated_size,
6370 requested_size);
6371 if (!tts_data)
6372 return AVERROR(ENOMEM);
6373 sc->tts_data = tts_data;
6374
6375 // In case there were samples without time to sample entries, ensure they get
6376 // zero valued entries. This ensures clips which mix boxes with and
6377 // without time to sample entries don't pickup uninitialized data.
6378 if (sc->tts_count < sti->nb_index_entries)
6379 memset(sc->tts_data + sc->tts_count, 0,
6380 sizeof(*sc->tts_data) * (sti->nb_index_entries - sc->tts_count));
6381
6382 if (index_entry_pos < sti->nb_index_entries) {
6383 // Make hole in index_entries and tts_data for new samples
6384 memmove(sti->index_entries + index_entry_pos + entries,
6385 sti->index_entries + index_entry_pos,
6386 sizeof(*sti->index_entries) *
6387 (sti->nb_index_entries - index_entry_pos));
6388 memmove(sc->tts_data + index_entry_pos + entries,
6389 sc->tts_data + index_entry_pos,
6390 sizeof(*sc->tts_data) * (sti->nb_index_entries - index_entry_pos));
6391 if (index_entry_pos < sc->current_sample) {
6392 sc->current_sample += entries;
6393 }
6394 }
6395
6396 sti->nb_index_entries += entries;
6397 sc->tts_count = sti->nb_index_entries;
6398 sc->stts_count = sti->nb_index_entries;
6400 sc->ctts_count = sti->nb_index_entries;
6401
6402 // Record the index_entry position in frag_index of this fragment
6403 if (frag_stream_info) {
6404 frag_stream_info->index_entry = index_entry_pos;
6405 if (frag_stream_info->index_base < 0)
6406 frag_stream_info->index_base = index_entry_pos;
6407 }
6408
6409 if (index_entry_pos > 0)
6410 prev_dts = sti->index_entries[index_entry_pos-1].timestamp;
6411
6412 for (i = 0; i < entries && !pb->eof_reached; i++) {
6413 unsigned sample_size = frag->size;
6414 int sample_flags = i ? frag->flags : first_sample_flags;
6415 unsigned sample_duration = frag->duration;
6416 unsigned ctts_duration = 0;
6417 int keyframe = 0;
6418 int index_entry_flags = 0;
6419
6420 if (flags & MOV_TRUN_SAMPLE_DURATION) sample_duration = avio_rb32(pb);
6421 if (flags & MOV_TRUN_SAMPLE_SIZE) sample_size = avio_rb32(pb);
6422 if (flags & MOV_TRUN_SAMPLE_FLAGS) sample_flags = avio_rb32(pb);
6423 if (flags & MOV_TRUN_SAMPLE_CTS) ctts_duration = avio_rb32(pb);
6424
6425 if (sample_duration > c->max_stts_delta) {
6426 av_log(c->fc, AV_LOG_WARNING,
6427 "Too large sample duration %u in trun entry %u in st:%d. Clipping to 1.\n",
6428 sample_duration, i, st->index);
6429 sample_duration = 1;
6430 }
6431
6432 mov_update_dts_shift(sc, ctts_duration, c->fc);
6433 if (pts != AV_NOPTS_VALUE) {
6434 dts = pts - sc->dts_shift;
6435 if (flags & MOV_TRUN_SAMPLE_CTS) {
6436 dts -= ctts_duration;
6437 } else {
6438 dts -= sc->time_offset;
6439 }
6440 av_log(c->fc, AV_LOG_DEBUG,
6441 "pts %"PRId64" calculated dts %"PRId64
6442 " sc->dts_shift %d ctts.duration %d"
6443 " sc->time_offset %"PRId64
6444 " flags & MOV_TRUN_SAMPLE_CTS %d\n",
6445 pts, dts,
6446 sc->dts_shift, ctts_duration,
6449 }
6450
6451 keyframe =
6452 !(sample_flags & (MOV_FRAG_SAMPLE_FLAG_IS_NON_SYNC |
6454 if (keyframe) {
6455 distance = 0;
6456 index_entry_flags |= AVINDEX_KEYFRAME;
6457 }
6458 // Fragments can overlap in time. Discard overlapping frames after
6459 // decoding.
6460 if (prev_dts >= dts)
6461 index_entry_flags |= AVINDEX_DISCARD_FRAME;
6462
6463 sti->index_entries[index_entry_pos].pos = offset;
6464 sti->index_entries[index_entry_pos].timestamp = dts;
6465 sti->index_entries[index_entry_pos].size = sample_size;
6466 sti->index_entries[index_entry_pos].min_distance = distance;
6467 sti->index_entries[index_entry_pos].flags = index_entry_flags;
6468
6469 sc->tts_data[index_entry_pos].count = 1;
6470 sc->tts_data[index_entry_pos].offset = ctts_duration;
6471 sc->tts_data[index_entry_pos].duration = sample_duration;
6472 index_entry_pos++;
6473
6474 av_log(c->fc, AV_LOG_TRACE, "AVIndex stream %d, sample %d, offset %"PRIx64", dts %"PRId64", "
6475 "size %u, distance %d, keyframe %d\n", st->index,
6476 index_entry_pos, offset, dts, sample_size, distance, keyframe);
6477 distance++;
6478 if (av_sat_add64(dts, sample_duration) != dts + (uint64_t)sample_duration)
6479 return AVERROR_INVALIDDATA;
6480 dts += sample_duration;
6481 offset += sample_size;
6482 sc->data_size += sample_size;
6483
6484 if (sample_duration <= INT64_MAX - sc->duration_for_fps &&
6485 1 <= INT_MAX - sc->nb_frames_for_fps
6486 ) {
6487 sc->duration_for_fps += sample_duration;
6488 sc->nb_frames_for_fps ++;
6489 }
6490 }
6491 if (frag_stream_info)
6492 frag_stream_info->next_trun_dts = dts + sc->time_offset;
6493 if (i < entries) {
6494 // EOF found before reading all entries. Fix the hole this would
6495 // leave in index_entries and tts_data
6496 int gap = entries - i;
6497 memmove(sti->index_entries + index_entry_pos,
6498 sti->index_entries + index_entry_pos + gap,
6499 sizeof(*sti->index_entries) *
6500 (sti->nb_index_entries - (index_entry_pos + gap)));
6501 memmove(sc->tts_data + index_entry_pos,
6502 sc->tts_data + index_entry_pos + gap,
6503 sizeof(*sc->tts_data) *
6504 (sc->tts_count - (index_entry_pos + gap)));
6505
6506 sti->nb_index_entries -= gap;
6507 sc->tts_count -= gap;
6508 if (index_entry_pos < sc->current_sample) {
6509 sc->current_sample -= gap;
6510 }
6511 entries = i;
6512 }
6513
6514 // The end of this new fragment may overlap in time with the start
6515 // of the next fragment in index_entries. Mark the samples in the next
6516 // fragment that overlap with AVINDEX_DISCARD_FRAME
6517 prev_dts = AV_NOPTS_VALUE;
6518 if (index_entry_pos > 0)
6519 prev_dts = sti->index_entries[index_entry_pos-1].timestamp;
6520 for (int i = index_entry_pos; i < sti->nb_index_entries; i++) {
6521 if (prev_dts < sti->index_entries[i].timestamp)
6522 break;
6524 }
6525
6526 // If a hole was created to insert the new index_entries into,
6527 // the index_entry recorded for all subsequent moof must
6528 // be incremented by the number of entries inserted.
6529 fix_frag_index_entries(&c->frag_index, next_frag_index,
6530 frag->track_id, entries);
6531
6532 if (pb->eof_reached) {
6533 av_log(c->fc, AV_LOG_WARNING, "reached eof, corrupted TRUN atom\n");
6534 return AVERROR_EOF;
6535 }
6536
6537 frag->implicit_offset = offset;
6538
6539 sc->track_end = dts + sc->time_offset;
6540 if (st->duration < sc->track_end)
6541 st->duration = sc->track_end;
6542
6543 return 0;
6544}
6545
6547{
6548 int64_t stream_size = avio_size(pb);
6549 int64_t offset = av_sat_add64(avio_tell(pb), atom.size), pts, timestamp;
6550 uint8_t version, is_complete;
6551 int64_t offadd;
6552 unsigned i, j, track_id, item_count;
6553 AVStream *st = NULL;
6554 AVStream *ref_st = NULL;
6555 MOVStreamContext *sc, *ref_sc = NULL;
6556 AVRational timescale;
6557
6558 version = avio_r8(pb);
6559 if (version > 1) {
6560 avpriv_request_sample(c->fc, "sidx version %u", version);
6561 return 0;
6562 }
6563
6564 avio_rb24(pb); // flags
6565
6566 track_id = avio_rb32(pb); // Reference ID
6567 for (i = 0; i < c->fc->nb_streams; i++) {
6568 sc = c->fc->streams[i]->priv_data;
6569 if (sc->id == track_id) {
6570 st = c->fc->streams[i];
6571 break;
6572 }
6573 }
6574 if (!st) {
6575 av_log(c->fc, AV_LOG_WARNING, "could not find corresponding track id %d\n", track_id);
6576 return 0;
6577 }
6578
6579 sc = st->priv_data;
6580
6581 timescale = av_make_q(1, avio_rb32(pb));
6582
6583 if (timescale.den <= 0) {
6584 av_log(c->fc, AV_LOG_ERROR, "Invalid sidx timescale 1/%d\n", timescale.den);
6585 return AVERROR_INVALIDDATA;
6586 }
6587
6588 if (version == 0) {
6589 pts = avio_rb32(pb);
6590 offadd= avio_rb32(pb);
6591 } else {
6592 pts = avio_rb64(pb);
6593 offadd= avio_rb64(pb);
6594 }
6595 if (av_sat_add64(offset, offadd) != offset + (uint64_t)offadd)
6596 return AVERROR_INVALIDDATA;
6597
6598 offset += (uint64_t)offadd;
6599
6600 avio_rb16(pb); // reserved
6601
6602 item_count = avio_rb16(pb);
6603 if (item_count == 0)
6604 return AVERROR_INVALIDDATA;
6605
6606 for (i = 0; i < item_count; i++) {
6607 int index;
6608 MOVFragmentStreamInfo * frag_stream_info;
6609 uint32_t size = avio_rb32(pb);
6610 uint32_t duration = avio_rb32(pb);
6611 if (size & 0x80000000) {
6612 avpriv_request_sample(c->fc, "sidx reference_type 1");
6613 return AVERROR_PATCHWELCOME;
6614 }
6615 avio_rb32(pb); // sap_flags
6616 timestamp = av_rescale_q(pts, timescale, st->time_base);
6617
6619 frag_stream_info = get_frag_stream_info(&c->frag_index, index, track_id);
6620 if (frag_stream_info)
6621 frag_stream_info->sidx_pts = timestamp;
6622
6623 if (av_sat_add64(offset, size) != offset + (uint64_t)size ||
6624 av_sat_add64(pts, duration) != pts + (uint64_t)duration
6625 )
6626 return AVERROR_INVALIDDATA;
6627 offset += size;
6628 pts += duration;
6629 }
6630
6631 st->duration = sc->track_end = pts;
6632
6633 sc->has_sidx = 1;
6634
6635 // See if the remaining bytes are just an mfra which we can ignore.
6636 is_complete = offset == stream_size;
6637 if (!is_complete && (pb->seekable & AVIO_SEEKABLE_NORMAL) && stream_size > 0 ) {
6638 int64_t ret;
6639 int64_t original_pos = avio_tell(pb);
6640 if (!c->have_read_mfra_size) {
6641 if ((ret = avio_seek(pb, stream_size - 4, SEEK_SET)) < 0)
6642 return ret;
6643 c->mfra_size = avio_rb32(pb);
6644 c->have_read_mfra_size = 1;
6645 if ((ret = avio_seek(pb, original_pos, SEEK_SET)) < 0)
6646 return ret;
6647 }
6648 if (offset == stream_size - c->mfra_size)
6649 is_complete = 1;
6650 }
6651
6652 if (is_complete) {
6653 // Find first entry in fragment index that came from an sidx.
6654 // This will pretty much always be the first entry.
6655 for (i = 0; i < c->frag_index.nb_items; i++) {
6656 MOVFragmentIndexItem * item = &c->frag_index.item[i];
6657 for (j = 0; ref_st == NULL && j < item->nb_stream_info; j++) {
6659 si = &item->stream_info[j];
6660 if (si->sidx_pts != AV_NOPTS_VALUE) {
6661 ref_st = c->fc->streams[j];
6662 ref_sc = ref_st->priv_data;
6663 break;
6664 }
6665 }
6666 }
6667 if (ref_st) for (i = 0; i < c->fc->nb_streams; i++) {
6668 st = c->fc->streams[i];
6669 sc = st->priv_data;
6670 if (!sc->has_sidx) {
6671 st->duration = sc->track_end = av_rescale(ref_st->duration, sc->time_scale, ref_sc->time_scale);
6672 }
6673 }
6674
6675 if (offadd == 0)
6676 c->frag_index.complete = 1;
6677 }
6678
6679 return 0;
6680}
6681
6682/* this atom should be null (from specs), but some buggy files put the 'moov' atom inside it... */
6683/* like the files created with Adobe Premiere 5.0, for samples see */
6684/* http://graphics.tudelft.nl/~wouter/publications/soundtests/ */
6686{
6687 int err;
6688
6689 if (atom.size < 8)
6690 return 0; /* continue */
6691 if (avio_rb32(pb) != 0) { /* 0 sized mdat atom... use the 'wide' atom size */
6692 avio_skip(pb, atom.size - 4);
6693 return 0;
6694 }
6695 atom.type = avio_rl32(pb);
6696 atom.size -= 8;
6697 if (atom.type != MKTAG('m','d','a','t')) {
6698 avio_skip(pb, atom.size);
6699 return 0;
6700 }
6701 err = mov_read_mdat(c, pb, atom);
6702 return err;
6703}
6704
6706{
6707#if CONFIG_ZLIB
6709 uint8_t *cmov_data;
6710 uint8_t *moov_data; /* uncompressed data */
6711 long cmov_len, moov_len;
6712 int ret = -1;
6713
6714 avio_rb32(pb); /* dcom atom */
6715 if (avio_rl32(pb) != MKTAG('d','c','o','m'))
6716 return AVERROR_INVALIDDATA;
6717 if (avio_rl32(pb) != MKTAG('z','l','i','b')) {
6718 av_log(c->fc, AV_LOG_ERROR, "unknown compression for cmov atom !\n");
6719 return AVERROR_INVALIDDATA;
6720 }
6721 avio_rb32(pb); /* cmvd atom */
6722 if (avio_rl32(pb) != MKTAG('c','m','v','d'))
6723 return AVERROR_INVALIDDATA;
6724 moov_len = avio_rb32(pb); /* uncompressed size */
6725 cmov_len = atom.size - 6 * 4;
6726
6727 cmov_data = av_malloc(cmov_len);
6728 if (!cmov_data)
6729 return AVERROR(ENOMEM);
6730 moov_data = av_malloc(moov_len);
6731 if (!moov_data) {
6732 av_free(cmov_data);
6733 return AVERROR(ENOMEM);
6734 }
6735 ret = ffio_read_size(pb, cmov_data, cmov_len);
6736 if (ret < 0)
6737 goto free_and_return;
6738
6739 ret = AVERROR_INVALIDDATA;
6740 if (uncompress (moov_data, (uLongf *) &moov_len, (const Bytef *)cmov_data, cmov_len) != Z_OK)
6741 goto free_and_return;
6742 ffio_init_read_context(&ctx, moov_data, moov_len);
6743 ctx.pub.seekable = AVIO_SEEKABLE_NORMAL;
6744 atom.type = MKTAG('m','o','o','v');
6745 atom.size = moov_len;
6746 ret = mov_read_default(c, &ctx.pub, atom);
6747free_and_return:
6748 av_free(moov_data);
6749 av_free(cmov_data);
6750 return ret;
6751#else
6752 av_log(c->fc, AV_LOG_ERROR, "this file requires zlib support compiled in\n");
6753 return AVERROR(ENOSYS);
6754#endif
6755}
6756
6757/* edit list atom */
6759{
6760 MOVStreamContext *sc;
6761 int i, edit_count, version;
6762 int64_t elst_entry_size;
6763
6764 if (c->fc->nb_streams < 1 || c->ignore_editlist)
6765 return 0;
6766 sc = c->fc->streams[c->fc->nb_streams-1]->priv_data;
6767
6768 version = avio_r8(pb); /* version */
6769 avio_rb24(pb); /* flags */
6770 edit_count = avio_rb32(pb); /* entries */
6771 atom.size -= 8;
6772
6773 elst_entry_size = version == 1 ? 20 : 12;
6774 if (atom.size != edit_count * elst_entry_size) {
6775 if (c->fc->strict_std_compliance >= FF_COMPLIANCE_STRICT) {
6776 av_log(c->fc, AV_LOG_ERROR, "Invalid edit list entry_count: %d for elst atom of size: %"PRId64" bytes.\n",
6777 edit_count, atom.size + 8);
6778 return AVERROR_INVALIDDATA;
6779 } else {
6780 edit_count = atom.size / elst_entry_size;
6781 if (edit_count * elst_entry_size != atom.size) {
6782 av_log(c->fc, AV_LOG_WARNING, "ELST atom of %"PRId64" bytes, bigger than %d entries.\n", atom.size, edit_count);
6783 }
6784 }
6785 }
6786
6787 if (!edit_count)
6788 return 0;
6789 if (sc->elst_data)
6790 av_log(c->fc, AV_LOG_WARNING, "Duplicated ELST atom\n");
6791 av_free(sc->elst_data);
6792 sc->elst_count = 0;
6793 sc->elst_data = av_malloc_array(edit_count, sizeof(*sc->elst_data));
6794 if (!sc->elst_data)
6795 return AVERROR(ENOMEM);
6796
6797 av_log(c->fc, AV_LOG_TRACE, "track[%u].edit_count = %i\n", c->fc->nb_streams - 1, edit_count);
6798 for (i = 0; i < edit_count && atom.size > 0 && !pb->eof_reached; i++) {
6799 MOVElst *e = &sc->elst_data[i];
6800
6801 if (version == 1) {
6802 e->duration = avio_rb64(pb);
6803 e->time = avio_rb64(pb);
6804 atom.size -= 16;
6805 } else {
6806 e->duration = avio_rb32(pb); /* segment duration */
6807 e->time = (int32_t)avio_rb32(pb); /* media time */
6808 atom.size -= 8;
6809 }
6810 e->rate = avio_rb32(pb) / 65536.0;
6811 atom.size -= 4;
6812 av_log(c->fc, AV_LOG_TRACE, "duration=%"PRId64" time=%"PRId64" rate=%f\n",
6813 e->duration, e->time, e->rate);
6814
6815 if (e->time < 0 && e->time != -1 &&
6816 c->fc->strict_std_compliance >= FF_COMPLIANCE_STRICT) {
6817 av_log(c->fc, AV_LOG_ERROR, "Track %d, edit %d: Invalid edit list media time=%"PRId64"\n",
6818 c->fc->nb_streams-1, i, e->time);
6819 return AVERROR_INVALIDDATA;
6820 }
6821 if (e->duration < 0) {
6822 av_log(c->fc, AV_LOG_ERROR, "Track %d, edit %d: Invalid edit list duration=%"PRId64"\n",
6823 c->fc->nb_streams-1, i, e->duration);
6824 return AVERROR_INVALIDDATA;
6825 }
6826 }
6827 sc->elst_count = i;
6828
6829 return 0;
6830}
6831
6833{
6834 MOVStreamContext *sc;
6835 int err;
6836
6837 if (c->fc->nb_streams < 1)
6838 return AVERROR_INVALIDDATA;
6839 sc = c->fc->streams[c->fc->nb_streams - 1]->priv_data;
6840
6841 if (atom.size % sizeof(uint32_t))
6842 return AVERROR_INVALIDDATA;
6843
6844 MovTref *tag = mov_add_tref_tag(sc, atom.type);
6845 if (!tag)
6846 return AVERROR(ENOMEM);
6847
6848 int nb_timecode_track = atom.size >> 2;
6849 for (int i = 0; i < nb_timecode_track; i++) {
6850 if (avio_feof(pb))
6851 return AVERROR_INVALIDDATA;
6852 err = mov_add_tref_id(tag, avio_rb32(pb));
6853 if (err < 0)
6854 return err;
6855 }
6856
6857 return 0;
6858}
6859
6861{
6862 AVStream *st;
6863 int version, color_range, color_primaries, color_trc, color_space;
6864
6865 if (c->fc->nb_streams < 1)
6866 return 0;
6867 st = c->fc->streams[c->fc->nb_streams - 1];
6868
6869 if (atom.size < 5) {
6870 av_log(c->fc, AV_LOG_ERROR, "Empty VP Codec Configuration box\n");
6871 return AVERROR_INVALIDDATA;
6872 }
6873
6874 version = avio_r8(pb);
6875 if (version != 1) {
6876 av_log(c->fc, AV_LOG_WARNING, "Unsupported VP Codec Configuration box version %d\n", version);
6877 return 0;
6878 }
6879 avio_skip(pb, 3); /* flags */
6880
6881 avio_skip(pb, 2); /* profile + level */
6882 color_range = avio_r8(pb); /* bitDepth, chromaSubsampling, videoFullRangeFlag */
6884 color_trc = avio_r8(pb);
6885 color_space = avio_r8(pb);
6886 if (avio_rb16(pb)) /* codecIntializationDataSize */
6887 return AVERROR_INVALIDDATA;
6888
6891 if (!av_color_transfer_name(color_trc))
6892 color_trc = AVCOL_TRC_UNSPECIFIED;
6893 if (!av_color_space_name(color_space))
6894 color_space = AVCOL_SPC_UNSPECIFIED;
6895
6898 st->codecpar->color_trc = color_trc;
6899 st->codecpar->color_space = color_space;
6900
6901 return 0;
6902}
6903
6905{
6906 MOVStreamContext *sc;
6907 int i, version;
6908
6909 if (c->fc->nb_streams < 1)
6910 return AVERROR_INVALIDDATA;
6911
6912 sc = c->fc->streams[c->fc->nb_streams - 1]->priv_data;
6913
6914 if (atom.size < 5) {
6915 av_log(c->fc, AV_LOG_ERROR, "Empty Mastering Display Metadata box\n");
6916 return AVERROR_INVALIDDATA;
6917 }
6918
6919 version = avio_r8(pb);
6920 if (version) {
6921 av_log(c->fc, AV_LOG_WARNING, "Unsupported Mastering Display Metadata box version %d\n", version);
6922 return 0;
6923 }
6924 if (sc->mastering) {
6925 av_log(c->fc, AV_LOG_WARNING, "Ignoring duplicate Mastering Display Metadata\n");
6926 return 0;
6927 }
6928
6929 avio_skip(pb, 3); /* flags */
6930
6932 if (!sc->mastering)
6933 return AVERROR(ENOMEM);
6934
6935 for (i = 0; i < 3; i++) {
6936 sc->mastering->display_primaries[i][0] = av_make_q(avio_rb16(pb), 1 << 16);
6937 sc->mastering->display_primaries[i][1] = av_make_q(avio_rb16(pb), 1 << 16);
6938 }
6939 sc->mastering->white_point[0] = av_make_q(avio_rb16(pb), 1 << 16);
6940 sc->mastering->white_point[1] = av_make_q(avio_rb16(pb), 1 << 16);
6941
6942 sc->mastering->max_luminance = av_make_q(avio_rb32(pb), 1 << 8);
6943 sc->mastering->min_luminance = av_make_q(avio_rb32(pb), 1 << 14);
6944
6945 sc->mastering->has_primaries = 1;
6946 sc->mastering->has_luminance = 1;
6947
6948 return 0;
6949}
6950
6952{
6953 MOVStreamContext *sc;
6954 const int mapping[3] = {1, 2, 0};
6955 const int chroma_den = 50000;
6956 const int luma_den = 10000;
6957 int i;
6958
6959 if (c->fc->nb_streams < 1)
6960 return AVERROR_INVALIDDATA;
6961
6962 sc = c->fc->streams[c->fc->nb_streams - 1]->priv_data;
6963
6964 if (atom.size < 24) {
6965 av_log(c->fc, AV_LOG_ERROR, "Invalid Mastering Display Color Volume box\n");
6966 return AVERROR_INVALIDDATA;
6967 }
6968
6969 if (sc->mastering) {
6970 av_log(c->fc, AV_LOG_WARNING, "Ignoring duplicate Mastering Display Color Volume\n");
6971 return 0;
6972 }
6973
6975 if (!sc->mastering)
6976 return AVERROR(ENOMEM);
6977
6978 for (i = 0; i < 3; i++) {
6979 const int j = mapping[i];
6980 sc->mastering->display_primaries[j][0] = av_make_q(avio_rb16(pb), chroma_den);
6981 sc->mastering->display_primaries[j][1] = av_make_q(avio_rb16(pb), chroma_den);
6982 }
6983 sc->mastering->white_point[0] = av_make_q(avio_rb16(pb), chroma_den);
6984 sc->mastering->white_point[1] = av_make_q(avio_rb16(pb), chroma_den);
6985
6986 sc->mastering->max_luminance = av_make_q(avio_rb32(pb), luma_den);
6987 sc->mastering->min_luminance = av_make_q(avio_rb32(pb), luma_den);
6988
6989 sc->mastering->has_luminance = 1;
6990 sc->mastering->has_primaries = 1;
6991
6992 return 0;
6993}
6994
6996{
6997 MOVStreamContext *sc;
6998 int version;
6999
7000 if (c->fc->nb_streams < 1)
7001 return AVERROR_INVALIDDATA;
7002
7003 sc = c->fc->streams[c->fc->nb_streams - 1]->priv_data;
7004
7005 if (atom.size < 5) {
7006 av_log(c->fc, AV_LOG_ERROR, "Empty Content Light Level box\n");
7007 return AVERROR_INVALIDDATA;
7008 }
7009
7010 version = avio_r8(pb);
7011 if (version) {
7012 av_log(c->fc, AV_LOG_WARNING, "Unsupported Content Light Level box version %d\n", version);
7013 return 0;
7014 }
7015 avio_skip(pb, 3); /* flags */
7016
7017 if (sc->coll){
7018 av_log(c->fc, AV_LOG_WARNING, "Ignoring duplicate COLL\n");
7019 return 0;
7020 }
7021
7023 if (!sc->coll)
7024 return AVERROR(ENOMEM);
7025
7026 sc->coll->MaxCLL = avio_rb16(pb);
7027 sc->coll->MaxFALL = avio_rb16(pb);
7028
7029 return 0;
7030}
7031
7033{
7034 MOVStreamContext *sc;
7035
7036 if (c->fc->nb_streams < 1)
7037 return AVERROR_INVALIDDATA;
7038
7039 sc = c->fc->streams[c->fc->nb_streams - 1]->priv_data;
7040
7041 if (atom.size < 4) {
7042 av_log(c->fc, AV_LOG_ERROR, "Empty Content Light Level Info box\n");
7043 return AVERROR_INVALIDDATA;
7044 }
7045
7046 if (sc->coll){
7047 av_log(c->fc, AV_LOG_WARNING, "Ignoring duplicate CLLI/COLL\n");
7048 return 0;
7049 }
7050
7052 if (!sc->coll)
7053 return AVERROR(ENOMEM);
7054
7055 sc->coll->MaxCLL = avio_rb16(pb);
7056 sc->coll->MaxFALL = avio_rb16(pb);
7057
7058 return 0;
7059}
7060
7062{
7063 MOVStreamContext *sc;
7064 const int illuminance_den = 10000;
7065 const int ambient_den = 50000;
7066 if (c->fc->nb_streams < 1)
7067 return AVERROR_INVALIDDATA;
7068 sc = c->fc->streams[c->fc->nb_streams - 1]->priv_data;
7069 if (atom.size < 6) {
7070 av_log(c->fc, AV_LOG_ERROR, "Empty Ambient Viewing Environment Info box\n");
7071 return AVERROR_INVALIDDATA;
7072 }
7073 if (sc->ambient){
7074 av_log(c->fc, AV_LOG_WARNING, "Ignoring duplicate AMVE\n");
7075 return 0;
7076 }
7078 if (!sc->ambient)
7079 return AVERROR(ENOMEM);
7080 sc->ambient->ambient_illuminance = av_make_q(avio_rb32(pb), illuminance_den);
7081 sc->ambient->ambient_light_x = av_make_q(avio_rb16(pb), ambient_den);
7082 sc->ambient->ambient_light_y = av_make_q(avio_rb16(pb), ambient_den);
7083 return 0;
7084}
7085
7087{
7088 AVStream *st;
7089 MOVStreamContext *sc;
7090 enum AVStereo3DType type;
7091 int mode;
7092
7093 if (c->fc->nb_streams < 1)
7094 return 0;
7095
7096 st = c->fc->streams[c->fc->nb_streams - 1];
7097 sc = st->priv_data;
7098
7099 if (atom.size < 5) {
7100 av_log(c->fc, AV_LOG_ERROR, "Empty stereoscopic video box\n");
7101 return AVERROR_INVALIDDATA;
7102 }
7103
7104 if (sc->stereo3d)
7105 return AVERROR_INVALIDDATA;
7106
7107 avio_skip(pb, 4); /* version + flags */
7108
7109 mode = avio_r8(pb);
7110 switch (mode) {
7111 case 0:
7113 break;
7114 case 1:
7116 break;
7117 case 2:
7119 break;
7120 default:
7121 av_log(c->fc, AV_LOG_WARNING, "Unknown st3d mode value %d\n", mode);
7122 return 0;
7123 }
7124
7126 if (!sc->stereo3d)
7127 return AVERROR(ENOMEM);
7128
7129 sc->stereo3d->type = type;
7130 return 0;
7131}
7132
7134{
7135 AVStream *st;
7136 MOVStreamContext *sc;
7137 int size = 0;
7138 int64_t remaining;
7139 uint32_t tag = 0;
7141
7142 if (c->fc->nb_streams < 1)
7143 return 0;
7144
7145 st = c->fc->streams[c->fc->nb_streams - 1];
7146 sc = st->priv_data;
7147
7148 remaining = atom.size;
7149 while (remaining > 0) {
7150 size = avio_rb32(pb);
7151 if (size < 8 || size > remaining ) {
7152 av_log(c->fc, AV_LOG_ERROR, "Invalid child size in pack box\n");
7153 return AVERROR_INVALIDDATA;
7154 }
7155
7156 tag = avio_rl32(pb);
7157 switch (tag) {
7158 case MKTAG('p','k','i','n'): {
7159 if (size != 16) {
7160 av_log(c->fc, AV_LOG_ERROR, "Invalid size of pkin box: %d\n", size);
7161 return AVERROR_INVALIDDATA;
7162 }
7163 avio_skip(pb, 1); // version
7164 avio_skip(pb, 3); // flags
7165
7166 tag = avio_rl32(pb);
7167 switch (tag) {
7168 case MKTAG('s','i','d','e'):
7170 break;
7171 case MKTAG('o','v','e','r'):
7173 break;
7174 case 0:
7175 // This means value will be set in another layer
7176 break;
7177 default:
7178 av_log(c->fc, AV_LOG_WARNING, "Unknown tag in pkin: %s\n",
7180 avio_skip(pb, size - 8);
7181 break;
7182 }
7183
7184 break;
7185 }
7186 default:
7187 av_log(c->fc, AV_LOG_WARNING, "Unknown tag in pack: %s\n",
7189 avio_skip(pb, size - 8);
7190 break;
7191 }
7192 remaining -= size;
7193 }
7194
7195 if (remaining != 0) {
7196 av_log(c->fc, AV_LOG_ERROR, "Broken pack box\n");
7197 return AVERROR_INVALIDDATA;
7198 }
7199
7200 if (type == AV_STEREO3D_2D)
7201 return 0;
7202
7203 if (!sc->stereo3d) {
7205 if (!sc->stereo3d)
7206 return AVERROR(ENOMEM);
7207 }
7208
7209 sc->stereo3d->type = type;
7210
7211 return 0;
7212}
7213
7215{
7216 AVStream *st;
7217 MOVStreamContext *sc;
7218 int size, version, layout;
7219 int32_t yaw, pitch, roll;
7220 uint32_t l = 0, t = 0, r = 0, b = 0;
7221 uint32_t tag, padding = 0;
7222 enum AVSphericalProjection projection;
7223
7224 if (c->fc->nb_streams < 1)
7225 return 0;
7226
7227 st = c->fc->streams[c->fc->nb_streams - 1];
7228 sc = st->priv_data;
7229
7230 if (atom.size < 8) {
7231 av_log(c->fc, AV_LOG_ERROR, "Empty spherical video box\n");
7232 return AVERROR_INVALIDDATA;
7233 }
7234
7235 size = avio_rb32(pb);
7236 if (size <= 12 || size > atom.size)
7237 return AVERROR_INVALIDDATA;
7238
7239 tag = avio_rl32(pb);
7240 if (tag != MKTAG('s','v','h','d')) {
7241 av_log(c->fc, AV_LOG_ERROR, "Missing spherical video header\n");
7242 return 0;
7243 }
7244 version = avio_r8(pb);
7245 if (version != 0) {
7246 av_log(c->fc, AV_LOG_WARNING, "Unknown spherical version %d\n",
7247 version);
7248 return 0;
7249 }
7250 avio_skip(pb, 3); /* flags */
7251 avio_skip(pb, size - 12); /* metadata_source */
7252
7253 size = avio_rb32(pb);
7254 if (size > atom.size)
7255 return AVERROR_INVALIDDATA;
7256
7257 tag = avio_rl32(pb);
7258 if (tag != MKTAG('p','r','o','j')) {
7259 av_log(c->fc, AV_LOG_ERROR, "Missing projection box\n");
7260 return 0;
7261 }
7262
7263 size = avio_rb32(pb);
7264 if (size > atom.size)
7265 return AVERROR_INVALIDDATA;
7266
7267 tag = avio_rl32(pb);
7268 if (tag != MKTAG('p','r','h','d')) {
7269 av_log(c->fc, AV_LOG_ERROR, "Missing projection header box\n");
7270 return 0;
7271 }
7272 version = avio_r8(pb);
7273 if (version != 0) {
7274 av_log(c->fc, AV_LOG_WARNING, "Unknown spherical version %d\n",
7275 version);
7276 return 0;
7277 }
7278 avio_skip(pb, 3); /* flags */
7279
7280 /* 16.16 fixed point */
7281 yaw = avio_rb32(pb);
7282 pitch = avio_rb32(pb);
7283 roll = avio_rb32(pb);
7284
7285 size = avio_rb32(pb);
7286 if (size > atom.size)
7287 return AVERROR_INVALIDDATA;
7288
7289 tag = avio_rl32(pb);
7290 version = avio_r8(pb);
7291 if (version != 0) {
7292 av_log(c->fc, AV_LOG_WARNING, "Unknown spherical version %d\n",
7293 version);
7294 return 0;
7295 }
7296 avio_skip(pb, 3); /* flags */
7297 switch (tag) {
7298 case MKTAG('c','b','m','p'):
7299 layout = avio_rb32(pb);
7300 if (layout) {
7301 av_log(c->fc, AV_LOG_WARNING,
7302 "Unsupported cubemap layout %d\n", layout);
7303 return 0;
7304 }
7305 projection = AV_SPHERICAL_CUBEMAP;
7306 padding = avio_rb32(pb);
7307 break;
7308 case MKTAG('e','q','u','i'):
7309 t = avio_rb32(pb);
7310 b = avio_rb32(pb);
7311 l = avio_rb32(pb);
7312 r = avio_rb32(pb);
7313
7314 if (b >= UINT_MAX - t || r >= UINT_MAX - l) {
7315 av_log(c->fc, AV_LOG_ERROR,
7316 "Invalid bounding rectangle coordinates "
7317 "%"PRIu32",%"PRIu32",%"PRIu32",%"PRIu32"\n", l, t, r, b);
7318 return AVERROR_INVALIDDATA;
7319 }
7320
7321 if (l || t || r || b)
7323 else
7324 projection = AV_SPHERICAL_EQUIRECTANGULAR;
7325 break;
7326 default:
7327 av_log(c->fc, AV_LOG_ERROR, "Unknown projection type: %s\n", av_fourcc2str(tag));
7328 return 0;
7329 }
7330
7332 if (!sc->spherical)
7333 return AVERROR(ENOMEM);
7334
7335 sc->spherical->projection = projection;
7336
7337 sc->spherical->yaw = yaw;
7338 sc->spherical->pitch = pitch;
7339 sc->spherical->roll = roll;
7340
7341 sc->spherical->padding = padding;
7342
7343 sc->spherical->bound_left = l;
7344 sc->spherical->bound_top = t;
7345 sc->spherical->bound_right = r;
7346 sc->spherical->bound_bottom = b;
7347
7348 return 0;
7349}
7350
7352{
7353 AVStream *st;
7354 MOVStreamContext *sc;
7355 int size;
7356 uint32_t tag;
7357 enum AVSphericalProjection projection;
7358
7359 if (c->fc->nb_streams < 1)
7360 return 0;
7361
7362 st = c->fc->streams[c->fc->nb_streams - 1];
7363 sc = st->priv_data;
7364
7365 if (atom.size < 16) {
7366 av_log(c->fc, AV_LOG_ERROR, "Invalid size for proj box: %"PRIu64"\n", atom.size);
7367 return AVERROR_INVALIDDATA;
7368 }
7369
7370 size = avio_rb32(pb);
7371 if (size < 16) {
7372 av_log(c->fc, AV_LOG_ERROR, "Invalid size for prji box: %d\n", size);
7373 return AVERROR_INVALIDDATA;
7374 } else if (size > 16) {
7375 av_log(c->fc, AV_LOG_WARNING, "Box has more bytes (%d) than prji box required (16) \n", size);
7376 }
7377
7378 tag = avio_rl32(pb);
7379 if (tag != MKTAG('p','r','j','i')) {
7380 av_log(c->fc, AV_LOG_ERROR, "Invalid child box of proj box: %s\n",
7382 return AVERROR_INVALIDDATA;
7383 }
7384
7385 // version and flags, only support (0, 0)
7386 unsigned n = avio_rl32(pb);
7387 if (n != 0) {
7388 av_log(c->fc, AV_LOG_ERROR, "prji version %u, flag %u are not supported\n",
7389 n & 0xFF, n >> 8);
7390 return AVERROR_PATCHWELCOME;
7391 }
7392
7393 tag = avio_rl32(pb);
7394 switch (tag) {
7395 case MKTAG('r','e','c','t'):
7396 projection = AV_SPHERICAL_RECTILINEAR;
7397 break;
7398 case MKTAG('e','q','u','i'):
7399 projection = AV_SPHERICAL_EQUIRECTANGULAR;
7400 break;
7401 case MKTAG('h','e','q','u'):
7403 break;
7404 case MKTAG('f','i','s','h'):
7405 projection = AV_SPHERICAL_FISHEYE;
7406 break;
7407 case MKTAG('p','r','i','m'):
7409 break;
7410 default:
7411 av_log(c->fc, AV_LOG_ERROR, "Invalid projection type in prji box: %s\n", av_fourcc2str(tag));
7412 return AVERROR_INVALIDDATA;
7413 }
7414
7416 if (!sc->spherical)
7417 return AVERROR(ENOMEM);
7418
7419 sc->spherical->projection = projection;
7420
7421 return 0;
7422}
7423
7425{
7426 AVStream *st;
7427 MOVStreamContext *sc;
7428 int size, flags = 0;
7429 int64_t remaining;
7430 uint32_t tag, baseline = 0;
7433 enum AVStereo3DPrimaryEye primary_eye = AV_PRIMARY_EYE_NONE;
7434 AVRational horizontal_disparity_adjustment = { 0, 1 };
7435
7436 if (c->fc->nb_streams < 1)
7437 return 0;
7438
7439 st = c->fc->streams[c->fc->nb_streams - 1];
7440 sc = st->priv_data;
7441
7442 remaining = atom.size;
7443 while (remaining > 0) {
7444 size = avio_rb32(pb);
7445 if (size < 8 || size > remaining ) {
7446 av_log(c->fc, AV_LOG_ERROR, "Invalid child size in eyes box\n");
7447 return AVERROR_INVALIDDATA;
7448 }
7449
7450 tag = avio_rl32(pb);
7451 switch (tag) {
7452 case MKTAG('s','t','r','i'): {
7453 int has_right, has_left;
7454 uint8_t tmp;
7455 if (size != 13) {
7456 av_log(c->fc, AV_LOG_ERROR, "Invalid size of stri box: %d\n", size);
7457 return AVERROR_INVALIDDATA;
7458 }
7459 avio_skip(pb, 1); // version
7460 avio_skip(pb, 3); // flags
7461
7462 tmp = avio_r8(pb);
7463
7464 // eye_views_reversed
7465 if (tmp & 8) {
7467 }
7468 // has_additional_views
7469 if (tmp & 4) {
7470 // skip...
7471 }
7472
7473 has_right = tmp & 2; // has_right_eye_view
7474 has_left = tmp & 1; // has_left_eye_view
7475
7476 if (has_left && has_right)
7478 else if (has_left)
7479 view = AV_STEREO3D_VIEW_LEFT;
7480 else if (has_right)
7482 if (has_left || has_right)
7484
7485 break;
7486 }
7487 case MKTAG('h','e','r','o'): {
7488 int tmp;
7489 if (size != 13) {
7490 av_log(c->fc, AV_LOG_ERROR, "Invalid size of hero box: %d\n", size);
7491 return AVERROR_INVALIDDATA;
7492 }
7493 avio_skip(pb, 1); // version
7494 avio_skip(pb, 3); // flags
7495
7496 tmp = avio_r8(pb);
7497 if (tmp == 0)
7498 primary_eye = AV_PRIMARY_EYE_NONE;
7499 else if (tmp == 1)
7500 primary_eye = AV_PRIMARY_EYE_LEFT;
7501 else if (tmp == 2)
7502 primary_eye = AV_PRIMARY_EYE_RIGHT;
7503 else
7504 av_log(c->fc, AV_LOG_WARNING, "Unknown hero eye type: %d\n", tmp);
7505
7506 break;
7507 }
7508 case MKTAG('c','a','m','s'): {
7509 uint32_t subtag;
7510 int subsize;
7511 if (size != 24) {
7512 av_log(c->fc, AV_LOG_ERROR, "Invalid size of cams box: %d\n", size);
7513 return AVERROR_INVALIDDATA;
7514 }
7515
7516 subsize = avio_rb32(pb);
7517 if (subsize != 16) {
7518 av_log(c->fc, AV_LOG_ERROR, "Invalid size of blin box: %d\n", size);
7519 return AVERROR_INVALIDDATA;
7520 }
7521
7522 subtag = avio_rl32(pb);
7523 if (subtag != MKTAG('b','l','i','n')) {
7524 av_log(c->fc, AV_LOG_ERROR, "Expected blin box, got %s\n",
7525 av_fourcc2str(subtag));
7526 return AVERROR_INVALIDDATA;
7527 }
7528
7529 avio_skip(pb, 1); // version
7530 avio_skip(pb, 3); // flags
7531
7532 baseline = avio_rb32(pb);
7533
7534 break;
7535 }
7536 case MKTAG('c','m','f','y'): {
7537 uint32_t subtag;
7538 int subsize;
7539 int32_t adjustment;
7540 if (size != 24) {
7541 av_log(c->fc, AV_LOG_ERROR, "Invalid size of cmfy box: %d\n", size);
7542 return AVERROR_INVALIDDATA;
7543 }
7544
7545 subsize = avio_rb32(pb);
7546 if (subsize != 16) {
7547 av_log(c->fc, AV_LOG_ERROR, "Invalid size of dadj box: %d\n", size);
7548 return AVERROR_INVALIDDATA;
7549 }
7550
7551 subtag = avio_rl32(pb);
7552 if (subtag != MKTAG('d','a','d','j')) {
7553 av_log(c->fc, AV_LOG_ERROR, "Expected dadj box, got %s\n",
7554 av_fourcc2str(subtag));
7555 return AVERROR_INVALIDDATA;
7556 }
7557
7558 avio_skip(pb, 1); // version
7559 avio_skip(pb, 3); // flags
7560
7561 adjustment = (int32_t) avio_rb32(pb);
7562
7563 horizontal_disparity_adjustment.num = (int) adjustment;
7564 horizontal_disparity_adjustment.den = 10000;
7565
7566 break;
7567 }
7568 default:
7569 av_log(c->fc, AV_LOG_WARNING, "Unknown tag in eyes: %s\n",
7571 avio_skip(pb, size - 8);
7572 break;
7573 }
7574 remaining -= size;
7575 }
7576
7577 if (remaining != 0) {
7578 av_log(c->fc, AV_LOG_ERROR, "Broken eyes box\n");
7579 return AVERROR_INVALIDDATA;
7580 }
7581
7582 if (type == AV_STEREO3D_2D)
7583 return 0;
7584
7585 if (!sc->stereo3d) {
7587 if (!sc->stereo3d)
7588 return AVERROR(ENOMEM);
7589 }
7590
7591 sc->stereo3d->flags = flags;
7592 /* eyes/stri only records packed vs single-eye, not SBS/TB. Keep a more
7593 * specific type already set by st3d. */
7594 if (type != AV_STEREO3D_UNSPEC)
7595 sc->stereo3d->type = type;
7596 else if (sc->stereo3d->type == AV_STEREO3D_2D)
7597 sc->stereo3d->type = type;
7598 sc->stereo3d->view = view;
7599 sc->stereo3d->primary_eye = primary_eye;
7600 sc->stereo3d->baseline = baseline;
7601 sc->stereo3d->horizontal_disparity_adjustment = horizontal_disparity_adjustment;
7602
7603 return 0;
7604}
7605
7607{
7608 int size;
7609 int64_t remaining;
7610 uint32_t tag;
7611
7612 if (c->fc->nb_streams < 1)
7613 return 0;
7614
7615 if (atom.size < 8) {
7616 av_log(c->fc, AV_LOG_ERROR, "Empty video extension usage box\n");
7617 return AVERROR_INVALIDDATA;
7618 }
7619
7620 remaining = atom.size;
7621 while (remaining > 0) {
7622 size = avio_rb32(pb);
7623 if (size < 8 || size > remaining ) {
7624 av_log(c->fc, AV_LOG_ERROR, "Invalid child size in vexu box\n");
7625 return AVERROR_INVALIDDATA;
7626 }
7627
7628 tag = avio_rl32(pb);
7629 switch (tag) {
7630 case MKTAG('p','r','o','j'): {
7631 MOVAtom proj = { tag, size - 8 };
7632 int ret = mov_read_vexu_proj(c, pb, proj);
7633 if (ret < 0)
7634 return ret;
7635 break;
7636 }
7637 case MKTAG('e','y','e','s'): {
7638 MOVAtom eyes = { tag, size - 8 };
7639 int ret = mov_read_eyes(c, pb, eyes);
7640 if (ret < 0)
7641 return ret;
7642 break;
7643 }
7644 case MKTAG('p','a','c','k'): {
7645 MOVAtom pack = { tag, size - 8 };
7646 int ret = mov_read_pack(c, pb, pack);
7647 if (ret < 0)
7648 return ret;
7649 break;
7650 }
7651 default:
7652 av_log(c->fc, AV_LOG_WARNING, "Unknown tag in vexu: %s\n",
7654 avio_skip(pb, size - 8);
7655 break;
7656 }
7657 remaining -= size;
7658 }
7659
7660 if (remaining != 0) {
7661 av_log(c->fc, AV_LOG_ERROR, "Broken vexu box\n");
7662 return AVERROR_INVALIDDATA;
7663 }
7664
7665 return 0;
7666}
7667
7669{
7670 AVStream *st;
7671 MOVStreamContext *sc;
7672
7673 if (c->fc->nb_streams < 1)
7674 return 0;
7675
7676 st = c->fc->streams[c->fc->nb_streams - 1];
7677 sc = st->priv_data;
7678
7679 if (atom.size != 4) {
7680 av_log(c->fc, AV_LOG_ERROR, "Invalid size of hfov box: %"PRIu64"\n", atom.size);
7681 return AVERROR_INVALIDDATA;
7682 }
7683
7684
7685 if (!sc->stereo3d) {
7687 if (!sc->stereo3d)
7688 return AVERROR(ENOMEM);
7689 }
7690
7692 sc->stereo3d->horizontal_field_of_view.den = 1000; // thousands of a degree
7693
7694 return 0;
7695}
7696
7698{
7699 int ret = 0;
7700 uint8_t *buffer = av_malloc(len + 1);
7701 const char *val;
7702
7703 if (!buffer)
7704 return AVERROR(ENOMEM);
7705 buffer[len] = '\0';
7706
7707 ret = ffio_read_size(pb, buffer, len);
7708 if (ret < 0)
7709 goto out;
7710
7711 /* Check for mandatory keys and values, try to support XML as best-effort */
7712 if (!sc->spherical &&
7713 av_stristr(buffer, "<GSpherical:StitchingSoftware>") &&
7714 (val = av_stristr(buffer, "<GSpherical:Spherical>")) &&
7715 av_stristr(val, "true") &&
7716 (val = av_stristr(buffer, "<GSpherical:Stitched>")) &&
7717 av_stristr(val, "true") &&
7718 (val = av_stristr(buffer, "<GSpherical:ProjectionType>")) &&
7719 av_stristr(val, "equirectangular")) {
7721 if (!sc->spherical)
7722 goto out;
7723
7725
7726 if (av_stristr(buffer, "<GSpherical:StereoMode>") && !sc->stereo3d) {
7727 enum AVStereo3DType mode;
7728
7729 if (av_stristr(buffer, "left-right"))
7731 else if (av_stristr(buffer, "top-bottom"))
7733 else
7735
7737 if (!sc->stereo3d)
7738 goto out;
7739
7740 sc->stereo3d->type = mode;
7741 }
7742
7743 /* orientation */
7744 val = av_stristr(buffer, "<GSpherical:InitialViewHeadingDegrees>");
7745 if (val)
7746 sc->spherical->yaw = strtol(val, NULL, 10) * (1 << 16);
7747 val = av_stristr(buffer, "<GSpherical:InitialViewPitchDegrees>");
7748 if (val)
7749 sc->spherical->pitch = strtol(val, NULL, 10) * (1 << 16);
7750 val = av_stristr(buffer, "<GSpherical:InitialViewRollDegrees>");
7751 if (val)
7752 sc->spherical->roll = strtol(val, NULL, 10) * (1 << 16);
7753 }
7754
7755out:
7756 av_free(buffer);
7757 return ret;
7758}
7759
7761{
7762 AVStream *st;
7763 MOVStreamContext *sc;
7764 int64_t ret;
7765 AVUUID uuid;
7766 static const AVUUID uuid_isml_manifest = {
7767 0xa5, 0xd4, 0x0b, 0x30, 0xe8, 0x14, 0x11, 0xdd,
7768 0xba, 0x2f, 0x08, 0x00, 0x20, 0x0c, 0x9a, 0x66
7769 };
7770 static const AVUUID uuid_xmp = {
7771 0xbe, 0x7a, 0xcf, 0xcb, 0x97, 0xa9, 0x42, 0xe8,
7772 0x9c, 0x71, 0x99, 0x94, 0x91, 0xe3, 0xaf, 0xac
7773 };
7774 static const AVUUID uuid_spherical = {
7775 0xff, 0xcc, 0x82, 0x63, 0xf8, 0x55, 0x4a, 0x93,
7776 0x88, 0x14, 0x58, 0x7a, 0x02, 0x52, 0x1f, 0xdd,
7777 };
7778
7779 if (atom.size < AV_UUID_LEN || atom.size >= FFMIN(INT_MAX, SIZE_MAX))
7780 return AVERROR_INVALIDDATA;
7781
7782 if (c->fc->nb_streams < 1)
7783 return 0;
7784 st = c->fc->streams[c->fc->nb_streams - 1];
7785 sc = st->priv_data;
7786
7787 ret = ffio_read_size(pb, uuid, AV_UUID_LEN);
7788 if (ret < 0)
7789 return ret;
7790 if (av_uuid_equal(uuid, uuid_isml_manifest)) {
7791 uint8_t *buffer, *ptr;
7792 char *endptr;
7793 size_t len = atom.size - AV_UUID_LEN;
7794
7795 if (len < 4) {
7796 return AVERROR_INVALIDDATA;
7797 }
7798 ret = avio_skip(pb, 4); // zeroes
7799 len -= 4;
7800
7801 buffer = av_mallocz(len + 1);
7802 if (!buffer) {
7803 return AVERROR(ENOMEM);
7804 }
7805 ret = ffio_read_size(pb, buffer, len);
7806 if (ret < 0) {
7807 av_free(buffer);
7808 return ret;
7809 }
7810
7811 ptr = buffer;
7812 while ((ptr = av_stristr(ptr, "systemBitrate=\""))) {
7813 ptr += sizeof("systemBitrate=\"") - 1;
7814 c->bitrates_count++;
7815 c->bitrates = av_realloc_f(c->bitrates, c->bitrates_count, sizeof(*c->bitrates));
7816 if (!c->bitrates) {
7817 c->bitrates_count = 0;
7818 av_free(buffer);
7819 return AVERROR(ENOMEM);
7820 }
7821 errno = 0;
7822 ret = strtol(ptr, &endptr, 10);
7823 if (ret < 0 || errno || *endptr != '"') {
7824 c->bitrates[c->bitrates_count - 1] = 0;
7825 } else {
7826 c->bitrates[c->bitrates_count - 1] = ret;
7827 }
7828 }
7829
7830 av_free(buffer);
7831 } else if (av_uuid_equal(uuid, uuid_xmp)) {
7832 uint8_t *buffer;
7833 size_t len = atom.size - AV_UUID_LEN;
7834 if (c->export_xmp) {
7835 buffer = av_mallocz(len + 1);
7836 if (!buffer) {
7837 return AVERROR(ENOMEM);
7838 }
7839 ret = ffio_read_size(pb, buffer, len);
7840 if (ret < 0) {
7841 av_free(buffer);
7842 return ret;
7843 }
7844 buffer[len] = '\0';
7845 av_dict_set(&c->fc->metadata, "xmp",
7847 } else {
7848 // skip all uuid atom, which makes it fast for long uuid-xmp file
7849 ret = avio_skip(pb, len);
7850 if (ret < 0)
7851 return ret;
7852 }
7853 } else if (av_uuid_equal(uuid, uuid_spherical)) {
7854 size_t len = atom.size - AV_UUID_LEN;
7855 ret = mov_parse_uuid_spherical(sc, pb, len);
7856 if (ret < 0)
7857 return ret;
7858 if (!sc->spherical)
7859 av_log(c->fc, AV_LOG_WARNING, "Invalid spherical metadata found\n");
7860 }
7861
7862 return 0;
7863}
7864
7866{
7867 int ret;
7868 uint8_t content[16];
7869
7870 if (atom.size < 8)
7871 return 0;
7872
7873 ret = ffio_read_size(pb, content, FFMIN(sizeof(content), atom.size));
7874 if (ret < 0)
7875 return ret;
7876
7877 if ( !c->found_moov
7878 && !c->found_mdat
7879 && !memcmp(content, "Anevia\x1A\x1A", 8)
7880 && c->use_mfra_for == FF_MOV_FLAG_MFRA_AUTO) {
7881 c->use_mfra_for = FF_MOV_FLAG_MFRA_PTS;
7882 }
7883
7884 return 0;
7885}
7886
7888{
7889 uint32_t format = avio_rl32(pb);
7890 MOVStreamContext *sc;
7891 enum AVCodecID id;
7892 AVStream *st;
7893
7894 if (c->fc->nb_streams < 1)
7895 return 0;
7896 st = c->fc->streams[c->fc->nb_streams - 1];
7897 sc = st->priv_data;
7898
7899 switch (sc->format)
7900 {
7901 case MKTAG('e','n','c','v'): // encrypted video
7902 case MKTAG('e','n','c','a'): // encrypted audio
7903 id = mov_codec_id(st, format);
7904 if (st->codecpar->codec_id != AV_CODEC_ID_NONE &&
7905 st->codecpar->codec_id != id) {
7906 av_log(c->fc, AV_LOG_WARNING,
7907 "ignoring 'frma' atom of '%.4s', stream has codec id %d\n",
7908 (char*)&format, st->codecpar->codec_id);
7909 break;
7910 }
7911
7912 st->codecpar->codec_id = id;
7913 sc->format = format;
7914 break;
7915
7916 default:
7917 if (format != sc->format) {
7918 av_log(c->fc, AV_LOG_WARNING,
7919 "ignoring 'frma' atom of '%.4s', stream format is '%.4s'\n",
7920 (char*)&format, (char*)&sc->format);
7921 }
7922 break;
7923 }
7924
7925 return 0;
7926}
7927
7928/**
7929 * Gets the current encryption info and associated current stream context. If
7930 * we are parsing a track fragment, this will return the specific encryption
7931 * info for this fragment; otherwise this will return the global encryption
7932 * info for the current stream.
7933 */
7935{
7936 MOVFragmentStreamInfo *frag_stream_info;
7937 AVStream *st;
7938 int i;
7939
7940 frag_stream_info = get_current_frag_stream_info(&c->frag_index);
7941 if (frag_stream_info) {
7942 for (i = 0; i < c->fc->nb_streams; i++) {
7943 *sc = c->fc->streams[i]->priv_data;
7944 if ((*sc)->id == frag_stream_info->id) {
7945 st = c->fc->streams[i];
7946 break;
7947 }
7948 }
7949 if (i == c->fc->nb_streams)
7950 return 0;
7951 *sc = st->priv_data;
7952
7953 if (!frag_stream_info->encryption_index) {
7954 // If this stream isn't encrypted, don't create the index.
7955 if (!(*sc)->cenc.default_encrypted_sample)
7956 return 0;
7957 frag_stream_info->encryption_index = av_mallocz(sizeof(*frag_stream_info->encryption_index));
7958 if (!frag_stream_info->encryption_index)
7959 return AVERROR(ENOMEM);
7960 }
7961 *encryption_index = frag_stream_info->encryption_index;
7962 return 1;
7963 } else {
7964 // No current track fragment, using stream level encryption info.
7965
7966 if (c->fc->nb_streams < 1)
7967 return 0;
7968 st = c->fc->streams[c->fc->nb_streams - 1];
7969 *sc = st->priv_data;
7970
7971 if (!(*sc)->cenc.encryption_index) {
7972 // If this stream isn't encrypted, don't create the index.
7973 if (!(*sc)->cenc.default_encrypted_sample)
7974 return 0;
7975 (*sc)->cenc.encryption_index = av_mallocz(sizeof(*frag_stream_info->encryption_index));
7976 if (!(*sc)->cenc.encryption_index)
7977 return AVERROR(ENOMEM);
7978 }
7979
7980 *encryption_index = (*sc)->cenc.encryption_index;
7981 return 1;
7982 }
7983}
7984
7986{
7987 int i, ret;
7988 unsigned int subsample_count;
7989 AVSubsampleEncryptionInfo *subsamples;
7990
7991 if (!sc->cenc.default_encrypted_sample) {
7992 av_log(c->fc, AV_LOG_ERROR, "Missing schm or tenc\n");
7993 return AVERROR_INVALIDDATA;
7994 }
7995
7996 if (sc->cenc.per_sample_iv_size || use_subsamples) {
7998 if (!*sample)
7999 return AVERROR(ENOMEM);
8000 } else
8001 *sample = NULL;
8002
8003 if (sc->cenc.per_sample_iv_size != 0) {
8004 if ((ret = ffio_read_size(pb, (*sample)->iv, sc->cenc.per_sample_iv_size)) < 0) {
8005 av_log(c->fc, AV_LOG_ERROR, "failed to read the initialization vector\n");
8007 *sample = NULL;
8008 return ret;
8009 }
8010 }
8011
8012 if (use_subsamples) {
8013 subsample_count = avio_rb16(pb);
8014 av_free((*sample)->subsamples);
8015 (*sample)->subsamples = av_calloc(subsample_count, sizeof(*subsamples));
8016 if (!(*sample)->subsamples) {
8018 *sample = NULL;
8019 return AVERROR(ENOMEM);
8020 }
8021
8022 for (i = 0; i < subsample_count && !pb->eof_reached; i++) {
8023 (*sample)->subsamples[i].bytes_of_clear_data = avio_rb16(pb);
8024 (*sample)->subsamples[i].bytes_of_protected_data = avio_rb32(pb);
8025 }
8026
8027 if (pb->eof_reached) {
8028 av_log(c->fc, AV_LOG_ERROR, "hit EOF while reading sub-sample encryption info\n");
8030 *sample = NULL;
8031 return AVERROR_INVALIDDATA;
8032 }
8033 (*sample)->subsample_count = subsample_count;
8034 }
8035
8036 return 0;
8037}
8038
8040{
8041 AVEncryptionInfo **encrypted_samples;
8042 MOVEncryptionIndex *encryption_index;
8043 MOVStreamContext *sc;
8044 int use_subsamples, ret;
8045 unsigned int sample_count, i, alloc_size = 0;
8046
8047 ret = get_current_encryption_info(c, &encryption_index, &sc);
8048 if (ret != 1)
8049 return ret;
8050
8051 if (encryption_index->nb_encrypted_samples) {
8052 // This can happen if we have both saio/saiz and senc atoms.
8053 av_log(c->fc, AV_LOG_DEBUG, "Ignoring duplicate encryption info in senc\n");
8054 return 0;
8055 }
8056
8057 avio_r8(pb); /* version */
8058 use_subsamples = avio_rb24(pb) & 0x02; /* flags */
8059
8060 sample_count = avio_rb32(pb);
8061 if (sample_count >= INT_MAX / sizeof(*encrypted_samples))
8062 return AVERROR(ENOMEM);
8063
8064 for (i = 0; i < sample_count; i++) {
8065 unsigned int min_samples = FFMIN(FFMAX(i + 1, 1024 * 1024), sample_count);
8066 encrypted_samples = av_fast_realloc(encryption_index->encrypted_samples, &alloc_size,
8067 min_samples * sizeof(*encrypted_samples));
8068 if (encrypted_samples) {
8069 encryption_index->encrypted_samples = encrypted_samples;
8070
8072 c, pb, sc, &encryption_index->encrypted_samples[i], use_subsamples);
8073 } else {
8074 ret = AVERROR(ENOMEM);
8075 }
8076 if (pb->eof_reached) {
8077 av_log(c->fc, AV_LOG_ERROR, "Hit EOF while reading senc\n");
8078 if (ret >= 0)
8079 av_encryption_info_free(encryption_index->encrypted_samples[i]);
8080 ret = AVERROR_INVALIDDATA;
8081 }
8082
8083 if (ret < 0) {
8084 for (; i > 0; i--)
8085 av_encryption_info_free(encryption_index->encrypted_samples[i - 1]);
8086 av_freep(&encryption_index->encrypted_samples);
8087 return ret;
8088 }
8089 }
8090 encryption_index->nb_encrypted_samples = sample_count;
8091
8092 return 0;
8093}
8094
8096{
8097 AVEncryptionInfo **sample, **encrypted_samples;
8098 int64_t prev_pos;
8099 size_t sample_count, sample_info_size, i;
8100 int ret = 0;
8101 unsigned int alloc_size = 0;
8102
8103 if (encryption_index->nb_encrypted_samples)
8104 return 0;
8105 sample_count = encryption_index->auxiliary_info_sample_count;
8106 if (encryption_index->auxiliary_offsets_count != 1) {
8107 av_log(c->fc, AV_LOG_ERROR, "Multiple auxiliary info chunks are not supported\n");
8108 return AVERROR_PATCHWELCOME;
8109 }
8110 if (sample_count >= INT_MAX / sizeof(*encrypted_samples))
8111 return AVERROR(ENOMEM);
8112
8113 prev_pos = avio_tell(pb);
8114 if (!(pb->seekable & AVIO_SEEKABLE_NORMAL) ||
8115 avio_seek(pb, encryption_index->auxiliary_offsets[0], SEEK_SET) != encryption_index->auxiliary_offsets[0]) {
8116 av_log(c->fc, AV_LOG_INFO, "Failed to seek for auxiliary info, will only parse senc atoms for encryption info\n");
8117 goto finish;
8118 }
8119
8120 for (i = 0; i < sample_count && !pb->eof_reached; i++) {
8121 unsigned int min_samples = FFMIN(FFMAX(i + 1, 1024 * 1024), sample_count);
8122 encrypted_samples = av_fast_realloc(encryption_index->encrypted_samples, &alloc_size,
8123 min_samples * sizeof(*encrypted_samples));
8124 if (!encrypted_samples) {
8125 ret = AVERROR(ENOMEM);
8126 goto finish;
8127 }
8128 encryption_index->encrypted_samples = encrypted_samples;
8129
8130 sample = &encryption_index->encrypted_samples[i];
8131 sample_info_size = encryption_index->auxiliary_info_default_size
8132 ? encryption_index->auxiliary_info_default_size
8133 : encryption_index->auxiliary_info_sizes[i];
8134
8135 ret = mov_read_sample_encryption_info(c, pb, sc, sample, sample_info_size > sc->cenc.per_sample_iv_size);
8136 if (ret < 0)
8137 goto finish;
8138 }
8139 if (pb->eof_reached) {
8140 av_log(c->fc, AV_LOG_ERROR, "Hit EOF while reading auxiliary info\n");
8141 ret = AVERROR_INVALIDDATA;
8142 } else {
8143 encryption_index->nb_encrypted_samples = sample_count;
8144 }
8145
8146finish:
8147 avio_seek(pb, prev_pos, SEEK_SET);
8148 if (ret < 0) {
8149 for (; i > 0; i--) {
8150 av_encryption_info_free(encryption_index->encrypted_samples[i - 1]);
8151 }
8152 av_freep(&encryption_index->encrypted_samples);
8153 }
8154 return ret;
8155}
8156
8158{
8159 MOVEncryptionIndex *encryption_index;
8160 MOVStreamContext *sc;
8161 int ret;
8162 unsigned int sample_count, aux_info_type, aux_info_param;
8163
8164 ret = get_current_encryption_info(c, &encryption_index, &sc);
8165 if (ret != 1)
8166 return ret;
8167
8168 if (encryption_index->nb_encrypted_samples) {
8169 // This can happen if we have both saio/saiz and senc atoms.
8170 av_log(c->fc, AV_LOG_DEBUG, "Ignoring duplicate encryption info in saiz\n");
8171 return 0;
8172 }
8173
8174 if (encryption_index->auxiliary_info_sample_count) {
8175 av_log(c->fc, AV_LOG_ERROR, "Duplicate saiz atom\n");
8176 return AVERROR_INVALIDDATA;
8177 }
8178
8179 avio_r8(pb); /* version */
8180 if (avio_rb24(pb) & 0x01) { /* flags */
8181 aux_info_type = avio_rb32(pb);
8182 aux_info_param = avio_rb32(pb);
8184 if (aux_info_type != sc->cenc.default_encrypted_sample->scheme) {
8185 av_log(c->fc, AV_LOG_DEBUG, "Ignoring saiz box with non-zero aux_info_type\n");
8186 return 0;
8187 }
8188 if (aux_info_param != 0) {
8189 av_log(c->fc, AV_LOG_DEBUG, "Ignoring saiz box with non-zero aux_info_type_parameter\n");
8190 return 0;
8191 }
8192 } else {
8193 // Didn't see 'schm' or 'tenc', so this isn't encrypted.
8194 if ((aux_info_type == MKBETAG('c','e','n','c') ||
8195 aux_info_type == MKBETAG('c','e','n','s') ||
8196 aux_info_type == MKBETAG('c','b','c','1') ||
8197 aux_info_type == MKBETAG('c','b','c','s')) &&
8198 aux_info_param == 0) {
8199 av_log(c->fc, AV_LOG_ERROR, "Saw encrypted saiz without schm/tenc\n");
8200 return AVERROR_INVALIDDATA;
8201 } else {
8202 return 0;
8203 }
8204 }
8205 } else if (!sc->cenc.default_encrypted_sample) {
8206 // Didn't see 'schm' or 'tenc', so this isn't encrypted.
8207 return 0;
8208 }
8209
8210 encryption_index->auxiliary_info_default_size = avio_r8(pb);
8211 sample_count = avio_rb32(pb);
8212
8213 if (encryption_index->auxiliary_info_default_size == 0) {
8214 if (sample_count == 0)
8215 return AVERROR_INVALIDDATA;
8216
8217 encryption_index->auxiliary_info_sizes = av_malloc(sample_count);
8218 if (!encryption_index->auxiliary_info_sizes)
8219 return AVERROR(ENOMEM);
8220
8221 ret = avio_read(pb, encryption_index->auxiliary_info_sizes, sample_count);
8222 if (ret != sample_count) {
8223 av_freep(&encryption_index->auxiliary_info_sizes);
8224
8225 if (ret >= 0)
8226 ret = AVERROR_INVALIDDATA;
8227 av_log(c->fc, AV_LOG_ERROR, "Failed to read the auxiliary info, %s\n",
8228 av_err2str(ret));
8229 return ret;
8230 }
8231 }
8232 encryption_index->auxiliary_info_sample_count = sample_count;
8233
8234 if (encryption_index->auxiliary_offsets_count) {
8235 return mov_parse_auxiliary_info(c, sc, pb, encryption_index);
8236 }
8237
8238 return 0;
8239}
8240
8242{
8243 uint64_t *auxiliary_offsets;
8244 MOVEncryptionIndex *encryption_index;
8245 MOVStreamContext *sc;
8246 int i, ret;
8247 unsigned int version, entry_count, aux_info_type, aux_info_param;
8248 unsigned int alloc_size = 0;
8249
8250 ret = get_current_encryption_info(c, &encryption_index, &sc);
8251 if (ret != 1)
8252 return ret;
8253
8254 if (encryption_index->nb_encrypted_samples) {
8255 // This can happen if we have both saio/saiz and senc atoms.
8256 av_log(c->fc, AV_LOG_DEBUG, "Ignoring duplicate encryption info in saio\n");
8257 return 0;
8258 }
8259
8260 if (encryption_index->auxiliary_offsets_count) {
8261 av_log(c->fc, AV_LOG_ERROR, "Duplicate saio atom\n");
8262 return AVERROR_INVALIDDATA;
8263 }
8264
8265 version = avio_r8(pb); /* version */
8266 if (avio_rb24(pb) & 0x01) { /* flags */
8267 aux_info_type = avio_rb32(pb);
8268 aux_info_param = avio_rb32(pb);
8270 if (aux_info_type != sc->cenc.default_encrypted_sample->scheme) {
8271 av_log(c->fc, AV_LOG_DEBUG, "Ignoring saio box with non-zero aux_info_type\n");
8272 return 0;
8273 }
8274 if (aux_info_param != 0) {
8275 av_log(c->fc, AV_LOG_DEBUG, "Ignoring saio box with non-zero aux_info_type_parameter\n");
8276 return 0;
8277 }
8278 } else {
8279 // Didn't see 'schm' or 'tenc', so this isn't encrypted.
8280 if ((aux_info_type == MKBETAG('c','e','n','c') ||
8281 aux_info_type == MKBETAG('c','e','n','s') ||
8282 aux_info_type == MKBETAG('c','b','c','1') ||
8283 aux_info_type == MKBETAG('c','b','c','s')) &&
8284 aux_info_param == 0) {
8285 av_log(c->fc, AV_LOG_ERROR, "Saw encrypted saio without schm/tenc\n");
8286 return AVERROR_INVALIDDATA;
8287 } else {
8288 return 0;
8289 }
8290 }
8291 } else if (!sc->cenc.default_encrypted_sample) {
8292 // Didn't see 'schm' or 'tenc', so this isn't encrypted.
8293 return 0;
8294 }
8295
8296 entry_count = avio_rb32(pb);
8297 if (entry_count >= INT_MAX / sizeof(*auxiliary_offsets))
8298 return AVERROR(ENOMEM);
8299
8300 for (i = 0; i < entry_count && !pb->eof_reached; i++) {
8301 unsigned int min_offsets = FFMIN(FFMAX(i + 1, 1024), entry_count);
8302 auxiliary_offsets = av_fast_realloc(
8303 encryption_index->auxiliary_offsets, &alloc_size,
8304 min_offsets * sizeof(*auxiliary_offsets));
8305 if (!auxiliary_offsets) {
8306 av_freep(&encryption_index->auxiliary_offsets);
8307 return AVERROR(ENOMEM);
8308 }
8309 encryption_index->auxiliary_offsets = auxiliary_offsets;
8310
8311 if (version == 0) {
8312 encryption_index->auxiliary_offsets[i] = avio_rb32(pb);
8313 } else {
8314 encryption_index->auxiliary_offsets[i] = avio_rb64(pb);
8315 }
8316 if (c->frag_index.current >= 0) {
8317 encryption_index->auxiliary_offsets[i] += c->fragment.base_data_offset;
8318 }
8319 }
8320
8321 if (pb->eof_reached) {
8322 av_log(c->fc, AV_LOG_ERROR, "Hit EOF while reading saio\n");
8323 av_freep(&encryption_index->auxiliary_offsets);
8324 return AVERROR_INVALIDDATA;
8325 }
8326
8327 encryption_index->auxiliary_offsets_count = entry_count;
8328
8329 if (encryption_index->auxiliary_info_sample_count) {
8330 return mov_parse_auxiliary_info(c, sc, pb, encryption_index);
8331 }
8332
8333 return 0;
8334}
8335
8337{
8338 AVEncryptionInitInfo *info, *old_init_info;
8339 uint8_t **key_ids;
8340 AVStream *st;
8341 const AVPacketSideData *old_side_data;
8342 uint8_t *side_data, *extra_data;
8343 size_t side_data_size;
8344 int ret = 0;
8345 unsigned int version, kid_count, extra_data_size, alloc_size = 0;
8346
8347 if (c->fc->nb_streams < 1)
8348 return 0;
8349 st = c->fc->streams[c->fc->nb_streams-1];
8350
8351 version = avio_r8(pb); /* version */
8352 avio_rb24(pb); /* flags */
8353
8354 info = av_encryption_init_info_alloc(/* system_id_size */ 16, /* num_key_ids */ 0,
8355 /* key_id_size */ 16, /* data_size */ 0);
8356 if (!info)
8357 return AVERROR(ENOMEM);
8358
8359 if ((ret = ffio_read_size(pb, info->system_id, 16)) < 0) {
8360 av_log(c->fc, AV_LOG_ERROR, "Failed to read the system id\n");
8361 goto finish;
8362 }
8363
8364 if (version > 0) {
8365 kid_count = avio_rb32(pb);
8366 if (kid_count >= INT_MAX / sizeof(*key_ids)) {
8367 ret = AVERROR(ENOMEM);
8368 goto finish;
8369 }
8370
8371 for (unsigned int i = 0; i < kid_count && !pb->eof_reached; i++) {
8372 unsigned int min_kid_count = FFMIN(FFMAX(i + 1, 1024), kid_count);
8373 key_ids = av_fast_realloc(info->key_ids, &alloc_size,
8374 min_kid_count * sizeof(*key_ids));
8375 if (!key_ids) {
8376 ret = AVERROR(ENOMEM);
8377 goto finish;
8378 }
8379 info->key_ids = key_ids;
8380
8381 info->key_ids[i] = av_mallocz(16);
8382 if (!info->key_ids[i]) {
8383 ret = AVERROR(ENOMEM);
8384 goto finish;
8385 }
8386 info->num_key_ids = i + 1;
8387
8388 if ((ret = ffio_read_size(pb, info->key_ids[i], 16)) < 0) {
8389 av_log(c->fc, AV_LOG_ERROR, "Failed to read the key id\n");
8390 goto finish;
8391 }
8392 }
8393
8394 if (pb->eof_reached) {
8395 av_log(c->fc, AV_LOG_ERROR, "Hit EOF while reading pssh\n");
8396 ret = AVERROR_INVALIDDATA;
8397 goto finish;
8398 }
8399 }
8400
8401 extra_data_size = avio_rb32(pb);
8402 extra_data = av_malloc(extra_data_size);
8403 if (!extra_data) {
8404 ret = AVERROR(ENOMEM);
8405 goto finish;
8406 }
8407 ret = avio_read(pb, extra_data, extra_data_size);
8408 if (ret != extra_data_size) {
8409 av_free(extra_data);
8410
8411 if (ret >= 0)
8412 ret = AVERROR_INVALIDDATA;
8413 goto finish;
8414 }
8415
8416 av_freep(&info->data); // malloc(0) may still allocate something.
8417 info->data = extra_data;
8418 info->data_size = extra_data_size;
8419
8420 // If there is existing initialization data, append to the list.
8423 if (old_side_data) {
8424 old_init_info = av_encryption_init_info_get_side_data(old_side_data->data, old_side_data->size);
8425 if (old_init_info) {
8426 // Append to the end of the list.
8427 for (AVEncryptionInitInfo *cur = old_init_info;; cur = cur->next) {
8428 if (!cur->next) {
8429 cur->next = info;
8430 break;
8431 }
8432 }
8433 info = old_init_info;
8434 } else {
8435 // Assume existing side-data will be valid, so the only error we could get is OOM.
8436 ret = AVERROR(ENOMEM);
8437 goto finish;
8438 }
8439 }
8440
8441 side_data = av_encryption_init_info_add_side_data(info, &side_data_size);
8442 if (!side_data) {
8443 ret = AVERROR(ENOMEM);
8444 goto finish;
8445 }
8449 side_data, side_data_size, 0))
8450 av_free(side_data);
8451
8452finish:
8454 return ret;
8455}
8456
8458{
8459 AVStream *st;
8460 MOVStreamContext *sc;
8461
8462 if (c->fc->nb_streams < 1)
8463 return 0;
8464 st = c->fc->streams[c->fc->nb_streams-1];
8465 sc = st->priv_data;
8466
8467 if (sc->pseudo_stream_id != 0) {
8468 av_log(c->fc, AV_LOG_ERROR, "schm boxes are only supported in first sample descriptor\n");
8469 return AVERROR_PATCHWELCOME;
8470 }
8471
8472 if (atom.size < 8)
8473 return AVERROR_INVALIDDATA;
8474
8475 avio_rb32(pb); /* version and flags */
8476
8477 if (!sc->cenc.default_encrypted_sample) {
8479 if (!sc->cenc.default_encrypted_sample) {
8480 return AVERROR(ENOMEM);
8481 }
8482 }
8483
8485 return 0;
8486}
8487
8489{
8490 AVStream *st;
8491 MOVStreamContext *sc;
8492 unsigned int version, pattern, is_protected, iv_size;
8493
8494 if (c->fc->nb_streams < 1)
8495 return 0;
8496 st = c->fc->streams[c->fc->nb_streams-1];
8497 sc = st->priv_data;
8498
8499 if (sc->pseudo_stream_id != 0) {
8500 av_log(c->fc, AV_LOG_ERROR, "tenc atom are only supported in first sample descriptor\n");
8501 return AVERROR_PATCHWELCOME;
8502 }
8503
8504 if (!sc->cenc.default_encrypted_sample) {
8506 if (!sc->cenc.default_encrypted_sample) {
8507 return AVERROR(ENOMEM);
8508 }
8509 }
8510
8511 if (atom.size < 20)
8512 return AVERROR_INVALIDDATA;
8513
8514 version = avio_r8(pb); /* version */
8515 avio_rb24(pb); /* flags */
8516
8517 avio_r8(pb); /* reserved */
8518 pattern = avio_r8(pb);
8519
8520 if (version > 0) {
8522 sc->cenc.default_encrypted_sample->skip_byte_block = pattern & 0xf;
8523 }
8524
8525 is_protected = avio_r8(pb);
8526 if (is_protected && !sc->cenc.encryption_index) {
8527 // The whole stream should be by-default encrypted.
8529 if (!sc->cenc.encryption_index)
8530 return AVERROR(ENOMEM);
8531 }
8532 iv_size = avio_r8(pb);
8533 if (iv_size != 0 && iv_size != 8 && iv_size != 16) {
8534 av_log(c->fc, AV_LOG_ERROR, "invalid per-sample IV size value\n");
8535 return AVERROR_INVALIDDATA;
8536 }
8537 sc->cenc.per_sample_iv_size = iv_size;
8538 if (avio_read(pb, sc->cenc.default_encrypted_sample->key_id, 16) != 16) {
8539 av_log(c->fc, AV_LOG_ERROR, "failed to read the default key ID\n");
8540 return AVERROR_INVALIDDATA;
8541 }
8542
8543 if (is_protected && !sc->cenc.per_sample_iv_size) {
8544 iv_size = avio_r8(pb);
8545 if (iv_size != 8 && iv_size != 16) {
8546 av_log(c->fc, AV_LOG_ERROR, "invalid default_constant_IV_size in tenc atom\n");
8547 return AVERROR_INVALIDDATA;
8548 }
8549
8550 if (avio_read(pb, sc->cenc.default_encrypted_sample->iv, iv_size) != iv_size) {
8551 av_log(c->fc, AV_LOG_ERROR, "failed to read the default IV\n");
8552 return AVERROR_INVALIDDATA;
8553 }
8554 }
8555
8556 return 0;
8557}
8558
8560{
8561 AVStream *st;
8562 int last, type, size, ret;
8563 uint8_t buf[4];
8564
8565 if (c->fc->nb_streams < 1)
8566 return 0;
8567 st = c->fc->streams[c->fc->nb_streams-1];
8568
8569 if ((uint64_t)atom.size > (1<<30) || atom.size < 42)
8570 return AVERROR_INVALIDDATA;
8571
8572 /* Check FlacSpecificBox version. */
8573 if (avio_r8(pb) != 0)
8574 return AVERROR_INVALIDDATA;
8575
8576 avio_rb24(pb); /* Flags */
8577
8578 if (avio_read(pb, buf, sizeof(buf)) != sizeof(buf)) {
8579 av_log(c->fc, AV_LOG_ERROR, "failed to read FLAC metadata block header\n");
8580 return pb->error < 0 ? pb->error : AVERROR_INVALIDDATA;
8581 }
8582 flac_parse_block_header(buf, &last, &type, &size);
8583
8585 av_log(c->fc, AV_LOG_ERROR, "STREAMINFO must be first FLACMetadataBlock\n");
8586 return AVERROR_INVALIDDATA;
8587 }
8588
8589 ret = ff_get_extradata(c->fc, st->codecpar, pb, size);
8590 if (ret < 0)
8591 return ret;
8592
8593 if (!last)
8594 av_log(c->fc, AV_LOG_WARNING, "non-STREAMINFO FLACMetadataBlock(s) ignored\n");
8595
8596 return 0;
8597}
8598
8600 AVDictionaryEntry *key_entry_hex;
8601 char kid_hex[16*2+1];
8602
8603 if (c->decryption_default_key && c->decryption_default_key_len != len) {
8604 av_log(c->fc, AV_LOG_ERROR, "invalid default decryption key length: got %d, expected %d\n", c->decryption_default_key_len, len);
8605 return -1;
8606 }
8607
8608 if (!c->decryption_keys) {
8609 av_assert0(c->decryption_default_key);
8610 memcpy(out, c->decryption_default_key, len);
8611 return 0;
8612 }
8613
8614 if (sample->key_id_size != 16) {
8615 av_log(c->fc, AV_LOG_ERROR, "invalid key ID size: got %u, expected 16\n", sample->key_id_size);
8616 return -1;
8617 }
8618
8619 ff_data_to_hex(kid_hex, sample->key_id, 16, 1);
8620 key_entry_hex = av_dict_get(c->decryption_keys, kid_hex, NULL, AV_DICT_DONT_STRDUP_KEY|AV_DICT_DONT_STRDUP_VAL);
8621 if (!key_entry_hex) {
8622 if (!c->decryption_default_key) {
8623 av_log(c->fc, AV_LOG_ERROR, "unable to find KID %s\n", kid_hex);
8624 return -1;
8625 }
8626 memcpy(out, c->decryption_default_key, len);
8627 return 0;
8628 }
8629 if (strlen(key_entry_hex->value) != len*2) {
8630 return -1;
8631 }
8632 ff_hex_to_data(out, key_entry_hex->value);
8633 return 0;
8634}
8635
8637{
8638 int i, ret;
8639 int bytes_of_protected_data;
8640 uint8_t decryption_key[AES_CTR_KEY_SIZE];
8641
8642 if (!sc->cenc.aes_ctr) {
8643 ret = get_key_from_kid(decryption_key, sizeof(decryption_key), c, sample);
8644 if (ret < 0) {
8645 return ret;
8646 }
8647
8648 /* initialize the cipher */
8650 if (!sc->cenc.aes_ctr) {
8651 return AVERROR(ENOMEM);
8652 }
8653
8654 ret = av_aes_ctr_init(sc->cenc.aes_ctr, decryption_key);
8655 if (ret < 0) {
8656 return ret;
8657 }
8658 }
8659
8661
8662 if (!sample->subsample_count) {
8663 /* decrypt the whole packet */
8664 av_aes_ctr_crypt(sc->cenc.aes_ctr, input, input, size);
8665 return 0;
8666 }
8667
8668 for (i = 0; i < sample->subsample_count; i++) {
8669 if (sample->subsamples[i].bytes_of_clear_data + (int64_t)sample->subsamples[i].bytes_of_protected_data > size) {
8670 av_log(c->fc, AV_LOG_ERROR, "subsample size exceeds the packet size left\n");
8671 return AVERROR_INVALIDDATA;
8672 }
8673
8674 /* skip the clear bytes */
8675 input += sample->subsamples[i].bytes_of_clear_data;
8676 size -= sample->subsamples[i].bytes_of_clear_data;
8677
8678 /* decrypt the encrypted bytes */
8679
8680 bytes_of_protected_data = sample->subsamples[i].bytes_of_protected_data;
8681 av_aes_ctr_crypt(sc->cenc.aes_ctr, input, input, bytes_of_protected_data);
8682
8683 input += bytes_of_protected_data;
8684 size -= bytes_of_protected_data;
8685 }
8686
8687 if (size > 0) {
8688 av_log(c->fc, AV_LOG_ERROR, "leftover packet bytes after subsample processing\n");
8689 return AVERROR_INVALIDDATA;
8690 }
8691
8692 return 0;
8693}
8694
8696{
8697 int i, ret;
8698 int num_of_encrypted_blocks;
8699 uint8_t iv[16];
8700 uint8_t decryption_key[16];
8701
8702 if (!sc->cenc.aes_ctx) {
8703 ret = get_key_from_kid(decryption_key, sizeof(decryption_key), c, sample);
8704 if (ret < 0) {
8705 return ret;
8706 }
8707
8708 /* initialize the cipher */
8709 sc->cenc.aes_ctx = av_aes_alloc();
8710 if (!sc->cenc.aes_ctx) {
8711 return AVERROR(ENOMEM);
8712 }
8713
8714 ret = av_aes_init(sc->cenc.aes_ctx, decryption_key, 16 * 8, 1);
8715 if (ret < 0) {
8716 return ret;
8717 }
8718 }
8719
8720 memcpy(iv, sample->iv, 16);
8721
8722 /* whole-block full sample encryption */
8723 if (!sample->subsample_count) {
8724 /* decrypt the whole packet */
8725 av_aes_crypt(sc->cenc.aes_ctx, input, input, size/16, iv, 1);
8726 return 0;
8727 }
8728
8729 for (i = 0; i < sample->subsample_count; i++) {
8730 if (sample->subsamples[i].bytes_of_clear_data + (int64_t)sample->subsamples[i].bytes_of_protected_data > size) {
8731 av_log(c->fc, AV_LOG_ERROR, "subsample size exceeds the packet size left\n");
8732 return AVERROR_INVALIDDATA;
8733 }
8734
8735 if (sample->subsamples[i].bytes_of_protected_data % 16) {
8736 av_log(c->fc, AV_LOG_ERROR, "subsample BytesOfProtectedData is not a multiple of 16\n");
8737 return AVERROR_INVALIDDATA;
8738 }
8739
8740 /* skip the clear bytes */
8741 input += sample->subsamples[i].bytes_of_clear_data;
8742 size -= sample->subsamples[i].bytes_of_clear_data;
8743
8744 /* decrypt the encrypted bytes */
8745 num_of_encrypted_blocks = sample->subsamples[i].bytes_of_protected_data/16;
8746 if (num_of_encrypted_blocks > 0) {
8747 av_aes_crypt(sc->cenc.aes_ctx, input, input, num_of_encrypted_blocks, iv, 1);
8748 }
8749 input += sample->subsamples[i].bytes_of_protected_data;
8750 size -= sample->subsamples[i].bytes_of_protected_data;
8751 }
8752
8753 if (size > 0) {
8754 av_log(c->fc, AV_LOG_ERROR, "leftover packet bytes after subsample processing\n");
8755 return AVERROR_INVALIDDATA;
8756 }
8757
8758 return 0;
8759}
8760
8762{
8763 int i, ret, rem_bytes;
8764 uint8_t *data;
8765 uint8_t decryption_key[AES_CTR_KEY_SIZE];
8766
8767 if (!sc->cenc.aes_ctr) {
8768 ret = get_key_from_kid(decryption_key, sizeof(decryption_key), c, sample);
8769 if (ret < 0) {
8770 return ret;
8771 }
8772
8773 /* initialize the cipher */
8775 if (!sc->cenc.aes_ctr) {
8776 return AVERROR(ENOMEM);
8777 }
8778
8779 ret = av_aes_ctr_init(sc->cenc.aes_ctr, decryption_key);
8780 if (ret < 0) {
8781 return ret;
8782 }
8783 }
8784
8786
8787 /* whole-block full sample encryption */
8788 if (!sample->subsample_count) {
8789 /* decrypt the whole packet */
8790 av_aes_ctr_crypt(sc->cenc.aes_ctr, input, input, size);
8791 return 0;
8792 } else if (!sample->crypt_byte_block && !sample->skip_byte_block) {
8793 av_log(c->fc, AV_LOG_ERROR, "pattern encryption is not present in 'cens' scheme\n");
8794 return AVERROR_INVALIDDATA;
8795 }
8796
8797 for (i = 0; i < sample->subsample_count; i++) {
8798 if (sample->subsamples[i].bytes_of_clear_data + (int64_t)sample->subsamples[i].bytes_of_protected_data > size) {
8799 av_log(c->fc, AV_LOG_ERROR, "subsample size exceeds the packet size left\n");
8800 return AVERROR_INVALIDDATA;
8801 }
8802
8803 /* skip the clear bytes */
8804 input += sample->subsamples[i].bytes_of_clear_data;
8805 size -= sample->subsamples[i].bytes_of_clear_data;
8806
8807 /* decrypt the encrypted bytes */
8808 data = input;
8809 rem_bytes = sample->subsamples[i].bytes_of_protected_data;
8810 while (rem_bytes > 0) {
8811 if (rem_bytes < 16*sample->crypt_byte_block) {
8812 break;
8813 }
8814 av_aes_ctr_crypt(sc->cenc.aes_ctr, data, data, 16*sample->crypt_byte_block);
8815 data += 16*sample->crypt_byte_block;
8816 rem_bytes -= 16*sample->crypt_byte_block;
8817 data += FFMIN(16*sample->skip_byte_block, rem_bytes);
8818 rem_bytes -= FFMIN(16*sample->skip_byte_block, rem_bytes);
8819 }
8820 input += sample->subsamples[i].bytes_of_protected_data;
8821 size -= sample->subsamples[i].bytes_of_protected_data;
8822 }
8823
8824 if (size > 0) {
8825 av_log(c->fc, AV_LOG_ERROR, "leftover packet bytes after subsample processing\n");
8826 return AVERROR_INVALIDDATA;
8827 }
8828
8829 return 0;
8830}
8831
8833{
8834 int i, ret, rem_bytes;
8835 uint8_t iv[16];
8836 uint8_t *data;
8837 uint8_t decryption_key[16];
8838
8839 if (!sc->cenc.aes_ctx) {
8840 ret = get_key_from_kid(decryption_key, sizeof(decryption_key), c, sample);
8841 if (ret < 0) {
8842 return ret;
8843 }
8844
8845 /* initialize the cipher */
8846 sc->cenc.aes_ctx = av_aes_alloc();
8847 if (!sc->cenc.aes_ctx) {
8848 return AVERROR(ENOMEM);
8849 }
8850
8851 ret = av_aes_init(sc->cenc.aes_ctx, decryption_key, 16 * 8, 1);
8852 if (ret < 0) {
8853 return ret;
8854 }
8855 }
8856
8857 /* whole-block full sample encryption */
8858 if (!sample->subsample_count) {
8859 /* decrypt the whole packet */
8860 memcpy(iv, sample->iv, 16);
8861 av_aes_crypt(sc->cenc.aes_ctx, input, input, size/16, iv, 1);
8862 return 0;
8863 } else if (!sample->crypt_byte_block && !sample->skip_byte_block) {
8864 av_log(c->fc, AV_LOG_ERROR, "pattern encryption is not present in 'cbcs' scheme\n");
8865 return AVERROR_INVALIDDATA;
8866 }
8867
8868 for (i = 0; i < sample->subsample_count; i++) {
8869 if (sample->subsamples[i].bytes_of_clear_data + (int64_t)sample->subsamples[i].bytes_of_protected_data > size) {
8870 av_log(c->fc, AV_LOG_ERROR, "subsample size exceeds the packet size left\n");
8871 return AVERROR_INVALIDDATA;
8872 }
8873
8874 /* skip the clear bytes */
8875 input += sample->subsamples[i].bytes_of_clear_data;
8876 size -= sample->subsamples[i].bytes_of_clear_data;
8877
8878 /* decrypt the encrypted bytes */
8879 memcpy(iv, sample->iv, 16);
8880 data = input;
8881 rem_bytes = sample->subsamples[i].bytes_of_protected_data;
8882 while (rem_bytes > 0) {
8883 if (rem_bytes < 16*sample->crypt_byte_block) {
8884 break;
8885 }
8886 av_aes_crypt(sc->cenc.aes_ctx, data, data, sample->crypt_byte_block, iv, 1);
8887 data += 16*sample->crypt_byte_block;
8888 rem_bytes -= 16*sample->crypt_byte_block;
8889 data += FFMIN(16*sample->skip_byte_block, rem_bytes);
8890 rem_bytes -= FFMIN(16*sample->skip_byte_block, rem_bytes);
8891 }
8892 input += sample->subsamples[i].bytes_of_protected_data;
8893 size -= sample->subsamples[i].bytes_of_protected_data;
8894 }
8895
8896 if (size > 0) {
8897 av_log(c->fc, AV_LOG_ERROR, "leftover packet bytes after subsample processing\n");
8898 return AVERROR_INVALIDDATA;
8899 }
8900
8901 return 0;
8902}
8903
8904static int cenc_decrypt(MOVContext *c, MOVStreamContext *sc, AVEncryptionInfo *sample, uint8_t *input, int size)
8905{
8906 if (sample->scheme == MKBETAG('c','e','n','c') && !sample->crypt_byte_block && !sample->skip_byte_block) {
8907 return cenc_scheme_decrypt(c, sc, sample, input, size);
8908 } else if (sample->scheme == MKBETAG('c','b','c','1') && !sample->crypt_byte_block && !sample->skip_byte_block) {
8909 return cbc1_scheme_decrypt(c, sc, sample, input, size);
8910 } else if (sample->scheme == MKBETAG('c','e','n','s')) {
8911 return cens_scheme_decrypt(c, sc, sample, input, size);
8912 } else if (sample->scheme == MKBETAG('c','b','c','s')) {
8913 return cbcs_scheme_decrypt(c, sc, sample, input, size);
8914 } else {
8915 av_log(c->fc, AV_LOG_ERROR, "invalid encryption scheme\n");
8916 return AVERROR_INVALIDDATA;
8917 }
8918}
8919
8921{
8922 int current = frag_index->current;
8923
8924 if (!frag_index->nb_items)
8925 return NULL;
8926
8927 // Check frag_index->current is the right one for pkt. It can out of sync.
8928 if (current >= 0 && current < frag_index->nb_items) {
8929 if (frag_index->item[current].moof_offset < pkt->pos &&
8930 (current + 1 == frag_index->nb_items ||
8931 frag_index->item[current + 1].moof_offset > pkt->pos))
8932 return get_frag_stream_info(frag_index, current, id);
8933 }
8934
8935
8936 for (int i = 0; i < frag_index->nb_items; i++) {
8937 if (frag_index->item[i].moof_offset > pkt->pos)
8938 break;
8939 current = i;
8940 }
8941 frag_index->current = current;
8942 return get_frag_stream_info(frag_index, current, id);
8943}
8944
8945static int cenc_filter(MOVContext *mov, AVStream* st, MOVStreamContext *sc, AVPacket *pkt, int current_index)
8946{
8947 MOVFragmentStreamInfo *frag_stream_info;
8948 MOVEncryptionIndex *encryption_index;
8949 AVEncryptionInfo *encrypted_sample;
8950 int encrypted_index, ret;
8951
8952 frag_stream_info = get_frag_stream_info_from_pkt(&mov->frag_index, pkt, sc->id);
8953 encrypted_index = current_index;
8954 encryption_index = NULL;
8955 if (frag_stream_info) {
8956 // Note this only supports encryption info in the first sample descriptor.
8957 if (frag_stream_info->stsd_id == 1) {
8958 if (frag_stream_info->encryption_index) {
8959 encrypted_index = current_index - frag_stream_info->index_base;
8960 encryption_index = frag_stream_info->encryption_index;
8961 } else {
8962 encryption_index = sc->cenc.encryption_index;
8963 }
8964 }
8965 } else {
8966 encryption_index = sc->cenc.encryption_index;
8967 }
8968
8969 if (encryption_index) {
8970 if (encryption_index->auxiliary_info_sample_count &&
8971 !encryption_index->nb_encrypted_samples) {
8972 av_log(mov->fc, AV_LOG_ERROR, "saiz atom found without saio\n");
8973 return AVERROR_INVALIDDATA;
8974 }
8975 if (encryption_index->auxiliary_offsets_count &&
8976 !encryption_index->nb_encrypted_samples) {
8977 av_log(mov->fc, AV_LOG_ERROR, "saio atom found without saiz\n");
8978 return AVERROR_INVALIDDATA;
8979 }
8980
8981 encrypted_sample = NULL;
8982 if (!encryption_index->nb_encrypted_samples) {
8983 // Full-sample encryption with default settings.
8984 encrypted_sample = sc->cenc.default_encrypted_sample;
8985 } else if (encrypted_index >= 0 && encrypted_index < encryption_index->nb_encrypted_samples) {
8986 // Per-sample setting override.
8987 encrypted_sample = encryption_index->encrypted_samples[encrypted_index];
8988 if (!encrypted_sample) {
8989 encrypted_sample = sc->cenc.default_encrypted_sample;
8990 }
8991 }
8992
8993 if (!encrypted_sample) {
8994 av_log(mov->fc, AV_LOG_ERROR, "Incorrect number of samples in encryption info\n");
8995 return AVERROR_INVALIDDATA;
8996 }
8997
8998 if (mov->decryption_keys || mov->decryption_default_key) {
8999 return cenc_decrypt(mov, sc, encrypted_sample, pkt->data, pkt->size);
9000 } else {
9001 size_t size;
9002 uint8_t *side_data = av_encryption_info_add_side_data(encrypted_sample, &size);
9003 if (!side_data)
9004 return AVERROR(ENOMEM);
9006 if (ret < 0)
9007 av_free(side_data);
9008 return ret;
9009 }
9010 }
9011
9012 return 0;
9013}
9014
9016{
9017 const int OPUS_SEEK_PREROLL_MS = 80;
9018 int ret;
9019 AVStream *st;
9020 size_t size;
9021 uint16_t pre_skip;
9022
9023 if (c->fc->nb_streams < 1)
9024 return 0;
9025 st = c->fc->streams[c->fc->nb_streams-1];
9026
9027 if ((uint64_t)atom.size > (1<<30) || atom.size < 11 || st->codecpar->extradata)
9028 return AVERROR_INVALIDDATA;
9029
9030 /* Check OpusSpecificBox version. */
9031 if (avio_r8(pb) != 0) {
9032 av_log(c->fc, AV_LOG_ERROR, "unsupported OpusSpecificBox version\n");
9033 return AVERROR_INVALIDDATA;
9034 }
9035
9036 /* OpusSpecificBox size plus magic for Ogg OpusHead header. */
9037 size = atom.size + 8;
9038
9039 if ((ret = ff_alloc_extradata(st->codecpar, size)) < 0)
9040 return ret;
9041
9042 AV_WL32A(st->codecpar->extradata, MKTAG('O','p','u','s'));
9043 AV_WL32A(st->codecpar->extradata + 4, MKTAG('H','e','a','d'));
9044 AV_WB8(st->codecpar->extradata + 8, 1); /* OpusHead version */
9045 if ((ret = ffio_read_size(pb, st->codecpar->extradata + 9, size - 9)) < 0) {
9047 st->codecpar->extradata_size = 0;
9048 return ret;
9049 }
9050
9051 /* OpusSpecificBox is stored in big-endian, but OpusHead is
9052 little-endian; aside from the preceding magic and version they're
9053 otherwise currently identical. Data after output gain at offset 16
9054 doesn't need to be bytewapped. */
9055 pre_skip = AV_RB16A(st->codecpar->extradata + 10);
9056 AV_WL16A(st->codecpar->extradata + 10, pre_skip);
9057 AV_WL32A(st->codecpar->extradata + 12, AV_RB32A(st->codecpar->extradata + 12));
9058 AV_WL16A(st->codecpar->extradata + 16, AV_RB16A(st->codecpar->extradata + 16));
9059
9060 st->codecpar->initial_padding = pre_skip;
9062 (AVRational){1, 1000},
9063 (AVRational){1, 48000});
9064
9065 return 0;
9066}
9067
9069{
9070 AVStream *st;
9071 unsigned format_info;
9072 int channel_assignment, channel_assignment1, channel_assignment2;
9073 int ratebits;
9074 uint64_t chmask;
9075
9076 if (c->fc->nb_streams < 1)
9077 return 0;
9078 st = c->fc->streams[c->fc->nb_streams-1];
9079
9080 if (atom.size < 10)
9081 return AVERROR_INVALIDDATA;
9082
9083 format_info = avio_rb32(pb);
9084
9085 ratebits = (format_info >> 28) & 0xF;
9086 channel_assignment1 = (format_info >> 15) & 0x1F;
9087 channel_assignment2 = format_info & 0x1FFF;
9088 if (channel_assignment2)
9089 channel_assignment = channel_assignment2;
9090 else
9091 channel_assignment = channel_assignment1;
9092
9093 st->codecpar->frame_size = 40 << (ratebits & 0x7);
9094 st->codecpar->sample_rate = mlp_samplerate(ratebits);
9095
9097 chmask = truehd_layout(channel_assignment);
9099
9100 return 0;
9101}
9102
9104{
9105 AVStream *st;
9106 uint8_t buf[ISOM_DVCC_DVVC_SIZE];
9107 int ret;
9108 int64_t read_size = atom.size;
9109
9110 if (c->fc->nb_streams < 1)
9111 return 0;
9112 st = c->fc->streams[c->fc->nb_streams-1];
9113
9114 // At most 24 bytes
9115 read_size = FFMIN(read_size, ISOM_DVCC_DVVC_SIZE);
9116
9117 if ((ret = ffio_read_size(pb, buf, read_size)) < 0)
9118 return ret;
9119
9120 return ff_isom_parse_dvcc_dvvc(c->fc, st, buf, read_size);
9121}
9122
9124{
9125 AVStream *st;
9126 AVPacketSideData *sd;
9127 int ret;
9128
9129 if (c->fc->nb_streams < 1)
9130 return 0;
9131 st = c->fc->streams[c->fc->nb_streams - 1];
9132
9133 if (atom.size < 23 || atom.size > INT_MAX - AV_INPUT_BUFFER_PADDING_SIZE)
9134 return AVERROR_INVALIDDATA;
9135
9139 atom.size, 0);
9140 if (!sd)
9141 return AVERROR(ENOMEM);
9142
9143 ret = ffio_read_size(pb, sd->data, atom.size);
9144 if (ret < 0)
9145 return ret;
9146
9147 return 0;
9148}
9149
9151{
9152 AVStream *st;
9153 uint8_t *buf;
9154 int ret, old_size, num_arrays;
9155
9156 if (c->fc->nb_streams < 1)
9157 return 0;
9158 st = c->fc->streams[c->fc->nb_streams-1];
9159
9160 if (!st->codecpar->extradata_size)
9161 // TODO: handle lhvC when present before hvcC
9162 return 0;
9163
9164 if (atom.size < 6 || st->codecpar->extradata_size < 23 ||
9165 atom.size > INT_MAX - AV_INPUT_BUFFER_PADDING_SIZE) {
9166 return AVERROR_INVALIDDATA;
9167 }
9168
9170 if (!buf)
9171 return AVERROR(ENOMEM);
9172 memset(buf + atom.size, 0, AV_INPUT_BUFFER_PADDING_SIZE);
9173
9174 ret = ffio_read_size(pb, buf, atom.size);
9175 if (ret < 0) {
9176 av_free(buf);
9177 av_log(c->fc, AV_LOG_WARNING, "lhvC atom truncated\n");
9178 return 0;
9179 }
9180
9181 num_arrays = buf[5];
9182 old_size = st->codecpar->extradata_size;
9183 atom.size -= 8 /* account for mov_realloc_extradata offsetting */
9184 + 6 /* lhvC bytes before the arrays*/;
9185
9186 ret = mov_realloc_extradata(st->codecpar, atom);
9187 if (ret < 0) {
9188 av_free(buf);
9189 return ret;
9190 }
9191
9192 st->codecpar->extradata[22] += num_arrays;
9193 memcpy(st->codecpar->extradata + old_size, buf + 6, atom.size + 8);
9194
9196
9197 av_free(buf);
9198 return 0;
9199}
9200
9202{
9203 AVFormatContext *ctx = c->fc;
9204 AVStream *st = NULL;
9205 AVBPrint scheme_buf, value_buf;
9206 int64_t scheme_str_len = 0, value_str_len = 0;
9207 int version, flags, ret = AVERROR_BUG;
9208 int64_t size = atom.size;
9209
9210 if (atom.size < 6)
9211 // 4 bytes for version + flags, 2x 1 byte for null
9212 return AVERROR_INVALIDDATA;
9213
9214 if (c->fc->nb_streams < 1)
9215 return 0;
9216 st = c->fc->streams[c->fc->nb_streams-1];
9217
9218 version = avio_r8(pb);
9219 flags = avio_rb24(pb);
9220 size -= 4;
9221
9222 if (version != 0 || flags != 0) {
9224 "Unsupported 'kind' box with version %d, flags: %x",
9225 version, flags);
9226 return AVERROR_INVALIDDATA;
9227 }
9228
9231
9232 if ((scheme_str_len = ff_read_string_to_bprint_overwrite(pb, &scheme_buf,
9233 size)) < 0) {
9234 ret = scheme_str_len;
9235 goto cleanup;
9236 }
9237
9238 if (scheme_str_len + 1 >= size) {
9239 // we need to have another string, even if nullptr.
9240 // we check with + 1 since we expect that if size was not hit,
9241 // an additional null was read.
9242 ret = AVERROR_INVALIDDATA;
9243 goto cleanup;
9244 }
9245
9246 size -= scheme_str_len + 1;
9247
9248 if ((value_str_len = ff_read_string_to_bprint_overwrite(pb, &value_buf,
9249 size)) < 0) {
9250 ret = value_str_len;
9251 goto cleanup;
9252 }
9253
9254 if (value_str_len == size) {
9255 // in case of no trailing null, box is not valid.
9256 ret = AVERROR_INVALIDDATA;
9257 goto cleanup;
9258 }
9259
9261 "%s stream %d KindBox(scheme: %s, value: %s)\n",
9263 st->index,
9264 scheme_buf.str, value_buf.str);
9265
9266 for (int i = 0; ff_mov_track_kind_table[i].scheme_uri; i++) {
9268 if (!av_strstart(scheme_buf.str, map.scheme_uri, NULL))
9269 continue;
9270
9271 for (int j = 0; map.value_maps[j].disposition; j++) {
9272 const struct MP4TrackKindValueMapping value_map = map.value_maps[j];
9273 if (!av_strstart(value_buf.str, value_map.value, NULL))
9274 continue;
9275
9276 st->disposition |= value_map.disposition;
9277 }
9278 }
9279
9280 ret = 0;
9281
9282cleanup:
9283
9284 av_bprint_finalize(&scheme_buf, NULL);
9285 av_bprint_finalize(&value_buf, NULL);
9286
9287 return ret;
9288}
9289
9291{
9292 AVStream *st;
9293 AVChannelLayout ch_layout = { 0 };
9294 int ret, i, version, type;
9295 int ambisonic_order, channel_order, normalization, channel_count;
9296 int ambi_channels, non_diegetic_channels;
9297
9298 if (c->fc->nb_streams < 1)
9299 return 0;
9300
9301 st = c->fc->streams[c->fc->nb_streams - 1];
9302
9303 if (atom.size < 16) {
9304 av_log(c->fc, AV_LOG_ERROR, "SA3D audio box too small\n");
9305 return AVERROR_INVALIDDATA;
9306 }
9307
9308 version = avio_r8(pb);
9309 if (version) {
9310 av_log(c->fc, AV_LOG_WARNING, "Unsupported SA3D box version %d\n", version);
9311 return 0;
9312 }
9313
9314 type = avio_r8(pb);
9315 if (type & 0x7f) {
9316 av_log(c->fc, AV_LOG_WARNING,
9317 "Unsupported ambisonic type %d\n", type & 0x7f);
9318 return 0;
9319 }
9320 non_diegetic_channels = (type >> 7) * 2; // head_locked_stereo
9321
9322 ambisonic_order = avio_rb32(pb);
9323
9324 channel_order = avio_r8(pb);
9325 if (channel_order) {
9326 av_log(c->fc, AV_LOG_WARNING,
9327 "Unsupported channel_order %d\n", channel_order);
9328 return 0;
9329 }
9330
9331 normalization = avio_r8(pb);
9332 if (normalization) {
9333 av_log(c->fc, AV_LOG_WARNING,
9334 "Unsupported normalization %d\n", normalization);
9335 return 0;
9336 }
9337
9338 channel_count = avio_rb32(pb);
9339 if (ambisonic_order < 0 || ambisonic_order > 31 ||
9340 channel_count != ((ambisonic_order + 1LL) * (ambisonic_order + 1LL) +
9341 non_diegetic_channels)) {
9342 av_log(c->fc, AV_LOG_ERROR,
9343 "Invalid number of channels (%d / %d)\n",
9344 channel_count, ambisonic_order);
9345 return 0;
9346 }
9347 ambi_channels = channel_count - non_diegetic_channels;
9348
9349 ret = av_channel_layout_custom_init(&ch_layout, channel_count);
9350 if (ret < 0)
9351 return 0;
9352
9353 for (i = 0; i < channel_count; i++) {
9354 unsigned channel = avio_rb32(pb);
9355
9356 if (channel >= channel_count) {
9357 av_log(c->fc, AV_LOG_ERROR, "Invalid channel index (%d / %d)\n",
9358 channel, ambisonic_order);
9359 av_channel_layout_uninit(&ch_layout);
9360 return 0;
9361 }
9362 if (channel >= ambi_channels)
9363 ch_layout.u.map[i].id = channel - ambi_channels;
9364 else
9365 ch_layout.u.map[i].id = AV_CHAN_AMBISONIC_BASE + channel;
9366 }
9367
9369 if (ret < 0) {
9370 av_channel_layout_uninit(&ch_layout);
9371 return 0;
9372 }
9373
9375 st->codecpar->ch_layout = ch_layout;
9376
9377 return 0;
9378}
9379
9381{
9382 AVStream *st;
9383 int version;
9384
9385 if (c->fc->nb_streams < 1)
9386 return 0;
9387
9388 st = c->fc->streams[c->fc->nb_streams - 1];
9389
9390 if (atom.size < 5) {
9391 av_log(c->fc, AV_LOG_ERROR, "Empty SAND audio box\n");
9392 return AVERROR_INVALIDDATA;
9393 }
9394
9395 version = avio_r8(pb);
9396 if (version) {
9397 av_log(c->fc, AV_LOG_WARNING, "Unsupported SAND box version %d\n", version);
9398 return 0;
9399 }
9400
9402
9403 return 0;
9404}
9405
9406static int rb_size(AVIOContext *pb, int64_t *value, int size)
9407{
9408 if (size == 0)
9409 *value = 0;
9410 else if (size == 1)
9411 *value = avio_r8(pb);
9412 else if (size == 2)
9413 *value = avio_rb16(pb);
9414 else if (size == 4)
9415 *value = avio_rb32(pb);
9416 else if (size == 8) {
9417 *value = avio_rb64(pb);
9418 if (*value < 0)
9419 return -1;
9420 } else
9421 return -1;
9422 return size;
9423}
9424
9426{
9427 AVBPrint aux_type;
9428 HEIFItem *item;
9429
9430 avio_r8(pb); /* version */
9431 avio_rb24(pb); /* flags */
9432
9434 ff_read_string_to_bprint_overwrite(pb, &aux_type, atom.size - 4);
9435
9436 av_log(c->fc, AV_LOG_TRACE, "auxC: item_id %d, aux_type %s\n",
9437 c->cur_item_id, aux_type.str);
9438
9439 item = get_heif_item(c, c->cur_item_id);
9440 if (item && (av_stristr(aux_type.str, "hdrgainmap")))
9441 item->is_gainmap = 1;
9442
9443 return 0;
9444}
9445
9447{
9448 avio_rb32(pb); // version & flags.
9449 c->primary_item_id = avio_rb16(pb);
9450 av_log(c->fc, AV_LOG_TRACE, "pitm: primary_item_id %d\n", c->primary_item_id);
9451 return atom.size;
9452}
9453
9455{
9456 c->idat_offset = avio_tell(pb);
9457 return 0;
9458}
9459
9461{
9462 HEIFItem **heif_item;
9463 int version, offset_size, length_size, base_offset_size, index_size;
9464 int item_count, extent_count;
9465 int64_t base_offset, extent_offset, extent_length;
9466 uint8_t value;
9467
9468 if (c->found_iloc) {
9469 av_log(c->fc, AV_LOG_INFO, "Duplicate iloc box found\n");
9470 return 0;
9471 }
9472
9473 version = avio_r8(pb);
9474 avio_rb24(pb); // flags.
9475
9476 value = avio_r8(pb);
9477 offset_size = (value >> 4) & 0xF;
9478 length_size = value & 0xF;
9479 value = avio_r8(pb);
9480 base_offset_size = (value >> 4) & 0xF;
9481 index_size = !version ? 0 : (value & 0xF);
9482 if (index_size) {
9483 avpriv_report_missing_feature(c->fc, "iloc: index_size != 0");
9484 return AVERROR_PATCHWELCOME;
9485 }
9486 item_count = (version < 2) ? avio_rb16(pb) : avio_rb32(pb);
9487
9488 if (item_count > atom.size)
9489 return AVERROR_INVALIDDATA;
9490
9491 heif_item = av_realloc_array(c->heif_item, FFMAX(item_count, c->nb_heif_item), sizeof(*c->heif_item));
9492 if (!heif_item)
9493 return AVERROR(ENOMEM);
9494 c->heif_item = heif_item;
9495 if (item_count > c->nb_heif_item)
9496 memset(&c->heif_item[c->nb_heif_item], 0,
9497 sizeof(*c->heif_item) * (item_count - c->nb_heif_item));
9498 c->nb_heif_item = FFMAX(c->nb_heif_item, item_count);
9499
9500 av_log(c->fc, AV_LOG_TRACE, "iloc: item_count %d\n", item_count);
9501 for (int i = 0; i < item_count; i++) {
9502 HEIFItem *item = NULL;
9503 int item_id = (version < 2) ? avio_rb16(pb) : avio_rb32(pb);
9504 int offset_type = (version > 0) ? avio_rb16(pb) & 0xf : 0;
9505 int j;
9506
9507 if (avio_feof(pb))
9508 return AVERROR_INVALIDDATA;
9509 if (offset_type > 1) {
9510 avpriv_report_missing_feature(c->fc, "iloc offset type %d", offset_type);
9511 return AVERROR_PATCHWELCOME;
9512 }
9513
9514 avio_rb16(pb); // data_reference_index.
9515 if (rb_size(pb, &base_offset, base_offset_size) < 0)
9516 return AVERROR_INVALIDDATA;
9517 extent_count = avio_rb16(pb);
9518 if (extent_count > 1) {
9519 // For still AVIF images, we only support one extent item.
9520 avpriv_report_missing_feature(c->fc, "iloc: extent_count > 1");
9521 return AVERROR_PATCHWELCOME;
9522 }
9523
9524 if (rb_size(pb, &extent_offset, offset_size) < 0 ||
9525 rb_size(pb, &extent_length, length_size) < 0 ||
9526 base_offset > INT64_MAX - extent_offset)
9527 return AVERROR_INVALIDDATA;
9528
9529 for (j = 0; j < c->nb_heif_item; j++) {
9530 item = c->heif_item[j];
9531 if (!item)
9532 item = c->heif_item[j] = av_mallocz(sizeof(*item));
9533 else if (item->item_id != item_id)
9534 continue;
9535 break;
9536 }
9537 if (!item)
9538 return AVERROR(ENOMEM);
9539 if (j == c->nb_heif_item)
9540 return AVERROR_INVALIDDATA;
9541
9542 item->item_id = item_id;
9543
9544 if (offset_type == 1)
9545 item->is_idat_relative = 1;
9546 item->extent_length = extent_length;
9547 item->extent_offset = base_offset + extent_offset;
9548 av_log(c->fc, AV_LOG_TRACE, "iloc: item_idx %d, item->item_id %d, offset_type %d, "
9549 "extent_offset %"PRId64", extent_length %"PRId64"\n",
9550 i, item->item_id, offset_type, item->extent_offset, item->extent_length);
9551 }
9552
9553 c->found_iloc = 1;
9554 return atom.size;
9555}
9556
9558{
9559 HEIFItem *item = NULL;
9560 AVBPrint item_name;
9561 int64_t size = atom.size;
9562 uint32_t item_type;
9563 int item_id;
9564 int i, version, flags, ret;
9565
9566 version = avio_r8(pb);
9567 flags = avio_rb24(pb);
9568 size -= 4;
9569 if (size < 0)
9570 return AVERROR_INVALIDDATA;
9571
9572 if (version < 2) {
9573 avpriv_report_missing_feature(c->fc, "infe version < 2");
9574 avio_skip(pb, size);
9575 return 1;
9576 }
9577
9578 item_id = version > 2 ? avio_rb32(pb) : avio_rb16(pb);
9579 avio_rb16(pb); // item_protection_index
9580 item_type = avio_rl32(pb);
9581 size -= 8;
9582 if (size < 1)
9583 return AVERROR_INVALIDDATA;
9584
9587 if (ret < 0) {
9589 return ret;
9590 }
9591
9592 av_log(c->fc, AV_LOG_TRACE, "infe: item_id %d, item_type %s, item_name %s\n",
9593 item_id, av_fourcc2str(item_type), item_name.str);
9594
9595 size -= ret + 1;
9596 if (size > 0)
9597 avio_skip(pb, size);
9598
9599 for (i = 0; i < c->nb_heif_item; i++) {
9600 item = c->heif_item[i];
9601 if (!item)
9602 item = c->heif_item[i] = av_mallocz(sizeof(*item));
9603 else if (item->item_id != item_id)
9604 continue;
9605 break;
9606 }
9607 if (!item) {
9609 return AVERROR(ENOMEM);
9610 }
9611 if (i == c->nb_heif_item) {
9613 return AVERROR_INVALIDDATA;
9614 }
9615
9616 av_freep(&item->name);
9617 av_bprint_finalize(&item_name, ret ? &item->name : NULL);
9618 item->item_id = item_id;
9619 item->type = item_type;
9620 item->flags = flags;
9621
9622 switch (item_type) {
9623 case MKTAG('a','v','0','1'):
9624 case MKTAG('j','p','e','g'):
9625 case MKTAG('h','v','c','1'):
9626 ret = heif_add_stream(c, item);
9627 if (ret < 0)
9628 return ret;
9629 break;
9630 }
9631
9632 return 0;
9633}
9634
9636{
9637 HEIFItem **heif_item;
9638 int entry_count;
9639 int version, got_stream = 0, ret, i;
9640
9641 if (c->found_iinf) {
9642 av_log(c->fc, AV_LOG_WARNING, "Duplicate iinf box found\n");
9643 return 0;
9644 }
9645
9646 version = avio_r8(pb);
9647 avio_rb24(pb); // flags.
9648 entry_count = version ? avio_rb32(pb) : avio_rb16(pb);
9649
9650 if (entry_count > atom.size)
9651 return AVERROR_INVALIDDATA;
9652
9653 /* account for the version/flags/entry_count fields already consumed,
9654 * so the per-entry loop below can bound each infe box by what is
9655 * actually left in this iinf box, the same way mov_read_iprp() bounds
9656 * ipco/ipma entries by the remaining iprp size. */
9657 atom.size -= version ? 8 : 6;
9658 if (atom.size < 0)
9659 return AVERROR_INVALIDDATA;
9660
9661 heif_item = av_realloc_array(c->heif_item, FFMAX(entry_count, c->nb_heif_item), sizeof(*c->heif_item));
9662 if (!heif_item)
9663 return AVERROR(ENOMEM);
9664 c->heif_item = heif_item;
9665 if (entry_count > c->nb_heif_item)
9666 memset(&c->heif_item[c->nb_heif_item], 0,
9667 sizeof(*c->heif_item) * (entry_count - c->nb_heif_item));
9668 c->nb_heif_item = FFMAX(c->nb_heif_item, entry_count);
9669
9670 for (i = 0; i < entry_count; i++) {
9671 MOVAtom infe;
9672
9673 infe.size = avio_rb32(pb);
9674 infe.type = avio_rl32(pb);
9675 if (avio_feof(pb) || infe.size < 8 || infe.size > atom.size ||
9676 infe.type != MKTAG('i','n','f','e')) {
9677 ret = AVERROR_INVALIDDATA;
9678 goto fail;
9679 }
9680
9681 atom.size -= infe.size;
9682 infe.size -= 8;
9683
9684 ret = mov_read_infe(c, pb, infe);
9685 if (ret < 0)
9686 goto fail;
9687 if (!ret)
9688 got_stream = 1;
9689 }
9690
9691 c->found_iinf = got_stream;
9692 return 0;
9693fail:
9694 for (; i >= 0; i--) {
9695 HEIFItem *item = c->heif_item[i];
9696
9697 if (!item)
9698 continue;
9699
9700 av_freep(&item->name);
9701 }
9702 return ret;
9703}
9704
9706 HEIFItem *item, int version, int entries)
9707{
9708 HEIFGroup *tmap = av_realloc_array(c->heif_group, c->nb_heif_group + 1U,
9709 sizeof(*c->heif_group));
9710 int ret;
9711
9712 if (!tmap)
9713 return AVERROR(ENOMEM);
9714 c->heif_group = tmap;
9715
9716 if (entries != 2) {
9717 avpriv_report_missing_feature(c->fc, "Derived image item of type %s with an "
9718 "item reference count other than 2",
9719 av_fourcc2str(item->type));
9720 return 0;
9721 }
9722
9723 tmap = &tmap[c->nb_heif_group];
9724
9725 tmap->item_idx_list = NULL; // Not needed
9726 tmap->item_id_list = av_malloc_array(entries, sizeof(*tmap->item_id_list));
9727 tmap->item_list = av_calloc(entries, sizeof(*tmap->item_list));
9728 if (!tmap->item_id_list || !tmap->item_list) {
9729 ret = AVERROR(ENOMEM);
9730 goto fail;
9731 }
9732
9733 /* 'to' item ids */
9734 for (int i = 0; i < entries; i++) {
9735 tmap->item_id_list[i] = version ? avio_rb32(pb) : avio_rb16(pb);
9736
9737 if (avio_feof(pb)) {
9738 ret = AVERROR_INVALIDDATA;
9739 goto fail;
9740 }
9741 }
9742
9743 tmap->nb_items = entries;
9744 tmap->item = item;
9745 ++c->nb_heif_group;
9746
9747 return 0;
9748fail:
9749 av_freep(&tmap->item_id_list);
9750 av_freep(&tmap->item_list);
9751
9752 return ret;
9753}
9754
9756 HEIFItem *item, int version, int entries)
9757{
9758 HEIFGroup *grid = av_realloc_array(c->heif_group, c->nb_heif_group + 1U,
9759 sizeof(*c->heif_group));
9760 int ret;
9761
9762 if (!grid)
9763 return AVERROR(ENOMEM);
9764 c->heif_group = grid;
9765 grid = &grid[c->nb_heif_group];
9766
9767 grid->item_id_list = av_malloc_array(entries, sizeof(*grid->item_id_list));
9768 grid->item_idx_list = av_calloc(entries, sizeof(*grid->item_idx_list));
9769 grid->item_list = av_calloc(entries, sizeof(*grid->item_list));
9770 if (!grid->item_id_list || !grid->item_list || !grid->item_idx_list) {
9771 ret = AVERROR(ENOMEM);
9772 goto fail;
9773 }
9774 /* 'to' item ids */
9775 for (int i = 0; i < entries; i++) {
9776 grid->item_id_list[i] = version ? avio_rb32(pb) : avio_rb16(pb);
9777
9778 if (avio_feof(pb)) {
9779 ret = AVERROR_INVALIDDATA;
9780 goto fail;
9781 }
9782 }
9783
9784 grid->nb_items = entries;
9785 grid->item = item;
9786 ++c->nb_heif_group;
9787
9788 return 0;
9789fail:
9790 av_freep(&grid->item_id_list);
9791 av_freep(&grid->item_idx_list);
9792 av_freep(&grid->item_list);
9793
9794 return ret;
9795}
9796
9798{
9799 HEIFItem *item = NULL;
9800 int entries;
9801 int from_item_id = version ? avio_rb32(pb) : avio_rb16(pb);
9802 int ret;
9803
9804 for (int i = 0; i < c->nb_heif_group; i++) {
9805 if (c->heif_group[i].item->item_id == from_item_id) {
9806 av_log(c->fc, AV_LOG_ERROR, "More than one 'dimg' box "
9807 "referencing the same Derived Image item\n");
9808 return AVERROR_INVALIDDATA;
9809 }
9810 }
9811 for (int i = 0; i < c->nb_heif_item; i++) {
9812 if (!c->heif_item[i] || c->heif_item[i]->item_id != from_item_id)
9813 continue;
9814 item = c->heif_item[i];
9815
9816 switch (item->type) {
9817 case MKTAG('g','r','i','d'):
9818 case MKTAG('i','o','v','l'):
9819 case MKTAG('t','m','a','p'):
9820 break;
9821 default:
9822 avpriv_report_missing_feature(c->fc, "Derived Image item of type %s",
9823 av_fourcc2str(item->type));
9824 return 0;
9825 }
9826 break;
9827 }
9828 if (!item) {
9829 av_log(c->fc, AV_LOG_ERROR, "Missing derived image information\n");
9830 return AVERROR_INVALIDDATA;
9831 }
9832
9833 entries = avio_rb16(pb);
9834 if (!entries) {
9835 av_log(c->fc, AV_LOG_ERROR,
9836 "Derived image item references no input images\n");
9837 return AVERROR_INVALIDDATA;
9838 }
9839
9840 av_log(c->fc, AV_LOG_TRACE, "dimg: from_item_id %d, entries %d\n",
9841 from_item_id, entries);
9842
9843 switch (item->type) {
9844 case MKTAG('g','r','i','d'):
9845 case MKTAG('i','o','v','l'):
9846 ret = mov_read_iref_dimg_grid(c, pb, item, version, entries);
9847 break;
9848 case MKTAG('t','m','a','p'):
9849 ret = mov_read_iref_dimg_tmap(c, pb, item, version, entries);
9850 break;
9851 default:
9852 av_unreachable("item->type should have been checked above");
9853 }
9854
9855 return ret;
9856}
9857
9859 int version, uint32_t size)
9860{
9861 HEIFItem *from_item = NULL;
9862 int entries;
9863 int item_id_size = version ? 4 : 2;
9864 int from_item_id = version ? avio_rb32(pb) : avio_rb16(pb);
9865 const HEIFItemRef ref = { type, from_item_id };
9866
9867 from_item = get_heif_item(c, from_item_id);
9868 if (!from_item) {
9869 av_log(c->fc, AV_LOG_ERROR, "Missing stream referenced by %s iref\n",
9871 return AVERROR_INVALIDDATA;
9872 }
9873
9874 entries = avio_rb16(pb);
9875 if ((int64_t)entries * item_id_size > (int64_t)size - item_id_size - 2) {
9876 av_log(c->fc, AV_LOG_ERROR, "iref %s entry count %d exceeds the sub-box size\n",
9877 av_fourcc2str(type), entries);
9878 return AVERROR_INVALIDDATA;
9879 }
9880 /* 'to' item ids */
9881 for (int i = 0; i < entries; i++) {
9882 HEIFItem *item = get_heif_item(c, version ? avio_rb32(pb) : avio_rb16(pb));
9883
9884 if (avio_feof(pb))
9885 return AVERROR_INVALIDDATA;
9886
9887 if (!item) {
9888 av_log(c->fc, AV_LOG_WARNING, "Missing stream referenced by %s item\n",
9890 continue;
9891 }
9892
9893 if (!av_dynarray2_add((void **)&item->iref_from_list, &item->nb_iref_from_list,
9894 sizeof(*item->iref_from_list), (const uint8_t *)&ref))
9895 return AVERROR(ENOMEM);
9896 }
9897
9898 av_log(c->fc, AV_LOG_TRACE, "%s: from_item_id %d, entries %d\n",
9899 av_fourcc2str(type), from_item_id, entries);
9900
9901 return 0;
9902}
9903
9905 int version, uint32_t size)
9906{
9907 HEIFItem *from_item = NULL;
9908 int entries;
9909 unsigned from_item_id = version ? avio_rb32(pb) : avio_rb16(pb);
9910
9911 from_item = get_heif_item(c, from_item_id);
9912 if (!from_item) {
9913 av_log(c->fc, AV_LOG_ERROR, "Missing item referenced by %s iref\n",
9915 return AVERROR_INVALIDDATA;
9916 }
9917
9918 entries = avio_rb16(pb);
9919 if (entries != 1) {
9920 avpriv_report_missing_feature(c->fc, "%s iref with an item reference "
9921 "count other than 1",
9923 return 0;
9924 }
9925
9926 /* 'to' item ids */
9927 for (int i = 0; i < entries; i++) {
9928 unsigned to_item_id = version ? avio_rb32(pb) : avio_rb16(pb);
9929 const HEIFItemRef ref = { type, to_item_id };
9930 HEIFItem *item = get_heif_item(c, to_item_id);
9931
9932 if (avio_feof(pb))
9933 return AVERROR_INVALIDDATA;
9934
9935 if (!item) {
9936 av_log(c->fc, AV_LOG_WARNING, "Missing item referenced by %s iref\n",
9938 continue;
9939 }
9940
9941 if (!av_dynarray2_add((void **)&from_item->iref_to_list, &from_item->nb_iref_to_list,
9942 sizeof(*from_item->iref_to_list), (const uint8_t *)&ref))
9943 return AVERROR(ENOMEM);
9944 }
9945
9946 av_log(c->fc, AV_LOG_TRACE, "%s: from_item_id %d, entries %d\n",
9947 av_fourcc2str(type), from_item_id, entries);
9948
9949 return 0;
9950}
9951
9953{
9954 int version = avio_r8(pb);
9955 int ret;
9956
9957 avio_rb24(pb); // flags
9958 atom.size -= 4;
9959
9960 if (version > 1) {
9961 av_log(c->fc, AV_LOG_WARNING, "Unknown iref box version %d\n", version);
9962 return 0;
9963 }
9964
9965 while (atom.size) {
9966 int64_t next = avio_tell(pb);
9967 uint32_t type, size = avio_rb32(pb);
9968
9969 if (size < 14 || size > atom.size || next > INT64_MAX - size)
9970 return AVERROR_INVALIDDATA;
9971
9972 next += size;
9973 type = avio_rl32(pb);
9974 switch (type) {
9975 case MKTAG('d','i','m','g'):
9976 ret = mov_read_iref_dimg(c, pb, version);
9977 if (ret < 0)
9978 return ret;
9979 break;
9980 case MKTAG('c','d','s','c'):
9981 ret = mov_read_iref_cdsc(c, pb, type, version, size - 8);
9982 if (ret < 0)
9983 return ret;
9984 break;
9985 case MKTAG('a','u','x','l'):
9986 case MKTAG('t','h','m','b'):
9987 ret = mov_read_iref_auxl(c, pb, type, version, size - 8);
9988 if (ret < 0)
9989 return ret;
9990 break;
9991 default:
9992 av_log(c->fc, AV_LOG_DEBUG, "Unknown iref type %s size %"PRIu32"\n",
9994 }
9995
9996 atom.size -= size;
9997 avio_seek(pb, next, SEEK_SET);
9998 }
9999 return 0;
10000}
10001
10003{
10004 HEIFItem *item;
10005 uint32_t width, height;
10006
10007 avio_r8(pb); /* version */
10008 avio_rb24(pb); /* flags */
10009 width = avio_rb32(pb);
10010 height = avio_rb32(pb);
10011
10012 av_log(c->fc, AV_LOG_TRACE, "ispe: item_id %d, width %"PRIu32", height %"PRIu32"\n",
10013 c->cur_item_id, width, height);
10014
10015 if (!width || !height || width > INT_MAX || height > INT_MAX) {
10016 av_log(c->fc, AV_LOG_ERROR, "Invalid ispe dimensions %"PRIu32"x%"PRIu32"\n",
10017 width, height);
10018 return AVERROR_INVALIDDATA;
10019 }
10020
10021 item = get_heif_item(c, c->cur_item_id);
10022 if (item) {
10023 item->width = width;
10024 item->height = height;
10025 }
10026
10027 return 0;
10028}
10029
10031{
10032 HEIFItem *item;
10033 int angle;
10034
10035 angle = avio_r8(pb) & 0x3;
10036
10037 av_log(c->fc, AV_LOG_TRACE, "irot: item_id %d, angle %u\n",
10038 c->cur_item_id, angle);
10039
10040 item = get_heif_item(c, c->cur_item_id);
10041 if (item) {
10042 // angle * 90 specifies the angle (in anti-clockwise direction)
10043 // in units of degrees.
10044 item->rotation = angle * 90;
10045 }
10046
10047 return 0;
10048}
10049
10051{
10052 HEIFItem *item;
10053 int axis;
10054
10055 axis = avio_r8(pb) & 0x1;
10056
10057 av_log(c->fc, AV_LOG_TRACE, "imir: item_id %d, axis %u\n",
10058 c->cur_item_id, axis);
10059
10060 item = get_heif_item(c, c->cur_item_id);
10061 if (item) {
10062 item->hflip = axis;
10063 item->vflip = !axis;
10064 }
10065
10066 return 0;
10067}
10068
10070{
10071 typedef struct MOVAtoms {
10072 FFIOContext b;
10073 uint32_t type;
10074 int64_t size;
10075 uint8_t *data;
10076 } MOVAtoms;
10077 MOVAtoms *atoms = NULL;
10078 MOVAtom a;
10079 unsigned count;
10080 int nb_atoms = 0;
10081 int version, flags;
10082 int ret;
10083
10084 a.size = avio_rb32(pb);
10085 a.type = avio_rl32(pb);
10086
10087 if (a.size < 8 || a.size > atom.size || a.type != MKTAG('i','p','c','o'))
10088 return AVERROR_INVALIDDATA;
10089
10090 atom.size -= a.size;
10091 a.size -= 8;
10092 while (a.size >= 8) {
10093 MOVAtoms *ref = av_dynarray2_add((void**)&atoms, &nb_atoms, sizeof(MOVAtoms), NULL);
10094 if (!ref) {
10095 ret = AVERROR(ENOMEM);
10096 goto fail;
10097 }
10098 ref->data = NULL;
10099 ref->size = avio_rb32(pb);
10100 ref->type = avio_rl32(pb);
10101 if (ref->size > a.size || ref->size < 8)
10102 break;
10103 ref->data = av_malloc(ref->size);
10104 if (!ref->data) {
10105 ret = AVERROR_INVALIDDATA;
10106 goto fail;
10107 }
10108 av_log(c->fc, AV_LOG_TRACE, "ipco: index %d, box type %s\n", nb_atoms, av_fourcc2str(ref->type));
10109 AV_WB32(ref->data, ref->size);
10110 AV_WL32(ref->data + 4, ref->type);
10111 if (avio_read(pb, ref->data + 8, ref->size - 8) != ref->size - 8) {
10112 ret = AVERROR_INVALIDDATA;
10113 goto fail;
10114 }
10115 ffio_init_read_context(&ref->b, ref->data, ref->size);
10116 a.size -= ref->size;
10117 }
10118
10119 if (a.size) {
10120 ret = AVERROR_INVALIDDATA;
10121 goto fail;
10122 }
10123
10124 a.size = avio_rb32(pb);
10125 a.type = avio_rl32(pb);
10126
10127 if (a.size < 16 || a.size > atom.size || a.type != MKTAG('i','p','m','a')) {
10128 ret = AVERROR_INVALIDDATA;
10129 goto fail;
10130 }
10131
10132 version = avio_r8(pb);
10133 flags = avio_rb24(pb);
10134 count = avio_rb32(pb);
10135 a.size -= 16;
10136
10137 for (int i = 0; i < count; i++) {
10138 int item_id = version ? avio_rb32(pb) : avio_rb16(pb);
10139 int assoc_count = avio_r8(pb);
10140
10141 a.size -= (version ? 5 : 3) + assoc_count * (1 + (flags & 1));
10142 if (avio_feof(pb) || a.size < 0) {
10143 ret = AVERROR_INVALIDDATA;
10144 goto fail;
10145 }
10146
10147 for (int j = 0; j < assoc_count; j++) {
10148 MOVAtoms *ref;
10149 int index = avio_r8(pb) & 0x7f;
10150 if (flags & 1) {
10151 index <<= 8;
10152 index |= avio_r8(pb);
10153 }
10154 if (!index)
10155 continue;
10156 if (index > nb_atoms) {
10157 ret = AVERROR_INVALIDDATA;
10158 goto fail;
10159 }
10160 ref = &atoms[--index];
10161
10162 av_log(c->fc, AV_LOG_TRACE, "ipma: property_index %d, item_id %d, item_type %s\n",
10163 index + 1, item_id, av_fourcc2str(ref->type));
10164
10165 c->cur_item_id = item_id;
10166
10167 ret = mov_read_default(c, &ref->b.pub,
10168 (MOVAtom) { .size = ref->size,
10169 .type = MKTAG('i','p','c','o') });
10170 if (ret < 0)
10171 goto fail;
10172 ffio_init_read_context(&ref->b, ref->data, ref->size);
10173 }
10174 }
10175
10176 ret = 0;
10177fail:
10178 c->cur_item_id = -1;
10179 for (int i = 0; i < nb_atoms; i++)
10180 av_free(atoms[i].data);
10181 av_free(atoms);
10182
10183 return ret;
10184}
10185
10187{
10188 avio_rb32(pb); // version & flags
10189 uint16_t graphics_mode = avio_rb16(pb);
10190 // ignored: opcolor[3]
10191
10192 if (c->fc->nb_streams < 1)
10193 return 0;
10194 AVStream *st = c->fc->streams[c->fc->nb_streams - 1];
10196 return 0;
10197
10198 switch (graphics_mode) {
10202 break;
10205 break;
10208 break;
10209 default:
10211 av_log(c->fc, AV_LOG_WARNING, "Unhandled graphics mode: 0x%x\n",
10212 graphics_mode);
10213 break;
10214 }
10215
10216 return 0;
10217}
10218
10220{
10221 AVFormatContext *ctx = c->fc;
10222 AVStream *st;
10223 int profile_level_indication, reference_ch_layout, config_length;
10224 int ret = 0;
10225
10226 if (ctx->nb_streams < 1)
10227 return 0;
10228
10229 st = ctx->streams[ctx->nb_streams - 1];
10231 return 0;
10232
10233 if (avio_r8(pb) != 1) // ConfigurationVersion
10234 return 0;
10235
10236 profile_level_indication = avio_r8(pb);
10237 st->codecpar->profile = (profile_level_indication - 1) / 5;
10238 st->codecpar->level = ((profile_level_indication - 1) % 5) + 1;
10239
10240 reference_ch_layout = avio_r8(pb);
10241 config_length = avio_rb16(pb);
10242 if (config_length)
10243 ret = ff_get_extradata(ctx, st->codecpar, pb, config_length);
10244
10245 if (!reference_ch_layout ||
10246 reference_ch_layout >= FF_ARRAY_ELEMS(ff_mpa_cicp_channel_layout_masks)) {
10247 av_log(ctx, AV_LOG_WARNING, "Unknown referenceChannelLayout value: %d\n", reference_ch_layout);
10248 return ret;
10249 }
10250
10252 ff_mpa_cicp_channel_layout_masks[reference_ch_layout]);
10253
10254 return ret;
10255}
10256
10258{ MKTAG('A','C','L','R'), mov_read_aclr },
10259{ MKTAG('A','P','R','G'), mov_read_avid },
10260{ MKTAG('A','A','L','P'), mov_read_avid },
10261{ MKTAG('A','R','E','S'), mov_read_ares },
10262{ MKTAG('a','v','s','s'), mov_read_avss },
10263{ MKTAG('a','v','1','C'), mov_read_glbl },
10264{ MKTAG('c','h','p','l'), mov_read_chpl },
10265{ MKTAG('c','o','6','4'), mov_read_stco },
10266{ MKTAG('c','o','l','r'), mov_read_colr },
10267{ MKTAG('c','t','t','s'), mov_read_ctts }, /* composition time to sample */
10268{ MKTAG('d','i','n','f'), mov_read_default },
10269{ MKTAG('D','p','x','E'), mov_read_dpxe },
10270{ MKTAG('d','r','e','f'), mov_read_dref },
10271{ MKTAG('e','d','t','s'), mov_read_default },
10272{ MKTAG('e','l','s','t'), mov_read_elst },
10273{ MKTAG('e','n','d','a'), mov_read_enda },
10274{ MKTAG('f','i','e','l'), mov_read_fiel },
10275{ MKTAG('a','d','r','m'), mov_read_adrm },
10276{ MKTAG('f','t','y','p'), mov_read_ftyp },
10277{ MKTAG('g','l','b','l'), mov_read_glbl },
10278{ MKTAG('h','d','l','r'), mov_read_hdlr },
10279{ MKTAG('i','l','s','t'), mov_read_ilst },
10280{ MKTAG('j','p','2','h'), mov_read_jp2h },
10281{ MKTAG('m','d','a','t'), mov_read_mdat },
10282{ MKTAG('m','d','h','d'), mov_read_mdhd },
10283{ MKTAG('m','d','i','a'), mov_read_default },
10284{ MKTAG('m','e','t','a'), mov_read_meta },
10285{ MKTAG('m','i','n','f'), mov_read_default },
10286{ MKTAG('m','o','o','f'), mov_read_moof },
10287{ MKTAG('m','o','o','v'), mov_read_moov },
10288{ MKTAG('m','v','e','x'), mov_read_default },
10289{ MKTAG('m','v','h','d'), mov_read_mvhd },
10290{ MKTAG('S','M','I',' '), mov_read_svq3 },
10291{ MKTAG('a','l','a','c'), mov_read_alac }, /* alac specific atom */
10292{ MKTAG('a','v','c','C'), mov_read_glbl },
10293{ MKTAG('p','a','s','p'), mov_read_pasp },
10294{ MKTAG('c','l','a','p'), mov_read_clap },
10295{ MKTAG('c','d','s','c'), mov_read_cdsc_rndr },
10296{ MKTAG('r','n','d','r'), mov_read_cdsc_rndr },
10297{ MKTAG('s','b','a','s'), mov_read_sbas },
10298{ MKTAG('v','d','e','p'), mov_read_vdep },
10299{ MKTAG('s','i','d','x'), mov_read_sidx },
10300{ MKTAG('s','t','b','l'), mov_read_default },
10301{ MKTAG('s','t','c','o'), mov_read_stco },
10302{ MKTAG('s','t','p','s'), mov_read_stps },
10303{ MKTAG('s','t','r','f'), mov_read_strf },
10304{ MKTAG('s','t','s','c'), mov_read_stsc },
10305{ MKTAG('s','t','s','d'), mov_read_stsd }, /* sample description */
10306{ MKTAG('s','t','s','s'), mov_read_stss }, /* sync sample */
10307{ MKTAG('s','t','s','z'), mov_read_stsz }, /* sample size */
10308{ MKTAG('s','t','t','s'), mov_read_stts },
10309{ MKTAG('s','t','z','2'), mov_read_stsz }, /* compact sample size */
10310{ MKTAG('s','d','t','p'), mov_read_sdtp }, /* independent and disposable samples */
10311{ MKTAG('t','k','h','d'), mov_read_tkhd }, /* track header */
10312{ MKTAG('t','f','d','t'), mov_read_tfdt },
10313{ MKTAG('t','f','h','d'), mov_read_tfhd }, /* track fragment header */
10314{ MKTAG('t','r','a','k'), mov_read_trak },
10315{ MKTAG('t','r','a','f'), mov_read_default },
10316{ MKTAG('t','r','e','f'), mov_read_default },
10317{ MKTAG('t','m','c','d'), mov_read_tmcd },
10318{ MKTAG('c','h','a','p'), mov_read_chap },
10319{ MKTAG('t','r','e','x'), mov_read_trex },
10320{ MKTAG('t','r','u','n'), mov_read_trun },
10321{ MKTAG('u','d','t','a'), mov_read_default },
10322{ MKTAG('w','a','v','e'), mov_read_wave },
10323{ MKTAG('e','s','d','s'), mov_read_esds },
10324{ MKTAG('d','a','c','3'), mov_read_dac3 }, /* AC-3 info */
10325{ MKTAG('d','e','c','3'), mov_read_dec3 }, /* EAC-3 info */
10326{ MKTAG('d','d','t','s'), mov_read_ddts }, /* DTS audio descriptor */
10327{ MKTAG('w','i','d','e'), mov_read_wide }, /* place holder */
10328{ MKTAG('w','f','e','x'), mov_read_wfex },
10329{ MKTAG('c','m','o','v'), mov_read_cmov },
10330{ MKTAG('c','h','a','n'), mov_read_chan }, /* channel layout from quicktime */
10331{ MKTAG('c','h','n','l'), mov_read_chnl }, /* channel layout from ISO-14496-12 */
10332{ MKTAG('d','v','c','1'), mov_read_dvc1 },
10333{ MKTAG('s','g','p','d'), mov_read_sgpd },
10334{ MKTAG('s','b','g','p'), mov_read_sbgp },
10335{ MKTAG('h','v','c','C'), mov_read_glbl },
10336{ MKTAG('v','v','c','C'), mov_read_glbl },
10337{ MKTAG('u','u','i','d'), mov_read_uuid },
10338{ MKTAG('C','i','n', 0x8e), mov_read_targa_y216 },
10339{ MKTAG('f','r','e','e'), mov_read_free },
10340{ MKTAG('-','-','-','-'), mov_read_custom },
10341{ MKTAG('s','i','n','f'), mov_read_default },
10342{ MKTAG('f','r','m','a'), mov_read_frma },
10343{ MKTAG('s','e','n','c'), mov_read_senc },
10344{ MKTAG('s','a','i','z'), mov_read_saiz },
10345{ MKTAG('s','a','i','o'), mov_read_saio },
10346{ MKTAG('p','s','s','h'), mov_read_pssh },
10347{ MKTAG('s','c','h','m'), mov_read_schm },
10348{ MKTAG('s','c','h','i'), mov_read_default },
10349{ MKTAG('t','e','n','c'), mov_read_tenc },
10350{ MKTAG('d','f','L','a'), mov_read_dfla },
10351{ MKTAG('s','t','3','d'), mov_read_st3d }, /* stereoscopic 3D video box */
10352{ MKTAG('s','v','3','d'), mov_read_sv3d }, /* spherical video box */
10353{ MKTAG('v','e','x','u'), mov_read_vexu }, /* video extension usage */
10354{ MKTAG('h','f','o','v'), mov_read_hfov },
10355{ MKTAG('d','O','p','s'), mov_read_dops },
10356{ MKTAG('d','m','l','p'), mov_read_dmlp },
10357{ MKTAG('S','m','D','m'), mov_read_smdm },
10358{ MKTAG('C','o','L','L'), mov_read_coll },
10359{ MKTAG('v','p','c','C'), mov_read_vpcc },
10360{ MKTAG('m','d','c','v'), mov_read_mdcv },
10361{ MKTAG('c','l','l','i'), mov_read_clli },
10362{ MKTAG('d','v','c','C'), mov_read_dvcc_dvvc },
10363{ MKTAG('d','v','v','C'), mov_read_dvcc_dvvc },
10364{ MKTAG('d','v','w','C'), mov_read_dvcc_dvvc },
10365{ MKTAG('h','v','c','E'), mov_read_hvce },
10366{ MKTAG('k','i','n','d'), mov_read_kind },
10367{ MKTAG('S','A','3','D'), mov_read_SA3D }, /* ambisonic audio box */
10368{ MKTAG('S','A','N','D'), mov_read_SAND }, /* non diegetic audio box */
10369{ MKTAG('i','l','o','c'), mov_read_iloc },
10370{ MKTAG('p','c','m','C'), mov_read_pcmc }, /* PCM configuration box */
10371{ MKTAG('p','i','t','m'), mov_read_pitm },
10372{ MKTAG('e','v','c','C'), mov_read_glbl },
10373{ MKTAG('a','u','x','C'), mov_read_auxc },
10374{ MKTAG('i','d','a','t'), mov_read_idat },
10375{ MKTAG('i','m','i','r'), mov_read_imir },
10376{ MKTAG('i','r','e','f'), mov_read_iref },
10377{ MKTAG('i','s','p','e'), mov_read_ispe },
10378{ MKTAG('i','r','o','t'), mov_read_irot },
10379{ MKTAG('i','p','r','p'), mov_read_iprp },
10380{ MKTAG('i','i','n','f'), mov_read_iinf },
10381{ MKTAG('a','m','v','e'), mov_read_amve }, /* ambient viewing environment box */
10382{ MKTAG('l','h','v','C'), mov_read_lhvc },
10383{ MKTAG('l','v','c','C'), mov_read_glbl },
10384{ MKTAG('a','p','v','C'), mov_read_glbl },
10385#if CONFIG_IAMFDEC
10386{ MKTAG('i','a','c','b'), mov_read_iacb },
10387#endif
10388{ MKTAG('s','r','a','t'), mov_read_srat },
10389{ MKTAG('v','m','h','d'), mov_read_vmhd },
10390{ MKTAG('m','h','a','C'), mov_read_mhac },
10391{ 0, NULL }
10392};
10393
10395{
10396 int64_t total_size = 0;
10397 MOVAtom a;
10398 int i;
10399
10400 if (c->atom_depth > 10) {
10401 av_log(c->fc, AV_LOG_ERROR, "Atoms too deeply nested\n");
10402 return AVERROR_INVALIDDATA;
10403 }
10404 c->atom_depth ++;
10405
10406 if (atom.size < 0)
10407 atom.size = INT64_MAX;
10408 while (total_size <= atom.size - 8) {
10409 int (*parse)(MOVContext*, AVIOContext*, MOVAtom) = NULL;
10410 a.size = avio_rb32(pb);
10411 a.type = avio_rl32(pb);
10412 if (avio_feof(pb))
10413 break;
10414 if (((a.type == MKTAG('f','r','e','e') && c->moov_retry) ||
10415 a.type == MKTAG('h','o','o','v')) &&
10416 a.size >= 8 &&
10417 c->fc->strict_std_compliance < FF_COMPLIANCE_STRICT) {
10418 uint32_t type;
10419 avio_skip(pb, 4);
10420 type = avio_rl32(pb);
10421 if (avio_feof(pb))
10422 break;
10423 avio_seek(pb, -8, SEEK_CUR);
10424 if (type == MKTAG('m','v','h','d') ||
10425 type == MKTAG('c','m','o','v')) {
10426 av_log(c->fc, AV_LOG_ERROR, "Detected moov in a free or hoov atom.\n");
10427 a.type = MKTAG('m','o','o','v');
10428 }
10429 }
10430 if (atom.type != MKTAG('r','o','o','t') &&
10431 atom.type != MKTAG('m','o','o','v')) {
10432 if (a.type == MKTAG('t','r','a','k') ||
10433 a.type == MKTAG('m','d','a','t')) {
10434 av_log(c->fc, AV_LOG_ERROR, "Broken file, trak/mdat not at top-level\n");
10435 avio_skip(pb, -8);
10436 c->atom_depth --;
10437 return 0;
10438 }
10439 }
10440 total_size += 8;
10441 if (a.size == 1 && total_size + 8 <= atom.size) { /* 64 bit extended size */
10442 a.size = avio_rb64(pb) - 8;
10443 total_size += 8;
10444 }
10445 av_log(c->fc, AV_LOG_TRACE, "type:'%s' parent:'%s' sz: %"PRId64" %"PRId64" %"PRId64"\n",
10446 av_fourcc2str(a.type), av_fourcc2str(atom.type), a.size, total_size, atom.size);
10447 if (a.size == 0) {
10448 a.size = atom.size - total_size + 8;
10449 }
10450 if (a.size < 0)
10451 break;
10452 a.size -= 8;
10453 if (a.size < 0)
10454 break;
10455 a.size = FFMIN(a.size, atom.size - total_size);
10456
10457 for (i = 0; mov_default_parse_table[i].type; i++)
10458 if (mov_default_parse_table[i].type == a.type) {
10460 break;
10461 }
10462
10463 // container is user data
10464 if (!parse && (atom.type == MKTAG('u','d','t','a') ||
10465 atom.type == MKTAG('i','l','s','t')))
10467
10468 // Supports parsing the QuickTime Metadata Keys.
10469 // https://developer.apple.com/library/mac/documentation/QuickTime/QTFF/Metadata/Metadata.html
10470 if (!parse && c->found_hdlr_mdta &&
10471 atom.type == MKTAG('m','e','t','a') &&
10472 a.type == MKTAG('k','e','y','s') &&
10473 c->meta_keys_count == 0) {
10475 }
10476
10477 if (!parse) { /* skip leaf atoms data */
10478 avio_skip(pb, a.size);
10479 } else {
10480 int64_t start_pos = avio_tell(pb);
10481 int64_t left;
10482 int err = parse(c, pb, a);
10483 if (err < 0) {
10484 c->atom_depth --;
10485 return err;
10486 }
10487 if (c->found_moov && c->found_mdat && a.size <= INT64_MAX - start_pos &&
10488 ((!(pb->seekable & AVIO_SEEKABLE_NORMAL) || c->fc->flags & AVFMT_FLAG_IGNIDX || c->frag_index.complete) ||
10489 start_pos + a.size == avio_size(pb))) {
10490 if (!(pb->seekable & AVIO_SEEKABLE_NORMAL) || c->fc->flags & AVFMT_FLAG_IGNIDX || c->frag_index.complete)
10491 c->next_root_atom = start_pos + a.size;
10492 c->atom_depth --;
10493 return 0;
10494 }
10495 left = a.size - avio_tell(pb) + start_pos;
10496 if (left > 0) /* skip garbage at atom end */
10497 avio_skip(pb, left);
10498 else if (left < 0) {
10499 av_log(c->fc, AV_LOG_WARNING,
10500 "overread end of atom '%s' by %"PRId64" bytes\n",
10501 av_fourcc2str(a.type), -left);
10502 avio_seek(pb, left, SEEK_CUR);
10503 }
10504 }
10505
10506 total_size += a.size;
10507 }
10508
10509 if (total_size < atom.size && atom.size < 0x7ffff)
10510 avio_skip(pb, atom.size - total_size);
10511
10512 c->atom_depth --;
10513 return 0;
10514}
10515
10516static int mov_probe(const AVProbeData *p)
10517{
10519 uint32_t tag;
10520 int score = 0;
10521 int moov_offset = -1;
10522
10523 /* check file header */
10524 offset = 0;
10525 for (;;) {
10526 int64_t size;
10527 int minsize = 8;
10528 /* ignore invalid offset */
10529 if ((offset + 8ULL) > (unsigned int)p->buf_size)
10530 break;
10531 size = AV_RB32(p->buf + offset);
10532 if (size == 1 && offset + 16 <= (unsigned int)p->buf_size) {
10533 size = AV_RB64(p->buf+offset + 8);
10534 minsize = 16;
10535 } else if (size == 0) {
10536 size = p->buf_size - offset;
10537 }
10538 if (size < minsize) {
10539 offset += 4;
10540 continue;
10541 }
10542 tag = AV_RL32(p->buf + offset + 4);
10543 switch(tag) {
10544 /* check for obvious tags */
10545 case MKTAG('m','o','o','v'):
10546 moov_offset = offset + 4;
10548 case MKTAG('m','d','a','t'):
10549 case MKTAG('p','n','o','t'): /* detect movs with preview pics like ew.mov and april.mov */
10550 case MKTAG('u','d','t','a'): /* Packet Video PVAuthor adds this and a lot of more junk */
10551 case MKTAG('f','t','y','p'):
10552 if (tag == MKTAG('f','t','y','p') &&
10553 ( AV_RL32(p->buf + offset + 8) == MKTAG('j','p','2',' ')
10554 || AV_RL32(p->buf + offset + 8) == MKTAG('j','p','x',' ')
10555 || AV_RL32(p->buf + offset + 8) == MKTAG('j','x','l',' ')
10556 )) {
10557 score = FFMAX(score, 5);
10558 } else {
10559 score = AVPROBE_SCORE_MAX;
10560 }
10561 break;
10562 /* those are more common words, so rate then a bit less */
10563 case MKTAG('e','d','i','w'): /* xdcam files have reverted first tags */
10564 case MKTAG('w','i','d','e'):
10565 case MKTAG('f','r','e','e'):
10566 case MKTAG('j','u','n','k'):
10567 case MKTAG('p','i','c','t'):
10568 score = FFMAX(score, AVPROBE_SCORE_MAX - 5);
10569 break;
10570 case MKTAG(0x82,0x82,0x7f,0x7d):
10571 score = FFMAX(score, AVPROBE_SCORE_EXTENSION - 5);
10572 break;
10573 case MKTAG('s','k','i','p'):
10574 case MKTAG('u','u','i','d'):
10575 case MKTAG('p','r','f','l'):
10576 /* if we only find those cause probedata is too small at least rate them */
10577 score = FFMAX(score, AVPROBE_SCORE_EXTENSION);
10578 break;
10579 }
10580 if (size > INT64_MAX - offset)
10581 break;
10582 offset += size;
10583 }
10584 if (score > AVPROBE_SCORE_MAX - 50 && moov_offset != -1) {
10585 /* moov atom in the header - we should make sure that this is not a
10586 * MOV-packed MPEG-PS */
10587 offset = moov_offset;
10588
10589 while (offset < (p->buf_size - 16)) { /* Sufficient space */
10590 /* We found an actual hdlr atom */
10591 if (AV_RL32(p->buf + offset ) == MKTAG('h','d','l','r') &&
10592 AV_RL32(p->buf + offset + 8) == MKTAG('m','h','l','r') &&
10593 AV_RL32(p->buf + offset + 12) == MKTAG('M','P','E','G')) {
10594 av_log(NULL, AV_LOG_WARNING, "Found media data tag MPEG indicating this is a MOV-packed MPEG-PS.\n");
10595 /* We found a media handler reference atom describing an
10596 * MPEG-PS-in-MOV, return a
10597 * low score to force expanding the probe window until
10598 * mpegps_probe finds what it needs */
10599 return 5;
10600 } else {
10601 /* Keep looking */
10602 offset += 2;
10603 }
10604 }
10605 }
10606
10607 return score;
10608}
10609
10610// must be done after parsing all trak because there's no order requirement
10612{
10613 MOVContext *mov = s->priv_data;
10614 MOVStreamContext *sc;
10615 int64_t cur_pos;
10616 int i, j;
10617 int chapter_track;
10618
10619 for (j = 0; j < mov->nb_chapter_tracks; j++) {
10620 AVStream *st = NULL;
10621 FFStream *sti = NULL;
10622 chapter_track = mov->chapter_tracks[j];
10623 for (i = 0; i < s->nb_streams; i++) {
10624 sc = mov->fc->streams[i]->priv_data;
10625 if (sc->id == chapter_track) {
10626 st = s->streams[i];
10627 break;
10628 }
10629 }
10630 if (!st) {
10631 av_log(s, AV_LOG_ERROR, "Referenced QT chapter track not found\n");
10632 continue;
10633 }
10634 sti = ffstream(st);
10635
10636 sc = st->priv_data;
10637 cur_pos = avio_tell(sc->pb);
10638
10641 if (!st->attached_pic.data && sti->nb_index_entries) {
10642 // Retrieve the first frame, if possible
10643 AVIndexEntry *sample = &sti->index_entries[0];
10644 if (avio_seek(sc->pb, sample->pos, SEEK_SET) != sample->pos) {
10645 av_log(s, AV_LOG_ERROR, "Failed to retrieve first frame\n");
10646 goto finish;
10647 }
10648
10649 if (ff_add_attached_pic(s, st, sc->pb, NULL, sample->size) < 0)
10650 goto finish;
10651 }
10652 } else {
10655 st->discard = AVDISCARD_ALL;
10656 for (int i = 0; i < sti->nb_index_entries; i++) {
10658 int64_t end = i+1 < sti->nb_index_entries ? sti->index_entries[i+1].timestamp : st->duration;
10659 uint8_t *title;
10660 uint16_t ch;
10661 int len, title_len;
10662
10663 if (end < sample->timestamp) {
10664 av_log(s, AV_LOG_WARNING, "ignoring stream duration which is shorter than chapters\n");
10665 end = AV_NOPTS_VALUE;
10666 }
10667
10668 if (avio_seek(sc->pb, sample->pos, SEEK_SET) != sample->pos) {
10669 av_log(s, AV_LOG_ERROR, "Chapter %d not found in file\n", i);
10670 goto finish;
10671 }
10672
10673 // the first two bytes are the length of the title
10674 len = avio_rb16(sc->pb);
10675 if (len > sample->size-2)
10676 continue;
10677 title_len = 2*len + 1;
10678 if (!(title = av_mallocz(title_len)))
10679 goto finish;
10680
10681 // The samples could theoretically be in any encoding if there's an encd
10682 // atom following, but in practice are only utf-8 or utf-16, distinguished
10683 // instead by the presence of a BOM
10684 if (!len) {
10685 title[0] = 0;
10686 } else {
10687 ch = avio_rb16(sc->pb);
10688 if (ch == 0xfeff)
10689 avio_get_str16be(sc->pb, len, title, title_len);
10690 else if (ch == 0xfffe)
10691 avio_get_str16le(sc->pb, len, title, title_len);
10692 else {
10693 AV_WB16(title, ch);
10694 if (len == 1 || len == 2)
10695 title[len] = 0;
10696 else
10697 avio_get_str(sc->pb, INT_MAX, title + 2, len - 1);
10698 }
10699 }
10700
10701 avpriv_new_chapter(s, i, st->time_base, sample->timestamp, end, title);
10702 av_freep(&title);
10703 }
10704 }
10705finish:
10706 avio_seek(sc->pb, cur_pos, SEEK_SET);
10707 }
10708}
10709
10711 int64_t value, int flags)
10712{
10713 AVTimecode tc;
10714 char buf[AV_TIMECODE_STR_SIZE];
10715 AVRational rate = st->avg_frame_rate;
10716 int ret = av_timecode_init(&tc, rate, flags, 0, s);
10717 if (ret < 0)
10718 return ret;
10719 av_dict_set(&st->metadata, "timecode",
10720 av_timecode_make_string(&tc, buf, value), 0);
10721 return 0;
10722}
10723
10725{
10726 MOVStreamContext *sc = st->priv_data;
10727 FFStream *const sti = ffstream(st);
10728 char buf[AV_TIMECODE_STR_SIZE];
10729 int64_t cur_pos = avio_tell(sc->pb);
10730 int hh, mm, ss, ff, drop;
10731
10732 if (!sti->nb_index_entries)
10733 return -1;
10734
10735 avio_seek(sc->pb, sti->index_entries->pos, SEEK_SET);
10736 avio_skip(s->pb, 13);
10737 hh = avio_r8(s->pb);
10738 mm = avio_r8(s->pb);
10739 ss = avio_r8(s->pb);
10740 drop = avio_r8(s->pb);
10741 ff = avio_r8(s->pb);
10742 snprintf(buf, AV_TIMECODE_STR_SIZE, "%02d:%02d:%02d%c%02d",
10743 hh, mm, ss, drop ? ';' : ':', ff);
10744 av_dict_set(&st->metadata, "timecode", buf, 0);
10745
10746 avio_seek(sc->pb, cur_pos, SEEK_SET);
10747 return 0;
10748}
10749
10751{
10752 MOVStreamContext *sc = st->priv_data;
10753 FFStream *const sti = ffstream(st);
10754 int flags = 0;
10755 int64_t cur_pos = avio_tell(sc->pb);
10756 int64_t value;
10757 AVRational tc_rate = st->avg_frame_rate;
10758 int tmcd_nb_frames = sc->tmcd_nb_frames;
10759 int rounded_tc_rate;
10760
10761 if (!sti->nb_index_entries)
10762 return -1;
10763
10764 if (!tc_rate.num || !tc_rate.den || !tmcd_nb_frames)
10765 return -1;
10766
10767 avio_seek(sc->pb, sti->index_entries->pos, SEEK_SET);
10768 value = avio_rb32(s->pb);
10769
10770 if (sc->tmcd_flags & 0x0001) flags |= AV_TIMECODE_FLAG_DROPFRAME;
10771 if (sc->tmcd_flags & 0x0002) flags |= AV_TIMECODE_FLAG_24HOURSMAX;
10772 if (sc->tmcd_flags & 0x0004) flags |= AV_TIMECODE_FLAG_ALLOWNEGATIVE;
10773
10774 /* Assume Counter flag is set to 1 in tmcd track (even though it is likely
10775 * not the case) and thus assume "frame number format" instead of QT one.
10776 * No sample with tmcd track can be found with a QT timecode at the moment,
10777 * despite what the tmcd track "suggests" (Counter flag set to 0 means QT
10778 * format). */
10779
10780 /* 60 fps content have tmcd_nb_frames set to 30 but tc_rate set to 60, so
10781 * we multiply the frame number with the quotient.
10782 * See tickets #9492, #9710. */
10783 rounded_tc_rate = (tc_rate.num + tc_rate.den / 2LL) / tc_rate.den;
10784 /* Work around files where tmcd_nb_frames is rounded down from frame rate
10785 * instead of up. See ticket #5978. */
10786 if (tmcd_nb_frames == tc_rate.num / tc_rate.den &&
10787 s->strict_std_compliance < FF_COMPLIANCE_STRICT)
10788 tmcd_nb_frames = rounded_tc_rate;
10789 value = av_rescale(value, rounded_tc_rate, tmcd_nb_frames);
10790
10792
10793 avio_seek(sc->pb, cur_pos, SEEK_SET);
10794 return 0;
10795}
10796
10798 int i;
10799 if (!index || !*index) return;
10800 for (i = 0; i < (*index)->nb_encrypted_samples; i++) {
10801 av_encryption_info_free((*index)->encrypted_samples[i]);
10802 }
10803 av_freep(&(*index)->encrypted_samples);
10804 av_freep(&(*index)->auxiliary_info_sizes);
10805 av_freep(&(*index)->auxiliary_offsets);
10806 av_freep(index);
10807}
10808
10810{
10811 MOVStreamContext *sc = st->priv_data;
10812
10813 if (!sc || --sc->refcount) {
10814 st->priv_data = NULL;
10815 return;
10816 }
10817
10818 av_freep(&sc->tts_data);
10819 for (int i = 0; i < sc->drefs_count; i++) {
10820 av_freep(&sc->drefs[i].path);
10821 av_freep(&sc->drefs[i].dir);
10822 }
10823 av_freep(&sc->drefs);
10824
10825 sc->drefs_count = 0;
10826
10827 if (!sc->pb_is_copied)
10828 ff_format_io_close(s, &sc->pb);
10829
10830 sc->pb = NULL;
10831 av_freep(&sc->chunk_offsets);
10832 av_freep(&sc->stsc_data);
10833 av_freep(&sc->sample_sizes);
10834 av_freep(&sc->keyframes);
10835 av_freep(&sc->ctts_data);
10836 av_freep(&sc->stts_data);
10837 av_freep(&sc->sdtp_data);
10838 av_freep(&sc->stps_data);
10839 av_freep(&sc->elst_data);
10840 av_freep(&sc->rap_group);
10841 av_freep(&sc->sync_group);
10842 av_freep(&sc->sgpd_sync);
10846 av_freep(&sc->index_ranges);
10847 for (int i = 0; i < sc->nb_tref_tags; i++)
10848 av_freep(&sc->tref_tags[i].id);
10849 av_freep(&sc->tref_tags);
10850
10851 if (sc->extradata)
10852 for (int i = 0; i < sc->stsd_count; i++)
10853 av_free(sc->extradata[i]);
10854 av_freep(&sc->extradata);
10856
10860
10861 av_freep(&sc->stereo3d);
10862 av_freep(&sc->spherical);
10863 av_freep(&sc->mastering);
10864 av_freep(&sc->coll);
10865 av_freep(&sc->ambient);
10866
10867#if CONFIG_IAMFDEC
10868 if (sc->iamf)
10870#endif
10871 av_freep(&sc->iamf);
10872}
10873
10875{
10876 MOVContext *mov = s->priv_data;
10877 int i, j;
10878
10879 for (i = 0; i < s->nb_streams; i++) {
10880 AVStream *st = s->streams[i];
10881
10883 }
10884
10885 av_freep(&mov->dv_demux);
10887 mov->dv_fctx = NULL;
10888
10889 if (mov->meta_keys) {
10890 for (i = 1; i < mov->meta_keys_count; i++) {
10891 av_freep(&mov->meta_keys[i]);
10892 }
10893 av_freep(&mov->meta_keys);
10894 }
10895
10896 av_freep(&mov->trex_data);
10897 av_freep(&mov->bitrates);
10898
10899 for (i = 0; i < mov->frag_index.nb_items; i++) {
10901 for (j = 0; j < mov->frag_index.item[i].nb_stream_info; j++) {
10902 mov_free_encryption_index(&frag[j].encryption_index);
10903 }
10905 }
10906 av_freep(&mov->frag_index.item);
10907
10908 av_freep(&mov->aes_decrypt);
10909 av_freep(&mov->chapter_tracks);
10910 for (i = 0; i < mov->nb_heif_item; i++) {
10911 if (!mov->heif_item[i])
10912 continue;
10913 av_freep(&mov->heif_item[i]->name);
10917 av_exif_free(&mov->heif_item[i]->ifd);
10918 av_freep(&mov->heif_item[i]);
10919 }
10920 av_freep(&mov->heif_item);
10921 for (i = 0; i < mov->nb_heif_group; i++) {
10925 }
10926 av_freep(&mov->heif_group);
10927
10928 return 0;
10929}
10930
10931static int tmcd_is_referenced(AVFormatContext *s, int tmcd_id)
10932{
10933 int i;
10934
10935 for (i = 0; i < s->nb_streams; i++) {
10936 AVStream *st = s->streams[i];
10937 MOVStreamContext *sc = st->priv_data;
10938 MovTref *tag = mov_find_tref_tag(sc, MKTAG('t','m','c','d'));
10939
10940 if (!tag)
10941 continue;
10942 if (mov_find_tref_id(tag, tmcd_id))
10943 return 1;
10944 }
10945 return 0;
10946}
10947
10948/* look for a tmcd track not referenced by any video track, and export it globally */
10950{
10951 int i;
10952
10953 for (i = 0; i < s->nb_streams; i++) {
10954 AVStream *st = s->streams[i];
10955
10956 if (st->codecpar->codec_tag == MKTAG('t','m','c','d') &&
10957 !tmcd_is_referenced(s, st->id)) {
10958 AVDictionaryEntry *tcr = av_dict_get(st->metadata, "timecode", NULL, 0);
10959 if (tcr) {
10960 av_dict_set(&s->metadata, "timecode", tcr->value, 0);
10961 break;
10962 }
10963 }
10964 }
10965}
10966
10968{
10969 int version, fieldlength, i, j;
10971 uint32_t size = avio_rb32(f);
10972 unsigned track_id, item_count;
10973
10974 if (avio_rb32(f) != MKBETAG('t', 'f', 'r', 'a')) {
10975 return 1;
10976 }
10977 av_log(mov->fc, AV_LOG_VERBOSE, "found tfra\n");
10978
10979 version = avio_r8(f);
10980 avio_rb24(f);
10981 track_id = avio_rb32(f);
10982 fieldlength = avio_rb32(f);
10983 item_count = avio_rb32(f);
10984 for (i = 0; i < item_count; i++) {
10985 int64_t time, offset;
10986 int index;
10987 MOVFragmentStreamInfo * frag_stream_info;
10988
10989 if (avio_feof(f)) {
10990 return AVERROR_INVALIDDATA;
10991 }
10992
10993 if (version == 1) {
10994 time = avio_rb64(f);
10995 offset = avio_rb64(f);
10996 } else {
10997 time = avio_rb32(f);
10998 offset = avio_rb32(f);
10999 }
11000
11001 // The first sample of each stream in a fragment is always a random
11002 // access sample. So it's entry in the tfra can be used as the
11003 // initial PTS of the fragment.
11005 frag_stream_info = get_frag_stream_info(&mov->frag_index, index, track_id);
11006 if (frag_stream_info &&
11007 frag_stream_info->first_tfra_pts == AV_NOPTS_VALUE)
11008 frag_stream_info->first_tfra_pts = time;
11009
11010 for (j = 0; j < ((fieldlength >> 4) & 3) + 1; j++)
11011 avio_r8(f);
11012 for (j = 0; j < ((fieldlength >> 2) & 3) + 1; j++)
11013 avio_r8(f);
11014 for (j = 0; j < ((fieldlength >> 0) & 3) + 1; j++)
11015 avio_r8(f);
11016 }
11017
11018 avio_seek(f, pos + size, SEEK_SET);
11019 return 0;
11020}
11021
11023{
11024 int64_t stream_size = avio_size(f);
11025 int64_t original_pos = avio_tell(f);
11026 int64_t seek_ret;
11027 int ret = -1;
11028 if ((seek_ret = avio_seek(f, stream_size - 4, SEEK_SET)) < 0) {
11029 ret = seek_ret;
11030 goto fail;
11031 }
11032 c->mfra_size = avio_rb32(f);
11033 c->have_read_mfra_size = 1;
11034 if (!c->mfra_size || c->mfra_size > stream_size) {
11035 av_log(c->fc, AV_LOG_DEBUG, "doesn't look like mfra (unreasonable size)\n");
11036 goto fail;
11037 }
11038 if ((seek_ret = avio_seek(f, -((int64_t) c->mfra_size), SEEK_CUR)) < 0) {
11039 ret = seek_ret;
11040 goto fail;
11041 }
11042 if (avio_rb32(f) != c->mfra_size) {
11043 av_log(c->fc, AV_LOG_DEBUG, "doesn't look like mfra (size mismatch)\n");
11044 goto fail;
11045 }
11046 if (avio_rb32(f) != MKBETAG('m', 'f', 'r', 'a')) {
11047 av_log(c->fc, AV_LOG_DEBUG, "doesn't look like mfra (tag mismatch)\n");
11048 goto fail;
11049 }
11050 av_log(c->fc, AV_LOG_VERBOSE, "stream has mfra\n");
11051 do {
11052 ret = read_tfra(c, f);
11053 if (ret < 0)
11054 goto fail;
11055 } while (!ret);
11056 ret = 0;
11057 c->frag_index.complete = 1;
11058fail:
11059 seek_ret = avio_seek(f, original_pos, SEEK_SET);
11060 if (seek_ret < 0) {
11061 av_log(c->fc, AV_LOG_ERROR,
11062 "failed to seek back after looking for mfra\n");
11063 ret = seek_ret;
11064 }
11065 return ret;
11066}
11067
11069 AVPacketSideData **coded_side_data, int *nb_coded_side_data,
11070 const HEIFItem *item)
11071{
11072 AVPacketSideData *sd =
11073 (AVPacketSideData *)av_packet_side_data_get(*coded_side_data,
11074 *nb_coded_side_data,
11076 const AVExifMetadata *ifd = &item->ifd;
11077 AVBufferRef *buf = NULL;
11079 int err;
11080
11081 if (sd)
11082 return 0;
11083
11084 err = av_exif_write(s, ifd, &buf, AV_EXIF_T_OFF);
11085 if (err < 0)
11086 return err;
11087
11088 offset = AV_RB32(buf->data) + 4;
11089 if (offset >= buf->size) {
11090 av_buffer_unref(&buf);
11091 return AVERROR_INVALIDDATA;
11092 }
11093 sd = av_packet_side_data_new(coded_side_data, nb_coded_side_data,
11094 AV_PKT_DATA_EXIF, buf->size - offset, 0);
11095 if (!sd) {
11096 av_buffer_unref(&buf);
11097 return AVERROR(ENOMEM);
11098 }
11099 memcpy(sd->data, buf->data + offset, buf->size - offset);
11100
11101 av_buffer_unref(&buf);
11102
11103 return 0;
11104}
11105
11106static int set_icc_profile_from_item(AVPacketSideData **coded_side_data, int *nb_coded_side_data,
11107 const HEIFItem *item)
11108{
11109 AVPacketSideData *sd =
11110 (AVPacketSideData *)av_packet_side_data_get(*coded_side_data,
11111 *nb_coded_side_data,
11113
11114 if (sd)
11115 return 0;
11116
11117 sd = av_packet_side_data_new(coded_side_data, nb_coded_side_data,
11119 item->icc_profile_size, 0);
11120 if (!sd)
11121 return AVERROR(ENOMEM);
11122
11123 memcpy(sd->data, item->icc_profile, item->icc_profile_size);
11124
11125 return 0;
11126}
11127
11128static int set_display_matrix_from_item(AVPacketSideData **coded_side_data, int *nb_coded_side_data,
11129 const HEIFItem *item)
11130{
11131 int32_t *matrix;
11132 AVPacketSideData *sd =
11133 (AVPacketSideData *)av_packet_side_data_get(*coded_side_data,
11134 *nb_coded_side_data,
11136
11137 if (sd)
11138 return 0;
11139
11140 sd = av_packet_side_data_new(coded_side_data, nb_coded_side_data,
11142 9 * sizeof(*matrix), 0);
11143 if (!sd)
11144 return AVERROR(ENOMEM);
11145
11146 matrix = (int32_t*)sd->data;
11147 /* rotation is in the counter-clockwise direction whereas
11148 * av_display_rotation_set() expects its argument to be
11149 * oriented clockwise, so we need to negate it. */
11152
11153 return 0;
11154}
11155
11157 AVStreamGroupTileGrid *tile_grid)
11158{
11159 MOVContext *c = s->priv_data;
11160 const HEIFItem *item = grid->item;
11161 int64_t coded_width = 0, coded_height = 0;
11162 int64_t offset = 0, pos = avio_tell(s->pb);
11163 int64_t x = 0, y = 0;
11164 int i = 0;
11165 int tile_rows, tile_cols;
11166 int flags, size;
11167
11168 if (!(s->pb->seekable & AVIO_SEEKABLE_NORMAL)) {
11169 av_log(c->fc, AV_LOG_INFO, "grid box with non seekable input\n");
11170 return AVERROR_PATCHWELCOME;
11171 }
11172 if (item->is_idat_relative) {
11173 if (!c->idat_offset) {
11174 av_log(c->fc, AV_LOG_ERROR, "missing idat box required by the image grid\n");
11175 return AVERROR_INVALIDDATA;
11176 }
11177 offset = c->idat_offset;
11178 }
11179
11180 if (offset > INT64_MAX - item->extent_offset)
11181 return AVERROR_INVALIDDATA;
11182
11183 avio_seek(s->pb, item->extent_offset + offset, SEEK_SET);
11184
11185 avio_r8(s->pb); /* version */
11186 flags = avio_r8(s->pb);
11187
11188 tile_rows = avio_r8(s->pb) + 1;
11189 tile_cols = avio_r8(s->pb) + 1;
11190 /* actual width and height of output image */
11191 tile_grid->width = (flags & 1) ? avio_rb32(s->pb) : avio_rb16(s->pb);
11192 tile_grid->height = (flags & 1) ? avio_rb32(s->pb) : avio_rb16(s->pb);
11193
11194 av_log(c->fc, AV_LOG_TRACE, "grid: grid_rows %d grid_cols %d output_width %d output_height %d\n",
11195 tile_rows, tile_cols, tile_grid->width, tile_grid->height);
11196
11197 avio_seek(s->pb, pos, SEEK_SET);
11198
11200 tile_grid->nb_tiles = grid->nb_items;
11201
11202 if (tile_grid->nb_tiles != size)
11203 return AVERROR_INVALIDDATA;
11204
11205 for (int i = 0; i < tile_cols; i++)
11206 coded_width += grid->item_list[i]->width;
11207 for (int i = 0; i < size; i += tile_cols)
11208 coded_height += grid->item_list[i]->height;
11209
11210 if (coded_width > INT_MAX || coded_height > INT_MAX)
11211 return AVERROR_INVALIDDATA;
11212
11213 tile_grid->coded_width = coded_width;
11214 tile_grid->coded_height = coded_height;
11215
11216 tile_grid->offsets = av_calloc(tile_grid->nb_tiles, sizeof(*tile_grid->offsets));
11217 if (!tile_grid->offsets)
11218 return AVERROR(ENOMEM);
11219
11220 while (y < tile_grid->coded_height) {
11221 int left_col = i;
11222
11223 while (x < tile_grid->coded_width) {
11224 if (i == tile_grid->nb_tiles)
11225 return AVERROR_INVALIDDATA;
11226
11227 tile_grid->offsets[i].idx = grid->item_idx_list[i];
11228 tile_grid->offsets[i].horizontal = x;
11229 tile_grid->offsets[i].vertical = y;
11230
11231 x += grid->item_list[i++]->width;
11232 }
11233
11234 if (x > tile_grid->coded_width) {
11235 av_log(c->fc, AV_LOG_ERROR, "Non uniform HEIF tiles\n");
11236 return AVERROR_INVALIDDATA;
11237 }
11238
11239 x = 0;
11240 y += grid->item_list[left_col]->height;
11241 }
11242
11243 if (y > tile_grid->coded_height || i != tile_grid->nb_tiles) {
11244 av_log(c->fc, AV_LOG_ERROR, "Non uniform HEIF tiles\n");
11245 return AVERROR_INVALIDDATA;
11246 }
11247
11248 return 0;
11249}
11250
11252 AVStreamGroupTileGrid *tile_grid)
11253{
11254 MOVContext *c = s->priv_data;
11255 const HEIFItem *item = grid->item;
11256 uint16_t canvas_fill_value[4];
11257 int64_t offset = 0, pos = avio_tell(s->pb);
11258 int ret = 0, flags;
11259
11260 if (!(s->pb->seekable & AVIO_SEEKABLE_NORMAL)) {
11261 av_log(c->fc, AV_LOG_INFO, "iovl box with non seekable input\n");
11262 return AVERROR_PATCHWELCOME;
11263 }
11264 if (item->is_idat_relative) {
11265 if (!c->idat_offset) {
11266 av_log(c->fc, AV_LOG_ERROR, "missing idat box required by the image overlay\n");
11267 return AVERROR_INVALIDDATA;
11268 }
11269 offset = c->idat_offset;
11270 }
11271
11272 if (offset > INT64_MAX - item->extent_offset)
11273 return AVERROR_INVALIDDATA;
11274
11275 avio_seek(s->pb, item->extent_offset + offset, SEEK_SET);
11276
11277 avio_r8(s->pb); /* version */
11278 flags = avio_r8(s->pb);
11279
11280 for (int i = 0; i < 4; i++)
11281 canvas_fill_value[i] = avio_rb16(s->pb);
11282 av_log(c->fc, AV_LOG_TRACE, "iovl: canvas_fill_value { %u, %u, %u, %u }\n",
11283 canvas_fill_value[0], canvas_fill_value[1],
11284 canvas_fill_value[2], canvas_fill_value[3]);
11285 for (int i = 0; i < 4; i++)
11286 tile_grid->background[i] = canvas_fill_value[i];
11287
11288 /* actual width and height of output image */
11289 tile_grid->width =
11290 tile_grid->coded_width = (flags & 1) ? avio_rb32(s->pb) : avio_rb16(s->pb);
11291 tile_grid->height =
11292 tile_grid->coded_height = (flags & 1) ? avio_rb32(s->pb) : avio_rb16(s->pb);
11293
11294 av_log(c->fc, AV_LOG_TRACE, "iovl: output_width %d, output_height %d\n",
11295 tile_grid->width, tile_grid->height);
11296
11297 tile_grid->nb_tiles = grid->nb_items;
11298 tile_grid->offsets = av_malloc_array(tile_grid->nb_tiles, sizeof(*tile_grid->offsets));
11299 if (!tile_grid->offsets) {
11300 ret = AVERROR(ENOMEM);
11301 goto fail;
11302 }
11303
11304 for (int i = 0; i < tile_grid->nb_tiles; i++) {
11305 tile_grid->offsets[i].idx = grid->item_idx_list[i];
11306 tile_grid->offsets[i].horizontal = (flags & 1) ? avio_rb32(s->pb) : avio_rb16(s->pb);
11307 tile_grid->offsets[i].vertical = (flags & 1) ? avio_rb32(s->pb) : avio_rb16(s->pb);
11308 av_log(c->fc, AV_LOG_TRACE, "iovl: stream_idx[%d] %u, "
11309 "horizontal_offset[%d] %d, vertical_offset[%d] %d\n",
11310 i, tile_grid->offsets[i].idx,
11311 i, tile_grid->offsets[i].horizontal, i, tile_grid->offsets[i].vertical);
11312 }
11313
11314fail:
11315 avio_seek(s->pb, pos, SEEK_SET);
11316
11317 return ret;
11318}
11319
11321{
11322 MOVContext *c = s->priv_data;
11323 AVExifMetadata *ifd = &item->ifd;
11324 uint8_t *buf;
11325 int64_t offset = 0, pos = avio_tell(s->pb);
11326 unsigned orientation_id = av_exif_get_tag_id("Orientation");
11327 int err;
11328
11329 if (!(s->pb->seekable & AVIO_SEEKABLE_NORMAL)) {
11330 av_log(c->fc, AV_LOG_WARNING, "Exif metadata with non seekable input\n");
11331 return AVERROR_PATCHWELCOME;
11332 }
11333 if (ref->is_idat_relative) {
11334 if (!c->idat_offset) {
11335 av_log(c->fc, AV_LOG_ERROR, "missing idat box required by the Exif metadata\n");
11336 return AVERROR_INVALIDDATA;
11337 }
11338 offset = c->idat_offset;
11339 }
11340
11341 buf = av_malloc(ref->extent_length);
11342 if (!buf)
11343 return AVERROR(ENOMEM);
11344
11345 if (offset > INT64_MAX - ref->extent_offset) {
11346 err = AVERROR(ENOMEM);
11347 goto fail;
11348 }
11349
11350 avio_seek(s->pb, ref->extent_offset + offset, SEEK_SET);
11351 err = avio_read(s->pb, buf, ref->extent_length);
11352 if (err != ref->extent_length) {
11353 if (err > 0)
11354 err = AVERROR_INVALIDDATA;
11355 goto fail;
11356 }
11357
11358 // HEIF spec states that Exif metadata is informative. The irot item property is
11359 // the normative source of rotation information. So we remove any Orientation tag
11360 // present in the Exif buffer.
11361 err = av_exif_parse_buffer(s, buf, ref->extent_length, ifd, AV_EXIF_T_OFF);
11362 if (err < 0) {
11363 av_log(s, AV_LOG_ERROR, "Unable to parse Exif metadata\n");
11364 goto fail;
11365 }
11366
11367 err = av_exif_remove_entry(s, ifd, orientation_id, 0);
11368 if (err < 0)
11369 goto fail;
11370
11371 err = 0;
11372fail:
11373 av_free(buf);
11374 if (err < 0)
11375 av_exif_free(ifd);
11376 avio_seek(s->pb, pos, SEEK_SET);
11377
11378 return err;
11379}
11380
11382 AVPacketSideData **coded_side_data,
11383 int *nb_coded_side_data)
11384{
11385 int err;
11386
11387 /* exif */
11388 if (item->ifd.count) {
11389 err = set_exif_from_item(s, coded_side_data, nb_coded_side_data, item);
11390 if (err < 0)
11391 return err;
11392 }
11393
11394 /* rotation */
11395 if (item->rotation || item->hflip || item->vflip) {
11396 err = set_display_matrix_from_item(coded_side_data, nb_coded_side_data, item);
11397 if (err < 0)
11398 return err;
11399 }
11400
11401 /* ICC profile */
11402 if (item->icc_profile_size) {
11403 err = set_icc_profile_from_item(coded_side_data, nb_coded_side_data, item);
11404 if (err < 0)
11405 return err;
11406 }
11407
11408 return 0;
11409}
11410
11412 AVPacketSideData **coded_side_data,
11413 int *nb_coded_side_data)
11414{
11415 MOVContext *mov = s->priv_data;
11416 int err;
11417
11418 for (int j = 0; j < item->nb_iref_from_list; j++) {
11420
11421 av_assert0(ref);
11422 switch(ref->type) {
11423 case MKTAG('E','x','i','f'):
11424 err = mov_parse_exif_item(s, item, ref);
11425 if (err < 0 && (s->error_recognition & AV_EF_EXPLODE))
11426 return err;
11427 break;
11428 default:
11429 break;
11430 }
11431 }
11432
11433 err = mov_apply_heif_item_references(s, item, coded_side_data, nb_coded_side_data);
11434 if (err < 0)
11435 return err;
11436
11437 return 0;
11438}
11439
11441{
11442 MOVContext *mov = s->priv_data;
11443
11444 for (int i = 0; i < mov->nb_heif_group; i++) {
11445 AVStreamGroup *stg;
11446 AVStreamGroupTileGrid *tile_grid;
11447 const HEIFGroup *grid = &mov->heif_group[i];
11448 int err;
11449
11450 if (!grid->item || (grid->item->type != MKTAG('g','r','i','d') &&
11451 grid->item->type != MKTAG('i','o','v','l')))
11452 continue;
11453
11455 if (!stg)
11456 return AVERROR(ENOMEM);
11457
11458 stg->id = grid->item->item_id;
11459 tile_grid = stg->params.tile_grid;
11460
11461 for (int j = 0; j < grid->nb_items; j++) {
11462 int tile_id = grid->item_id_list[j];
11463 HEIFItem *item = get_heif_item(mov, tile_id);
11464 AVStream *st;
11465
11466 if (!item) {
11467 av_log(s, AV_LOG_WARNING, "HEIF item id %d referenced by grid id %d doesn't "
11468 "exist\n",
11469 tile_id, grid->item->item_id);
11471 stg = NULL;
11472 break;
11473 }
11474
11475 st = item->st;
11476 if (!st) {
11477 av_log(s, AV_LOG_WARNING, "HEIF item id %d from grid id %d doesn't "
11478 "reference a stream\n",
11479 tile_id, grid->item->item_id);
11481 stg = NULL;
11482 break;
11483 }
11484
11485 grid->item_list[j] = item;
11486 grid->item_idx_list[j] = stg->nb_entries;
11487
11488 err = avformat_stream_group_add_stream(stg, st);
11489 if (err < 0) {
11490 int l;
11491 if (err != AVERROR(EEXIST))
11492 return err;
11493
11494 for (l = 0; l < stg->nb_entries; l++)
11495 if (stg->entries[l]->stream->index == st->index)
11496 break;
11497 av_assert0(l < stg->nb_entries);
11498 grid->item_idx_list[j] = l;
11499 }
11500
11501 if (item->item_id != mov->primary_item_id)
11503 }
11504 if (!stg)
11505 continue;
11506
11507 switch (grid->item->type) {
11508 case MKTAG('g','r','i','d'):
11509 err = read_image_grid(s, grid, tile_grid);
11510 break;
11511 case MKTAG('i','o','v','l'):
11512 err = read_image_iovl(s, grid, tile_grid);
11513 break;
11514 default:
11515 av_assert0(0);
11516 }
11517 if (err < 0)
11518 return err;
11519
11521 &stg->nb_coded_side_data);
11522 if (err < 0)
11523 return err;
11524
11525 if (grid->item->name)
11526 av_dict_set(&stg->metadata, "title", grid->item->name, 0);
11527 if (grid->item->item_id == mov->primary_item_id)
11529
11530 grid->item->stg = stg;
11531 }
11532
11533 return 0;
11534}
11535
11537{
11538 MOVContext *mov = s->priv_data;
11539 AVStreamGroup *stg;
11540 AVStreamGroupLayeredVideo *layered_video;
11541 AVGainMapParams *gain = NULL;
11542 uint8_t *payload = NULL;
11543 int64_t pos, offset = 0;
11544 size_t gain_size;
11545 int64_t err64;
11546 int err;
11547
11548 if (!(s->pb->seekable & AVIO_SEEKABLE_NORMAL)) {
11549 av_log(s, AV_LOG_WARNING, "tmap box with non seekable input\n");
11550 return 0;
11551 }
11552
11554 if (!stg)
11555 return AVERROR(ENOMEM);
11556
11557 stg->id = tmap->item->item_id;
11558 layered_video = stg->params.layered_video;
11559
11560 for (int j = 0; j < tmap->nb_items; j++) {
11561 int item_id = tmap->item_id_list[j];
11562 HEIFItem *item = get_heif_item(mov, item_id);
11563 AVStreamGroup *child_stg;
11564 AVStream *st;
11565
11566 if (!item) {
11567 av_log(s, AV_LOG_WARNING, "HEIF item id %d referenced by tmap id %d doesn't "
11568 "exist\n",
11569 item_id, tmap->item->item_id);
11571 return 0;
11572 }
11573
11574 st = item->st;
11575 child_stg = item->stg;
11576 if (!st && !child_stg) {
11577 av_log(s, AV_LOG_WARNING, "HEIF item id %d from tmap id %d doesn't "
11578 "reference a stream or tmap\n",
11579 item_id, tmap->item->item_id);
11581 return 0;
11582 }
11583 av_assert0(!st != !child_stg);
11584
11585 tmap->item_list[j] = item;
11586
11587 if (st)
11588 err = avformat_stream_group_add_stream(stg, st);
11589 else
11590 err = avformat_stream_group_add_stream_group(stg, child_stg);
11591 if (err < 0) {
11592 if (err == AVERROR(EEXIST))
11593 err = AVERROR_INVALIDDATA;
11594
11595 return err;
11596 }
11597
11598 if ((item->flags & MOV_INFE_FLAG_HIDDEN)) {
11599 if (st)
11601 else
11603 }
11604 }
11605
11606 layered_video->width = tmap->item->width;
11607 layered_video->height = tmap->item->height;
11608
11609 if (tmap->item->is_idat_relative) {
11610 if (!mov->idat_offset) {
11611 av_log(s, AV_LOG_ERROR, "Missing idat box required by the tmap\n");
11612 return AVERROR_INVALIDDATA;
11613 }
11614 offset = mov->idat_offset;
11615 }
11616
11617 if (offset > INT64_MAX - tmap->item->extent_offset)
11618 return AVERROR_INVALIDDATA;
11619
11620 gain = av_gain_map_params_alloc(&gain_size);
11621 if (!gain)
11622 return AVERROR(ENOMEM);
11623
11624 payload = av_malloc(tmap->item->extent_length);
11625 if (!payload) {
11626 return AVERROR(ENOMEM);
11627 goto fail;
11628 }
11629
11630 pos = avio_tell(s->pb);
11631 err64 = avio_seek(s->pb, tmap->item->extent_offset + offset, SEEK_SET);
11632 if (err64 != tmap->item->extent_offset + offset) {
11633 err64 = err64 < 0 ? err64 : AVERROR_INVALIDDATA;
11634 goto fail;
11635 }
11636 avio_r8(s->pb); /* version */
11637
11638 err = avio_read(s->pb, payload, tmap->item->extent_length);
11639 if (err == tmap->item->extent_length)
11640 err64 = avio_seek(s->pb, pos, SEEK_SET);
11641 else {
11642 err = err < 0 ? err : AVERROR_INVALIDDATA;
11643 goto fail;
11644 }
11645 if (err64 != pos) {
11646 err = err64 < 0 ? err64 : AVERROR_INVALIDDATA;
11647 goto fail;
11648 }
11649
11650 err = av_gain_map_params_from_iso21496(gain, payload, tmap->item->extent_length);
11651 av_freep(&payload);
11652 if (err < 0)
11653 goto fail;
11654
11655 for (int j = 0; j < tmap->nb_items; j++) {
11656 HEIFItem *item = tmap->item_list[j];
11657 AVPacketSideData *sd;
11658 AVPacketSideData **coded_side_data;
11659 int *nb_coded_side_data;
11660
11661 if (!(item->flags & MOV_INFE_FLAG_HIDDEN))
11662 continue;
11663
11664 layered_video->el_index = j;
11665
11666 if (item->st) {
11667 coded_side_data = &item->st->codecpar->coded_side_data;
11668 nb_coded_side_data = &item->st->codecpar->nb_coded_side_data;
11669 } else {
11670 av_assert0(item->stg);
11671 coded_side_data = &item->stg->coded_side_data;
11672 nb_coded_side_data = &item->stg->nb_coded_side_data;
11673 }
11674
11675 sd = av_packet_side_data_add(coded_side_data, nb_coded_side_data,
11677 (uint8_t *)gain, gain_size, 0);
11678 if (!sd) {
11679 av_free(gain);
11680 return AVERROR(ENOMEM);
11681 }
11682 gain = NULL;
11683
11684 break;
11685 }
11686 av_free(gain);
11687
11689 &stg->nb_coded_side_data);
11690 if (err < 0)
11691 return err;
11692
11693 if (tmap->item->name)
11694 av_dict_set(&stg->metadata, "title", tmap->item->name, 0);
11695 if (tmap->item->item_id == mov->primary_item_id)
11697
11698 tmap->item->stg = stg;
11699
11700 return 0;
11701fail:
11702 av_free(gain);
11703 av_free(payload);
11704
11705 return err;
11706}
11707
11708// Parse Apple style Gain Map metadata from Exif values
11709// See https://developer.apple.com/documentation/appkit/applying-apple-hdr-effect-to-your-photos
11711 HEIFItem *base, HEIFItem *gain_map)
11712{
11713 AVStreamGroupLayeredVideo *layered_video;
11714 AVStreamGroup *stg;
11715 AVGainMapParams *gain;
11716 AVPacketSideData **coded_side_data;
11717 int *nb_coded_side_data;
11718 AVExifEntry *entry, *maker33 = NULL, *maker48 = NULL;
11719 double maker_33 = 0.0, maker_48 = 0.0, headroom;
11720 size_t gain_size;
11721 int err;
11722
11723 if ((!gain_map->st && !gain_map->stg) ||
11724 (!base->st && !base->stg)) {
11725 av_log(s, AV_LOG_WARNING, "HEIF gain_map id %d or its base doesn't reference "
11726 "a stream or group\n",
11727 gain_map->item_id);
11728 return 0;
11729 }
11730
11731 if (!base->ifd.count)
11732 return 0;
11733
11734 err = av_exif_get_entry(s, &base->ifd, 0x8769, 0, &entry);
11735 if (err > 0)
11736 err = av_exif_get_entry(s, &entry->value.ifd, 0x927c, 0, &entry);
11737 if (err > 0) {
11738 av_exif_get_entry(s, &entry->value.ifd, 0x21, 0, &maker33);
11739 av_exif_get_entry(s, &entry->value.ifd, 0x30, 0, &maker48);
11740 }
11741 if ((!maker33 && !maker48) ||
11742 (maker33 && maker33->type != AV_TIFF_SRATIONAL) ||
11743 (maker48 && maker48->type != AV_TIFF_SRATIONAL))
11744 return 0;
11745
11746 if (maker33)
11747 maker_33 = av_q2d(*maker33->value.rat);
11748 if (maker48)
11749 maker_48 = av_q2d(*maker48->value.rat);
11750
11751 if (maker_33 < 1.0) {
11752 if (maker_48 <= 0.01) {
11753 headroom = -20.0 * maker_48 + 1.8;
11754 } else {
11755 headroom = -0.101 * maker_48 + 1.601;
11756 }
11757 } else {
11758 if (maker_48 <= 0.01) {
11759 headroom = -70.0 * maker_48 + 3.0;
11760 } else {
11761 headroom = -0.303 * maker_48 + 2.303;
11762 }
11763 }
11764 if (headroom <= 0.0)
11765 return 0;
11766
11768 if (!stg)
11769 return AVERROR(ENOMEM);
11770
11771 stg->id = gain_map->item_id;
11772 layered_video = stg->params.layered_video;
11773
11774 layered_video->width = base->width;
11775 layered_video->height = base->height;
11776 layered_video->el_index = 1;
11777
11778 av_assert0(!base->st != !base->stg);
11779 if (base->st)
11780 err = avformat_stream_group_add_stream(stg, base->st);
11781 else
11783 if (err < 0) {
11784 if (err == AVERROR(EEXIST))
11785 err = AVERROR_INVALIDDATA;
11786 return err;
11787 }
11788
11789 av_assert0(!gain_map->st != !gain_map->stg);
11790 if (gain_map->st) {
11791 coded_side_data = &gain_map->st->codecpar->coded_side_data;
11792 nb_coded_side_data = &gain_map->st->codecpar->nb_coded_side_data;
11793 err = avformat_stream_group_add_stream(stg, gain_map->st);
11794 } else {
11795 coded_side_data = &gain_map->stg->coded_side_data;
11796 nb_coded_side_data = &gain_map->stg->nb_coded_side_data;
11797 err = avformat_stream_group_add_stream_group(stg, gain_map->stg);
11798 }
11799 if (err < 0) {
11800 if (err == AVERROR(EEXIST))
11801 err = AVERROR_INVALIDDATA;
11802 return err;
11803 }
11804
11805 gain = av_gain_map_params_alloc(&gain_size);
11806 if (!gain)
11807 return AVERROR(ENOMEM);
11808
11809 gain->use_base_color_space = 1;
11810 gain->alternate_hdr_headroom = av_d2q(headroom, INT_MAX);
11811 gain->nb_channels = 1;
11812 gain->channels[0].base_offset = (AVRational) { 0, 1 };
11813 gain->channels[0].alternate_offset = (AVRational) { 0, 1 };
11815
11816 AVPacketSideData *sd = av_packet_side_data_add(coded_side_data, nb_coded_side_data,
11818 (uint8_t *)gain, gain_size, 0);
11819 if (!sd) {
11820 av_free(gain);
11821 return AVERROR(ENOMEM);
11822 }
11823
11824 // Apply all references from the base image except Exif to the Gain Map group
11825 int count = base->ifd.count;
11826 base->ifd.count = 0;
11828 &stg->nb_coded_side_data);
11829 base->ifd.count = count;
11830 if (err < 0)
11831 return err;
11832
11833 return 0;
11834}
11835
11837{
11838 MOVContext *mov = s->priv_data;
11839 int err;
11840
11841 for (int i = 0; i < mov->nb_heif_group; i++) {
11842 const HEIFGroup *tmap = &mov->heif_group[i];
11843
11844 if (!tmap->item)
11845 continue;
11846
11847 switch (tmap->item->type) {
11848 case MKTAG('t','m','a','p'):
11850 if (err < 0)
11851 return err;
11852 break;
11853 default:
11854 break;
11855 }
11856 }
11857
11858 for (int i = 0; i < mov->nb_heif_item; i++) {
11859 HEIFItem *item = mov->heif_item[i];
11860 int err;
11861
11862 if (!item)
11863 continue;
11864
11865 for (int j = 0; j < item->nb_iref_to_list; j++) {
11866 HEIFItem *ref = get_heif_item(mov, item->iref_to_list[j].item_id);
11867
11868 av_assert0(ref);
11869 switch(item->iref_to_list[j].type) {
11870 case MKTAG('a','u','x','l'):
11871 if (!item->is_gainmap)
11872 break;
11873
11875 if (err < 0)
11876 return err;
11877 break;
11878 }
11879 }
11880 }
11881
11882 return 0;
11883}
11884
11886{
11887 MOVContext *mov = s->priv_data;
11888 int err;
11889
11890 for (int i = 0; i < mov->nb_heif_item; i++) {
11891 HEIFItem *item = mov->heif_item[i];
11892 MOVStreamContext *sc;
11893 AVStream *st;
11894 int64_t offset = 0;
11895
11896 if (!item)
11897 continue;
11898 if (!item->st) {
11899 continue;
11900 }
11901 if (item->is_idat_relative) {
11902 if (!mov->idat_offset) {
11903 av_log(s, AV_LOG_ERROR, "Missing idat box for item %d\n", item->item_id);
11904 return AVERROR_INVALIDDATA;
11905 }
11906 offset = mov->idat_offset;
11907 }
11908
11909 st = item->st;
11910 sc = st->priv_data;
11911 st->codecpar->width = item->width;
11912 st->codecpar->height = item->height;
11913
11914 sc->sample_size = sc->stsz_sample_size = item->extent_length;
11915 sc->sample_count = 1;
11916
11917 err = sanity_checks(s, sc, st->index);
11918 if (err)
11919 return AVERROR_INVALIDDATA;
11920
11921 if (offset > INT64_MAX - item->extent_offset)
11922 return AVERROR_INVALIDDATA;
11923
11924 sc->chunk_offsets[0] = item->extent_offset + offset;
11925
11928 if (err < 0)
11929 return err;
11930
11931 if (item->name)
11932 av_dict_set(&st->metadata, "title", item->name, 0);
11933 if (item->item_id == mov->primary_item_id)
11935
11936 mov_build_index(mov, st);
11937 }
11938
11939 if (mov->nb_heif_group) {
11940 err = mov_parse_tiles(s);
11941 if (err < 0)
11942 return err;
11943
11945 if (err < 0)
11946 return err;
11947 }
11948
11949 return 0;
11950}
11951
11953{
11954 int err;
11955
11956 for (int i = 0; i < s->nb_streams; i++) {
11957 AVStreamGroup *stg;
11958 const AVDictionaryEntry *tcr;
11959 AVStream *st = s->streams[i];
11960
11961 if (st->codecpar->codec_tag != MKTAG('t','m','c','d'))
11962 continue;
11963
11965 if (!stg)
11966 return AVERROR(ENOMEM);
11967
11968 stg->id = st->id;
11969 tcr = av_dict_get(st->metadata, "timecode", NULL, 0);
11970
11971 for (int j = 0; j < s->nb_streams; j++) {
11972 AVStream *st2 = s->streams[j];
11973 MOVStreamContext *sc2 = st2->priv_data;
11974 MovTref *tag = mov_find_tref_tag(sc2, MKTAG('t','m','c','d'));
11975
11976 if (!tag)
11977 continue;
11978
11979 for (int k = 0; k < tag->nb_id; k++) {
11980 if (tag->id[k] != st->id)
11981 continue;
11982
11983 err = avformat_stream_group_add_stream(stg, st2);
11984 if (err < 0)
11985 return err;
11986
11987 if (tcr)
11988 av_dict_set(&st2->metadata, "timecode", tcr->value, AV_DICT_DONT_OVERWRITE);
11989 }
11990 }
11991
11992 if (!stg->nb_entries) {
11994 continue;
11995 }
11996
11997 err = avformat_stream_group_add_stream(stg, st);
11998 if (err < 0)
11999 return err;
12000
12001 stg->params.tref->metadata_index = stg->nb_entries - 1;
12002 }
12004
12005 return 0;
12006}
12007
12009 uint32_t *tref_id, int nb_tref_id, int first_index)
12010{
12011 if (!nb_tref_id)
12012 return NULL;
12013
12014 for (int i = first_index; i < s->nb_streams; i++)
12015 for (int j = 0; j < nb_tref_id; j++)
12016 if (s->streams[i]->index != st->index &&
12017 s->streams[i]->id == tref_id[j])
12018 return s->streams[i];
12019
12020 return NULL;
12021}
12022
12024{
12025 static const uint32_t tref_tags[] = {
12026 MKTAG('c','d','s','c'),
12027 MKTAG('r','n','d','r'),
12028 };
12029
12030 int err;
12031
12032 // Don't try to add a group if there's only one track
12033 if (s->nb_streams <= 1)
12034 return 0;
12035
12036 for (int i = 0; i < s->nb_streams; i++) {
12037 AVStream *st = s->streams[i];
12038 MOVStreamContext *sc = st->priv_data;
12039
12040 for (int c = 0; c < FF_ARRAY_ELEMS(tref_tags); c++) {
12041 AVStreamGroup *stg;
12042 AVStream *st_ref;
12043 MovTref *tag = mov_find_tref_tag(sc, tref_tags[c]);
12044
12045 if (!tag)
12046 continue;
12047
12048 st_ref = mov_find_reference_track(s, st, tag->id, tag->nb_id, 0);
12049 if (!st_ref) {
12050 av_log(s, AV_LOG_WARNING, "Failed to find referenced stream\n");
12051 continue;
12052 }
12053
12055 if (!stg)
12056 return AVERROR(ENOMEM);
12057
12058 stg->id = st_ref->id;
12059
12060 err = avformat_stream_group_add_stream(stg, st_ref);
12061 if (err < 0)
12062 return err;
12063
12064 err = avformat_stream_group_add_stream(stg, st);
12065 if (err < 0)
12066 return err;
12067
12068 stg->params.tref->metadata_index = stg->nb_entries - 1;
12069 }
12070 }
12071
12072 return 0;
12073}
12074
12076{
12077 int err;
12078
12079 // Don't try to add a group if there's only one track
12080 if (s->nb_streams <= 1)
12081 return 0;
12082
12083 for (int i = 0; i < s->nb_streams; i++) {
12084 AVStreamGroup *stg;
12085 AVStream *st = s->streams[i];
12086 AVStream *st_base;
12087 MOVStreamContext *sc = st->priv_data;
12088 MovTref *tag = mov_find_tref_tag(sc, MKTAG('s','b','a','s'));
12089 int j = 0;
12090
12091 /* Find an enhancement stream. */
12092 if (st->codecpar->codec_id != AV_CODEC_ID_LCEVC || !tag)
12093 continue;
12094
12096 if (!stg)
12097 return AVERROR(ENOMEM);
12098
12099 stg->id = st->id;
12102
12103 while (st_base = mov_find_reference_track(s, st, tag->id, tag->nb_id, j)) {
12104 err = avformat_stream_group_add_stream(stg, st_base);
12105 if (err < 0)
12106 return err;
12107
12108 j = st_base->index + 1;
12109 }
12110 if (!j) {
12111 int loglevel = (s->error_recognition & AV_EF_EXPLODE) ? AV_LOG_ERROR : AV_LOG_WARNING;
12112 av_log(s, loglevel, "Failed to find base stream for LCEVC stream\n");
12114 if (s->error_recognition & AV_EF_EXPLODE)
12115 return AVERROR_INVALIDDATA;
12116 continue;
12117 }
12118
12119 err = avformat_stream_group_add_stream(stg, st);
12120 if (err < 0)
12121 return err;
12122
12123 stg->params.layered_video->el_index = stg->nb_entries - 1;
12124 }
12125
12126 return 0;
12127}
12128
12130{
12131 int err;
12132
12133 if (s->nb_streams <= 1)
12134 return 0;
12135
12136 /* Identify legacy dual-track Dolby Vision profile 7 carriage per Annex
12137 * C of "Dolby Vision Streams Within the ISO Base Media File Format",
12138 * v2.7.1. The 'vdep' track reference type is shared with depth video
12139 * and multi-view dependencies. The spec-mandated DV-specific sample
12140 * entry combined with the dvcC configuration record disambiguates
12141 * those uses. */
12142 for (int i = 0; i < s->nb_streams; i++) {
12143 AVStreamGroup *stg;
12144 AVStream *st = s->streams[i];
12145 AVStream *st_base;
12146 MOVStreamContext *sc = st->priv_data;
12147 MovTref *tag = mov_find_tref_tag(sc, MKTAG('v','d','e','p'));
12148 const AVPacketSideData *sd;
12150
12151 if (st->codecpar->codec_id != AV_CODEC_ID_HEVC || !tag)
12152 continue;
12153
12154 if (st->codecpar->codec_tag != MKTAG('d','v','h','e') &&
12155 st->codecpar->codec_tag != MKTAG('d','v','h','1'))
12156 continue;
12157
12161 if (!sd)
12162 continue;
12163 dovi = (const AVDOVIDecoderConfigurationRecord *)sd->data;
12164
12165 /* EL track of a dual-track stream: rpu_present_flag = 1,
12166 * el_present_flag = 1, bl_present_flag = 0, dv_profile = 7. */
12167 if (dovi->dv_profile != 7 || !dovi->rpu_present_flag ||
12168 !dovi->el_present_flag || dovi->bl_present_flag)
12169 continue;
12170
12171 st_base = mov_find_reference_track(s, st, tag->id, tag->nb_id, 0);
12172 if (!st_base) {
12173 int loglevel = (s->error_recognition & AV_EF_EXPLODE) ? AV_LOG_ERROR : AV_LOG_WARNING;
12174 av_log(s, loglevel, "Failed to find base layer for Dolby Vision EL stream\n");
12175 if (s->error_recognition & AV_EF_EXPLODE)
12176 return AVERROR_INVALIDDATA;
12177 continue;
12178 }
12179
12181 if (!stg)
12182 return AVERROR(ENOMEM);
12183
12184 stg->id = st->id;
12185
12186 err = avformat_stream_group_add_stream(stg, st_base);
12187 if (err < 0)
12188 return err;
12189
12190 err = avformat_stream_group_add_stream(stg, st);
12191 if (err < 0)
12192 return err;
12193
12194 stg->params.layered_video->el_index = stg->nb_entries - 1;
12195 stg->params.layered_video->width = st_base->codecpar->width;
12196 stg->params.layered_video->height = st_base->codecpar->height;
12197 }
12198
12199 return 0;
12200}
12201
12203{
12204 int highest_id = 0, lowest_iamf_id = INT_MAX;
12205
12206 for (int i = 0; i < s->nb_streams; i++) {
12207 const AVStream *st = s->streams[i];
12208 const MOVStreamContext *sc = st->priv_data;
12209 if (!sc->iamf)
12210 highest_id = FFMAX(highest_id, st->id);
12211 }
12212
12213 for (int i = 0; i < s->nb_stream_groups; i++) {
12214 AVStreamGroup *stg = s->stream_groups[i];
12216 continue;
12217 for (int j = 0; j < stg->nb_entries; j++) {
12218 AVStream *st = stg->entries[j]->stream;
12219 lowest_iamf_id = FFMIN(lowest_iamf_id, st->id);
12220 }
12221 }
12222
12223 if (highest_id < lowest_iamf_id)
12224 return;
12225
12226 highest_id += !lowest_iamf_id;
12227 for (int i = 0; highest_id > 1 && i < s->nb_stream_groups; i++) {
12228 AVStreamGroup *stg = s->stream_groups[i];
12230 continue;
12231 for (int j = 0; j < stg->nb_entries; j++) {
12232 AVStream *st = stg->entries[j]->stream;
12233 MOVStreamContext *sc = st->priv_data;
12234 st->id += highest_id;
12235 sc->iamf_stream_offset = highest_id;
12236 }
12237 }
12238}
12239
12241{
12242 MOVContext *mov = s->priv_data;
12243 AVIOContext *pb = s->pb;
12244 int j, err;
12245 MOVAtom atom = { AV_RL32("root") };
12246 int i;
12247
12248 mov->fc = s;
12249 mov->trak_index = -1;
12250 mov->primary_item_id = -1;
12251 mov->cur_item_id = -1;
12252 /* .mov and .mp4 aren't streamable anyway (only progressive download if moov is before mdat) */
12254 atom.size = avio_size(pb);
12255 else
12256 atom.size = INT64_MAX;
12257
12258 /* check MOV header */
12259 do {
12260 if (mov->moov_retry)
12261 avio_seek(pb, 0, SEEK_SET);
12262 if ((err = mov_read_default(mov, pb, atom)) < 0) {
12263 av_log(s, AV_LOG_ERROR, "error reading header\n");
12264 return err;
12265 }
12266 } while ((pb->seekable & AVIO_SEEKABLE_NORMAL) &&
12267 !mov->found_moov && (!mov->found_iloc || !mov->found_iinf) && !mov->moov_retry++);
12268 if (!mov->found_moov && !mov->found_iloc && !mov->found_iinf) {
12269 av_log(s, AV_LOG_ERROR, "moov atom not found\n");
12270 return AVERROR_INVALIDDATA;
12271 }
12272 av_log(mov->fc, AV_LOG_TRACE, "on_parse_exit_offset=%"PRId64"\n", avio_tell(pb));
12273
12274 if (mov->found_iloc && mov->found_iinf) {
12275 err = mov_parse_heif_items(s);
12276 if (err < 0)
12277 return err;
12278 }
12279 // prevent iloc and iinf boxes from being parsed while reading packets.
12280 // this is needed because an iinf box may have been parsed but ignored
12281 // for having old infe boxes which create no streams.
12282 mov->found_iloc = mov->found_iinf = 1;
12283
12284 if (pb->seekable & AVIO_SEEKABLE_NORMAL) {
12285 if (mov->nb_chapter_tracks > 0 && !mov->ignore_chapters)
12287 for (i = 0; i < s->nb_streams; i++)
12288 if (s->streams[i]->codecpar->codec_tag == AV_RL32("tmcd")) {
12289 mov_read_timecode_track(s, s->streams[i]);
12290 } else if (s->streams[i]->codecpar->codec_tag == AV_RL32("rtmd")) {
12291 mov_read_rtmd_track(s, s->streams[i]);
12292 }
12293 }
12294
12295 /* Create metadata stream groups. */
12297 if (err < 0)
12298 return err;
12299
12300 /* copy timecode metadata from tmcd tracks to the related video streams */
12302 if (err < 0)
12303 return err;
12304
12305 /* Create LCEVC stream groups. */
12307 if (err < 0)
12308 return err;
12309
12310 /* Create Dolby Vision Profile 7 stream groups. */
12312 if (err < 0)
12313 return err;
12314
12315 for (i = 0; i < s->nb_streams; i++) {
12316 AVStream *st = s->streams[i];
12317 FFStream *const sti = ffstream(st);
12318 MOVStreamContext *sc = st->priv_data;
12319 uint32_t dvdsub_clut[FF_DVDCLUT_CLUT_LEN] = {0};
12320 fix_timescale(mov, sc);
12321
12322 /* Set the primary extradata based on the first Sample if it doesn't reference the first stsd entry. */
12323 if (sc->stsc_count && sc->extradata_size && !sc->iamf &&
12324 sc->stsc_data[0].id > 1 && sc->stsc_data[0].id <= sc->stsd_count) {
12325 sc->last_stsd_index = sc->stsc_data[0].id - 1;
12328 if (sc->extradata_size[sc->last_stsd_index]) {
12330 if (!st->codecpar->extradata)
12331 return AVERROR(ENOMEM);
12333 }
12334 }
12335
12339 }
12342 sc->time_scale*(int64_t)sc->nb_frames_for_fps, sc->duration_for_fps, INT_MAX);
12344 if (st->codecpar->width <= 0 || st->codecpar->height <= 0) {
12345 st->codecpar->width = sc->width;
12346 st->codecpar->height = sc->height;
12347 }
12350
12351 for (j = 0; j < FF_DVDCLUT_CLUT_LEN; j++)
12352 dvdsub_clut[j] = AV_RB32(st->codecpar->extradata + j * 4);
12353
12354 err = ff_dvdclut_yuv_to_rgb(dvdsub_clut, FF_DVDCLUT_CLUT_SIZE);
12355 if (err < 0)
12356 return err;
12357
12359 st->codecpar->extradata_size = 0;
12360
12362 st->codecpar);
12363 if (err < 0)
12364 return err;
12365 }
12366 }
12367 if (mov->handbrake_version &&
12368 mov->handbrake_version <= 1000000*0 + 1000*10 + 2 && // 0.10.2
12370 av_log(s, AV_LOG_VERBOSE, "Forcing full parsing for mp3 stream\n");
12372 }
12373 }
12374
12375 if (mov->trex_data || mov->use_mfra_for > 0) {
12376 for (i = 0; i < s->nb_streams; i++) {
12377 AVStream *st = s->streams[i];
12378 MOVStreamContext *sc = st->priv_data;
12379 if (sc->duration_for_fps > 0) {
12380 /* Akin to sc->data_size * 8 * sc->time_scale / sc->duration_for_fps but accounting for overflows. */
12382 if (st->codecpar->bit_rate == INT64_MIN) {
12383 av_log(s, AV_LOG_WARNING, "Overflow during bit rate calculation %"PRId64" * 8 * %d\n",
12384 sc->data_size, sc->time_scale);
12385 st->codecpar->bit_rate = 0;
12386 if (s->error_recognition & AV_EF_EXPLODE)
12387 return AVERROR_INVALIDDATA;
12388 }
12389 }
12390 }
12391 }
12392
12393 for (i = 0; i < mov->bitrates_count && i < s->nb_streams; i++) {
12394 if (mov->bitrates[i]) {
12395 s->streams[i]->codecpar->bit_rate = mov->bitrates[i];
12396 }
12397 }
12398
12400
12401 for (i = 0; i < s->nb_streams; i++) {
12402 AVStream *st = s->streams[i];
12403 MOVStreamContext *sc = st->priv_data;
12404
12405 switch (st->codecpar->codec_type) {
12406 case AVMEDIA_TYPE_AUDIO:
12407 err = ff_replaygain_export(st, s->metadata);
12408 if (err < 0)
12409 return err;
12410 break;
12411 case AVMEDIA_TYPE_VIDEO:
12412 if (sc->display_matrix) {
12415 (uint8_t*)sc->display_matrix, sizeof(int32_t) * 9, 0))
12416 return AVERROR(ENOMEM);
12417
12418 sc->display_matrix = NULL;
12419 }
12420 if (sc->stereo3d) {
12423 (uint8_t *)sc->stereo3d, sc->stereo3d_size, 0))
12424 return AVERROR(ENOMEM);
12425
12426 sc->stereo3d = NULL;
12427 }
12428 if (sc->spherical) {
12431 (uint8_t *)sc->spherical, sc->spherical_size, 0))
12432 return AVERROR(ENOMEM);
12433
12434 sc->spherical = NULL;
12435 }
12436 if (sc->mastering) {
12439 (uint8_t *)sc->mastering, sc->mastering_size, 0))
12440 return AVERROR(ENOMEM);
12441
12442 sc->mastering = NULL;
12443 }
12444 if (sc->coll) {
12447 (uint8_t *)sc->coll, sc->coll_size, 0))
12448 return AVERROR(ENOMEM);
12449
12450 sc->coll = NULL;
12451 }
12452 if (sc->ambient) {
12455 (uint8_t *) sc->ambient, sc->ambient_size, 0))
12456 return AVERROR(ENOMEM);
12457
12458 sc->ambient = NULL;
12459 }
12460 break;
12461 }
12462 }
12463
12465
12467
12468 for (i = 0; i < mov->frag_index.nb_items; i++)
12469 if (mov->frag_index.item[i].moof_offset <= mov->fragment.moof_offset)
12470 mov->frag_index.item[i].headers_read = 1;
12471
12472 return 0;
12473}
12474
12476{
12478 int64_t best_dts = INT64_MAX;
12479 int i;
12480 MOVContext *mov = s->priv_data;
12481 int no_interleave = !mov->interleaved_read || !(s->pb->seekable & AVIO_SEEKABLE_NORMAL);
12482 for (i = 0; i < s->nb_streams; i++) {
12483 AVStream *avst = s->streams[i];
12484 FFStream *const avsti = ffstream(avst);
12485 MOVStreamContext *msc = avst->priv_data;
12486 if (msc->pb && msc->current_sample < avsti->nb_index_entries) {
12487 AVIndexEntry *current_sample = &avsti->index_entries[msc->current_sample];
12488 int64_t dts = av_rescale(current_sample->timestamp, AV_TIME_BASE, msc->time_scale);
12489 uint64_t dtsdiff = best_dts > dts ? best_dts - (uint64_t)dts : ((uint64_t)dts - best_dts);
12490 av_log(s, AV_LOG_TRACE, "stream %d, sample %d, dts %"PRId64"\n", i, msc->current_sample, dts);
12491 if (!sample || (no_interleave && current_sample->pos < sample->pos) ||
12492 ((s->pb->seekable & AVIO_SEEKABLE_NORMAL) &&
12493 ((msc->pb != s->pb && dts < best_dts) || (msc->pb == s->pb && dts != AV_NOPTS_VALUE &&
12494 ((dtsdiff <= AV_TIME_BASE && current_sample->pos < sample->pos) ||
12495 (dtsdiff > AV_TIME_BASE && dts < best_dts && mov->interleaved_read)))))) {
12496 sample = current_sample;
12497 best_dts = dts;
12498 *st = avst;
12499 }
12500 }
12501 }
12502 return sample;
12503}
12504
12505static int should_retry(AVIOContext *pb, int error_code) {
12506 if (error_code == AVERROR_EOF || avio_feof(pb))
12507 return 0;
12508
12509 return 1;
12510}
12511
12513{
12514 int ret;
12515 MOVContext *mov = s->priv_data;
12516
12517 if (index >= 0 && index < mov->frag_index.nb_items)
12518 target = mov->frag_index.item[index].moof_offset;
12519 if (target >= 0 && avio_seek(s->pb, target, SEEK_SET) != target) {
12520 av_log(mov->fc, AV_LOG_ERROR, "root atom offset 0x%"PRIx64": partial file\n", target);
12521 return AVERROR_INVALIDDATA;
12522 }
12523
12524 mov->next_root_atom = 0;
12525 if ((index < 0 && target >= 0) || index >= mov->frag_index.nb_items)
12526 index = search_frag_moof_offset(&mov->frag_index, target);
12527 if (index >= 0 && index < mov->frag_index.nb_items &&
12528 mov->frag_index.item[index].moof_offset == target) {
12529 if (index + 1 < mov->frag_index.nb_items)
12532 return 0;
12534 }
12535
12536 mov->found_mdat = 0;
12537
12538 ret = mov_read_default(mov, s->pb, (MOVAtom){ AV_RL32("root"), INT64_MAX });
12539 if (ret < 0)
12540 return ret;
12541 if (avio_feof(s->pb))
12542 return AVERROR_EOF;
12543 av_log(s, AV_LOG_TRACE, "read fragments, offset 0x%"PRIx64"\n", avio_tell(s->pb));
12544
12545 return 1;
12546}
12547
12549{
12550 MOVStreamContext *sc = st->priv_data;
12551 uint8_t *side, *extradata;
12552 int extradata_size;
12553
12554 /* Save the current index. */
12555 sc->last_stsd_index = sc->stsc_data[sc->stsc_index].id - 1;
12556
12557 /* Notify the decoder that extradata changed. */
12558 extradata_size = sc->extradata_size[sc->last_stsd_index];
12559 extradata = sc->extradata[sc->last_stsd_index];
12560 if (st->discard != AVDISCARD_ALL && extradata_size > 0 && extradata) {
12563 extradata_size);
12564 if (!side)
12565 return AVERROR(ENOMEM);
12566 memcpy(side, extradata, extradata_size);
12567 }
12568
12569 return 0;
12570}
12571
12572static int get_eia608_packet(AVIOContext *pb, AVPacket *pkt, int src_size)
12573{
12574 /* We can't make assumptions about the structure of the payload,
12575 because it may include multiple cdat and cdt2 samples. */
12576 const uint32_t cdat = AV_RB32("cdat");
12577 const uint32_t cdt2 = AV_RB32("cdt2");
12578 int ret, out_size = 0;
12579
12580 /* a valid payload must have size, 4cc, and at least 1 byte pair: */
12581 if (src_size < 10)
12582 return AVERROR_INVALIDDATA;
12583
12584 /* avoid an int overflow: */
12585 if ((src_size - 8) / 2 >= INT_MAX / 3)
12586 return AVERROR_INVALIDDATA;
12587
12588 ret = av_new_packet(pkt, ((src_size - 8) / 2) * 3);
12589 if (ret < 0)
12590 return ret;
12591
12592 /* parse and re-format the c608 payload in one pass. */
12593 while (src_size >= 10) {
12594 const uint32_t atom_size = avio_rb32(pb);
12595 const uint32_t atom_type = avio_rb32(pb);
12596 const uint32_t data_size = atom_size - 8;
12597 const uint8_t cc_field =
12598 atom_type == cdat ? 1 :
12599 atom_type == cdt2 ? 2 :
12600 0;
12601
12602 /* account for bytes consumed for atom size and type. */
12603 src_size -= 8;
12604
12605 /* make sure the data size stays within the buffer boundaries. */
12606 if (data_size < 2 || data_size > src_size) {
12607 ret = AVERROR_INVALIDDATA;
12608 break;
12609 }
12610
12611 /* make sure the data size is consistent with N byte pairs. */
12612 if (data_size % 2 != 0) {
12613 ret = AVERROR_INVALIDDATA;
12614 break;
12615 }
12616
12617 if (!cc_field) {
12618 /* neither cdat or cdt2 ... skip it */
12619 avio_skip(pb, data_size);
12620 src_size -= data_size;
12621 continue;
12622 }
12623
12624 for (uint32_t i = 0; i < data_size; i += 2) {
12625 pkt->data[out_size] = (0x1F << 3) | (1 << 2) | (cc_field - 1);
12626 pkt->data[out_size + 1] = avio_r8(pb);
12627 pkt->data[out_size + 2] = avio_r8(pb);
12628 out_size += 3;
12629 src_size -= 2;
12630 }
12631 }
12632
12633 if (src_size > 0)
12634 /* skip any remaining unread portion of the input payload */
12635 avio_skip(pb, src_size);
12636
12638 return ret;
12639}
12640
12642 int64_t current_index, AVPacket *pkt)
12643{
12644 MOVContext *mov = s->priv_data;
12645 MOVStreamContext *sc = st->priv_data;
12646
12647 pkt->stream_index = sc->ffindex;
12648 pkt->dts = sample->timestamp;
12649 if (sample->flags & AVINDEX_DISCARD_FRAME) {
12650 pkt->flags |= AV_PKT_FLAG_DISCARD;
12651 }
12652 if (sc->stts_count && sc->tts_index < sc->tts_count)
12653 pkt->duration = sc->tts_data[sc->tts_index].duration;
12654 if (sc->ctts_count && sc->tts_index < sc->tts_count) {
12655 pkt->pts = av_sat_add64(pkt->dts, av_sat_add64(sc->dts_shift, sc->tts_data[sc->tts_index].offset));
12656 } else {
12657 if (pkt->duration == 0) {
12658 int64_t next_dts = (sc->current_sample < ffstream(st)->nb_index_entries) ?
12660 if (next_dts >= pkt->dts)
12661 pkt->duration = next_dts - pkt->dts;
12662 }
12663 pkt->pts = pkt->dts;
12664 }
12665
12667 sc->current_sample >= ffstream(st)->nb_index_entries) {
12668 int64_t pts = av_rescale_q(pkt->pts, st->time_base, (AVRational){ 1, st->codecpar->sample_rate });
12669 int64_t total = av_rescale_q(st->duration, st->time_base, (AVRational){ 1, st->codecpar->sample_rate });
12670 int64_t duration = pkt->duration;
12671
12672 if (st->duration < pkt->pts) {
12673 duration = 0;
12674 } else
12675 duration = FFMIN(duration, (uint64_t)st->duration - pkt->pts);
12676
12677 duration = av_rescale_q(duration, st->time_base, (AVRational){ 1, st->codecpar->sample_rate });
12678
12679 if (!ffstream(st)->first_discard_sample)
12681 if (!ffstream(st)->last_discard_sample)
12682 ffstream(st)->last_discard_sample = total;
12683 }
12684
12685 if (sc->tts_data && sc->tts_index < sc->tts_count) {
12686 /* update tts context */
12687 sc->tts_sample++;
12688 if (sc->tts_index < sc->tts_count &&
12689 sc->tts_data[sc->tts_index].count == sc->tts_sample) {
12690 sc->tts_index++;
12691 sc->tts_sample = 0;
12692 }
12693 }
12694
12695 if (sc->sdtp_data && sc->current_sample <= sc->sdtp_count) {
12696 uint8_t sample_flags = sc->sdtp_data[sc->current_sample - 1];
12697 uint8_t sample_is_depended_on = (sample_flags >> 2) & 0x3;
12698 pkt->flags |= sample_is_depended_on == MOV_SAMPLE_DEPENDENCY_NO ? AV_PKT_FLAG_DISPOSABLE : 0;
12699 }
12700 pkt->flags |= sample->flags & AVINDEX_KEYFRAME ? AV_PKT_FLAG_KEY : 0;
12701 pkt->pos = sample->pos;
12702
12703 /* Multiple stsd handling. */
12704 if (sc->stsc_data) {
12705 if (sc->stsc_data[sc->stsc_index].id > 0 &&
12706 sc->stsc_data[sc->stsc_index].id - 1 < sc->stsd_count &&
12707 sc->stsc_data[sc->stsc_index].id - 1 != sc->last_stsd_index) {
12708 int ret = mov_change_extradata(st, pkt);
12709 if (ret < 0)
12710 return ret;
12711 }
12712
12713 /* Update the stsc index for the next sample */
12714 sc->stsc_sample++;
12717 sc->stsc_index++;
12718 sc->stsc_sample = 0;
12719 }
12720 }
12721
12722 return 0;
12723}
12724
12726{
12727 MOVContext *mov = s->priv_data;
12728 MOVStreamContext *sc;
12730 AVStream *st = NULL;
12731 FFStream *avsti = NULL;
12732 int64_t current_index;
12733 int ret;
12734 int i;
12735 mov->fc = s;
12736 retry:
12737 if (s->pb->pos == 0) {
12738
12739 // Discard current fragment index
12740 if (mov->frag_index.allocated_size > 0) {
12741 for(int i = 0; i < mov->frag_index.nb_items; i++) {
12743 }
12744 av_freep(&mov->frag_index.item);
12745 mov->frag_index.nb_items = 0;
12746 mov->frag_index.allocated_size = 0;
12747 mov->frag_index.current = -1;
12748 mov->frag_index.complete = 0;
12749 }
12750
12751 for (i = 0; i < s->nb_streams; i++) {
12752 AVStream *avst = s->streams[i];
12753 MOVStreamContext *msc = avst->priv_data;
12754
12755 // Clear current sample
12756 mov_current_sample_set(msc, 0);
12757 msc->tts_index = 0;
12758
12759 // Discard current index entries
12760 avsti = ffstream(avst);
12761 if (avsti->index_entries_allocated_size > 0) {
12762 av_freep(&avsti->index_entries);
12764 avsti->nb_index_entries = 0;
12765 }
12766 }
12767
12768 if ((ret = mov_switch_root(s, -1, -1)) < 0)
12769 return ret;
12770 }
12772 if (!sample || (mov->next_root_atom && sample->pos > mov->next_root_atom)) {
12773 if (!mov->next_root_atom)
12774 return AVERROR_EOF;
12775 if ((ret = mov_switch_root(s, mov->next_root_atom, -1)) < 0)
12776 return ret;
12777 goto retry;
12778 }
12779 sc = st->priv_data;
12780 /* must be done just before reading, to avoid infinite loop on sample */
12781 current_index = sc->current_index;
12783
12784 if (mov->next_root_atom) {
12785 sample->pos = FFMIN(sample->pos, mov->next_root_atom);
12786 sample->size = FFMIN(sample->size, (mov->next_root_atom - sample->pos));
12787 }
12788
12789 if (st->discard != AVDISCARD_ALL || sc->iamf) {
12790 int64_t ret64 = avio_seek(sc->pb, sample->pos, SEEK_SET);
12791 if (ret64 != sample->pos) {
12792 av_log(mov->fc, AV_LOG_ERROR, "stream %d, offset 0x%"PRIx64": partial file\n",
12793 sc->ffindex, sample->pos);
12794 if (should_retry(sc->pb, ret64)) {
12796 } else if (ret64 < 0) {
12797 return (int)ret64;
12798 }
12799 return AVERROR_INVALIDDATA;
12800 }
12801
12802 if (st->discard == AVDISCARD_NONKEY && !(sample->flags & AVINDEX_KEYFRAME)) {
12803 av_log(mov->fc, AV_LOG_DEBUG, "Nonkey frame from stream %d discarded due to AVDISCARD_NONKEY\n", sc->ffindex);
12804 goto retry;
12805 }
12806
12807 if (st->codecpar->codec_id == AV_CODEC_ID_EIA_608 && sample->size > 8)
12808 ret = get_eia608_packet(sc->pb, pkt, sample->size);
12809#if CONFIG_IAMFDEC
12810 else if (sc->iamf) {
12811 int64_t pts, dts, pos, duration;
12812 int flags, size = sample->size;
12813 ret = mov_finalize_packet(s, st, sample, current_index, pkt);
12814 pts = pkt->pts; dts = pkt->dts;
12815 pos = pkt->pos; flags = pkt->flags;
12816 duration = pkt->duration;
12817 while (!ret && size > 0) {
12818 ret = ff_iamf_read_packet(s, sc->iamf, sc->pb, size, sc->iamf_stream_offset, pkt);
12819 if (ret < 0) {
12820 if (should_retry(sc->pb, ret))
12822 return ret;
12823 }
12824 size -= ret;
12825
12826 if (pkt->flags & AV_PKT_FLAG_DISCARD) {
12828 ret = 0;
12829 continue;
12830 }
12831 pkt->pts = pts; pkt->dts = dts;
12832 pkt->pos = pos; pkt->flags |= flags;
12833 pkt->duration = duration;
12834 ret = ff_buffer_packet(s, pkt);
12835 }
12836 if (!ret)
12837 return FFERROR_REDO;
12838 }
12839#endif
12840 else if (st->codecpar->codec_id == AV_CODEC_ID_APV && sample->size > 4) {
12841 uint32_t au_size = avio_rb32(sc->pb);
12842 int explode = !!(mov->fc->error_recognition & AV_EF_EXPLODE);
12843 if (au_size > sample->size - 4) {
12844 av_log(s, explode ? AV_LOG_ERROR : AV_LOG_WARNING,
12845 "APV au_size %u exceeds sample body %d\n",
12846 au_size, sample->size - 4);
12847 if (explode)
12848 return AVERROR_INVALIDDATA;
12849 au_size = sample->size - 4;
12850 }
12851 ret = av_get_packet(sc->pb, pkt, au_size);
12852 } else
12853 ret = av_get_packet(sc->pb, pkt, sample->size);
12854 if (ret < 0) {
12855 if (should_retry(sc->pb, ret)) {
12857 }
12858 return ret;
12859 }
12860#if CONFIG_DV_DEMUXER
12861 if (mov->dv_demux && sc->dv_audio_container) {
12862 ret = avpriv_dv_produce_packet(mov->dv_demux, NULL, pkt->data, pkt->size, pkt->pos);
12864 if (ret < 0)
12865 return ret;
12866 ret = avpriv_dv_get_packet(mov->dv_demux, pkt);
12867 if (ret < 0)
12868 return ret;
12869 }
12870#endif
12871 if (sc->has_palette) {
12872 uint8_t *pal;
12873
12875 if (!pal) {
12876 av_log(mov->fc, AV_LOG_ERROR, "Cannot append palette to packet\n");
12877 } else {
12878 memcpy(pal, sc->palette, AVPALETTE_SIZE);
12879 sc->has_palette = 0;
12880 }
12881 }
12882 if (st->codecpar->codec_id == AV_CODEC_ID_MP3 && !ffstream(st)->need_parsing && pkt->size > 4) {
12883 if (ff_mpa_check_header(AV_RB32(pkt->data)) < 0)
12885 }
12886 }
12887
12888 ret = mov_finalize_packet(s, st, sample, current_index, pkt);
12889 if (ret < 0)
12890 return ret;
12891
12892 if (st->discard == AVDISCARD_ALL)
12893 goto retry;
12894
12895 if (mov->aax_mode)
12896 aax_filter(pkt->data, pkt->size, mov);
12897
12898 ret = cenc_filter(mov, st, sc, pkt, current_index);
12899 if (ret < 0) {
12900 return ret;
12901 }
12902
12903 return 0;
12904}
12905
12907{
12908 MOVContext *mov = s->priv_data;
12909 int index;
12910
12911 if (!mov->frag_index.complete)
12912 return 0;
12913
12914 index = search_frag_timestamp(s, &mov->frag_index, st, timestamp);
12915 if (index < 0)
12916 index = 0;
12917 if (!mov->frag_index.item[index].headers_read)
12918 return mov_switch_root(s, -1, index);
12919 if (index + 1 < mov->frag_index.nb_items)
12921
12922 return 0;
12923}
12924
12926{
12927 // TODO: a bisect search would scale much better
12928 for (int i = 0; i < sc->open_key_samples_count; i++) {
12929 const int oks = sc->open_key_samples[i];
12930 if (oks == sample)
12931 return 1;
12932 if (oks > sample) /* list is monotically increasing so we can stop early */
12933 break;
12934 }
12935 return 0;
12936}
12937
12938/*
12939 * Some key sample may be key frames but not IDR frames, so a random access to
12940 * them may not be allowed.
12941 */
12942static int can_seek_to_key_sample(AVStream *st, int sample, int64_t requested_pts)
12943{
12944 MOVStreamContext *sc = st->priv_data;
12945 FFStream *const sti = ffstream(st);
12946 int64_t key_sample_dts, key_sample_pts;
12947
12949 return 1;
12950
12951 if (sample >= sc->sample_offsets_count)
12952 return 1;
12953
12954 av_assert0(sample >= 0);
12955 key_sample_dts = sti->index_entries[sample].timestamp;
12956 key_sample_pts = key_sample_dts + sc->sample_offsets[sample] + sc->dts_shift;
12957
12958 /*
12959 * If the sample needs to be presented before an open key sample, they may
12960 * not be decodable properly, even though they come after in decoding
12961 * order.
12962 */
12963 if (is_open_key_sample(sc, sample) && key_sample_pts > requested_pts)
12964 return 0;
12965
12966 return 1;
12967}
12968
12969static int mov_seek_stream(AVFormatContext *s, AVStream *st, int64_t timestamp, int flags)
12970{
12971 MOVStreamContext *sc = st->priv_data;
12972 FFStream *const sti = ffstream(st);
12973 int sample, time_sample, ret, requested_sample;
12974 int64_t next_ts;
12975 unsigned int i;
12976
12977 // Here we consider timestamp to be PTS, hence try to offset it so that we
12978 // can search over the DTS timeline.
12979 timestamp -= (sc->min_corrected_pts + sc->dts_shift);
12980
12981 ret = mov_seek_fragment(s, st, timestamp);
12982 if (ret < 0)
12983 return ret;
12984
12985 for (;;) {
12986 sample = av_index_search_timestamp(st, timestamp, flags);
12987 av_log(s, AV_LOG_TRACE, "stream %d, timestamp %"PRId64", sample %d\n", st->index, timestamp, sample);
12988 if (sample < 0 && sti->nb_index_entries && timestamp < sti->index_entries[0].timestamp)
12989 sample = 0;
12990 if (sample < 0) /* not sure what to do */
12991 return AVERROR_INVALIDDATA;
12992
12993 if (!sample || can_seek_to_key_sample(st, sample, timestamp))
12994 break;
12995
12996 next_ts = timestamp - FFMAX(sc->min_sample_duration, 1);
12997 requested_sample = av_index_search_timestamp(st, next_ts, flags);
12998 if (requested_sample < 0)
12999 return AVERROR_INVALIDDATA;
13000
13001 // If we've reached a different sample trying to find a good pts to
13002 // seek to, give up searching because we'll end up seeking back to
13003 // sample 0 on every seek.
13004 if (sample != requested_sample && !can_seek_to_key_sample(st, requested_sample, next_ts))
13005 break;
13006
13007 timestamp = next_ts;
13008 }
13009
13011 av_log(s, AV_LOG_TRACE, "stream %d, found sample %d\n", st->index, sc->current_sample);
13012 /* adjust time to sample index */
13013 if (sc->tts_data) {
13014 time_sample = 0;
13015 for (i = 0; i < sc->tts_count; i++) {
13016 int next = time_sample + sc->tts_data[i].count;
13017 if (next > sc->current_sample) {
13018 sc->tts_index = i;
13019 sc->tts_sample = sc->current_sample - time_sample;
13020 break;
13021 }
13022 time_sample = next;
13023 }
13024 }
13025
13026 /* adjust stsd index */
13027 if (sc->chunk_count) {
13028 time_sample = 0;
13029 for (i = 0; i < sc->stsc_count; i++) {
13030 int64_t next = time_sample + mov_get_stsc_samples(sc, i);
13031 if (next > sc->current_sample) {
13032 sc->stsc_index = i;
13033 sc->stsc_sample = sc->current_sample - time_sample;
13034 break;
13035 }
13036 av_assert0(next == (int)next);
13037 time_sample = next;
13038 }
13039 }
13040
13041 return sample;
13042}
13043
13045{
13046 FFStream *const sti = ffstream(st);
13047 int64_t first_ts = sti->index_entries[0].timestamp;
13049 int64_t off;
13050
13052 return 0;
13053
13054 /* compute skip samples according to stream initial_padding, seek ts and first ts */
13055 off = av_rescale_q(ts - first_ts, st->time_base,
13056 (AVRational){1, st->codecpar->sample_rate});
13057 return FFMAX(st->codecpar->initial_padding - off, 0);
13058}
13059
13060static int mov_read_seek(AVFormatContext *s, int stream_index, int64_t sample_time, int flags)
13061{
13062 MOVContext *mc = s->priv_data;
13063 AVStream *st;
13064 FFStream *sti;
13065 int sample;
13066 int i;
13067
13068 if (stream_index >= s->nb_streams)
13069 return AVERROR_INVALIDDATA;
13070
13071 st = s->streams[stream_index];
13072 sti = ffstream(st);
13073 sample = mov_seek_stream(s, st, sample_time, flags);
13074 if (sample < 0)
13075 return sample;
13076
13077 if (mc->seek_individually) {
13078 /* adjust seek timestamp to found sample timestamp */
13079 int64_t seek_timestamp = sti->index_entries[sample].timestamp;
13081
13082 for (i = 0; i < s->nb_streams; i++) {
13083 AVStream *const st = s->streams[i];
13084 FFStream *const sti = ffstream(st);
13085 int64_t timestamp;
13086
13087 if (stream_index == i)
13088 continue;
13089
13090 timestamp = av_rescale_q(seek_timestamp, s->streams[stream_index]->time_base, st->time_base);
13091 sample = mov_seek_stream(s, st, timestamp, flags);
13092 if (sample >= 0)
13094 }
13095 } else {
13096 for (i = 0; i < s->nb_streams; i++) {
13097 MOVStreamContext *sc;
13098 st = s->streams[i];
13099 sc = st->priv_data;
13101 }
13102 while (1) {
13103 MOVStreamContext *sc;
13105 if (!entry)
13106 return AVERROR_INVALIDDATA;
13107 sc = st->priv_data;
13108 if (sc->ffindex == stream_index && sc->current_sample == sample)
13109 break;
13111 }
13112 }
13113 return 0;
13114}
13115
13116#define OFFSET(x) offsetof(MOVContext, x)
13117#define FLAGS AV_OPT_FLAG_VIDEO_PARAM | AV_OPT_FLAG_DECODING_PARAM
13118static const AVOption mov_options[] = {
13119 {"use_absolute_path",
13120 "allow using absolute path when opening alias, this is a possible security issue",
13121 OFFSET(use_absolute_path), AV_OPT_TYPE_BOOL, {.i64 = 0},
13122 0, 1, FLAGS},
13123 {"seek_streams_individually",
13124 "Seek each stream individually to the closest point",
13125 OFFSET(seek_individually), AV_OPT_TYPE_BOOL, { .i64 = 1 },
13126 0, 1, FLAGS},
13127 {"ignore_editlist", "Ignore the edit list atom.", OFFSET(ignore_editlist), AV_OPT_TYPE_BOOL, {.i64 = 0},
13128 0, 1, FLAGS},
13129 {"advanced_editlist",
13130 "Modify the AVIndex according to the editlists. Use this option to decode in the order specified by the edits.",
13131 OFFSET(advanced_editlist), AV_OPT_TYPE_BOOL, {.i64 = 1},
13132 0, 1, FLAGS},
13133 {"ignore_chapters", "", OFFSET(ignore_chapters), AV_OPT_TYPE_BOOL, {.i64 = 0},
13134 0, 1, FLAGS},
13135 {"use_mfra_for",
13136 "use mfra for fragment timestamps",
13137 OFFSET(use_mfra_for), AV_OPT_TYPE_INT, {.i64 = FF_MOV_FLAG_MFRA_AUTO},
13139 .unit = "use_mfra_for"},
13140 {"auto", "auto", 0, AV_OPT_TYPE_CONST, {.i64 = FF_MOV_FLAG_MFRA_AUTO}, 0, 0,
13141 FLAGS, .unit = "use_mfra_for" },
13142 {"dts", "dts", 0, AV_OPT_TYPE_CONST, {.i64 = FF_MOV_FLAG_MFRA_DTS}, 0, 0,
13143 FLAGS, .unit = "use_mfra_for" },
13144 {"pts", "pts", 0, AV_OPT_TYPE_CONST, {.i64 = FF_MOV_FLAG_MFRA_PTS}, 0, 0,
13145 FLAGS, .unit = "use_mfra_for" },
13146 {"use_tfdt", "use tfdt for fragment timestamps", OFFSET(use_tfdt), AV_OPT_TYPE_BOOL, {.i64 = 1},
13147 0, 1, FLAGS},
13148 { "export_all", "Export unrecognized metadata entries", OFFSET(export_all),
13149 AV_OPT_TYPE_BOOL, { .i64 = 0 }, 0, 1, .flags = FLAGS },
13150 { "export_xmp", "Export full XMP metadata", OFFSET(export_xmp),
13151 AV_OPT_TYPE_BOOL, { .i64 = 0 }, 0, 1, .flags = FLAGS },
13152 { "activation_bytes", "Secret bytes for Audible AAX files", OFFSET(activation_bytes),
13154 { "audible_key", "AES-128 Key for Audible AAXC files", OFFSET(audible_key),
13156 { "audible_iv", "AES-128 IV for Audible AAXC files", OFFSET(audible_iv),
13158 { "audible_fixed_key", // extracted from libAAX_SDK.so and AAXSDKWin.dll files!
13159 "Fixed key used for handling Audible AAX files", OFFSET(audible_fixed_key),
13160 AV_OPT_TYPE_BINARY, {.str="77214d4b196a87cd520045fd20a51d67"},
13161 .flags = AV_OPT_FLAG_DECODING_PARAM },
13162 { "decryption_key", "The default media decryption key (hex)", OFFSET(decryption_default_key), AV_OPT_TYPE_BINARY, .flags = AV_OPT_FLAG_DECODING_PARAM },
13163 { "decryption_keys", "The media decryption keys by KID (hex)", OFFSET(decryption_keys), AV_OPT_TYPE_DICT, .flags = AV_OPT_FLAG_DECODING_PARAM },
13164 { "enable_drefs", "Enable external track support.", OFFSET(enable_drefs), AV_OPT_TYPE_BOOL,
13165 {.i64 = 0}, 0, 1, FLAGS },
13166 { "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 },
13167 { "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 },
13168
13169 { NULL },
13170};
13171
13172static const AVClass mov_class = {
13173 .class_name = "mov,mp4,m4a,3gp,3g2,mj2",
13174 .item_name = av_default_item_name,
13175 .option = mov_options,
13176 .version = LIBAVUTIL_VERSION_INT,
13177};
13178
13180 .p.name = "mov,mp4,m4a,3gp,3g2,mj2",
13181 .p.long_name = NULL_IF_CONFIG_SMALL("QuickTime / MOV"),
13182 .p.priv_class = &mov_class,
13183 .p.extensions = "mov,mp4,m4a,3gp,3g2,mj2,psp,m4v,m4b,ism,ismv,isma,f4v,avif,heic,heif",
13185 .priv_data_size = sizeof(MOVContext),
13186 .flags_internal = FF_INFMT_FLAG_INIT_CLEANUP,
13192};
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:13179
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:1176
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:885
void av_exif_free(AVExifMetadata *ifd)
Frees all resources associated with the given EXIF metadata struct.
Definition exif.c:662
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:756
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:1275
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:399
static int64_t start_time
Definition ffplay.c:398
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:585
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:627
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:233
AVDictionaryEntry * av_dict_get(const AVDictionary *m, const char *key, const AVDictionaryEntry *prev, int flags)
Get a dictionary entry with matching key.
Definition dict.c:60
int av_dict_copy(AVDictionary **dst, const AVDictionary *src, int flags)
Copy entries from one AVDictionary struct into another.
Definition dict.c:247
#define AV_DICT_APPEND
If the entry already exists, append to it.
Definition dict.h:82
#define AV_DICT_DONT_STRDUP_VAL
Take ownership of a value that's been allocated with av_malloc() or another memory allocation functio...
Definition dict.h:79
int av_dict_set(AVDictionary **pm, const char *key, const char *value, int flags)
Set the given entry in *pm, overwriting an existing entry.
Definition dict.c:86
#define AV_DICT_DONT_OVERWRITE
Don't overwrite existing entries.
Definition dict.h:81
#define AV_DICT_DONT_STRDUP_KEY
Take ownership of a key that's been allocated with av_malloc() or another memory allocation function.
Definition dict.h:77
#define AV_DICT_MATCH_CASE
Only get an entry with exact-case key match.
Definition dict.h:74
int av_dict_set_int(AVDictionary **pm, const char *key, int64_t value, int flags)
Convenience wrapper for av_dict_set() that converts the value to a string and stores it.
Definition dict.c:177
#define AVERROR_PATCHWELCOME
Not yet implemented in FFmpeg, patches welcome.
Definition error.h:64
#define AVERROR_BUG
Internal bug, also see AVERROR_BUG2.
Definition error.h:52
#define AVERROR_INVALIDDATA
Invalid data found when processing input.
Definition error.h:61
#define AVERROR_EOF
End of file.
Definition error.h:57
#define av_err2str(errnum)
Convenience macro, the return value should be used only directly in function arguments but never stan...
Definition error.h:122
#define AVERROR(e)
Definition error.h:45
void av_iamf_audio_element_free(AVIAMFAudioElement **paudio_element)
Free an AVIAMFAudioElement and all its contents.
Definition iamf.c:338
@ AV_IAMF_AUDIO_ELEMENT_TYPE_SCENE
Definition iamf.h:349
void av_iamf_mix_presentation_free(AVIAMFMixPresentation **pmix_presentation)
Free an AVIAMFMixPresentation and all its contents.
Definition iamf.c:536
#define AV_LOG_TRACE
Extremely verbose debugging, useful for libav* development.
Definition log.h:236
#define AV_LOG_DEBUG
Stuff which is only useful for libav* developers.
Definition log.h:231
#define AV_LOG_WARNING
Something somehow does not look correct.
Definition log.h:216
#define AV_LOG_FATAL
Something went wrong and recovery is not possible.
Definition log.h:204
#define AV_LOG_VERBOSE
Detailed information.
Definition log.h:226
#define AV_LOG_INFO
Standard information.
Definition log.h:221
#define AV_LOG_ERROR
Something went wrong and cannot losslessly be recovered.
Definition log.h:210
const char * av_default_item_name(void *ptr)
Return the context name.
Definition log.c:241
AVRational av_add_q(AVRational b, AVRational c)
Add two rationals.
Definition rational.c:93
AVRational av_mul_q(AVRational b, AVRational c)
Multiply two rationals.
Definition rational.c:80
int av_reduce(int *dst_num, int *dst_den, int64_t num, int64_t den, int64_t max)
Reduce a fraction.
Definition rational.c:35
static AVRational av_make_q(int num, int den)
Create an AVRational.
Definition rational.h:71
AVRational av_d2q(double d, int max)
Convert a double precision floating point number to a rational.
Definition rational.c:110
static double av_q2d(AVRational a)
Convert an AVRational to a double.
Definition rational.h:104
static int av_cmp_q(AVRational a, AVRational b)
Compare two rationals.
Definition rational.h:89
AVRational av_sub_q(AVRational b, AVRational c)
Subtract one rational from another.
Definition rational.c:101
int64_t av_rescale(int64_t a, int64_t b, int64_t c)
Rescale a 64-bit integer with rounding to nearest.
int64_t av_rescale_q(int64_t a, AVRational bq, AVRational cq)
Rescale a 64-bit integer by 2 rational numbers.
void * av_dynarray2_add(void **tab_ptr, int *nb_ptr, size_t elem_size, const uint8_t *elem_data)
Add an element of size elem_size to a dynamic array.
Definition mem.c:447
void * av_fast_realloc(void *ptr, unsigned int *size, size_t min_size)
Reallocate the given buffer if it is not large enough, otherwise do nothing.
Definition mem.c:601
void * av_realloc_array(void *ptr, size_t nmemb, size_t size)
Definition mem.c:318
int av_reallocp(void *ptr, size_t size)
Allocate, reallocate, or free a block of memory through a pointer to a pointer.
Definition mem.c:289
int av_reallocp_array(void *ptr, size_t nmemb, size_t size)
Allocate, reallocate an array through a pointer to a pointer.
Definition mem.c:326
const char * av_get_media_type_string(enum AVMediaType media_type)
Return a string describing the media_type enum, NULL if media_type is unknown.
Definition utils.c:28
char * av_fourcc_make_string(char *buf, uint32_t fourcc)
Fill the provided buffer with a string containing a FourCC (four-character code) representation.
Definition utils.c:54
#define av_fourcc2str(fourcc)
Definition avutil.h:323
#define AV_FOURCC_MAX_STRING_SIZE
Definition avutil.h:321
@ AVMEDIA_TYPE_AUDIO
Definition avutil.h:201
@ AVMEDIA_TYPE_SUBTITLE
Definition avutil.h:203
@ AVMEDIA_TYPE_VIDEO
Definition avutil.h:200
@ AVMEDIA_TYPE_DATA
Opaque data information usually continuous.
Definition avutil.h:202
void av_sha_update(struct AVSHA *ctx, const uint8_t *data, size_t len)
Update hash value.
Definition sha.c:315
struct AVSHA * av_sha_alloc(void)
Allocate an AVSHA context.
Definition sha.c:46
void av_sha_final(AVSHA *ctx, uint8_t *digest)
Finish hashing and output digest value.
Definition sha.c:347
av_cold int av_sha_init(AVSHA *ctx, int bits)
Initialize SHA-1 or SHA-2 hashing.
Definition sha.c:274
size_t av_strlcat(char *dst, const char *src, size_t size)
Append the string src to the string dst, but to a total length of no more than size - 1 bytes,...
Definition avstring.c:95
char * av_stristr(const char *s1, const char *s2)
Locate the first case-independent occurrence in the string haystack of the string needle.
Definition avstring.c:58
int av_strstart(const char *str, const char *pfx, const char **ptr)
Return non-zero if pfx is a prefix of str.
Definition avstring.c:36
#define AV_NOPTS_VALUE
Undefined timestamp value.
Definition avutil.h:247
#define AV_TIME_BASE
Internal time base represented as integer.
Definition avutil.h:253
#define LIBAVUTIL_VERSION_INT
Definition version.h:85
void av_display_rotation_set(int32_t matrix[9], double angle)
Initialize a transformation matrix describing a pure clockwise rotation by the specified angle (in de...
Definition display.c:50
void av_display_matrix_flip(int32_t matrix[9], int hflip, int vflip)
Flip the input matrix horizontally and/or vertically.
Definition display.c:65
AVSphericalMapping * av_spherical_alloc(size_t *size)
Allocate a AVSphericalVideo structure and initialize its fields to default values.
Definition spherical.c:26
AVSphericalProjection
Projection of the video surface(s) on a sphere.
Definition spherical.h:47
@ AV_SPHERICAL_RECTILINEAR
Video frame displays on a flat, rectangular 2D surface.
Definition spherical.h:78
@ AV_SPHERICAL_EQUIRECTANGULAR
Video represents a sphere mapped on a flat surface using equirectangular projection.
Definition spherical.h:52
@ AV_SPHERICAL_EQUIRECTANGULAR_TILE
Video represents a portion of a sphere mapped on a flat surface using equirectangular projection.
Definition spherical.h:68
@ AV_SPHERICAL_CUBEMAP
Video frame is split into 6 faces of a cube, and arranged on a 3x2 layout.
Definition spherical.h:61
@ AV_SPHERICAL_HALF_EQUIRECTANGULAR
Video frame displays as a 180 degree equirectangular projection.
Definition spherical.h:73
@ AV_SPHERICAL_PARAMETRIC_IMMERSIVE
Parametric Immersive projection (Apple).
Definition spherical.h:90
@ AV_SPHERICAL_FISHEYE
Fisheye projection (Apple).
Definition spherical.h:84
AVStereo3DType
List of possible 3D Types.
Definition stereo3d.h:48
AVStereo3D * av_stereo3d_alloc_size(size_t *size)
Allocate an AVStereo3D structure and set its fields to default values.
Definition stereo3d.c:39
#define AV_STEREO3D_FLAG_INVERT
Inverted views, Right/Bottom represents the left view.
Definition stereo3d.h:194
AVStereo3DPrimaryEye
List of possible primary eyes.
Definition stereo3d.h:174
AVStereo3DView
List of possible view types.
Definition stereo3d.h:149
@ AV_STEREO3D_2D
Video is not stereoscopic (and metadata has to be there).
Definition stereo3d.h:52
@ AV_STEREO3D_TOPBOTTOM
Views are on top of each other.
Definition stereo3d.h:76
@ AV_STEREO3D_UNSPEC
Video is stereoscopic but the packing is unspecified.
Definition stereo3d.h:143
@ AV_STEREO3D_SIDEBYSIDE
Views are next to each other.
Definition stereo3d.h:64
@ AV_PRIMARY_EYE_NONE
Neither eye.
Definition stereo3d.h:178
@ AV_PRIMARY_EYE_LEFT
Left eye.
Definition stereo3d.h:183
@ AV_PRIMARY_EYE_RIGHT
Right eye.
Definition stereo3d.h:188
@ AV_STEREO3D_VIEW_RIGHT
Frame contains only the right view.
Definition stereo3d.h:163
@ AV_STEREO3D_VIEW_PACKED
Frame contains two packed views.
Definition stereo3d.h:153
@ AV_STEREO3D_VIEW_LEFT
Frame contains only the left view.
Definition stereo3d.h:158
@ AV_STEREO3D_VIEW_UNSPEC
Content is unspecified.
Definition stereo3d.h:168
int index
Definition gxfenc.c:90
int a
int tile_rows
#define MAX_REORDER_DELAY
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:5719
static int64_t mov_get_skip_samples(AVStream *st, int sample)
Definition mov.c:13044
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:12572
static int mov_read_iloc(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition mov.c:9460
static int mov_read_pack(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition mov.c:7133
static int read_image_grid(AVFormatContext *s, const HEIFGroup *grid, AVStreamGroupTileGrid *tile_grid)
Definition mov.c:11156
static int mov_apply_heif_item_references(AVFormatContext *s, HEIFItem *item, AVPacketSideData **coded_side_data, int *nb_coded_side_data)
Definition mov.c:11381
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:4232
static int mov_read_seek(AVFormatContext *s, int stream_index, int64_t sample_time, int flags)
Definition mov.c:13060
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:10809
static int mov_read_stsd(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition mov.c:3460
static void mov_parse_stsd_video(MOVContext *c, AVIOContext *pb, AVStream *st, MOVStreamContext *sc)
Definition mov.c:2934
static int heif_add_stream(MOVContext *c, HEIFItem *item)
Definition mov.c:5881
static int mov_read_dops(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition mov.c:9015
static int set_display_matrix_from_item(AVPacketSideData **coded_side_data, int *nb_coded_side_data, const HEIFItem *item)
Definition mov.c:11128
static int mov_compare_presentation_samples(const void *a, const void *b)
Definition mov.c:5289
static int mov_switch_root(AVFormatContext *s, int64_t target, int index)
Definition mov.c:12512
static int mov_read_vexu_proj(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition mov.c:7351
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:8599
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:9454
static int mov_parse_tmcd_streams(AVFormatContext *s)
Definition mov.c:11952
static int mov_read_lhvc(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition mov.c:9150
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:4478
static int mov_finalize_stsd_entry(MOVContext *c, AVStream *st)
Definition mov.c:3338
static int mov_read_pitm(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition mov.c:9446
static int mov_seek_stream(AVFormatContext *s, AVStream *st, int64_t timestamp, int flags)
Definition mov.c:12969
static int mov_read_packet(AVFormatContext *s, AVPacket *pkt)
Definition mov.c:12725
static int mov_parse_lcevc_streams(AVFormatContext *s)
Definition mov.c:12075
static int mov_read_hvce(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition mov.c:9123
static int cbcs_scheme_decrypt(MOVContext *c, MOVStreamContext *sc, AVEncryptionInfo *sample, uint8_t *input, int size)
Definition mov.c:8832
static int mov_read_default(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition mov.c:10394
static int mov_finalize_packet(AVFormatContext *s, AVStream *st, AVIndexEntry *sample, int64_t current_index, AVPacket *pkt)
Definition mov.c:12641
static int mov_read_stss(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition mov.c:3668
static uint64_t mov_dts_channel_layout_to_mask(unsigned int code)
Definition mov.c:1216
static int64_t get_stream_info_time(MOVFragmentStreamInfo *frag_stream_info)
Definition mov.c:1800
static int mov_read_saio(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition mov.c:8241
static int mov_skip_multiple_stsd(MOVContext *c, AVIOContext *pb, int codec_tag, int format, int64_t size)
Definition mov.c:3312
static int mov_read_iref_auxl(MOVContext *c, AVIOContext *pb, uint32_t type, int version, uint32_t size)
Definition mov.c:9904
#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:6832
int ff_mov_read_stsd_entries(MOVContext *c, AVIOContext *pb, int entries)
Definition mov.c:3359
static int mov_metadata_gnre(MOVContext *c, AVIOContext *pb, unsigned len, const char *key)
Definition mov.c:138
static int mov_read_dref(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition mov.c:656
static int mov_read_dpxe(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition mov.c:2412
static MovTref * mov_find_tref_tag(const MOVStreamContext *sc, uint32_t name)
Definition mov.c:2684
static int mov_read_eyes(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition mov.c:7424
static int cenc_scheme_decrypt(MOVContext *c, MOVStreamContext *sc, AVEncryptionInfo *sample, uint8_t *input, int size)
Definition mov.c:8636
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:9797
static int mov_read_stsz(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition mov.c:3723
static int mov_dts_stream_construction_to_profile(unsigned int sc)
Definition mov.c:1183
static int rb_size(AVIOContext *pb, int64_t *value, int size)
Definition mov.c:9406
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:12240
static int mov_read_dfla(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition mov.c:8559
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:7086
static int mov_read_elst(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition mov.c:6758
static int test_same_origin(const char *src, const char *ref)
Definition mov.c:5387
static int sanity_checks(void *log_obj, MOVStreamContext *sc, int index)
Definition mov.c:5544
static void mov_current_sample_set(MOVStreamContext *sc, int current_sample)
Definition mov.c:4490
static int mov_merge_tts_data(MOVContext *mov, AVStream *st, int flags)
Definition mov.c:4905
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:7214
static int mov_read_ddts(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition mov.c:1244
static int mov_read_sdtp(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition mov.c:3936
static int mov_read_stts(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition mov.c:3816
static int cenc_filter(MOVContext *mov, AVStream *st, MOVStreamContext *sc, AVPacket *pkt, int current_index)
Definition mov.c:8945
static const AVClass mov_class
Definition mov.c:13172
static int mov_read_sample_encryption_info(MOVContext *c, AVIOContext *pb, MOVStreamContext *sc, AVEncryptionInfo **sample, int use_subsamples)
Definition mov.c:7985
static int mov_read_meta(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition mov.c:5940
static int mov_read_smdm(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition mov.c:6904
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:6546
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:4827
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:10724
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:9068
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:8457
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:10967
static int mov_seek_fragment(AVFormatContext *s, AVStream *st, int64_t timestamp)
Definition mov.c:12906
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:11536
static int mov_parse_dovi_streams(AVFormatContext *s)
Definition mov.c:12129
static int mov_read_chnl(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition mov.c:1325
static void mov_metadata_creation_time(MOVContext *c, AVIOContext *pb, AVDictionary **metadata, int version)
Definition mov.c:1981
static int mov_stsc_index_valid(unsigned int index, unsigned int count)
Definition mov.c:3606
static int mov_read_hdlr(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition mov.c:800
#define MOV_MERGE_STTS
Definition mov.c:4899
static int mov_read_dvcc_dvvc(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition mov.c:9103
static int should_retry(AVIOContext *pb, int error_code)
Definition mov.c:12505
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:6165
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:7032
static int mov_read_trun(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition mov.c:6204
static void mov_update_dts_shift(MOVStreamContext *sc, int duration, void *logctx)
Definition mov.c:3974
static int mov_read_kind(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition mov.c:9201
static int mov_read_sbgp(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition mov.c:4125
static int mov_metadata_track_or_disc_number(MOVContext *c, AVIOContext *pb, unsigned len, const char *key)
Definition mov.c:95
static int mov_read_ares(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition mov.c:2439
static int mov_read_pssh(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition mov.c:8336
static int mov_finalize_stsd_codec(MOVContext *c, AVIOContext *pb, AVStream *st, MOVStreamContext *sc)
Definition mov.c:3208
static int mov_read_tkhd(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition mov.c:5966
static int mov_read_iprp(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition mov.c:10069
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:8761
static int read_image_iovl(AVFormatContext *s, const HEIFGroup *grid, AVStreamGroupTileGrid *tile_grid)
Definition mov.c:11251
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:11022
static int mov_read_iref_dimg_grid(MOVContext *c, AVIOContext *pb, HEIFItem *item, int version, int entries)
Definition mov.c:9755
#define MIN_DATA_ENTRY_BOX_SIZE
Definition mov.c:655
static int mov_change_extradata(AVStream *st, AVPacket *pkt)
Definition mov.c:12548
static int mov_read_mdcv(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition mov.c:6951
static int mov_read_timecode_track(AVFormatContext *s, AVStream *st)
Definition mov.c:10750
static int mov_read_imir(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition mov.c:10050
static int mov_read_stps(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition mov.c:3627
static int mov_read_svq3(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition mov.c:2527
static int mov_read_pcmc(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition mov.c:2134
static int mov_read_auxc(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition mov.c:9425
static int mov_parse_cdsc_and_rndr_streams(AVFormatContext *s)
Definition mov.c:12023
static const MOVParseTableEntry mov_default_parse_table[]
Definition mov.c:10257
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:9952
static int mov_read_trex(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition mov.c:6139
static int mov_read_saiz(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition mov.c:8157
static int mov_read_hfov(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition mov.c:7668
static int mov_read_free(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition mov.c:7865
static int set_icc_profile_from_item(AVPacketSideData **coded_side_data, int *nb_coded_side_data, const HEIFItem *item)
Definition mov.c:11106
static int mov_read_infe(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition mov.c:9557
static int mov_parse_heif_item_references(AVFormatContext *s, HEIFItem *item, AVPacketSideData **coded_side_data, int *nb_coded_side_data)
Definition mov.c:11411
static int mov_read_stsc(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition mov.c:3526
static AVStream * get_curr_st(MOVContext *c)
Get the current stream in the parsing process.
Definition mov.c:217
static int mov_parse_stsd_data(MOVContext *c, AVIOContext *pb, AVStream *st, MOVStreamContext *sc, int64_t size)
Definition mov.c:3135
static int mov_read_mdat(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition mov.c:1505
static int cbc1_scheme_decrypt(MOVContext *c, MOVStreamContext *sc, AVEncryptionInfo *sample, uint8_t *input, int size)
Definition mov.c:8695
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:11068
static void fix_timescale(MOVContext *c, MOVStreamContext *sc)
Definition mov.c:5488
static int mov_read_custom(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition mov.c:5780
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:7934
static int mov_read_close(AVFormatContext *s)
Definition mov.c:10874
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:5416
static MOVFragmentStreamInfo * get_frag_stream_info_from_pkt(MOVFragmentIndex *frag_index, AVPacket *pkt, int id)
Definition mov.c:8920
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:8488
static int mov_read_uuid(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition mov.c:7760
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:4835
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:4968
static void mov_update_sample_durations(MOVContext *mov, AVStream *st)
Definition mov.c:5302
static int mov_read_ctts(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition mov.c:3985
static int mov_find_tref_id(const MovTref *tag, uint32_t id)
Definition mov.c:2660
static int mov_parse_heif_layered_video(AVFormatContext *s)
Definition mov.c:11836
static int mov_read_amve(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition mov.c:7061
static int mov_read_keys(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition mov.c:5728
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:5958
static int can_seek_to_key_sample(AVStream *st, int sample, int64_t requested_pts)
Definition mov.c:12942
static int mov_parse_auxiliary_info(MOVContext *c, MOVStreamContext *sc, AVIOContext *pb, MOVEncryptionIndex *encryption_index)
Definition mov.c:8095
static int64_t mov_get_stsc_samples(MOVStreamContext *sc, unsigned int index)
Definition mov.c:3612
static int mov_read_vpcc(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition mov.c:6860
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:4328
static int mov_parse_tiles(AVFormatContext *s)
Definition mov.c:11440
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:4518
#define DDTS_SIZE
static int mov_read_iref_cdsc(MOVContext *c, AVIOContext *pb, uint32_t type, int version, uint32_t size)
Definition mov.c:9858
static int cenc_decrypt(MOVContext *c, MOVStreamContext *sc, AVEncryptionInfo *sample, uint8_t *input, int size)
Definition mov.c:8904
static int mov_read_senc(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition mov.c:8039
static int mov_parse_heif_layered_video_auxl(AVFormatContext *s, HEIFItem *base, HEIFItem *gain_map)
Definition mov.c:11710
static int mov_read_sgpd(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition mov.c:4066
static AVStream * mov_find_reference_track(AVFormatContext *s, AVStream *st, uint32_t *tref_id, int nb_tref_id, int first_index)
Definition mov.c:12008
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:4369
static int mov_read_trak(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition mov.c:5563
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:4381
static void mov_parse_stsd_subtitle(MOVContext *c, AVIOContext *pb, AVStream *st, MOVStreamContext *sc, int64_t size)
Definition mov.c:3119
static int mov_read_clap(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition mov.c:1374
static int mov_read_dvc1(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition mov.c:2635
static int mov_read_vdep(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition mov.c:2775
static int mov_read_SAND(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition mov.c:9380
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:10797
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:12202
#define OFFSET(x)
Definition mov.c:13116
static AVIndexEntry * mov_find_next_sample(AVFormatContext *s, AVStream **st)
Definition mov.c:12475
static int mov_read_chap(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition mov.c:6118
#define MOV_MERGE_CTTS
Definition mov.c:4898
static int is_open_key_sample(const MOVStreamContext *sc, int sample)
Definition mov.c:12925
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:9290
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:6995
static int mov_read_frma(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition mov.c:7887
static int mov_read_ispe(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition mov.c:10002
static int mov_codec_id(AVStream *st, uint32_t format)
Definition mov.c:2894
static void export_orphan_timecode(AVFormatContext *s)
Definition mov.c:10949
static int mov_parse_heif_items(AVFormatContext *s)
Definition mov.c:11885
static void mov_estimate_video_delay(MOVContext *c, AVStream *st)
Definition mov.c:4410
static int mov_read_vmhd(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition mov.c:10186
static int mov_read_tfhd(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition mov.c:6071
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:10030
static int mov_probe(const AVProbeData *p)
Definition mov.c:10516
static int parse_timecode_in_framenum_format(AVFormatContext *s, AVStream *st, int64_t value, int flags)
Definition mov.c:10710
static int mov_parse_uuid_spherical(MOVStreamContext *sc, AVIOContext *pb, size_t len)
Definition mov.c:7697
static void mov_current_sample_inc(MOVStreamContext *sc)
Definition mov.c:4466
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:9705
static int mov_read_targa_y216(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition mov.c:2425
static int get_edit_list_entry(MOVContext *mov, const MOVStreamContext *msc, unsigned int edit_list_index, int64_t *edit_list_media_time, int64_t *edit_list_duration, int64_t global_timescale)
Get ith edit list entry (media time, duration).
Definition mov.c:4186
static void mov_parse_stsd_audio(MOVContext *c, AVIOContext *pb, AVStream *st, MOVStreamContext *sc)
Definition mov.c:2998
static int mov_read_wide(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition mov.c:6685
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:9635
static int mov_parse_exif_item(AVFormatContext *s, HEIFItem *item, const HEIFItem *ref)
Definition mov.c:11320
static int tmcd_is_referenced(AVFormatContext *s, int tmcd_id)
Definition mov.c:10931
static void mov_read_chapters(AVFormatContext *s)
Definition mov.c:10611
static int mov_read_mhac(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition mov.c:10219
static int mov_read_cmov(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition mov.c:6705
static void set_frag_stream(MOVFragmentIndex *frag_index, int id)
Definition mov.c:1740
static const AVOption mov_options[]
Definition mov.c:13118
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:7606
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]