• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
32 #include "libavutil/attributes.h"
33 #include "libavutil/bprint.h"
34 #include "libavutil/channel_layout.h"
35 #include "libavutil/internal.h"
36 #include "libavutil/intreadwrite.h"
37 #include "libavutil/intfloat.h"
38 #include "libavutil/mathematics.h"
39 #include "libavutil/avassert.h"
40 #include "libavutil/avstring.h"
41 #include "libavutil/dict.h"
42 #include "libavutil/opt.h"
43 #include "libavutil/aes.h"
44 #include "libavutil/aes_ctr.h"
45 #include "libavutil/pixdesc.h"
46 #include "libavutil/sha.h"
47 #include "libavutil/spherical.h"
48 #include "libavutil/stereo3d.h"
49 #include "libavutil/timecode.h"
50 #include "libavutil/uuid.h"
51 #include "libavcodec/ac3tab.h"
52 #include "libavcodec/flac.h"
53 #include "libavcodec/hevc.h"
54 #include "libavcodec/mpegaudiodecheader.h"
55 #include "libavcodec/mlp_parse.h"
56 #include "avformat.h"
57 #include "internal.h"
58 #include "avio_internal.h"
59 #include "demux.h"
60 #include "dovi_isom.h"
61 #include "riff.h"
62 #include "isom.h"
63 #include "libavcodec/get_bits.h"
64 #include "id3v1.h"
65 #include "mov_chan.h"
66 #include "replaygain.h"
67 
68 #if CONFIG_ZLIB
69 #include <zlib.h>
70 #endif
71 
72 #include "qtpalette.h"
73 
74 #ifdef OHOS_DRM
75 #define MOV_DRM_PSSH_TITLE_LEN    (8)
76 
77 static const uint8_t g_pssh_title_buf[4] = { // 4:bufSize
78     0x70, 0x73, 0x73, 0x68
79 };
80 #endif
81 
82 /* those functions parse an atom */
83 /* links atom IDs to parse functions */
84 typedef struct MOVParseTableEntry {
85     uint32_t type;
86     int (*parse)(MOVContext *ctx, AVIOContext *pb, MOVAtom atom);
87 } MOVParseTableEntry;
88 
89 static int mov_read_default(MOVContext *c, AVIOContext *pb, MOVAtom atom);
90 static int mov_read_mfra(MOVContext *c, AVIOContext *f);
91 static int64_t add_ctts_entry(MOVCtts** ctts_data, unsigned int* ctts_count, unsigned int* allocated_size,
92                               int count, int duration);
93 
mov_metadata_track_or_disc_number(MOVContext * c,AVIOContext * pb,unsigned len,const char * key)94 static int mov_metadata_track_or_disc_number(MOVContext *c, AVIOContext *pb,
95                                              unsigned len, const char *key)
96 {
97     char buf[16];
98 
99     short current, total = 0;
100     avio_rb16(pb); // unknown
101     current = avio_rb16(pb);
102     if (len >= 6)
103         total = avio_rb16(pb);
104     if (!total)
105         snprintf(buf, sizeof(buf), "%d", current);
106     else
107         snprintf(buf, sizeof(buf), "%d/%d", current, total);
108     c->fc->event_flags |= AVFMT_EVENT_FLAG_METADATA_UPDATED;
109     av_dict_set(&c->fc->metadata, key, buf, 0);
110 
111     return 0;
112 }
113 
mov_metadata_int8_bypass_padding(MOVContext * c,AVIOContext * pb,unsigned len,const char * key)114 static int mov_metadata_int8_bypass_padding(MOVContext *c, AVIOContext *pb,
115                                             unsigned len, const char *key)
116 {
117     /* bypass padding bytes */
118     avio_r8(pb);
119     avio_r8(pb);
120     avio_r8(pb);
121 
122     c->fc->event_flags |= AVFMT_EVENT_FLAG_METADATA_UPDATED;
123     av_dict_set_int(&c->fc->metadata, key, avio_r8(pb), 0);
124 
125     return 0;
126 }
127 
mov_metadata_int8_no_padding(MOVContext * c,AVIOContext * pb,unsigned len,const char * key)128 static int mov_metadata_int8_no_padding(MOVContext *c, AVIOContext *pb,
129                                         unsigned len, const char *key)
130 {
131     c->fc->event_flags |= AVFMT_EVENT_FLAG_METADATA_UPDATED;
132     av_dict_set_int(&c->fc->metadata, key, avio_r8(pb), 0);
133 
134     return 0;
135 }
136 
mov_metadata_gnre(MOVContext * c,AVIOContext * pb,unsigned len,const char * key)137 static int mov_metadata_gnre(MOVContext *c, AVIOContext *pb,
138                              unsigned len, const char *key)
139 {
140     short genre;
141 
142     avio_r8(pb); // unknown
143 
144     genre = avio_r8(pb);
145     if (genre < 1 || genre > ID3v1_GENRE_MAX)
146         return 0;
147     c->fc->event_flags |= AVFMT_EVENT_FLAG_METADATA_UPDATED;
148     av_dict_set(&c->fc->metadata, key, ff_id3v1_genre_str[genre-1], 0);
149 
150     return 0;
151 }
152 
153 static const uint32_t mac_to_unicode[128] = {
154     0x00C4,0x00C5,0x00C7,0x00C9,0x00D1,0x00D6,0x00DC,0x00E1,
155     0x00E0,0x00E2,0x00E4,0x00E3,0x00E5,0x00E7,0x00E9,0x00E8,
156     0x00EA,0x00EB,0x00ED,0x00EC,0x00EE,0x00EF,0x00F1,0x00F3,
157     0x00F2,0x00F4,0x00F6,0x00F5,0x00FA,0x00F9,0x00FB,0x00FC,
158     0x2020,0x00B0,0x00A2,0x00A3,0x00A7,0x2022,0x00B6,0x00DF,
159     0x00AE,0x00A9,0x2122,0x00B4,0x00A8,0x2260,0x00C6,0x00D8,
160     0x221E,0x00B1,0x2264,0x2265,0x00A5,0x00B5,0x2202,0x2211,
161     0x220F,0x03C0,0x222B,0x00AA,0x00BA,0x03A9,0x00E6,0x00F8,
162     0x00BF,0x00A1,0x00AC,0x221A,0x0192,0x2248,0x2206,0x00AB,
163     0x00BB,0x2026,0x00A0,0x00C0,0x00C3,0x00D5,0x0152,0x0153,
164     0x2013,0x2014,0x201C,0x201D,0x2018,0x2019,0x00F7,0x25CA,
165     0x00FF,0x0178,0x2044,0x20AC,0x2039,0x203A,0xFB01,0xFB02,
166     0x2021,0x00B7,0x201A,0x201E,0x2030,0x00C2,0x00CA,0x00C1,
167     0x00CB,0x00C8,0x00CD,0x00CE,0x00CF,0x00CC,0x00D3,0x00D4,
168     0xF8FF,0x00D2,0x00DA,0x00DB,0x00D9,0x0131,0x02C6,0x02DC,
169     0x00AF,0x02D8,0x02D9,0x02DA,0x00B8,0x02DD,0x02DB,0x02C7,
170 };
171 
mov_read_mac_string(MOVContext * c,AVIOContext * pb,int len,char * dst,int dstlen)172 static int mov_read_mac_string(MOVContext *c, AVIOContext *pb, int len,
173                                char *dst, int dstlen)
174 {
175     char *p = dst;
176     char *end = dst+dstlen-1;
177     int i;
178 
179     for (i = 0; i < len; i++) {
180         uint8_t t, c = avio_r8(pb);
181 
182         if (p >= end)
183             continue;
184 
185         if (c < 0x80)
186             *p++ = c;
187         else if (p < end)
188             PUT_UTF8(mac_to_unicode[c-0x80], t, if (p < end) *p++ = t;);
189     }
190     *p = 0;
191     return p - dst;
192 }
193 
mov_read_covr(MOVContext * c,AVIOContext * pb,int type,int len)194 static int mov_read_covr(MOVContext *c, AVIOContext *pb, int type, int len)
195 {
196     AVStream *st;
197     MOVStreamContext *sc;
198     enum AVCodecID id;
199     int ret;
200 
201     switch (type) {
202     case 0xd:  id = AV_CODEC_ID_MJPEG; break;
203     case 0xe:  id = AV_CODEC_ID_PNG;   break;
204     case 0x1b: id = AV_CODEC_ID_BMP;   break;
205     default:
206         av_log(c->fc, AV_LOG_WARNING, "Unknown cover type: 0x%x.\n", type);
207         avio_skip(pb, len);
208         return 0;
209     }
210 
211     sc = av_mallocz(sizeof(*sc));
212     if (!sc)
213         return AVERROR(ENOMEM);
214     ret = ff_add_attached_pic(c->fc, NULL, pb, NULL, len);
215     if (ret < 0) {
216         av_free(sc);
217         return ret;
218     }
219     st = c->fc->streams[c->fc->nb_streams - 1];
220     st->priv_data = sc;
221 
222     if (st->attached_pic.size >= 8 && id != AV_CODEC_ID_BMP) {
223         if (AV_RB64(st->attached_pic.data) == 0x89504e470d0a1a0a) {
224             id = AV_CODEC_ID_PNG;
225         } else {
226             id = AV_CODEC_ID_MJPEG;
227         }
228     }
229     st->codecpar->codec_id   = id;
230 
231     return 0;
232 }
233 
234 // 3GPP TS 26.244
mov_metadata_loci(MOVContext * c,AVIOContext * pb,unsigned len)235 static int mov_metadata_loci(MOVContext *c, AVIOContext *pb, unsigned len)
236 {
237     char language[4] = { 0 };
238     char buf[200], place[100];
239     uint16_t langcode = 0;
240     double longitude, latitude, altitude;
241     const char *key = "location";
242 
243     if (len < 4 + 2 + 1 + 1 + 4 + 4 + 4) {
244         av_log(c->fc, AV_LOG_ERROR, "loci too short\n");
245         return AVERROR_INVALIDDATA;
246     }
247 
248     avio_skip(pb, 4); // version+flags
249     langcode = avio_rb16(pb);
250     ff_mov_lang_to_iso639(langcode, language);
251     len -= 6;
252 
253     len -= avio_get_str(pb, len, place, sizeof(place));
254     if (len < 1) {
255         av_log(c->fc, AV_LOG_ERROR, "place name too long\n");
256         return AVERROR_INVALIDDATA;
257     }
258     avio_skip(pb, 1); // role
259     len -= 1;
260 
261     if (len < 12) {
262         av_log(c->fc, AV_LOG_ERROR,
263                "loci too short (%u bytes left, need at least %d)\n", len, 12);
264         return AVERROR_INVALIDDATA;
265     }
266     longitude = ((int32_t) avio_rb32(pb)) / (float) (1 << 16);
267     latitude  = ((int32_t) avio_rb32(pb)) / (float) (1 << 16);
268     altitude  = ((int32_t) avio_rb32(pb)) / (float) (1 << 16);
269 
270     // Try to output in the same format as the ?xyz field
271     snprintf(buf, sizeof(buf), "%+08.4f%+09.4f",  latitude, longitude);
272     if (altitude)
273         av_strlcatf(buf, sizeof(buf), "%+f", altitude);
274     av_strlcatf(buf, sizeof(buf), "/%s", place);
275 
276     if (*language && strcmp(language, "und")) {
277         char key2[16];
278         snprintf(key2, sizeof(key2), "%s-%s", key, language);
279         av_dict_set(&c->fc->metadata, key2, buf, 0);
280     }
281     c->fc->event_flags |= AVFMT_EVENT_FLAG_METADATA_UPDATED;
282     return av_dict_set(&c->fc->metadata, key, buf, 0);
283 }
284 
mov_metadata_hmmt(MOVContext * c,AVIOContext * pb,unsigned len)285 static int mov_metadata_hmmt(MOVContext *c, AVIOContext *pb, unsigned len)
286 {
287     int i, n_hmmt;
288 
289     if (len < 2)
290         return 0;
291     if (c->ignore_chapters)
292         return 0;
293 
294     n_hmmt = avio_rb32(pb);
295     if (n_hmmt > len / 4)
296         return AVERROR_INVALIDDATA;
297     for (i = 0; i < n_hmmt && !pb->eof_reached; i++) {
298         int moment_time = avio_rb32(pb);
299         avpriv_new_chapter(c->fc, i, av_make_q(1, 1000), moment_time, AV_NOPTS_VALUE, NULL);
300     }
301     if (avio_feof(pb))
302         return AVERROR_INVALIDDATA;
303     return 0;
304 }
305 
mov_read_udta_string(MOVContext * c,AVIOContext * pb,MOVAtom atom)306 static int mov_read_udta_string(MOVContext *c, AVIOContext *pb, MOVAtom atom)
307 {
308     char tmp_key[AV_FOURCC_MAX_STRING_SIZE] = {0};
309     char key2[32], language[4] = {0};
310     char *str = NULL;
311     const char *key = NULL;
312     uint16_t langcode = 0;
313     uint32_t data_type = 0, str_size, str_size_alloc;
314     int (*parse)(MOVContext*, AVIOContext*, unsigned, const char*) = NULL;
315     int raw = 0;
316     int num = 0;
317 
318     switch (atom.type) {
319     case MKTAG( '@','P','R','M'): key = "premiere_version"; raw = 1; break;
320     case MKTAG( '@','P','R','Q'): key = "quicktime_version"; raw = 1; break;
321     case MKTAG( 'X','M','P','_'):
322         if (c->export_xmp) { key = "xmp"; raw = 1; } break;
323     case MKTAG( 'a','A','R','T'): key = "album_artist";    break;
324     case MKTAG( 'a','k','I','D'): key = "account_type";
325         parse = mov_metadata_int8_no_padding; break;
326     case MKTAG( 'a','p','I','D'): key = "account_id"; break;
327     case MKTAG( 'c','a','t','g'): key = "category"; break;
328     case MKTAG( 'c','p','i','l'): key = "compilation";
329         parse = mov_metadata_int8_no_padding; break;
330     case MKTAG( 'c','p','r','t'): key = "copyright"; break;
331     case MKTAG( 'd','e','s','c'): key = "description"; break;
332     case MKTAG( 'd','i','s','k'): key = "disc";
333         parse = mov_metadata_track_or_disc_number; break;
334     case MKTAG( 'e','g','i','d'): key = "episode_uid";
335         parse = mov_metadata_int8_no_padding; break;
336     case MKTAG( 'F','I','R','M'): key = "firmware"; raw = 1; break;
337     case MKTAG( 'g','n','r','e'): key = "genre";
338         parse = mov_metadata_gnre; break;
339     case MKTAG( 'h','d','v','d'): key = "hd_video";
340         parse = mov_metadata_int8_no_padding; break;
341     case MKTAG( 'H','M','M','T'):
342         return mov_metadata_hmmt(c, pb, atom.size);
343     case MKTAG( 'k','e','y','w'): key = "keywords";  break;
344     case MKTAG( 'l','d','e','s'): key = "synopsis";  break;
345     case MKTAG( 'l','o','c','i'):
346         return mov_metadata_loci(c, pb, atom.size);
347     case MKTAG( 'm','a','n','u'): key = "make"; break;
348     case MKTAG( 'm','o','d','l'): key = "model"; break;
349     case MKTAG( 'p','c','s','t'): key = "podcast";
350         parse = mov_metadata_int8_no_padding; break;
351     case MKTAG( 'p','g','a','p'): key = "gapless_playback";
352         parse = mov_metadata_int8_no_padding; break;
353     case MKTAG( 'p','u','r','d'): key = "purchase_date"; break;
354     case MKTAG( 'r','t','n','g'): key = "rating";
355         parse = mov_metadata_int8_no_padding; break;
356     case MKTAG( 's','o','a','a'): key = "sort_album_artist"; break;
357     case MKTAG( 's','o','a','l'): key = "sort_album";   break;
358     case MKTAG( 's','o','a','r'): key = "sort_artist";  break;
359     case MKTAG( 's','o','c','o'): key = "sort_composer"; break;
360     case MKTAG( 's','o','n','m'): key = "sort_name";    break;
361     case MKTAG( 's','o','s','n'): key = "sort_show";    break;
362     case MKTAG( 's','t','i','k'): key = "media_type";
363         parse = mov_metadata_int8_no_padding; break;
364     case MKTAG( 't','r','k','n'): key = "track";
365         parse = mov_metadata_track_or_disc_number; break;
366     case MKTAG( 't','v','e','n'): key = "episode_id"; break;
367     case MKTAG( 't','v','e','s'): key = "episode_sort";
368         parse = mov_metadata_int8_bypass_padding; break;
369     case MKTAG( 't','v','n','n'): key = "network";   break;
370     case MKTAG( 't','v','s','h'): key = "show";      break;
371     case MKTAG( 't','v','s','n'): key = "season_number";
372         parse = mov_metadata_int8_bypass_padding; break;
373     case MKTAG(0xa9,'A','R','T'): key = "artist";    break;
374     case MKTAG(0xa9,'P','R','D'): key = "producer";  break;
375     case MKTAG(0xa9,'a','l','b'): key = "album";     break;
376     case MKTAG(0xa9,'a','u','t'): key = "artist";    break;
377     case MKTAG(0xa9,'c','h','p'): key = "chapter";   break;
378     case MKTAG(0xa9,'c','m','t'): key = "comment";   break;
379     case MKTAG(0xa9,'c','o','m'): key = "composer";  break;
380     case MKTAG(0xa9,'c','p','y'): key = "copyright"; break;
381     case MKTAG(0xa9,'d','a','y'): key = "date";      break;
382     case MKTAG(0xa9,'d','i','r'): key = "director";  break;
383     case MKTAG(0xa9,'d','i','s'): key = "disclaimer"; break;
384     case MKTAG(0xa9,'e','d','1'): key = "edit_date"; break;
385     case MKTAG(0xa9,'e','n','c'): key = "encoder";   break;
386     case MKTAG(0xa9,'f','m','t'): key = "original_format"; break;
387     case MKTAG(0xa9,'g','e','n'): key = "genre";     break;
388     case MKTAG(0xa9,'g','r','p'): key = "grouping";  break;
389     case MKTAG(0xa9,'h','s','t'): key = "host_computer"; break;
390     case MKTAG(0xa9,'i','n','f'): key = "comment";   break;
391     case MKTAG(0xa9,'l','y','r'): key = "lyrics";    break;
392     case MKTAG(0xa9,'m','a','k'): key = "make";      break;
393     case MKTAG(0xa9,'m','o','d'): key = "model";     break;
394     case MKTAG(0xa9,'n','a','m'): key = "title";     break;
395     case MKTAG(0xa9,'o','p','e'): key = "original_artist"; break;
396     case MKTAG(0xa9,'p','r','d'): key = "producer";  break;
397     case MKTAG(0xa9,'p','r','f'): key = "performers"; break;
398     case MKTAG(0xa9,'r','e','q'): key = "playback_requirements"; break;
399     case MKTAG(0xa9,'s','r','c'): key = "original_source"; break;
400     case MKTAG(0xa9,'s','t','3'): key = "subtitle";  break;
401     case MKTAG(0xa9,'s','w','r'): key = "encoder";   break;
402     case MKTAG(0xa9,'t','o','o'): key = "encoder";   break;
403     case MKTAG(0xa9,'t','r','k'): key = "track";     break;
404     case MKTAG(0xa9,'u','r','l'): key = "URL";       break;
405     case MKTAG(0xa9,'w','r','n'): key = "warning";   break;
406     case MKTAG(0xa9,'w','r','t'): key = "composer";  break;
407     case MKTAG(0xa9,'x','y','z'): key = "location";  break;
408     }
409 retry:
410     if (c->itunes_metadata && atom.size > 8) {
411         int data_size = avio_rb32(pb);
412         int tag = avio_rl32(pb);
413         if (tag == MKTAG('d','a','t','a') && data_size <= atom.size && data_size >= 16) {
414             data_type = avio_rb32(pb); // type
415             avio_rb32(pb); // unknown
416             str_size = data_size - 16;
417             atom.size -= 16;
418 
419             if (!key && c->found_hdlr_mdta && c->meta_keys) {
420                 uint32_t index = av_bswap32(atom.type); // BE number has been read as LE
421                 if (index < c->meta_keys_count && index > 0) {
422                     key = c->meta_keys[index];
423                 } else if (atom.type != MKTAG('c', 'o', 'v', 'r')) {
424                     av_log(c->fc, AV_LOG_WARNING,
425                            "The index of 'data' is out of range: %"PRId32" < 1 or >= %d.\n",
426                            index, c->meta_keys_count);
427                 }
428             }
429             if (atom.type == MKTAG('c', 'o', 'v', 'r') ||
430                 (key && !strcmp(key, "com.apple.quicktime.artwork"))) {
431                 int ret = mov_read_covr(c, pb, data_type, str_size);
432                 if (ret < 0) {
433                     av_log(c->fc, AV_LOG_ERROR, "Error parsing cover art.\n");
434                     return ret;
435                 }
436                 atom.size -= str_size;
437                 if (atom.size > 8)
438                     goto retry;
439                 return ret;
440             }
441         } else return 0;
442     } else if (atom.size > 4 && key && !c->itunes_metadata && !raw) {
443         str_size = avio_rb16(pb); // string length
444         if (str_size > atom.size) {
445             raw = 1;
446             avio_seek(pb, -2, SEEK_CUR);
447             av_log(c->fc, AV_LOG_WARNING, "UDTA parsing failed retrying raw\n");
448             goto retry;
449         }
450         langcode = avio_rb16(pb);
451         ff_mov_lang_to_iso639(langcode, language);
452         atom.size -= 4;
453     } else
454         str_size = atom.size;
455 
456     if (c->export_all && !key) {
457         key = av_fourcc_make_string(tmp_key, atom.type);
458     }
459 
460     if (!key)
461         return 0;
462     if (atom.size < 0 || str_size >= INT_MAX/2)
463         return AVERROR_INVALIDDATA;
464 
465     // Allocates enough space if data_type is a int32 or float32 number, otherwise
466     // worst-case requirement for output string in case of utf8 coded input
467     num = (data_type >= 21 && data_type <= 23);
468     str_size_alloc = (num ? 512 : (raw ? str_size : str_size * 2)) + 1;
469     str = av_mallocz(str_size_alloc);
470     if (!str)
471         return AVERROR(ENOMEM);
472 
473     if (parse)
474         parse(c, pb, str_size, key);
475     else {
476         if (!raw && (data_type == 3 || (data_type == 0 && (langcode < 0x400 || langcode == 0x7fff)))) { // MAC Encoded
477             mov_read_mac_string(c, pb, str_size, str, str_size_alloc);
478 #ifdef OHOS_MOOV_LEVEL_META
479         } else if (data_type == 21 || data_type == 67) { // BE signed integer, variable size
480 #else
481         } else if (data_type == 21) { // BE signed integer, variable size
482 #endif
483             int val = 0;
484             if (str_size == 1)
485                 val = (int8_t)avio_r8(pb);
486             else if (str_size == 2)
487                 val = (int16_t)avio_rb16(pb);
488             else if (str_size == 3)
489                 val = ((int32_t)(avio_rb24(pb)<<8))>>8;
490             else if (str_size == 4)
491                 val = (int32_t)avio_rb32(pb);
492             if (snprintf(str, str_size_alloc, "%d", val) >= str_size_alloc) {
493                 av_log(c->fc, AV_LOG_ERROR,
494                        "Failed to store the number (%d) in string.\n", val);
495                 av_free(str);
496                 return AVERROR_INVALIDDATA;
497             }
498         } else if (data_type == 22) { // BE unsigned integer, variable size
499             unsigned int val = 0;
500             if (str_size == 1)
501                 val = avio_r8(pb);
502             else if (str_size == 2)
503                 val = avio_rb16(pb);
504             else if (str_size == 3)
505                 val = avio_rb24(pb);
506             else if (str_size == 4)
507                 val = avio_rb32(pb);
508             if (snprintf(str, str_size_alloc, "%u", val) >= str_size_alloc) {
509                 av_log(c->fc, AV_LOG_ERROR,
510                        "Failed to store the number (%u) in string.\n", val);
511                 av_free(str);
512                 return AVERROR_INVALIDDATA;
513             }
514         } else if (data_type == 23 && str_size >= 4) {  // BE float32
515             float val = av_int2float(avio_rb32(pb));
516             if (snprintf(str, str_size_alloc, "%f", val) >= str_size_alloc) {
517                 av_log(c->fc, AV_LOG_ERROR,
518                        "Failed to store the float32 number (%f) in string.\n", val);
519                 av_free(str);
520                 return AVERROR_INVALIDDATA;
521             }
522         } else if (data_type > 1 && data_type != 4) {
523             // data_type can be 0 if not set at all above. data_type 1 means
524             // UTF8 and 4 means "UTF8 sort". For any other type (UTF16 or e.g.
525             // a picture), don't return it blindly in a string that is supposed
526             // to be UTF8 text.
527             av_log(c->fc, AV_LOG_WARNING, "Skipping unhandled metadata %s of type %d\n", key, data_type);
528             av_free(str);
529             return 0;
530         } else {
531             int ret = ffio_read_size(pb, str, str_size);
532             if (ret < 0) {
533                 av_free(str);
534                 return ret;
535             }
536             str[str_size] = 0;
537         }
538         c->fc->event_flags |= AVFMT_EVENT_FLAG_METADATA_UPDATED;
539 #ifdef OHOS_MOOV_LEVEL_META
540         if (!strncmp(key, "moov_level_meta_key_", 20)) {
541             char* typeStr;
542             switch(data_type) {
543             case 1:
544                 typeStr = av_asprintf("%s%s", "00000001", str); // string
545                 break;
546             case 21:
547                 typeStr = av_asprintf("%s%s", "00000015", str); // int
548                 break;
549             case 23:
550                 typeStr = av_asprintf("%s%s", "00000017", str); // float
551                 break;
552             case 67:
553                 typeStr = av_asprintf("%s%s", "00000043", str); // int
554                 break;
555             default:
556                 typeStr = av_asprintf("%s%s", "0000004d", str); // unknow
557                 break;
558             }
559             if (!typeStr) {
560                 av_dict_set(&c->fc->metadata, key, str, 0);
561             } else {
562                 av_dict_set(&c->fc->metadata, key, typeStr, 0);
563                 av_freep(&typeStr);
564             }
565         } else {
566             av_dict_set(&c->fc->metadata, key, str, 0);
567         }
568 #else
569         av_dict_set(&c->fc->metadata, key, str, 0);
570 #endif
571         if (*language && strcmp(language, "und")) {
572             snprintf(key2, sizeof(key2), "%s-%s", key, language);
573             av_dict_set(&c->fc->metadata, key2, str, 0);
574         }
575         if (!strcmp(key, "encoder")) {
576             int major, minor, micro;
577             if (sscanf(str, "HandBrake %d.%d.%d", &major, &minor, &micro) == 3) {
578                 c->handbrake_version = 1000000*major + 1000*minor + micro;
579             }
580         }
581     }
582 
583     av_freep(&str);
584     return 0;
585 }
586 
mov_read_chpl(MOVContext * c,AVIOContext * pb,MOVAtom atom)587 static int mov_read_chpl(MOVContext *c, AVIOContext *pb, MOVAtom atom)
588 {
589     int64_t start;
590     int i, nb_chapters, str_len, version;
591     char str[256+1];
592     int ret;
593 
594     if (c->ignore_chapters)
595         return 0;
596 
597     if ((atom.size -= 5) < 0)
598         return 0;
599 
600     version = avio_r8(pb);
601     avio_rb24(pb);
602     if (version)
603         avio_rb32(pb); // ???
604     nb_chapters = avio_r8(pb);
605 
606     for (i = 0; i < nb_chapters; i++) {
607         if (atom.size < 9)
608             return 0;
609 
610         start = avio_rb64(pb);
611         str_len = avio_r8(pb);
612 
613         if ((atom.size -= 9+str_len) < 0)
614             return 0;
615 
616         ret = ffio_read_size(pb, str, str_len);
617         if (ret < 0)
618             return ret;
619         str[str_len] = 0;
620         avpriv_new_chapter(c->fc, i, (AVRational){1,10000000}, start, AV_NOPTS_VALUE, str);
621     }
622     return 0;
623 }
624 
625 #define MIN_DATA_ENTRY_BOX_SIZE 12
mov_read_dref(MOVContext * c,AVIOContext * pb,MOVAtom atom)626 static int mov_read_dref(MOVContext *c, AVIOContext *pb, MOVAtom atom)
627 {
628     AVStream *st;
629     MOVStreamContext *sc;
630     int entries, i, j;
631 
632     if (c->fc->nb_streams < 1)
633         return 0;
634     st = c->fc->streams[c->fc->nb_streams-1];
635     sc = st->priv_data;
636 
637     avio_rb32(pb); // version + flags
638     entries = avio_rb32(pb);
639     if (!entries ||
640         entries >  (atom.size - 1) / MIN_DATA_ENTRY_BOX_SIZE + 1 ||
641         entries >= UINT_MAX / sizeof(*sc->drefs))
642         return AVERROR_INVALIDDATA;
643 
644     for (i = 0; i < sc->drefs_count; i++) {
645         MOVDref *dref = &sc->drefs[i];
646         av_freep(&dref->path);
647         av_freep(&dref->dir);
648     }
649     av_free(sc->drefs);
650     sc->drefs_count = 0;
651     sc->drefs = av_mallocz(entries * sizeof(*sc->drefs));
652     if (!sc->drefs)
653         return AVERROR(ENOMEM);
654     sc->drefs_count = entries;
655 
656     for (i = 0; i < entries; i++) {
657         MOVDref *dref = &sc->drefs[i];
658         uint32_t size = avio_rb32(pb);
659         int64_t next = avio_tell(pb);
660 
661         if (size < 12 || next < 0 || next > INT64_MAX - size)
662             return AVERROR_INVALIDDATA;
663 
664         next += size - 4;
665 
666         dref->type = avio_rl32(pb);
667         avio_rb32(pb); // version + flags
668 
669         if (dref->type == MKTAG('a','l','i','s') && size > 150) {
670             /* macintosh alias record */
671             uint16_t volume_len, len;
672             int16_t type;
673             int ret;
674 
675             avio_skip(pb, 10);
676 
677             volume_len = avio_r8(pb);
678             volume_len = FFMIN(volume_len, 27);
679             ret = ffio_read_size(pb, dref->volume, 27);
680             if (ret < 0)
681                 return ret;
682             dref->volume[volume_len] = 0;
683             av_log(c->fc, AV_LOG_DEBUG, "volume %s, len %d\n", dref->volume, volume_len);
684 
685             avio_skip(pb, 12);
686 
687             len = avio_r8(pb);
688             len = FFMIN(len, 63);
689             ret = ffio_read_size(pb, dref->filename, 63);
690             if (ret < 0)
691                 return ret;
692             dref->filename[len] = 0;
693             av_log(c->fc, AV_LOG_DEBUG, "filename %s, len %d\n", dref->filename, len);
694 
695             avio_skip(pb, 16);
696 
697             /* read next level up_from_alias/down_to_target */
698             dref->nlvl_from = avio_rb16(pb);
699             dref->nlvl_to   = avio_rb16(pb);
700             av_log(c->fc, AV_LOG_DEBUG, "nlvl from %d, nlvl to %d\n",
701                    dref->nlvl_from, dref->nlvl_to);
702 
703             avio_skip(pb, 16);
704 
705             for (type = 0; type != -1 && avio_tell(pb) < next; ) {
706                 if (avio_feof(pb))
707                     return AVERROR_EOF;
708                 type = avio_rb16(pb);
709                 len = avio_rb16(pb);
710                 av_log(c->fc, AV_LOG_DEBUG, "type %d, len %d\n", type, len);
711                 if (len&1)
712                     len += 1;
713                 if (type == 2) { // absolute path
714                     av_free(dref->path);
715                     dref->path = av_mallocz(len+1);
716                     if (!dref->path)
717                         return AVERROR(ENOMEM);
718 
719                     ret = ffio_read_size(pb, dref->path, len);
720                     if (ret < 0) {
721                         av_freep(&dref->path);
722                         return ret;
723                     }
724                     if (len > volume_len && !strncmp(dref->path, dref->volume, volume_len)) {
725                         len -= volume_len;
726                         memmove(dref->path, dref->path+volume_len, len);
727                         dref->path[len] = 0;
728                     }
729                     // trim string of any ending zeros
730                     for (j = len - 1; j >= 0; j--) {
731                         if (dref->path[j] == 0)
732                             len--;
733                         else
734                             break;
735                     }
736                     for (j = 0; j < len; j++)
737                         if (dref->path[j] == ':' || dref->path[j] == 0)
738                             dref->path[j] = '/';
739                     av_log(c->fc, AV_LOG_DEBUG, "path %s\n", dref->path);
740                 } else if (type == 0) { // directory name
741                     av_free(dref->dir);
742                     dref->dir = av_malloc(len+1);
743                     if (!dref->dir)
744                         return AVERROR(ENOMEM);
745 
746                     ret = ffio_read_size(pb, dref->dir, len);
747                     if (ret < 0) {
748                         av_freep(&dref->dir);
749                         return ret;
750                     }
751                     dref->dir[len] = 0;
752                     for (j = 0; j < len; j++)
753                         if (dref->dir[j] == ':')
754                             dref->dir[j] = '/';
755                     av_log(c->fc, AV_LOG_DEBUG, "dir %s\n", dref->dir);
756                 } else
757                     avio_skip(pb, len);
758             }
759         } else {
760             av_log(c->fc, AV_LOG_DEBUG, "Unknown dref type 0x%08"PRIx32" size %"PRIu32"\n",
761                    dref->type, size);
762             entries--;
763             i--;
764         }
765         avio_seek(pb, next, SEEK_SET);
766     }
767     return 0;
768 }
769 
mov_read_hdlr(MOVContext * c,AVIOContext * pb,MOVAtom atom)770 static int mov_read_hdlr(MOVContext *c, AVIOContext *pb, MOVAtom atom)
771 {
772     AVStream *st;
773     uint32_t type;
774     uint32_t ctype;
775     int64_t title_size;
776     char *title_str;
777     int ret;
778 
779     avio_r8(pb); /* version */
780     avio_rb24(pb); /* flags */
781 
782     /* component type */
783     ctype = avio_rl32(pb);
784     type = avio_rl32(pb); /* component subtype */
785 
786     av_log(c->fc, AV_LOG_TRACE, "ctype=%s\n", av_fourcc2str(ctype));
787     av_log(c->fc, AV_LOG_TRACE, "stype=%s\n", av_fourcc2str(type));
788 
789     if (c->trak_index < 0) {  // meta not inside a trak
790         if (type == MKTAG('m','d','t','a')) {
791             c->found_hdlr_mdta = 1;
792         }
793         return 0;
794     }
795 
796     st = c->fc->streams[c->fc->nb_streams-1];
797 
798     if     (type == MKTAG('v','i','d','e'))
799         st->codecpar->codec_type = AVMEDIA_TYPE_VIDEO;
800     else if (type == MKTAG('s','o','u','n'))
801         st->codecpar->codec_type = AVMEDIA_TYPE_AUDIO;
802     else if (type == MKTAG('m','1','a',' '))
803         st->codecpar->codec_id = AV_CODEC_ID_MP2;
804 #ifdef OHOS_SUBTITLE_DEMUXER
805     else if ((type == MKTAG('s','u','b','p')) || (type == MKTAG('c','l','c','p')) || (type == MKTAG('t','e','x','t')))
806 #else
807     else if ((type == MKTAG('s','u','b','p')) || (type == MKTAG('c','l','c','p')))
808 #endif
809         st->codecpar->codec_type = AVMEDIA_TYPE_SUBTITLE;
810     avio_rb32(pb); /* component  manufacture */
811     avio_rb32(pb); /* component flags */
812     avio_rb32(pb); /* component flags mask */
813 
814     title_size = atom.size - 24;
815     if (title_size > 0) {
816         if (title_size > FFMIN(INT_MAX, SIZE_MAX-1))
817             return AVERROR_INVALIDDATA;
818         title_str = av_malloc(title_size + 1); /* Add null terminator */
819         if (!title_str)
820             return AVERROR(ENOMEM);
821 
822         ret = ffio_read_size(pb, title_str, title_size);
823         if (ret < 0) {
824             av_freep(&title_str);
825             return ret;
826         }
827         title_str[title_size] = 0;
828         if (title_str[0]) {
829             int off = (!c->isom && title_str[0] == title_size - 1);
830             // flag added so as to not set stream handler name if already set from mdia->hdlr
831             av_dict_set(&st->metadata, "handler_name", title_str + off, AV_DICT_DONT_OVERWRITE);
832 #ifdef OHOS_TIMED_META_TRACK
833             if (!strncmp(title_str + off, "timed_metadata", 14) && type == MKTAG('m', 'e', 't' ,'a')) {
834                 st->codecpar->codec_type = AVMEDIA_TYPE_TIMEDMETA;
835             }
836 #endif
837         }
838         av_freep(&title_str);
839     }
840 
841     return 0;
842 }
843 
mov_read_esds(MOVContext * c,AVIOContext * pb,MOVAtom atom)844 static int mov_read_esds(MOVContext *c, AVIOContext *pb, MOVAtom atom)
845 {
846     return ff_mov_read_esds(c->fc, pb);
847 }
848 
mov_read_dac3(MOVContext * c,AVIOContext * pb,MOVAtom atom)849 static int mov_read_dac3(MOVContext *c, AVIOContext *pb, MOVAtom atom)
850 {
851     AVStream *st;
852     enum AVAudioServiceType *ast;
853     int ac3info, acmod, lfeon, bsmod;
854     uint64_t mask;
855 
856     if (c->fc->nb_streams < 1)
857         return 0;
858     st = c->fc->streams[c->fc->nb_streams-1];
859 
860     ast = (enum AVAudioServiceType*)av_stream_new_side_data(st, AV_PKT_DATA_AUDIO_SERVICE_TYPE,
861                                                             sizeof(*ast));
862     if (!ast)
863         return AVERROR(ENOMEM);
864 
865     ac3info = avio_rb24(pb);
866     bsmod = (ac3info >> 14) & 0x7;
867     acmod = (ac3info >> 11) & 0x7;
868     lfeon = (ac3info >> 10) & 0x1;
869 
870     mask = ff_ac3_channel_layout_tab[acmod];
871     if (lfeon)
872         mask |= AV_CH_LOW_FREQUENCY;
873     av_channel_layout_uninit(&st->codecpar->ch_layout);
874     av_channel_layout_from_mask(&st->codecpar->ch_layout, mask);
875 
876     *ast = bsmod;
877     if (st->codecpar->ch_layout.nb_channels > 1 && bsmod == 0x7)
878         *ast = AV_AUDIO_SERVICE_TYPE_KARAOKE;
879 
880     return 0;
881 }
882 
mov_read_dec3(MOVContext * c,AVIOContext * pb,MOVAtom atom)883 static int mov_read_dec3(MOVContext *c, AVIOContext *pb, MOVAtom atom)
884 {
885     AVStream *st;
886     enum AVAudioServiceType *ast;
887     int eac3info, acmod, lfeon, bsmod;
888     uint64_t mask;
889 
890     if (c->fc->nb_streams < 1)
891         return 0;
892     st = c->fc->streams[c->fc->nb_streams-1];
893 
894     ast = (enum AVAudioServiceType*)av_stream_new_side_data(st, AV_PKT_DATA_AUDIO_SERVICE_TYPE,
895                                                             sizeof(*ast));
896     if (!ast)
897         return AVERROR(ENOMEM);
898 
899     /* No need to parse fields for additional independent substreams and its
900      * associated dependent substreams since libavcodec's E-AC-3 decoder
901      * does not support them yet. */
902     avio_rb16(pb); /* data_rate and num_ind_sub */
903     eac3info = avio_rb24(pb);
904     bsmod = (eac3info >> 12) & 0x1f;
905     acmod = (eac3info >>  9) & 0x7;
906     lfeon = (eac3info >>  8) & 0x1;
907 
908     mask = ff_ac3_channel_layout_tab[acmod];
909     if (lfeon)
910         mask |= AV_CH_LOW_FREQUENCY;
911     av_channel_layout_uninit(&st->codecpar->ch_layout);
912     av_channel_layout_from_mask(&st->codecpar->ch_layout, mask);
913 
914     *ast = bsmod;
915     if (st->codecpar->ch_layout.nb_channels > 1 && bsmod == 0x7)
916         *ast = AV_AUDIO_SERVICE_TYPE_KARAOKE;
917 
918     return 0;
919 }
920 
mov_read_ddts(MOVContext * c,AVIOContext * pb,MOVAtom atom)921 static int mov_read_ddts(MOVContext *c, AVIOContext *pb, MOVAtom atom)
922 {
923 #define DDTS_SIZE 20
924     uint8_t buf[DDTS_SIZE + AV_INPUT_BUFFER_PADDING_SIZE];
925     AVStream *st = NULL;
926     uint32_t frame_duration_code = 0;
927     uint32_t channel_layout_code = 0;
928     GetBitContext gb;
929     int ret;
930 
931     if ((ret = ffio_read_size(pb, buf, DDTS_SIZE)) < 0)
932         return ret;
933 
934     init_get_bits(&gb, buf, 8 * DDTS_SIZE);
935 
936     if (c->fc->nb_streams < 1) {
937         return 0;
938     }
939     st = c->fc->streams[c->fc->nb_streams-1];
940 
941     st->codecpar->sample_rate = get_bits_long(&gb, 32);
942     if (st->codecpar->sample_rate <= 0) {
943         av_log(c->fc, AV_LOG_ERROR, "Invalid sample rate %d\n", st->codecpar->sample_rate);
944         return AVERROR_INVALIDDATA;
945     }
946     skip_bits_long(&gb, 32); /* max bitrate */
947     st->codecpar->bit_rate = get_bits_long(&gb, 32);
948     st->codecpar->bits_per_coded_sample = get_bits(&gb, 8);
949     frame_duration_code = get_bits(&gb, 2);
950     skip_bits(&gb, 30); /* various fields */
951     channel_layout_code = get_bits(&gb, 16);
952 
953     st->codecpar->frame_size =
954             (frame_duration_code == 0) ? 512 :
955             (frame_duration_code == 1) ? 1024 :
956             (frame_duration_code == 2) ? 2048 :
957             (frame_duration_code == 3) ? 4096 : 0;
958 
959     if (channel_layout_code > 0xff) {
960         av_log(c->fc, AV_LOG_WARNING, "Unsupported DTS audio channel layout\n");
961     }
962     av_channel_layout_uninit(&st->codecpar->ch_layout);
963     av_channel_layout_from_mask(&st->codecpar->ch_layout,
964             ((channel_layout_code & 0x1) ? AV_CH_FRONT_CENTER : 0) |
965             ((channel_layout_code & 0x2) ? AV_CH_FRONT_LEFT : 0) |
966             ((channel_layout_code & 0x2) ? AV_CH_FRONT_RIGHT : 0) |
967             ((channel_layout_code & 0x4) ? AV_CH_SIDE_LEFT : 0) |
968             ((channel_layout_code & 0x4) ? AV_CH_SIDE_RIGHT : 0) |
969             ((channel_layout_code & 0x8) ? AV_CH_LOW_FREQUENCY : 0));
970 
971     return 0;
972 }
973 
mov_read_chan(MOVContext * c,AVIOContext * pb,MOVAtom atom)974 static int mov_read_chan(MOVContext *c, AVIOContext *pb, MOVAtom atom)
975 {
976     AVStream *st;
977 
978     if (c->fc->nb_streams < 1)
979         return 0;
980     st = c->fc->streams[c->fc->nb_streams-1];
981 
982     if (atom.size < 16)
983         return 0;
984 
985     /* skip version and flags */
986     avio_skip(pb, 4);
987 
988     ff_mov_read_chan(c->fc, pb, st, atom.size - 4);
989 
990     return 0;
991 }
992 
mov_read_wfex(MOVContext * c,AVIOContext * pb,MOVAtom atom)993 static int mov_read_wfex(MOVContext *c, AVIOContext *pb, MOVAtom atom)
994 {
995     AVStream *st;
996     int ret;
997 
998     if (c->fc->nb_streams < 1)
999         return 0;
1000     st = c->fc->streams[c->fc->nb_streams-1];
1001 
1002     if ((ret = ff_get_wav_header(c->fc, pb, st->codecpar, atom.size, 0)) < 0)
1003         av_log(c->fc, AV_LOG_WARNING, "get_wav_header failed\n");
1004 
1005     return ret;
1006 }
1007 
1008 /* This atom overrides any previously set aspect ratio */
mov_read_pasp(MOVContext * c,AVIOContext * pb,MOVAtom atom)1009 static int mov_read_pasp(MOVContext *c, AVIOContext *pb, MOVAtom atom)
1010 {
1011     const int num = avio_rb32(pb);
1012     const int den = avio_rb32(pb);
1013     AVStream *st;
1014 
1015     if (c->fc->nb_streams < 1)
1016         return 0;
1017     st = c->fc->streams[c->fc->nb_streams-1];
1018 
1019     if (den != 0) {
1020         av_reduce(&st->sample_aspect_ratio.num, &st->sample_aspect_ratio.den,
1021                   num, den, 32767);
1022     }
1023     return 0;
1024 }
1025 
1026 /* this atom contains actual media data */
mov_read_mdat(MOVContext * c,AVIOContext * pb,MOVAtom atom)1027 static int mov_read_mdat(MOVContext *c, AVIOContext *pb, MOVAtom atom)
1028 {
1029     if (atom.size == 0) /* wrong one (MP4) */
1030         return 0;
1031     c->found_mdat=1;
1032     return 0; /* now go for moov */
1033 }
1034 
1035 #define DRM_BLOB_SIZE 56
1036 
mov_read_adrm(MOVContext * c,AVIOContext * pb,MOVAtom atom)1037 static int mov_read_adrm(MOVContext *c, AVIOContext *pb, MOVAtom atom)
1038 {
1039     uint8_t intermediate_key[20];
1040     uint8_t intermediate_iv[20];
1041     uint8_t input[64];
1042     uint8_t output[64];
1043     uint8_t file_checksum[20];
1044     uint8_t calculated_checksum[20];
1045     char checksum_string[2 * sizeof(file_checksum) + 1];
1046     struct AVSHA *sha;
1047     int i;
1048     int ret = 0;
1049     uint8_t *activation_bytes = c->activation_bytes;
1050     uint8_t *fixed_key = c->audible_fixed_key;
1051 
1052     c->aax_mode = 1;
1053 
1054     sha = av_sha_alloc();
1055     if (!sha)
1056         return AVERROR(ENOMEM);
1057     av_free(c->aes_decrypt);
1058     c->aes_decrypt = av_aes_alloc();
1059     if (!c->aes_decrypt) {
1060         ret = AVERROR(ENOMEM);
1061         goto fail;
1062     }
1063 
1064     /* drm blob processing */
1065     avio_read(pb, output, 8); // go to offset 8, absolute position 0x251
1066     avio_read(pb, input, DRM_BLOB_SIZE);
1067     avio_read(pb, output, 4); // go to offset 4, absolute position 0x28d
1068     avio_read(pb, file_checksum, 20);
1069 
1070     // required by external tools
1071     ff_data_to_hex(checksum_string, file_checksum, sizeof(file_checksum), 1);
1072     av_log(c->fc, AV_LOG_INFO, "[aax] file checksum == %s\n", checksum_string);
1073 
1074     /* verify activation data */
1075     if (!activation_bytes) {
1076         av_log(c->fc, AV_LOG_WARNING, "[aax] activation_bytes option is missing!\n");
1077         ret = 0;  /* allow ffprobe to continue working on .aax files */
1078         goto fail;
1079     }
1080     if (c->activation_bytes_size != 4) {
1081         av_log(c->fc, AV_LOG_FATAL, "[aax] activation_bytes value needs to be 4 bytes!\n");
1082         ret = AVERROR(EINVAL);
1083         goto fail;
1084     }
1085 
1086     /* verify fixed key */
1087     if (c->audible_fixed_key_size != 16) {
1088         av_log(c->fc, AV_LOG_FATAL, "[aax] audible_fixed_key value needs to be 16 bytes!\n");
1089         ret = AVERROR(EINVAL);
1090         goto fail;
1091     }
1092 
1093     /* AAX (and AAX+) key derivation */
1094     av_sha_init(sha, 160);
1095     av_sha_update(sha, fixed_key, 16);
1096     av_sha_update(sha, activation_bytes, 4);
1097     av_sha_final(sha, intermediate_key);
1098     av_sha_init(sha, 160);
1099     av_sha_update(sha, fixed_key, 16);
1100     av_sha_update(sha, intermediate_key, 20);
1101     av_sha_update(sha, activation_bytes, 4);
1102     av_sha_final(sha, intermediate_iv);
1103     av_sha_init(sha, 160);
1104     av_sha_update(sha, intermediate_key, 16);
1105     av_sha_update(sha, intermediate_iv, 16);
1106     av_sha_final(sha, calculated_checksum);
1107     if (memcmp(calculated_checksum, file_checksum, 20)) { // critical error
1108         av_log(c->fc, AV_LOG_ERROR, "[aax] mismatch in checksums!\n");
1109         ret = AVERROR_INVALIDDATA;
1110         goto fail;
1111     }
1112     av_aes_init(c->aes_decrypt, intermediate_key, 128, 1);
1113     av_aes_crypt(c->aes_decrypt, output, input, DRM_BLOB_SIZE >> 4, intermediate_iv, 1);
1114     for (i = 0; i < 4; i++) {
1115         // file data (in output) is stored in big-endian mode
1116         if (activation_bytes[i] != output[3 - i]) { // critical error
1117             av_log(c->fc, AV_LOG_ERROR, "[aax] error in drm blob decryption!\n");
1118             ret = AVERROR_INVALIDDATA;
1119             goto fail;
1120         }
1121     }
1122     memcpy(c->file_key, output + 8, 16);
1123     memcpy(input, output + 26, 16);
1124     av_sha_init(sha, 160);
1125     av_sha_update(sha, input, 16);
1126     av_sha_update(sha, c->file_key, 16);
1127     av_sha_update(sha, fixed_key, 16);
1128     av_sha_final(sha, c->file_iv);
1129 
1130 fail:
1131     av_free(sha);
1132 
1133     return ret;
1134 }
1135 
mov_aaxc_crypto(MOVContext * c)1136 static int mov_aaxc_crypto(MOVContext *c)
1137 {
1138     if (c->audible_key_size != 16) {
1139         av_log(c->fc, AV_LOG_FATAL, "[aaxc] audible_key value needs to be 16 bytes!\n");
1140         return AVERROR(EINVAL);
1141     }
1142 
1143     if (c->audible_iv_size != 16) {
1144         av_log(c->fc, AV_LOG_FATAL, "[aaxc] audible_iv value needs to be 16 bytes!\n");
1145         return AVERROR(EINVAL);
1146     }
1147 
1148     c->aes_decrypt = av_aes_alloc();
1149     if (!c->aes_decrypt) {
1150         return AVERROR(ENOMEM);
1151     }
1152 
1153     memcpy(c->file_key, c->audible_key, 16);
1154     memcpy(c->file_iv, c->audible_iv, 16);
1155     c->aax_mode = 1;
1156 
1157     return 0;
1158 }
1159 
1160 // Audible AAX (and AAX+) bytestream decryption
aax_filter(uint8_t * input,int size,MOVContext * c)1161 static int aax_filter(uint8_t *input, int size, MOVContext *c)
1162 {
1163     int blocks = 0;
1164     unsigned char iv[16];
1165 
1166     memcpy(iv, c->file_iv, 16); // iv is overwritten
1167     blocks = size >> 4; // trailing bytes are not encrypted!
1168     av_aes_init(c->aes_decrypt, c->file_key, 128, 1);
1169     av_aes_crypt(c->aes_decrypt, input, input, blocks, iv, 1);
1170 
1171     return 0;
1172 }
1173 
1174 /* read major brand, minor version and compatible brands and store them as metadata */
mov_read_ftyp(MOVContext * c,AVIOContext * pb,MOVAtom atom)1175 static int mov_read_ftyp(MOVContext *c, AVIOContext *pb, MOVAtom atom)
1176 {
1177     uint32_t minor_ver;
1178     int comp_brand_size;
1179     char* comp_brands_str;
1180     uint8_t type[5] = {0};
1181     int ret = ffio_read_size(pb, type, 4);
1182     if (ret < 0)
1183         return ret;
1184     if (c->fc->nb_streams)
1185         return AVERROR_INVALIDDATA;
1186 
1187     if (strcmp(type, "qt  "))
1188         c->isom = 1;
1189     av_log(c->fc, AV_LOG_DEBUG, "ISO: File Type Major Brand: %.4s\n",(char *)&type);
1190     av_dict_set(&c->fc->metadata, "major_brand", type, 0);
1191     c->is_still_picture_avif = !strncmp(type, "avif", 4);
1192     minor_ver = avio_rb32(pb); /* minor version */
1193     av_dict_set_int(&c->fc->metadata, "minor_version", minor_ver, 0);
1194 
1195     comp_brand_size = atom.size - 8;
1196     if (comp_brand_size < 0 || comp_brand_size == INT_MAX)
1197         return AVERROR_INVALIDDATA;
1198     comp_brands_str = av_malloc(comp_brand_size + 1); /* Add null terminator */
1199     if (!comp_brands_str)
1200         return AVERROR(ENOMEM);
1201 
1202     ret = ffio_read_size(pb, comp_brands_str, comp_brand_size);
1203     if (ret < 0) {
1204         av_freep(&comp_brands_str);
1205         return ret;
1206     }
1207     comp_brands_str[comp_brand_size] = 0;
1208     av_dict_set(&c->fc->metadata, "compatible_brands",
1209                 comp_brands_str, AV_DICT_DONT_STRDUP_VAL);
1210 
1211     // Logic for handling Audible's .aaxc files
1212     if (!strcmp(type, "aaxc")) {
1213         mov_aaxc_crypto(c);
1214     }
1215 
1216     return 0;
1217 }
1218 
1219 /* this atom should contain all header atoms */
mov_read_moov(MOVContext * c,AVIOContext * pb,MOVAtom atom)1220 static int mov_read_moov(MOVContext *c, AVIOContext *pb, MOVAtom atom)
1221 {
1222     int ret;
1223 
1224     if (c->found_moov) {
1225         av_log(c->fc, AV_LOG_WARNING, "Found duplicated MOOV Atom. Skipped it\n");
1226         avio_skip(pb, atom.size);
1227         return 0;
1228     }
1229 
1230     if ((ret = mov_read_default(c, pb, atom)) < 0)
1231         return ret;
1232     /* we parsed the 'moov' atom, we can terminate the parsing as soon as we find the 'mdat' */
1233     /* so we don't parse the whole file if over a network */
1234     c->found_moov=1;
1235     return 0; /* now go for mdat */
1236 }
1237 
get_frag_stream_info(MOVFragmentIndex * frag_index,int index,int id)1238 static MOVFragmentStreamInfo * get_frag_stream_info(
1239     MOVFragmentIndex *frag_index,
1240     int index,
1241     int id)
1242 {
1243     int i;
1244     MOVFragmentIndexItem * item;
1245 
1246     if (index < 0 || index >= frag_index->nb_items)
1247         return NULL;
1248     item = &frag_index->item[index];
1249     for (i = 0; i < item->nb_stream_info; i++)
1250         if (item->stream_info[i].id == id)
1251             return &item->stream_info[i];
1252 
1253     // This shouldn't happen
1254     return NULL;
1255 }
1256 
set_frag_stream(MOVFragmentIndex * frag_index,int id)1257 static void set_frag_stream(MOVFragmentIndex *frag_index, int id)
1258 {
1259     int i;
1260     MOVFragmentIndexItem * item;
1261 
1262     if (frag_index->current < 0 ||
1263         frag_index->current >= frag_index->nb_items)
1264         return;
1265 
1266     item = &frag_index->item[frag_index->current];
1267     for (i = 0; i < item->nb_stream_info; i++)
1268         if (item->stream_info[i].id == id) {
1269             item->current = i;
1270             return;
1271         }
1272 
1273     // id not found.  This shouldn't happen.
1274     item->current = -1;
1275 }
1276 
get_current_frag_stream_info(MOVFragmentIndex * frag_index)1277 static MOVFragmentStreamInfo * get_current_frag_stream_info(
1278     MOVFragmentIndex *frag_index)
1279 {
1280     MOVFragmentIndexItem *item;
1281     if (frag_index->current < 0 ||
1282         frag_index->current >= frag_index->nb_items)
1283         return NULL;
1284 
1285     item = &frag_index->item[frag_index->current];
1286     if (item->current >= 0 && item->current < item->nb_stream_info)
1287         return &item->stream_info[item->current];
1288 
1289     // This shouldn't happen
1290     return NULL;
1291 }
1292 
search_frag_moof_offset(MOVFragmentIndex * frag_index,int64_t offset)1293 static int search_frag_moof_offset(MOVFragmentIndex *frag_index, int64_t offset)
1294 {
1295     int a, b, m;
1296     int64_t moof_offset;
1297 
1298     // Optimize for appending new entries
1299     if (!frag_index->nb_items ||
1300         frag_index->item[frag_index->nb_items - 1].moof_offset < offset)
1301         return frag_index->nb_items;
1302 
1303     a = -1;
1304     b = frag_index->nb_items;
1305 
1306     while (b - a > 1) {
1307         m = (a + b) >> 1;
1308         moof_offset = frag_index->item[m].moof_offset;
1309         if (moof_offset >= offset)
1310             b = m;
1311         if (moof_offset <= offset)
1312             a = m;
1313     }
1314     return b;
1315 }
1316 
get_stream_info_time(MOVFragmentStreamInfo * frag_stream_info)1317 static int64_t get_stream_info_time(MOVFragmentStreamInfo * frag_stream_info)
1318 {
1319     av_assert0(frag_stream_info);
1320     if (frag_stream_info->sidx_pts != AV_NOPTS_VALUE)
1321         return frag_stream_info->sidx_pts;
1322     if (frag_stream_info->first_tfra_pts != AV_NOPTS_VALUE)
1323         return frag_stream_info->first_tfra_pts;
1324     return frag_stream_info->tfdt_dts;
1325 }
1326 
get_frag_time(MOVFragmentIndex * frag_index,int index,int track_id)1327 static int64_t get_frag_time(MOVFragmentIndex *frag_index,
1328                              int index, int track_id)
1329 {
1330     MOVFragmentStreamInfo * frag_stream_info;
1331     int64_t timestamp;
1332     int i;
1333 
1334     if (track_id >= 0) {
1335         frag_stream_info = get_frag_stream_info(frag_index, index, track_id);
1336         if (frag_stream_info->sidx_pts != AV_NOPTS_VALUE)
1337             return frag_stream_info->sidx_pts;
1338         if (frag_stream_info->first_tfra_pts != AV_NOPTS_VALUE)
1339             return frag_stream_info->first_tfra_pts;
1340         return frag_stream_info->sidx_pts;
1341     }
1342 
1343     for (i = 0; i < frag_index->item[index].nb_stream_info; i++) {
1344         frag_stream_info = &frag_index->item[index].stream_info[i];
1345         timestamp = get_stream_info_time(frag_stream_info);
1346         if (timestamp != AV_NOPTS_VALUE)
1347             return timestamp;
1348     }
1349     return AV_NOPTS_VALUE;
1350 }
1351 
search_frag_timestamp(MOVFragmentIndex * frag_index,AVStream * st,int64_t timestamp)1352 static int search_frag_timestamp(MOVFragmentIndex *frag_index,
1353                                  AVStream *st, int64_t timestamp)
1354 {
1355     int a, b, m, m0;
1356     int64_t frag_time;
1357     int id = -1;
1358 
1359     if (st) {
1360         // If the stream is referenced by any sidx, limit the search
1361         // to fragments that referenced this stream in the sidx
1362         MOVStreamContext *sc = st->priv_data;
1363         if (sc->has_sidx)
1364             id = st->id;
1365     }
1366 
1367     a = -1;
1368     b = frag_index->nb_items;
1369 
1370     while (b - a > 1) {
1371         m0 = m = (a + b) >> 1;
1372 
1373         while (m < b &&
1374                (frag_time = get_frag_time(frag_index, m, id)) == AV_NOPTS_VALUE)
1375             m++;
1376 
1377         if (m < b && frag_time <= timestamp)
1378             a = m;
1379         else
1380             b = m0;
1381     }
1382 
1383     return a;
1384 }
1385 
update_frag_index(MOVContext * c,int64_t offset)1386 static int update_frag_index(MOVContext *c, int64_t offset)
1387 {
1388     int index, i;
1389     MOVFragmentIndexItem * item;
1390     MOVFragmentStreamInfo * frag_stream_info;
1391 
1392     // If moof_offset already exists in frag_index, return index to it
1393     index = search_frag_moof_offset(&c->frag_index, offset);
1394     if (index < c->frag_index.nb_items &&
1395         c->frag_index.item[index].moof_offset == offset)
1396         return index;
1397 
1398     // offset is not yet in frag index.
1399     // Insert new item at index (sorted by moof offset)
1400     item = av_fast_realloc(c->frag_index.item,
1401                            &c->frag_index.allocated_size,
1402                            (c->frag_index.nb_items + 1) *
1403                            sizeof(*c->frag_index.item));
1404     if (!item)
1405         return -1;
1406     c->frag_index.item = item;
1407 
1408     frag_stream_info = av_realloc_array(NULL, c->fc->nb_streams,
1409                                         sizeof(*item->stream_info));
1410     if (!frag_stream_info)
1411         return -1;
1412 
1413     for (i = 0; i < c->fc->nb_streams; i++) {
1414         // Avoid building frag index if streams lack track id.
1415         if (c->fc->streams[i]->id < 0) {
1416             av_free(frag_stream_info);
1417             return AVERROR_INVALIDDATA;
1418         }
1419 
1420         frag_stream_info[i].id = c->fc->streams[i]->id;
1421         frag_stream_info[i].sidx_pts = AV_NOPTS_VALUE;
1422         frag_stream_info[i].tfdt_dts = AV_NOPTS_VALUE;
1423         frag_stream_info[i].next_trun_dts = AV_NOPTS_VALUE;
1424         frag_stream_info[i].first_tfra_pts = AV_NOPTS_VALUE;
1425         frag_stream_info[i].index_entry = -1;
1426         frag_stream_info[i].encryption_index = NULL;
1427     }
1428 
1429     if (index < c->frag_index.nb_items)
1430         memmove(c->frag_index.item + index + 1, c->frag_index.item + index,
1431                 (c->frag_index.nb_items - index) * sizeof(*c->frag_index.item));
1432 
1433     item = &c->frag_index.item[index];
1434     item->headers_read = 0;
1435     item->current = 0;
1436     item->nb_stream_info = c->fc->nb_streams;
1437     item->moof_offset = offset;
1438     item->stream_info = frag_stream_info;
1439     c->frag_index.nb_items++;
1440 
1441     return index;
1442 }
1443 
fix_frag_index_entries(MOVFragmentIndex * frag_index,int index,int id,int entries)1444 static void fix_frag_index_entries(MOVFragmentIndex *frag_index, int index,
1445                                    int id, int entries)
1446 {
1447     int i;
1448     MOVFragmentStreamInfo * frag_stream_info;
1449 
1450     if (index < 0)
1451         return;
1452     for (i = index; i < frag_index->nb_items; i++) {
1453         frag_stream_info = get_frag_stream_info(frag_index, i, id);
1454         if (frag_stream_info && frag_stream_info->index_entry >= 0)
1455             frag_stream_info->index_entry += entries;
1456     }
1457 }
1458 
mov_read_moof(MOVContext * c,AVIOContext * pb,MOVAtom atom)1459 static int mov_read_moof(MOVContext *c, AVIOContext *pb, MOVAtom atom)
1460 {
1461     // Set by mov_read_tfhd(). mov_read_trun() will reject files missing tfhd.
1462     c->fragment.found_tfhd = 0;
1463 
1464     if (!c->has_looked_for_mfra && c->use_mfra_for > 0) {
1465         c->has_looked_for_mfra = 1;
1466         if (pb->seekable & AVIO_SEEKABLE_NORMAL) {
1467             int ret;
1468             av_log(c->fc, AV_LOG_VERBOSE, "stream has moof boxes, will look "
1469                     "for a mfra\n");
1470             if ((ret = mov_read_mfra(c, pb)) < 0) {
1471                 av_log(c->fc, AV_LOG_VERBOSE, "found a moof box but failed to "
1472                         "read the mfra (may be a live ismv)\n");
1473             }
1474         } else {
1475             av_log(c->fc, AV_LOG_VERBOSE, "found a moof box but stream is not "
1476                     "seekable, can not look for mfra\n");
1477         }
1478     }
1479     c->fragment.moof_offset = c->fragment.implicit_offset = avio_tell(pb) - 8;
1480     av_log(c->fc, AV_LOG_TRACE, "moof offset %"PRIx64"\n", c->fragment.moof_offset);
1481     c->frag_index.current = update_frag_index(c, c->fragment.moof_offset);
1482     return mov_read_default(c, pb, atom);
1483 }
1484 
mov_metadata_creation_time(AVDictionary ** metadata,int64_t time,void * logctx)1485 static void mov_metadata_creation_time(AVDictionary **metadata, int64_t time, void *logctx)
1486 {
1487     if (time) {
1488         if (time >= 2082844800)
1489             time -= 2082844800;  /* seconds between 1904-01-01 and Epoch */
1490 
1491         if ((int64_t)(time * 1000000ULL) / 1000000 != time) {
1492             av_log(logctx, AV_LOG_DEBUG, "creation_time is not representable\n");
1493             return;
1494         }
1495 
1496         avpriv_dict_set_timestamp(metadata, "creation_time", time * 1000000);
1497     }
1498 }
1499 
mov_read_mdhd(MOVContext * c,AVIOContext * pb,MOVAtom atom)1500 static int mov_read_mdhd(MOVContext *c, AVIOContext *pb, MOVAtom atom)
1501 {
1502     AVStream *st;
1503     MOVStreamContext *sc;
1504     int version;
1505     char language[4] = {0};
1506     unsigned lang;
1507     int64_t creation_time;
1508 
1509     if (c->fc->nb_streams < 1)
1510         return 0;
1511     st = c->fc->streams[c->fc->nb_streams-1];
1512     sc = st->priv_data;
1513 
1514     if (sc->time_scale) {
1515         av_log(c->fc, AV_LOG_ERROR, "Multiple mdhd?\n");
1516         return AVERROR_INVALIDDATA;
1517     }
1518 
1519     version = avio_r8(pb);
1520     if (version > 1) {
1521         avpriv_request_sample(c->fc, "Version %d", version);
1522         return AVERROR_PATCHWELCOME;
1523     }
1524     avio_rb24(pb); /* flags */
1525     if (version == 1) {
1526         creation_time = avio_rb64(pb);
1527         avio_rb64(pb);
1528     } else {
1529         creation_time = avio_rb32(pb);
1530         avio_rb32(pb); /* modification time */
1531     }
1532     mov_metadata_creation_time(&st->metadata, creation_time, c->fc);
1533 
1534     sc->time_scale = avio_rb32(pb);
1535     if (sc->time_scale <= 0) {
1536         av_log(c->fc, AV_LOG_ERROR, "Invalid mdhd time scale %d, defaulting to 1\n", sc->time_scale);
1537         sc->time_scale = 1;
1538     }
1539     st->duration = (version == 1) ? avio_rb64(pb) : avio_rb32(pb); /* duration */
1540 
1541     lang = avio_rb16(pb); /* language */
1542     if (ff_mov_lang_to_iso639(lang, language))
1543         av_dict_set(&st->metadata, "language", language, 0);
1544     avio_rb16(pb); /* quality */
1545 
1546 #ifdef OHOS_EXPAND_MP4_INFO
1547     st->time_scale = sc->time_scale;
1548 #endif
1549 
1550     return 0;
1551 }
1552 
mov_read_mvhd(MOVContext * c,AVIOContext * pb,MOVAtom atom)1553 static int mov_read_mvhd(MOVContext *c, AVIOContext *pb, MOVAtom atom)
1554 {
1555     int i;
1556     int64_t creation_time;
1557     int version = avio_r8(pb); /* version */
1558     avio_rb24(pb); /* flags */
1559 
1560     if (version == 1) {
1561         creation_time = avio_rb64(pb);
1562         avio_rb64(pb);
1563     } else {
1564         creation_time = avio_rb32(pb);
1565         avio_rb32(pb); /* modification time */
1566     }
1567     mov_metadata_creation_time(&c->fc->metadata, creation_time, c->fc);
1568     c->time_scale = avio_rb32(pb); /* time scale */
1569     if (c->time_scale <= 0) {
1570         av_log(c->fc, AV_LOG_ERROR, "Invalid mvhd time scale %d, defaulting to 1\n", c->time_scale);
1571         c->time_scale = 1;
1572     }
1573     av_log(c->fc, AV_LOG_TRACE, "time scale = %i\n", c->time_scale);
1574 
1575     c->duration = (version == 1) ? avio_rb64(pb) : avio_rb32(pb); /* duration */
1576     // set the AVFormatContext duration because the duration of individual tracks
1577     // may be inaccurate
1578     if (!c->trex_data)
1579         c->fc->duration = av_rescale(c->duration, AV_TIME_BASE, c->time_scale);
1580     avio_rb32(pb); /* preferred scale */
1581 
1582     avio_rb16(pb); /* preferred volume */
1583 
1584     avio_skip(pb, 10); /* reserved */
1585 
1586     /* movie display matrix, store it in main context and use it later on */
1587     for (i = 0; i < 3; i++) {
1588         c->movie_display_matrix[i][0] = avio_rb32(pb); // 16.16 fixed point
1589         c->movie_display_matrix[i][1] = avio_rb32(pb); // 16.16 fixed point
1590         c->movie_display_matrix[i][2] = avio_rb32(pb); //  2.30 fixed point
1591     }
1592 
1593     avio_rb32(pb); /* preview time */
1594     avio_rb32(pb); /* preview duration */
1595     avio_rb32(pb); /* poster time */
1596     avio_rb32(pb); /* selection time */
1597     avio_rb32(pb); /* selection duration */
1598     avio_rb32(pb); /* current time */
1599     avio_rb32(pb); /* next track ID */
1600 
1601     return 0;
1602 }
1603 
set_last_stream_little_endian(AVFormatContext * fc)1604 static void set_last_stream_little_endian(AVFormatContext *fc)
1605 {
1606     AVStream *st;
1607 
1608     if (fc->nb_streams < 1)
1609         return;
1610     st = fc->streams[fc->nb_streams-1];
1611 
1612     switch (st->codecpar->codec_id) {
1613     case AV_CODEC_ID_PCM_S16BE:
1614         st->codecpar->codec_id = AV_CODEC_ID_PCM_S16LE;
1615         break;
1616     case AV_CODEC_ID_PCM_S24BE:
1617         st->codecpar->codec_id = AV_CODEC_ID_PCM_S24LE;
1618         break;
1619     case AV_CODEC_ID_PCM_S32BE:
1620         st->codecpar->codec_id = AV_CODEC_ID_PCM_S32LE;
1621         break;
1622     case AV_CODEC_ID_PCM_F32BE:
1623         st->codecpar->codec_id = AV_CODEC_ID_PCM_F32LE;
1624         break;
1625     case AV_CODEC_ID_PCM_F64BE:
1626         st->codecpar->codec_id = AV_CODEC_ID_PCM_F64LE;
1627         break;
1628     default:
1629         break;
1630     }
1631 }
1632 
mov_read_enda(MOVContext * c,AVIOContext * pb,MOVAtom atom)1633 static int mov_read_enda(MOVContext *c, AVIOContext *pb, MOVAtom atom)
1634 {
1635     int little_endian = avio_rb16(pb) & 0xFF;
1636     av_log(c->fc, AV_LOG_TRACE, "enda %d\n", little_endian);
1637     if (little_endian == 1)
1638         set_last_stream_little_endian(c->fc);
1639     return 0;
1640 }
1641 
mov_read_pcmc(MOVContext * c,AVIOContext * pb,MOVAtom atom)1642 static int mov_read_pcmc(MOVContext *c, AVIOContext *pb, MOVAtom atom)
1643 {
1644     int format_flags;
1645 
1646     if (atom.size < 6) {
1647         av_log(c->fc, AV_LOG_ERROR, "Empty pcmC box\n");
1648         return AVERROR_INVALIDDATA;
1649     }
1650 
1651     avio_r8(pb);    // version
1652     avio_rb24(pb);  // flags
1653     format_flags = avio_r8(pb);
1654     if (format_flags == 1) // indicates little-endian format. If not present, big-endian format is used
1655         set_last_stream_little_endian(c->fc);
1656 
1657     return 0;
1658 }
1659 
mov_read_colr(MOVContext * c,AVIOContext * pb,MOVAtom atom)1660 static int mov_read_colr(MOVContext *c, AVIOContext *pb, MOVAtom atom)
1661 {
1662     AVStream *st;
1663     uint8_t *icc_profile;
1664     char color_parameter_type[5] = { 0 };
1665     uint16_t color_primaries, color_trc, color_matrix;
1666     int ret;
1667 
1668     if (c->fc->nb_streams < 1)
1669         return 0;
1670     st = c->fc->streams[c->fc->nb_streams - 1];
1671 
1672     ret = ffio_read_size(pb, color_parameter_type, 4);
1673     if (ret < 0)
1674         return ret;
1675     if (strncmp(color_parameter_type, "nclx", 4) &&
1676         strncmp(color_parameter_type, "nclc", 4) &&
1677         strncmp(color_parameter_type, "prof", 4)) {
1678         av_log(c->fc, AV_LOG_WARNING, "unsupported color_parameter_type %s\n",
1679                color_parameter_type);
1680         return 0;
1681     }
1682 
1683     if (!strncmp(color_parameter_type, "prof", 4)) {
1684         icc_profile = av_stream_new_side_data(st, AV_PKT_DATA_ICC_PROFILE, atom.size - 4);
1685         if (!icc_profile)
1686             return AVERROR(ENOMEM);
1687         ret = ffio_read_size(pb, icc_profile, atom.size - 4);
1688         if (ret < 0)
1689             return ret;
1690     } else {
1691         color_primaries = avio_rb16(pb);
1692         color_trc = avio_rb16(pb);
1693         color_matrix = avio_rb16(pb);
1694 
1695         av_log(c->fc, AV_LOG_TRACE,
1696                "%s: pri %d trc %d matrix %d",
1697                color_parameter_type, color_primaries, color_trc, color_matrix);
1698 
1699         if (!strncmp(color_parameter_type, "nclx", 4)) {
1700             uint8_t color_range = avio_r8(pb) >> 7;
1701             av_log(c->fc, AV_LOG_TRACE, " full %"PRIu8"", color_range);
1702             if (color_range)
1703                 st->codecpar->color_range = AVCOL_RANGE_JPEG;
1704             else
1705                 st->codecpar->color_range = AVCOL_RANGE_MPEG;
1706         }
1707 
1708         if (!av_color_primaries_name(color_primaries))
1709             color_primaries = AVCOL_PRI_UNSPECIFIED;
1710         if (!av_color_transfer_name(color_trc))
1711             color_trc = AVCOL_TRC_UNSPECIFIED;
1712         if (!av_color_space_name(color_matrix))
1713             color_matrix = AVCOL_SPC_UNSPECIFIED;
1714 
1715         st->codecpar->color_primaries = color_primaries;
1716         st->codecpar->color_trc       = color_trc;
1717         st->codecpar->color_space     = color_matrix;
1718         av_log(c->fc, AV_LOG_TRACE, "\n");
1719     }
1720     return 0;
1721 }
1722 
mov_read_fiel(MOVContext * c,AVIOContext * pb,MOVAtom atom)1723 static int mov_read_fiel(MOVContext *c, AVIOContext *pb, MOVAtom atom)
1724 {
1725     AVStream *st;
1726     unsigned mov_field_order;
1727     enum AVFieldOrder decoded_field_order = AV_FIELD_UNKNOWN;
1728 
1729     if (c->fc->nb_streams < 1) // will happen with jp2 files
1730         return 0;
1731     st = c->fc->streams[c->fc->nb_streams-1];
1732     if (atom.size < 2)
1733         return AVERROR_INVALIDDATA;
1734     mov_field_order = avio_rb16(pb);
1735     if ((mov_field_order & 0xFF00) == 0x0100)
1736         decoded_field_order = AV_FIELD_PROGRESSIVE;
1737     else if ((mov_field_order & 0xFF00) == 0x0200) {
1738         switch (mov_field_order & 0xFF) {
1739         case 0x01: decoded_field_order = AV_FIELD_TT;
1740                    break;
1741         case 0x06: decoded_field_order = AV_FIELD_BB;
1742                    break;
1743         case 0x09: decoded_field_order = AV_FIELD_TB;
1744                    break;
1745         case 0x0E: decoded_field_order = AV_FIELD_BT;
1746                    break;
1747         }
1748     }
1749     if (decoded_field_order == AV_FIELD_UNKNOWN && mov_field_order) {
1750         av_log(c->fc, AV_LOG_ERROR, "Unknown MOV field order 0x%04x\n", mov_field_order);
1751     }
1752     st->codecpar->field_order = decoded_field_order;
1753 
1754     return 0;
1755 }
1756 
mov_realloc_extradata(AVCodecParameters * par,MOVAtom atom)1757 static int mov_realloc_extradata(AVCodecParameters *par, MOVAtom atom)
1758 {
1759     int err = 0;
1760     uint64_t size = (uint64_t)par->extradata_size + atom.size + 8 + AV_INPUT_BUFFER_PADDING_SIZE;
1761     if (size > INT_MAX || (uint64_t)atom.size > INT_MAX)
1762         return AVERROR_INVALIDDATA;
1763     if ((err = av_reallocp(&par->extradata, size)) < 0) {
1764         par->extradata_size = 0;
1765         return err;
1766     }
1767     par->extradata_size = size - AV_INPUT_BUFFER_PADDING_SIZE;
1768     return 0;
1769 }
1770 
1771 /* Read a whole atom into the extradata return the size of the atom read, possibly truncated if != atom.size */
mov_read_atom_into_extradata(MOVContext * c,AVIOContext * pb,MOVAtom atom,AVCodecParameters * par,uint8_t * buf)1772 static int64_t mov_read_atom_into_extradata(MOVContext *c, AVIOContext *pb, MOVAtom atom,
1773                                         AVCodecParameters *par, uint8_t *buf)
1774 {
1775     int64_t result = atom.size;
1776     int err;
1777 
1778     AV_WB32(buf    , atom.size + 8);
1779     AV_WL32(buf + 4, atom.type);
1780     err = ffio_read_size(pb, buf + 8, atom.size);
1781     if (err < 0) {
1782         par->extradata_size -= atom.size;
1783         return err;
1784     } else if (err < atom.size) {
1785         av_log(c->fc, AV_LOG_WARNING, "truncated extradata\n");
1786         par->extradata_size -= atom.size - err;
1787         result = err;
1788     }
1789     memset(buf + 8 + err, 0, AV_INPUT_BUFFER_PADDING_SIZE);
1790     return result;
1791 }
1792 
1793 /* FIXME modify QDM2/SVQ3/H.264 decoders to take full atom as extradata */
mov_read_extradata(MOVContext * c,AVIOContext * pb,MOVAtom atom,enum AVCodecID codec_id)1794 static int mov_read_extradata(MOVContext *c, AVIOContext *pb, MOVAtom atom,
1795                               enum AVCodecID codec_id)
1796 {
1797     AVStream *st;
1798     uint64_t original_size;
1799     int err;
1800 
1801     if (c->fc->nb_streams < 1) // will happen with jp2 files
1802         return 0;
1803     st = c->fc->streams[c->fc->nb_streams-1];
1804 
1805     if (st->codecpar->codec_id != codec_id)
1806         return 0; /* unexpected codec_id - don't mess with extradata */
1807 
1808     original_size = st->codecpar->extradata_size;
1809     err = mov_realloc_extradata(st->codecpar, atom);
1810     if (err)
1811         return err;
1812 
1813     err =  mov_read_atom_into_extradata(c, pb, atom, st->codecpar,  st->codecpar->extradata + original_size);
1814     if (err < 0)
1815         return err;
1816     return 0; // Note: this is the original behavior to ignore truncation.
1817 }
1818 
1819 /* wrapper functions for reading ALAC/AVS/MJPEG/MJPEG2000 extradata atoms only for those codecs */
mov_read_alac(MOVContext * c,AVIOContext * pb,MOVAtom atom)1820 static int mov_read_alac(MOVContext *c, AVIOContext *pb, MOVAtom atom)
1821 {
1822     return mov_read_extradata(c, pb, atom, AV_CODEC_ID_ALAC);
1823 }
1824 
mov_read_avss(MOVContext * c,AVIOContext * pb,MOVAtom atom)1825 static int mov_read_avss(MOVContext *c, AVIOContext *pb, MOVAtom atom)
1826 {
1827     return mov_read_extradata(c, pb, atom, AV_CODEC_ID_AVS);
1828 }
1829 
mov_read_jp2h(MOVContext * c,AVIOContext * pb,MOVAtom atom)1830 static int mov_read_jp2h(MOVContext *c, AVIOContext *pb, MOVAtom atom)
1831 {
1832     return mov_read_extradata(c, pb, atom, AV_CODEC_ID_JPEG2000);
1833 }
1834 
mov_read_dpxe(MOVContext * c,AVIOContext * pb,MOVAtom atom)1835 static int mov_read_dpxe(MOVContext *c, AVIOContext *pb, MOVAtom atom)
1836 {
1837     return mov_read_extradata(c, pb, atom, AV_CODEC_ID_R10K);
1838 }
1839 
mov_read_avid(MOVContext * c,AVIOContext * pb,MOVAtom atom)1840 static int mov_read_avid(MOVContext *c, AVIOContext *pb, MOVAtom atom)
1841 {
1842     int ret = mov_read_extradata(c, pb, atom, AV_CODEC_ID_AVUI);
1843     if (!ret)
1844         ret = mov_read_extradata(c, pb, atom, AV_CODEC_ID_DNXHD);
1845     return ret;
1846 }
1847 
mov_read_targa_y216(MOVContext * c,AVIOContext * pb,MOVAtom atom)1848 static int mov_read_targa_y216(MOVContext *c, AVIOContext *pb, MOVAtom atom)
1849 {
1850     int ret = mov_read_extradata(c, pb, atom, AV_CODEC_ID_TARGA_Y216);
1851 
1852     if (!ret && c->fc->nb_streams >= 1) {
1853         AVCodecParameters *par = c->fc->streams[c->fc->nb_streams-1]->codecpar;
1854         if (par->extradata_size >= 40) {
1855             par->height = AV_RB16(&par->extradata[36]);
1856             par->width  = AV_RB16(&par->extradata[38]);
1857         }
1858     }
1859     return ret;
1860 }
1861 
mov_read_ares(MOVContext * c,AVIOContext * pb,MOVAtom atom)1862 static int mov_read_ares(MOVContext *c, AVIOContext *pb, MOVAtom atom)
1863 {
1864     if (c->fc->nb_streams >= 1) {
1865         AVStream *const  st = c->fc->streams[c->fc->nb_streams - 1];
1866         FFStream *const sti = ffstream(st);
1867         AVCodecParameters *par = st->codecpar;
1868 
1869         if (par->codec_tag == MKTAG('A', 'V', 'i', 'n') &&
1870             par->codec_id == AV_CODEC_ID_H264 &&
1871             atom.size > 11) {
1872             int cid;
1873             avio_skip(pb, 10);
1874             cid = avio_rb16(pb);
1875             /* For AVID AVCI50, force width of 1440 to be able to select the correct SPS and PPS */
1876             if (cid == 0xd4d || cid == 0xd4e)
1877                 par->width = 1440;
1878             return 0;
1879         } else if ((par->codec_tag == MKTAG('A', 'V', 'd', '1') ||
1880                     par->codec_tag == MKTAG('A', 'V', 'j', '2') ||
1881                     par->codec_tag == MKTAG('A', 'V', 'd', 'n')) &&
1882                    atom.size >= 24) {
1883             int num, den;
1884             avio_skip(pb, 12);
1885             num = avio_rb32(pb);
1886             den = avio_rb32(pb);
1887             if (num <= 0 || den <= 0)
1888                 return 0;
1889             switch (avio_rb32(pb)) {
1890             case 2:
1891                 if (den >= INT_MAX / 2)
1892                     return 0;
1893                 den *= 2;
1894             case 1:
1895                 sti->display_aspect_ratio = (AVRational){ num, den };
1896             default:
1897                 return 0;
1898             }
1899         }
1900     }
1901 
1902     return mov_read_avid(c, pb, atom);
1903 }
1904 
mov_read_aclr(MOVContext * c,AVIOContext * pb,MOVAtom atom)1905 static int mov_read_aclr(MOVContext *c, AVIOContext *pb, MOVAtom atom)
1906 {
1907     int ret = 0;
1908     int length = 0;
1909     uint64_t original_size;
1910     if (c->fc->nb_streams >= 1) {
1911         AVCodecParameters *par = c->fc->streams[c->fc->nb_streams-1]->codecpar;
1912         if (par->codec_id == AV_CODEC_ID_H264)
1913             return 0;
1914         if (atom.size == 16) {
1915             original_size = par->extradata_size;
1916             ret = mov_realloc_extradata(par, atom);
1917             if (!ret) {
1918                 length =  mov_read_atom_into_extradata(c, pb, atom, par, par->extradata + original_size);
1919                 if (length == atom.size) {
1920                     const uint8_t range_value = par->extradata[original_size + 19];
1921                     switch (range_value) {
1922                     case 1:
1923                         par->color_range = AVCOL_RANGE_MPEG;
1924                         break;
1925                     case 2:
1926                         par->color_range = AVCOL_RANGE_JPEG;
1927                         break;
1928                     default:
1929                         av_log(c->fc, AV_LOG_WARNING, "ignored unknown aclr value (%d)\n", range_value);
1930                         break;
1931                     }
1932                     ff_dlog(c->fc, "color_range: %d\n", par->color_range);
1933                 } else {
1934                   /* For some reason the whole atom was not added to the extradata */
1935                   av_log(c->fc, AV_LOG_ERROR, "aclr not decoded - incomplete atom\n");
1936                 }
1937             } else {
1938                 av_log(c->fc, AV_LOG_ERROR, "aclr not decoded - unable to add atom to extradata\n");
1939             }
1940         } else {
1941             av_log(c->fc, AV_LOG_WARNING, "aclr not decoded - unexpected size %"PRId64"\n", atom.size);
1942         }
1943     }
1944 
1945     return ret;
1946 }
1947 
mov_read_svq3(MOVContext * c,AVIOContext * pb,MOVAtom atom)1948 static int mov_read_svq3(MOVContext *c, AVIOContext *pb, MOVAtom atom)
1949 {
1950     return mov_read_extradata(c, pb, atom, AV_CODEC_ID_SVQ3);
1951 }
1952 
mov_read_wave(MOVContext * c,AVIOContext * pb,MOVAtom atom)1953 static int mov_read_wave(MOVContext *c, AVIOContext *pb, MOVAtom atom)
1954 {
1955     AVStream *st;
1956     int ret;
1957 
1958     if (c->fc->nb_streams < 1)
1959         return 0;
1960     st = c->fc->streams[c->fc->nb_streams-1];
1961 
1962     if ((uint64_t)atom.size > (1<<30))
1963         return AVERROR_INVALIDDATA;
1964 
1965     if (st->codecpar->codec_id == AV_CODEC_ID_QDM2 ||
1966         st->codecpar->codec_id == AV_CODEC_ID_QDMC ||
1967         st->codecpar->codec_id == AV_CODEC_ID_SPEEX) {
1968         // pass all frma atom to codec, needed at least for QDMC and QDM2
1969         ret = ff_get_extradata(c->fc, st->codecpar, pb, atom.size);
1970         if (ret < 0)
1971             return ret;
1972     } else if (atom.size > 8) { /* to read frma, esds atoms */
1973         if (st->codecpar->codec_id == AV_CODEC_ID_ALAC && atom.size >= 24) {
1974             uint64_t buffer;
1975             ret = ffio_ensure_seekback(pb, 8);
1976             if (ret < 0)
1977                 return ret;
1978             buffer = avio_rb64(pb);
1979             atom.size -= 8;
1980             if (  (buffer & 0xFFFFFFFF) == MKBETAG('f','r','m','a')
1981                 && buffer >> 32 <= atom.size
1982                 && buffer >> 32 >= 8) {
1983                 avio_skip(pb, -8);
1984                 atom.size += 8;
1985             } else if (!st->codecpar->extradata_size) {
1986 #define ALAC_EXTRADATA_SIZE 36
1987                 st->codecpar->extradata = av_mallocz(ALAC_EXTRADATA_SIZE + AV_INPUT_BUFFER_PADDING_SIZE);
1988                 if (!st->codecpar->extradata)
1989                     return AVERROR(ENOMEM);
1990                 st->codecpar->extradata_size = ALAC_EXTRADATA_SIZE;
1991                 AV_WB32(st->codecpar->extradata    , ALAC_EXTRADATA_SIZE);
1992                 AV_WB32(st->codecpar->extradata + 4, MKTAG('a','l','a','c'));
1993                 AV_WB64(st->codecpar->extradata + 12, buffer);
1994                 avio_read(pb, st->codecpar->extradata + 20, 16);
1995                 avio_skip(pb, atom.size - 24);
1996                 return 0;
1997             }
1998         }
1999         if ((ret = mov_read_default(c, pb, atom)) < 0)
2000             return ret;
2001     } else
2002         avio_skip(pb, atom.size);
2003     return 0;
2004 }
2005 
2006 /**
2007  * This function reads atom content and puts data in extradata without tag
2008  * nor size unlike mov_read_extradata.
2009  */
mov_read_glbl(MOVContext * c,AVIOContext * pb,MOVAtom atom)2010 static int mov_read_glbl(MOVContext *c, AVIOContext *pb, MOVAtom atom)
2011 {
2012     AVStream *st;
2013     int ret;
2014 
2015     if (c->fc->nb_streams < 1)
2016         return 0;
2017     st = c->fc->streams[c->fc->nb_streams-1];
2018 
2019     if ((uint64_t)atom.size > (1<<30))
2020         return AVERROR_INVALIDDATA;
2021 #ifdef OHOS_OPT_COMPAT
2022     if (atom.type == MKTAG('v','v','c','C')) {
2023         avio_rb32(pb);
2024         atom.size -= 4;
2025     }
2026 #endif
2027     if (atom.size >= 10) {
2028         // Broken files created by legacy versions of libavformat will
2029         // wrap a whole fiel atom inside of a glbl atom.
2030         unsigned size = avio_rb32(pb);
2031         unsigned type = avio_rl32(pb);
2032         if (avio_feof(pb))
2033             return AVERROR_INVALIDDATA;
2034         avio_seek(pb, -8, SEEK_CUR);
2035         if (type == MKTAG('f','i','e','l') && size == atom.size)
2036             return mov_read_default(c, pb, atom);
2037     }
2038     if (st->codecpar->extradata_size > 1 && st->codecpar->extradata) {
2039         av_log(c->fc, AV_LOG_WARNING, "ignoring multiple glbl\n");
2040         return 0;
2041     }
2042     ret = ff_get_extradata(c->fc, st->codecpar, pb, atom.size);
2043     if (ret < 0)
2044         return ret;
2045     if (atom.type == MKTAG('h','v','c','C') && st->codecpar->codec_tag == MKTAG('d','v','h','1'))
2046         /* HEVC-based Dolby Vision derived from hvc1.
2047            Happens to match with an identifier
2048            previously utilized for DV. Thus, if we have
2049            the hvcC extradata box available as specified,
2050            set codec to HEVC */
2051         st->codecpar->codec_id = AV_CODEC_ID_HEVC;
2052 #ifdef OHOS_OPT_COMPAT
2053     if (atom.type == MKTAG('v','v','c','C'))
2054         st->codecpar->codec_id = AV_CODEC_ID_VVC;
2055 #endif
2056     return 0;
2057 }
2058 
mov_read_dvc1(MOVContext * c,AVIOContext * pb,MOVAtom atom)2059 static int mov_read_dvc1(MOVContext *c, AVIOContext *pb, MOVAtom atom)
2060 {
2061     AVStream *st;
2062     uint8_t profile_level;
2063     int ret;
2064 
2065     if (c->fc->nb_streams < 1)
2066         return 0;
2067     st = c->fc->streams[c->fc->nb_streams-1];
2068 
2069     if (atom.size >= (1<<28) || atom.size < 7)
2070         return AVERROR_INVALIDDATA;
2071 
2072     profile_level = avio_r8(pb);
2073     if ((profile_level & 0xf0) != 0xc0)
2074         return 0;
2075 
2076     avio_seek(pb, 6, SEEK_CUR);
2077     ret = ff_get_extradata(c->fc, st->codecpar, pb, atom.size - 7);
2078     if (ret < 0)
2079         return ret;
2080 
2081     return 0;
2082 }
2083 
2084 /**
2085  * An strf atom is a BITMAPINFOHEADER struct. This struct is 40 bytes itself,
2086  * but can have extradata appended at the end after the 40 bytes belonging
2087  * to the struct.
2088  */
mov_read_strf(MOVContext * c,AVIOContext * pb,MOVAtom atom)2089 static int mov_read_strf(MOVContext *c, AVIOContext *pb, MOVAtom atom)
2090 {
2091     AVStream *st;
2092     int ret;
2093 
2094     if (c->fc->nb_streams < 1)
2095         return 0;
2096     if (atom.size <= 40)
2097         return 0;
2098     st = c->fc->streams[c->fc->nb_streams-1];
2099 
2100     if ((uint64_t)atom.size > (1<<30))
2101         return AVERROR_INVALIDDATA;
2102 
2103     avio_skip(pb, 40);
2104     ret = ff_get_extradata(c->fc, st->codecpar, pb, atom.size - 40);
2105     if (ret < 0)
2106         return ret;
2107 
2108     return 0;
2109 }
2110 
mov_read_stco(MOVContext * c,AVIOContext * pb,MOVAtom atom)2111 static int mov_read_stco(MOVContext *c, AVIOContext *pb, MOVAtom atom)
2112 {
2113     AVStream *st;
2114     MOVStreamContext *sc;
2115     unsigned int i, entries;
2116 
2117     if (c->trak_index < 0) {
2118         av_log(c->fc, AV_LOG_WARNING, "STCO outside TRAK\n");
2119         return 0;
2120     }
2121     if (c->fc->nb_streams < 1)
2122         return 0;
2123     st = c->fc->streams[c->fc->nb_streams-1];
2124     sc = st->priv_data;
2125 
2126     avio_r8(pb); /* version */
2127     avio_rb24(pb); /* flags */
2128 
2129     entries = avio_rb32(pb);
2130 
2131     if (!entries)
2132         return 0;
2133 
2134     if (sc->chunk_offsets) {
2135         av_log(c->fc, AV_LOG_WARNING, "Ignoring duplicated STCO atom\n");
2136         return 0;
2137     }
2138     av_free(sc->chunk_offsets);
2139     sc->chunk_count = 0;
2140     sc->chunk_offsets = av_malloc_array(entries, sizeof(*sc->chunk_offsets));
2141     if (!sc->chunk_offsets)
2142         return AVERROR(ENOMEM);
2143     sc->chunk_count = entries;
2144 
2145     if      (atom.type == MKTAG('s','t','c','o'))
2146         for (i = 0; i < entries && !pb->eof_reached; i++)
2147             sc->chunk_offsets[i] = avio_rb32(pb);
2148     else if (atom.type == MKTAG('c','o','6','4'))
2149         for (i = 0; i < entries && !pb->eof_reached; i++)
2150             sc->chunk_offsets[i] = avio_rb64(pb);
2151     else
2152         return AVERROR_INVALIDDATA;
2153 
2154     sc->chunk_count = i;
2155 
2156     if (pb->eof_reached) {
2157         av_log(c->fc, AV_LOG_WARNING, "reached eof, corrupted STCO atom\n");
2158         return AVERROR_EOF;
2159     }
2160 
2161     return 0;
2162 }
2163 
mov_codec_id(AVStream * st,uint32_t format)2164 static int mov_codec_id(AVStream *st, uint32_t format)
2165 {
2166     int id = ff_codec_get_id(ff_codec_movaudio_tags, format);
2167 
2168     if (id <= 0 &&
2169         ((format & 0xFFFF) == 'm' + ('s' << 8) ||
2170          (format & 0xFFFF) == 'T' + ('S' << 8)))
2171         id = ff_codec_get_id(ff_codec_wav_tags, av_bswap32(format) & 0xFFFF);
2172 
2173     if (st->codecpar->codec_type != AVMEDIA_TYPE_VIDEO && id > 0) {
2174         st->codecpar->codec_type = AVMEDIA_TYPE_AUDIO;
2175     } else if (st->codecpar->codec_type != AVMEDIA_TYPE_AUDIO &&
2176                /* skip old ASF MPEG-4 tag */
2177                format && format != MKTAG('m','p','4','s')) {
2178         id = ff_codec_get_id(ff_codec_movvideo_tags, format);
2179         if (id <= 0)
2180             id = ff_codec_get_id(ff_codec_bmp_tags, format);
2181         if (id > 0)
2182             st->codecpar->codec_type = AVMEDIA_TYPE_VIDEO;
2183         else if (st->codecpar->codec_type == AVMEDIA_TYPE_DATA ||
2184                     (st->codecpar->codec_type == AVMEDIA_TYPE_SUBTITLE &&
2185                     st->codecpar->codec_id == AV_CODEC_ID_NONE)) {
2186             id = ff_codec_get_id(ff_codec_movsubtitle_tags, format);
2187             if (id > 0)
2188                 st->codecpar->codec_type = AVMEDIA_TYPE_SUBTITLE;
2189             else
2190                 id = ff_codec_get_id(ff_codec_movdata_tags, format);
2191 #ifdef OHOS_TIMED_META_TRACK
2192         } else if (st->codecpar->codec_type == AVMEDIA_TYPE_TIMEDMETA) {
2193             id = AV_CODEC_ID_FFMETADATA;
2194         }
2195 #else
2196         }
2197 #endif
2198     }
2199 
2200     st->codecpar->codec_tag = format;
2201 
2202     return id;
2203 }
2204 
mov_parse_stsd_video(MOVContext * c,AVIOContext * pb,AVStream * st,MOVStreamContext * sc)2205 static void mov_parse_stsd_video(MOVContext *c, AVIOContext *pb,
2206                                  AVStream *st, MOVStreamContext *sc)
2207 {
2208     uint8_t codec_name[32] = { 0 };
2209     int64_t stsd_start;
2210     unsigned int len;
2211     uint32_t id = 0;
2212 
2213     /* The first 16 bytes of the video sample description are already
2214      * read in ff_mov_read_stsd_entries() */
2215     stsd_start = avio_tell(pb) - 16;
2216 
2217     avio_rb16(pb); /* version */
2218     avio_rb16(pb); /* revision level */
2219     id = avio_rl32(pb); /* vendor */
2220     av_dict_set(&st->metadata, "vendor_id", av_fourcc2str(id), 0);
2221     avio_rb32(pb); /* temporal quality */
2222     avio_rb32(pb); /* spatial quality */
2223 
2224     st->codecpar->width  = avio_rb16(pb); /* width */
2225     st->codecpar->height = avio_rb16(pb); /* height */
2226 
2227     avio_rb32(pb); /* horiz resolution */
2228     avio_rb32(pb); /* vert resolution */
2229     avio_rb32(pb); /* data size, always 0 */
2230     avio_rb16(pb); /* frames per samples */
2231 
2232     len = avio_r8(pb); /* codec name, pascal string */
2233     if (len > 31)
2234         len = 31;
2235     mov_read_mac_string(c, pb, len, codec_name, sizeof(codec_name));
2236     if (len < 31)
2237         avio_skip(pb, 31 - len);
2238 
2239     if (codec_name[0])
2240         av_dict_set(&st->metadata, "encoder", codec_name, 0);
2241 
2242     /* codec_tag YV12 triggers an UV swap in rawdec.c */
2243     if (!strncmp(codec_name, "Planar Y'CbCr 8-bit 4:2:0", 25)) {
2244         st->codecpar->codec_tag = MKTAG('I', '4', '2', '0');
2245         st->codecpar->width &= ~1;
2246         st->codecpar->height &= ~1;
2247     }
2248     /* Flash Media Server uses tag H.263 with Sorenson Spark */
2249     if (st->codecpar->codec_tag == MKTAG('H','2','6','3') &&
2250         !strncmp(codec_name, "Sorenson H263", 13))
2251         st->codecpar->codec_id = AV_CODEC_ID_FLV1;
2252 
2253     st->codecpar->bits_per_coded_sample = avio_rb16(pb); /* depth */
2254 
2255     avio_seek(pb, stsd_start, SEEK_SET);
2256 
2257     if (ff_get_qtpalette(st->codecpar->codec_id, pb, sc->palette)) {
2258         st->codecpar->bits_per_coded_sample &= 0x1F;
2259         sc->has_palette = 1;
2260     }
2261 }
2262 
mov_parse_stsd_audio(MOVContext * c,AVIOContext * pb,AVStream * st,MOVStreamContext * sc)2263 static void mov_parse_stsd_audio(MOVContext *c, AVIOContext *pb,
2264                                  AVStream *st, MOVStreamContext *sc)
2265 {
2266     int bits_per_sample, flags;
2267     uint16_t version = avio_rb16(pb);
2268     uint32_t id = 0;
2269     AVDictionaryEntry *compatible_brands = av_dict_get(c->fc->metadata, "compatible_brands", NULL, AV_DICT_MATCH_CASE);
2270     int channel_count;
2271 
2272     avio_rb16(pb); /* revision level */
2273     id = avio_rl32(pb); /* vendor */
2274     av_dict_set(&st->metadata, "vendor_id", av_fourcc2str(id), 0);
2275 
2276     channel_count = avio_rb16(pb);
2277 
2278     st->codecpar->ch_layout.order = AV_CHANNEL_ORDER_UNSPEC;
2279     st->codecpar->ch_layout.nb_channels = channel_count;
2280     st->codecpar->bits_per_coded_sample = avio_rb16(pb); /* sample size */
2281     av_log(c->fc, AV_LOG_TRACE, "audio channels %d\n", channel_count);
2282 
2283     sc->audio_cid = avio_rb16(pb);
2284     avio_rb16(pb); /* packet size = 0 */
2285 
2286     st->codecpar->sample_rate = ((avio_rb32(pb) >> 16));
2287 
2288     // Read QT version 1 fields. In version 0 these do not exist.
2289     av_log(c->fc, AV_LOG_TRACE, "version =%d, isom =%d\n", version, c->isom);
2290     if (!c->isom ||
2291         (compatible_brands && strstr(compatible_brands->value, "qt  ")) ||
2292         (sc->stsd_version == 0 && version > 0)) {
2293         if (version == 1) {
2294             sc->samples_per_frame = avio_rb32(pb);
2295             avio_rb32(pb); /* bytes per packet */
2296             sc->bytes_per_frame = avio_rb32(pb);
2297             avio_rb32(pb); /* bytes per sample */
2298         } else if (version == 2) {
2299             avio_rb32(pb); /* sizeof struct only */
2300             st->codecpar->sample_rate = av_int2double(avio_rb64(pb));
2301             channel_count = avio_rb32(pb);
2302             st->codecpar->ch_layout.order = AV_CHANNEL_ORDER_UNSPEC;
2303             st->codecpar->ch_layout.nb_channels = channel_count;
2304             avio_rb32(pb); /* always 0x7F000000 */
2305             st->codecpar->bits_per_coded_sample = avio_rb32(pb);
2306 
2307             flags = avio_rb32(pb); /* lpcm format specific flag */
2308             sc->bytes_per_frame   = avio_rb32(pb);
2309             sc->samples_per_frame = avio_rb32(pb);
2310             if (st->codecpar->codec_tag == MKTAG('l','p','c','m'))
2311                 st->codecpar->codec_id =
2312                     ff_mov_get_lpcm_codec_id(st->codecpar->bits_per_coded_sample,
2313                                              flags);
2314         }
2315         if (version == 0 || (version == 1 && sc->audio_cid != -2)) {
2316             /* can't correctly handle variable sized packet as audio unit */
2317             switch (st->codecpar->codec_id) {
2318             case AV_CODEC_ID_MP2:
2319             case AV_CODEC_ID_MP3:
2320                 ffstream(st)->need_parsing = AVSTREAM_PARSE_FULL;
2321                 break;
2322             }
2323         }
2324     }
2325 
2326     if (sc->format == 0) {
2327         if (st->codecpar->bits_per_coded_sample == 8)
2328             st->codecpar->codec_id = mov_codec_id(st, MKTAG('r','a','w',' '));
2329         else if (st->codecpar->bits_per_coded_sample == 16)
2330             st->codecpar->codec_id = mov_codec_id(st, MKTAG('t','w','o','s'));
2331     }
2332 
2333     switch (st->codecpar->codec_id) {
2334     case AV_CODEC_ID_PCM_S8:
2335     case AV_CODEC_ID_PCM_U8:
2336         if (st->codecpar->bits_per_coded_sample == 16)
2337             st->codecpar->codec_id = AV_CODEC_ID_PCM_S16BE;
2338         break;
2339     case AV_CODEC_ID_PCM_S16LE:
2340     case AV_CODEC_ID_PCM_S16BE:
2341         if (st->codecpar->bits_per_coded_sample == 8)
2342             st->codecpar->codec_id = AV_CODEC_ID_PCM_S8;
2343         else if (st->codecpar->bits_per_coded_sample == 24)
2344             st->codecpar->codec_id =
2345                 st->codecpar->codec_id == AV_CODEC_ID_PCM_S16BE ?
2346                 AV_CODEC_ID_PCM_S24BE : AV_CODEC_ID_PCM_S24LE;
2347         else if (st->codecpar->bits_per_coded_sample == 32)
2348              st->codecpar->codec_id =
2349                 st->codecpar->codec_id == AV_CODEC_ID_PCM_S16BE ?
2350                 AV_CODEC_ID_PCM_S32BE : AV_CODEC_ID_PCM_S32LE;
2351         break;
2352     /* set values for old format before stsd version 1 appeared */
2353     case AV_CODEC_ID_MACE3:
2354         sc->samples_per_frame = 6;
2355         sc->bytes_per_frame   = 2 * st->codecpar->ch_layout.nb_channels;
2356         break;
2357     case AV_CODEC_ID_MACE6:
2358         sc->samples_per_frame = 6;
2359         sc->bytes_per_frame   = 1 * st->codecpar->ch_layout.nb_channels;
2360         break;
2361     case AV_CODEC_ID_ADPCM_IMA_QT:
2362         sc->samples_per_frame = 64;
2363         sc->bytes_per_frame   = 34 * st->codecpar->ch_layout.nb_channels;
2364         break;
2365     case AV_CODEC_ID_GSM:
2366         sc->samples_per_frame = 160;
2367         sc->bytes_per_frame   = 33;
2368         break;
2369     default:
2370         break;
2371     }
2372 
2373     bits_per_sample = av_get_bits_per_sample(st->codecpar->codec_id);
2374     if (bits_per_sample && (bits_per_sample >> 3) * (uint64_t)st->codecpar->ch_layout.nb_channels <= INT_MAX) {
2375         st->codecpar->bits_per_coded_sample = bits_per_sample;
2376         sc->sample_size = (bits_per_sample >> 3) * st->codecpar->ch_layout.nb_channels;
2377     }
2378 }
2379 
mov_parse_stsd_subtitle(MOVContext * c,AVIOContext * pb,AVStream * st,MOVStreamContext * sc,int64_t size)2380 static void mov_parse_stsd_subtitle(MOVContext *c, AVIOContext *pb,
2381                                     AVStream *st, MOVStreamContext *sc,
2382                                     int64_t size)
2383 {
2384     // ttxt stsd contains display flags, justification, background
2385     // color, fonts, and default styles, so fake an atom to read it
2386     MOVAtom fake_atom = { .size = size };
2387     // mp4s contains a regular esds atom
2388     if (st->codecpar->codec_tag != AV_RL32("mp4s"))
2389         mov_read_glbl(c, pb, fake_atom);
2390     st->codecpar->width  = sc->width;
2391     st->codecpar->height = sc->height;
2392 }
2393 
yuv_to_rgba(uint32_t ycbcr)2394 static uint32_t yuv_to_rgba(uint32_t ycbcr)
2395 {
2396     uint8_t r, g, b;
2397     int y, cb, cr;
2398 
2399     y  = (ycbcr >> 16) & 0xFF;
2400     cr = (ycbcr >> 8)  & 0xFF;
2401     cb =  ycbcr        & 0xFF;
2402 
2403     b = av_clip_uint8((1164 * (y - 16)                     + 2018 * (cb - 128)) / 1000);
2404     g = av_clip_uint8((1164 * (y - 16) -  813 * (cr - 128) -  391 * (cb - 128)) / 1000);
2405     r = av_clip_uint8((1164 * (y - 16) + 1596 * (cr - 128)                    ) / 1000);
2406 
2407     return (r << 16) | (g << 8) | b;
2408 }
2409 
mov_rewrite_dvd_sub_extradata(AVStream * st)2410 static int mov_rewrite_dvd_sub_extradata(AVStream *st)
2411 {
2412     char buf[256] = {0};
2413     uint8_t *src = st->codecpar->extradata;
2414     int i, ret;
2415 
2416     if (st->codecpar->extradata_size != 64)
2417         return 0;
2418 
2419     if (st->codecpar->width > 0 &&  st->codecpar->height > 0)
2420         snprintf(buf, sizeof(buf), "size: %dx%d\n",
2421                  st->codecpar->width, st->codecpar->height);
2422     av_strlcat(buf, "palette: ", sizeof(buf));
2423 
2424     for (i = 0; i < 16; i++) {
2425         uint32_t yuv = AV_RB32(src + i * 4);
2426         uint32_t rgba = yuv_to_rgba(yuv);
2427 
2428         av_strlcatf(buf, sizeof(buf), "%06"PRIx32"%s", rgba, i != 15 ? ", " : "");
2429     }
2430 
2431     if (av_strlcat(buf, "\n", sizeof(buf)) >= sizeof(buf))
2432         return 0;
2433 
2434     ret = ff_alloc_extradata(st->codecpar, strlen(buf));
2435     if (ret < 0)
2436         return ret;
2437     memcpy(st->codecpar->extradata, buf, st->codecpar->extradata_size);
2438 
2439     return 0;
2440 }
2441 
2442 #ifdef OHOS_TIMED_META_TRACK
mov_parse_mebx_keyd(MOVContext * c,AVIOContext * pb,AVStream * st)2443 static int mov_parse_mebx_keyd(MOVContext *c, AVIOContext *pb, AVStream *st)
2444 {
2445     int atom_size = (int)avio_rb32(pb);
2446     avio_rb32(pb);  // local key id
2447     int keyd_size = (int)avio_rb32(pb);
2448     avio_rb32(pb);  // keyd
2449     avio_rb32(pb);  // mdta
2450     int key_value_size = keyd_size - 12;  // 12 bytes to skip
2451 
2452     unsigned char* buf = av_malloc(key_value_size + 1);
2453     if (!buf)
2454         return AVERROR(ENOMEM);
2455     int ret = ffio_read_size(pb, buf, key_value_size);
2456     if (ret < 0) {
2457         av_freep(&buf);
2458         av_log(c->fc, AV_LOG_WARNING, "failed to read key value\n");
2459         return ret;
2460     }
2461     buf[key_value_size] = 0;
2462     av_dict_set(&st->metadata, "timed_metadata_key", buf, 0);
2463     av_freep(&buf);
2464     return atom_size;
2465 }
2466 
mov_parse_mebx_data(MOVContext * c,AVIOContext * pb,AVStream * st,int64_t size)2467 static int mov_parse_mebx_data(MOVContext *c, AVIOContext *pb,
2468                                AVStream *st, int64_t size)
2469 {
2470     int read_size = 0;
2471 
2472     if (c->fc->nb_streams < 1)
2473         return 0;
2474     st = c->fc->streams[c->fc->nb_streams-1];
2475 
2476     int size_keys = (int)avio_rb32(pb);  // size of keys
2477     avio_rb32(pb);  // keys
2478     const int read_counts = 8;
2479     read_size += read_counts;
2480     while (read_size < size_keys) {
2481         int atom_size = mov_parse_mebx_keyd(c, pb, st);
2482         if (atom_size < 0) {
2483             return atom_size;
2484         }
2485         read_size += atom_size;
2486     }
2487     return 0;
2488 }
2489 
mov_read_cdsc(MOVContext * c,AVIOContext * pb,MOVAtom atom)2490 static int mov_read_cdsc(MOVContext *c, AVIOContext *pb, MOVAtom atom)
2491 {
2492     AVStream *st;
2493 
2494     if (c->fc->nb_streams < 1)
2495         return 0;
2496     st = c->fc->streams[c->fc->nb_streams - 1];
2497     int src_track_id = (int)avio_rb32(pb);
2498     char* metaKeyStr;
2499     metaKeyStr = av_d2str(src_track_id - 1);
2500     if (!metaKeyStr)
2501         return AVERROR(ENOMEM);
2502     av_dict_set(&st->metadata, "src_track_id", metaKeyStr, 0);
2503     av_freep(&metaKeyStr);
2504     return 0;
2505 }
2506 #endif
2507 
mov_parse_stsd_data(MOVContext * c,AVIOContext * pb,AVStream * st,MOVStreamContext * sc,int64_t size)2508 static int mov_parse_stsd_data(MOVContext *c, AVIOContext *pb,
2509                                 AVStream *st, MOVStreamContext *sc,
2510                                 int64_t size)
2511 {
2512     int ret;
2513 
2514     if (st->codecpar->codec_tag == MKTAG('t','m','c','d')) {
2515         if ((int)size != size)
2516             return AVERROR(ENOMEM);
2517 
2518         ret = ff_get_extradata(c->fc, st->codecpar, pb, size);
2519         if (ret < 0)
2520             return ret;
2521         if (size > 16) {
2522             MOVStreamContext *tmcd_ctx = st->priv_data;
2523             int val;
2524             val = AV_RB32(st->codecpar->extradata + 4);
2525             tmcd_ctx->tmcd_flags = val;
2526             st->avg_frame_rate.num = AV_RB32(st->codecpar->extradata + 8); /* timescale */
2527             st->avg_frame_rate.den = AV_RB32(st->codecpar->extradata + 12); /* frameDuration */
2528             tmcd_ctx->tmcd_nb_frames = st->codecpar->extradata[16]; /* number of frames */
2529             if (size > 30) {
2530                 uint32_t len = AV_RB32(st->codecpar->extradata + 18); /* name atom length */
2531                 uint32_t format = AV_RB32(st->codecpar->extradata + 22);
2532                 if (format == AV_RB32("name") && (int64_t)size >= (int64_t)len + 18) {
2533                     uint16_t str_size = AV_RB16(st->codecpar->extradata + 26); /* string length */
2534                     if (str_size > 0 && size >= (int)str_size + 30 &&
2535                         st->codecpar->extradata[30] /* Don't add empty string */) {
2536                         char *reel_name = av_malloc(str_size + 1);
2537                         if (!reel_name)
2538                             return AVERROR(ENOMEM);
2539                         memcpy(reel_name, st->codecpar->extradata + 30, str_size);
2540                         reel_name[str_size] = 0; /* Add null terminator */
2541                         av_dict_set(&st->metadata, "reel_name", reel_name,
2542                                     AV_DICT_DONT_STRDUP_VAL);
2543                     }
2544                 }
2545             }
2546         }
2547     } else {
2548         /* other codec type, just skip (rtp, mp4s ...) */
2549         avio_skip(pb, size);
2550     }
2551     return 0;
2552 }
2553 
mov_finalize_stsd_codec(MOVContext * c,AVIOContext * pb,AVStream * st,MOVStreamContext * sc)2554 static int mov_finalize_stsd_codec(MOVContext *c, AVIOContext *pb,
2555                                    AVStream *st, MOVStreamContext *sc)
2556 {
2557     FFStream *const sti = ffstream(st);
2558 
2559     if (st->codecpar->codec_type == AVMEDIA_TYPE_AUDIO &&
2560         !st->codecpar->sample_rate && sc->time_scale > 1)
2561         st->codecpar->sample_rate = sc->time_scale;
2562 
2563     /* special codec parameters handling */
2564     switch (st->codecpar->codec_id) {
2565 #if CONFIG_DV_DEMUXER
2566     case AV_CODEC_ID_DVAUDIO:
2567         c->dv_fctx = avformat_alloc_context();
2568         if (!c->dv_fctx) {
2569             av_log(c->fc, AV_LOG_ERROR, "dv demux context alloc error\n");
2570             return AVERROR(ENOMEM);
2571         }
2572         c->dv_demux = avpriv_dv_init_demux(c->dv_fctx);
2573         if (!c->dv_demux) {
2574             av_log(c->fc, AV_LOG_ERROR, "dv demux context init error\n");
2575             return AVERROR(ENOMEM);
2576         }
2577         sc->dv_audio_container = 1;
2578         st->codecpar->codec_id    = AV_CODEC_ID_PCM_S16LE;
2579         break;
2580 #endif
2581     /* no ifdef since parameters are always those */
2582     case AV_CODEC_ID_QCELP:
2583         av_channel_layout_uninit(&st->codecpar->ch_layout);
2584         st->codecpar->ch_layout = (AVChannelLayout)AV_CHANNEL_LAYOUT_MONO;
2585         // force sample rate for qcelp when not stored in mov
2586         if (st->codecpar->codec_tag != MKTAG('Q','c','l','p'))
2587             st->codecpar->sample_rate = 8000;
2588         // FIXME: Why is the following needed for some files?
2589         sc->samples_per_frame = 160;
2590         if (!sc->bytes_per_frame)
2591             sc->bytes_per_frame = 35;
2592         break;
2593     case AV_CODEC_ID_AMR_NB:
2594         av_channel_layout_uninit(&st->codecpar->ch_layout);
2595         st->codecpar->ch_layout = (AVChannelLayout)AV_CHANNEL_LAYOUT_MONO;
2596         /* force sample rate for amr, stsd in 3gp does not store sample rate */
2597         st->codecpar->sample_rate = 8000;
2598         break;
2599     case AV_CODEC_ID_AMR_WB:
2600         av_channel_layout_uninit(&st->codecpar->ch_layout);
2601         st->codecpar->ch_layout = (AVChannelLayout)AV_CHANNEL_LAYOUT_MONO;
2602         st->codecpar->sample_rate = 16000;
2603         break;
2604     case AV_CODEC_ID_MP2:
2605     case AV_CODEC_ID_MP3:
2606         /* force type after stsd for m1a hdlr */
2607         st->codecpar->codec_type = AVMEDIA_TYPE_AUDIO;
2608         break;
2609     case AV_CODEC_ID_GSM:
2610     case AV_CODEC_ID_ADPCM_MS:
2611     case AV_CODEC_ID_ADPCM_IMA_WAV:
2612     case AV_CODEC_ID_ILBC:
2613     case AV_CODEC_ID_MACE3:
2614     case AV_CODEC_ID_MACE6:
2615     case AV_CODEC_ID_QDM2:
2616         st->codecpar->block_align = sc->bytes_per_frame;
2617         break;
2618     case AV_CODEC_ID_ALAC:
2619         if (st->codecpar->extradata_size == 36) {
2620             int channel_count = AV_RB8(st->codecpar->extradata + 21);
2621             if (st->codecpar->ch_layout.nb_channels != channel_count) {
2622                 av_channel_layout_uninit(&st->codecpar->ch_layout);
2623                 st->codecpar->ch_layout.order = AV_CHANNEL_ORDER_UNSPEC;
2624                 st->codecpar->ch_layout.nb_channels = channel_count;
2625             }
2626             st->codecpar->sample_rate = AV_RB32(st->codecpar->extradata + 32);
2627         }
2628         break;
2629     case AV_CODEC_ID_AC3:
2630     case AV_CODEC_ID_EAC3:
2631     case AV_CODEC_ID_MPEG1VIDEO:
2632     case AV_CODEC_ID_VC1:
2633     case AV_CODEC_ID_VP8:
2634     case AV_CODEC_ID_VP9:
2635         sti->need_parsing = AVSTREAM_PARSE_FULL;
2636         break;
2637     case AV_CODEC_ID_AV1:
2638         /* field_order detection of H264 requires parsing */
2639     case AV_CODEC_ID_H264:
2640         sti->need_parsing = AVSTREAM_PARSE_HEADERS;
2641         break;
2642     default:
2643         break;
2644     }
2645     return 0;
2646 }
2647 
mov_skip_multiple_stsd(MOVContext * c,AVIOContext * pb,int codec_tag,int format,int64_t size)2648 static int mov_skip_multiple_stsd(MOVContext *c, AVIOContext *pb,
2649                                   int codec_tag, int format,
2650                                   int64_t size)
2651 {
2652     if (codec_tag &&
2653          (codec_tag != format &&
2654           // AVID 1:1 samples with differing data format and codec tag exist
2655           (codec_tag != AV_RL32("AV1x") || format != AV_RL32("AVup")) &&
2656           // prores is allowed to have differing data format and codec tag
2657           codec_tag != AV_RL32("apcn") && codec_tag != AV_RL32("apch") &&
2658           // so is dv (sigh)
2659           codec_tag != AV_RL32("dvpp") && codec_tag != AV_RL32("dvcp") &&
2660           (c->fc->video_codec_id ? ff_codec_get_id(ff_codec_movvideo_tags, format) != c->fc->video_codec_id
2661                                  : codec_tag != MKTAG('j','p','e','g')))) {
2662         /* Multiple fourcc, we skip JPEG. This is not correct, we should
2663          * export it as a separate AVStream but this needs a few changes
2664          * in the MOV demuxer, patch welcome. */
2665 
2666         av_log(c->fc, AV_LOG_WARNING, "multiple fourcc not supported\n");
2667         avio_skip(pb, size);
2668         return 1;
2669     }
2670 
2671     return 0;
2672 }
2673 
ff_mov_read_stsd_entries(MOVContext * c,AVIOContext * pb,int entries)2674 int ff_mov_read_stsd_entries(MOVContext *c, AVIOContext *pb, int entries)
2675 {
2676     av_log(c->fc, AV_LOG_INFO, "enter\n");
2677     AVStream *st;
2678     MOVStreamContext *sc;
2679     int pseudo_stream_id;
2680 
2681     av_assert0 (c->fc->nb_streams >= 1);
2682     st = c->fc->streams[c->fc->nb_streams-1];
2683     sc = st->priv_data;
2684 
2685     for (pseudo_stream_id = 0;
2686          pseudo_stream_id < entries && !pb->eof_reached;
2687          pseudo_stream_id++) {
2688         //Parsing Sample description table
2689         enum AVCodecID id;
2690         int ret, dref_id = 1;
2691         MOVAtom a = { AV_RL32("stsd") };
2692         int64_t start_pos = avio_tell(pb);
2693         int64_t size    = avio_rb32(pb); /* size */
2694         uint32_t format = avio_rl32(pb); /* data format */
2695         av_log(c->fc, AV_LOG_INFO, "stsd_entries, size:%ld, format:%u\n", size, format);
2696 
2697         if (size >= 16) {
2698             avio_rb32(pb); /* reserved */
2699             avio_rb16(pb); /* reserved */
2700             dref_id = avio_rb16(pb);
2701         } else if (size <= 7) {
2702             av_log(c->fc, AV_LOG_ERROR,
2703                    "invalid size %"PRId64" in stsd\n", size);
2704             return AVERROR_INVALIDDATA;
2705         }
2706 
2707         if (mov_skip_multiple_stsd(c, pb, st->codecpar->codec_tag, format,
2708                                    size - (avio_tell(pb) - start_pos))) {
2709             sc->stsd_count++;
2710             continue;
2711         }
2712 
2713         sc->pseudo_stream_id = st->codecpar->codec_tag ? -1 : pseudo_stream_id;
2714         sc->dref_id = dref_id;
2715         sc->format = format;
2716 
2717         id = mov_codec_id(st, format);
2718 
2719         av_log(c->fc, AV_LOG_TRACE,
2720                "size=%"PRId64" 4CC=%s codec_type=%d\n", size,
2721                av_fourcc2str(format), st->codecpar->codec_type);
2722 
2723         st->codecpar->codec_id = id;
2724         if (st->codecpar->codec_type==AVMEDIA_TYPE_VIDEO) {
2725             mov_parse_stsd_video(c, pb, st, sc);
2726         } else if (st->codecpar->codec_type==AVMEDIA_TYPE_AUDIO) {
2727             mov_parse_stsd_audio(c, pb, st, sc);
2728             if (st->codecpar->sample_rate < 0) {
2729                 av_log(c->fc, AV_LOG_ERROR, "Invalid sample rate %d\n", st->codecpar->sample_rate);
2730                 return AVERROR_INVALIDDATA;
2731             }
2732             if (st->codecpar->ch_layout.nb_channels < 0) {
2733                 av_log(c->fc, AV_LOG_ERROR, "Invalid channels %d\n", st->codecpar->ch_layout.nb_channels);
2734                 return AVERROR_INVALIDDATA;
2735             }
2736         } else if (st->codecpar->codec_type==AVMEDIA_TYPE_SUBTITLE){
2737             mov_parse_stsd_subtitle(c, pb, st, sc,
2738                                     size - (avio_tell(pb) - start_pos));
2739         } else {
2740 #ifdef OHOS_TIMED_META_TRACK
2741             if (st->codecpar->codec_type != AVMEDIA_TYPE_TIMEDMETA) {
2742                 ret = mov_parse_stsd_data(c, pb, st, sc,
2743                                           size - (avio_tell(pb) - start_pos));
2744             } else {
2745                 ret = mov_parse_mebx_data(c, pb, st,
2746                                           size - (avio_tell(pb) - start_pos));
2747             }
2748             if (ret < 0)
2749                 return ret;
2750 #else
2751             ret = mov_parse_stsd_data(c, pb, st, sc,
2752                                       size - (avio_tell(pb) - start_pos));
2753             if (ret < 0)
2754                 return ret;
2755 #endif
2756         }
2757         /* this will read extra atoms at the end (wave, alac, damr, avcC, hvcC, SMI ...) */
2758         a.size = size - (avio_tell(pb) - start_pos);
2759         av_log(c->fc, AV_LOG_INFO, "stsd_entries, a.size:%d\n", a.size);
2760         if (a.size > 8) {
2761             if ((ret = mov_read_default(c, pb, a)) < 0)
2762                 return ret;
2763         } else if (a.size > 0)
2764             avio_skip(pb, a.size);
2765 
2766         if (sc->extradata && st->codecpar->extradata) {
2767             int extra_size = st->codecpar->extradata_size;
2768 
2769             /* Move the current stream extradata to the stream context one. */
2770             sc->extradata_size[pseudo_stream_id] = extra_size;
2771             sc->extradata[pseudo_stream_id] = st->codecpar->extradata;
2772             st->codecpar->extradata      = NULL;
2773             st->codecpar->extradata_size = 0;
2774         }
2775         sc->stsd_count++;
2776     }
2777 
2778     if (pb->eof_reached) {
2779         av_log(c->fc, AV_LOG_WARNING, "reached eof, corrupted STSD atom\n");
2780         return AVERROR_EOF;
2781     }
2782 
2783     return 0;
2784 }
2785 
mov_read_stsd(MOVContext * c,AVIOContext * pb,MOVAtom atom)2786 static int mov_read_stsd(MOVContext *c, AVIOContext *pb, MOVAtom atom)
2787 {
2788     AVStream *st;
2789     MOVStreamContext *sc;
2790     int ret, entries;
2791 
2792     if (c->fc->nb_streams < 1)
2793         return 0;
2794     st = c->fc->streams[c->fc->nb_streams - 1];
2795     sc = st->priv_data;
2796 
2797     sc->stsd_version = avio_r8(pb);
2798     avio_rb24(pb); /* flags */
2799     entries = avio_rb32(pb);
2800 
2801     /* Each entry contains a size (4 bytes) and format (4 bytes). */
2802     if (entries <= 0 || entries > atom.size / 8 || entries > 1024) {
2803         av_log(c->fc, AV_LOG_ERROR, "invalid STSD entries %d\n", entries);
2804         return AVERROR_INVALIDDATA;
2805     }
2806 
2807     if (sc->extradata) {
2808         av_log(c->fc, AV_LOG_ERROR,
2809                "Duplicate stsd found in this track.\n");
2810         return AVERROR_INVALIDDATA;
2811     }
2812 
2813     /* Prepare space for hosting multiple extradata. */
2814     sc->extradata = av_calloc(entries, sizeof(*sc->extradata));
2815     if (!sc->extradata)
2816         return AVERROR(ENOMEM);
2817 
2818     sc->extradata_size = av_calloc(entries, sizeof(*sc->extradata_size));
2819     if (!sc->extradata_size) {
2820         ret = AVERROR(ENOMEM);
2821         goto fail;
2822     }
2823 
2824     ret = ff_mov_read_stsd_entries(c, pb, entries);
2825     if (ret < 0)
2826         goto fail;
2827 
2828     /* Restore back the primary extradata. */
2829     av_freep(&st->codecpar->extradata);
2830     st->codecpar->extradata_size = sc->extradata_size[0];
2831     if (sc->extradata_size[0]) {
2832         st->codecpar->extradata = av_mallocz(sc->extradata_size[0] + AV_INPUT_BUFFER_PADDING_SIZE);
2833         if (!st->codecpar->extradata)
2834             return AVERROR(ENOMEM);
2835         memcpy(st->codecpar->extradata, sc->extradata[0], sc->extradata_size[0]);
2836     }
2837 
2838     return mov_finalize_stsd_codec(c, pb, st, sc);
2839 fail:
2840     if (sc->extradata) {
2841         int j;
2842         for (j = 0; j < sc->stsd_count; j++)
2843             av_freep(&sc->extradata[j]);
2844     }
2845 
2846     av_freep(&sc->extradata);
2847     av_freep(&sc->extradata_size);
2848     return ret;
2849 }
2850 
mov_read_stsc(MOVContext * c,AVIOContext * pb,MOVAtom atom)2851 static int mov_read_stsc(MOVContext *c, AVIOContext *pb, MOVAtom atom)
2852 {
2853     AVStream *st;
2854     MOVStreamContext *sc;
2855     unsigned int i, entries;
2856 
2857     if (c->fc->nb_streams < 1)
2858         return 0;
2859     st = c->fc->streams[c->fc->nb_streams-1];
2860     sc = st->priv_data;
2861 
2862     avio_r8(pb); /* version */
2863     avio_rb24(pb); /* flags */
2864 
2865     entries = avio_rb32(pb);
2866     if ((uint64_t)entries * 12 + 4 > atom.size)
2867         return AVERROR_INVALIDDATA;
2868 
2869     av_log(c->fc, AV_LOG_TRACE, "track[%u].stsc.entries = %u\n", c->fc->nb_streams - 1, entries);
2870 
2871     if (!entries)
2872         return 0;
2873     if (sc->stsc_data) {
2874         av_log(c->fc, AV_LOG_WARNING, "Ignoring duplicated STSC atom\n");
2875         return 0;
2876     }
2877     av_free(sc->stsc_data);
2878     sc->stsc_count = 0;
2879     sc->stsc_data = av_malloc_array(entries, sizeof(*sc->stsc_data));
2880     if (!sc->stsc_data)
2881         return AVERROR(ENOMEM);
2882 
2883     for (i = 0; i < entries && !pb->eof_reached; i++) {
2884         sc->stsc_data[i].first = avio_rb32(pb);
2885         sc->stsc_data[i].count = avio_rb32(pb);
2886         sc->stsc_data[i].id = avio_rb32(pb);
2887     }
2888 
2889     sc->stsc_count = i;
2890     for (i = sc->stsc_count - 1; i < UINT_MAX; i--) {
2891         int64_t first_min = i + 1;
2892         if ((i+1 < sc->stsc_count && sc->stsc_data[i].first >= sc->stsc_data[i+1].first) ||
2893             (i > 0 && sc->stsc_data[i].first <= sc->stsc_data[i-1].first) ||
2894             sc->stsc_data[i].first < first_min ||
2895             sc->stsc_data[i].count < 1 ||
2896             sc->stsc_data[i].id < 1) {
2897             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);
2898             if (i+1 >= sc->stsc_count) {
2899                 if (sc->stsc_data[i].count == 0 && i > 0) {
2900                     sc->stsc_count --;
2901                     continue;
2902                 }
2903                 sc->stsc_data[i].first = FFMAX(sc->stsc_data[i].first, first_min);
2904                 if (i > 0 && sc->stsc_data[i].first <= sc->stsc_data[i-1].first)
2905                     sc->stsc_data[i].first = FFMIN(sc->stsc_data[i-1].first + 1LL, INT_MAX);
2906                 sc->stsc_data[i].count = FFMAX(sc->stsc_data[i].count, 1);
2907                 sc->stsc_data[i].id    = FFMAX(sc->stsc_data[i].id, 1);
2908                 continue;
2909             }
2910             av_assert0(sc->stsc_data[i+1].first >= 2);
2911             // We replace this entry by the next valid
2912             sc->stsc_data[i].first = sc->stsc_data[i+1].first - 1;
2913             sc->stsc_data[i].count = sc->stsc_data[i+1].count;
2914             sc->stsc_data[i].id    = sc->stsc_data[i+1].id;
2915         }
2916     }
2917 
2918     if (pb->eof_reached) {
2919         av_log(c->fc, AV_LOG_WARNING, "reached eof, corrupted STSC atom\n");
2920         return AVERROR_EOF;
2921     }
2922 
2923     return 0;
2924 }
2925 
mov_stsc_index_valid(unsigned int index,unsigned int count)2926 static inline int mov_stsc_index_valid(unsigned int index, unsigned int count)
2927 {
2928     return index < count - 1;
2929 }
2930 
2931 /* Compute the samples value for the stsc entry at the given index. */
mov_get_stsc_samples(MOVStreamContext * sc,unsigned int index)2932 static inline int64_t mov_get_stsc_samples(MOVStreamContext *sc, unsigned int index)
2933 {
2934     int chunk_count;
2935 
2936     if (mov_stsc_index_valid(index, sc->stsc_count))
2937         chunk_count = sc->stsc_data[index + 1].first - sc->stsc_data[index].first;
2938     else {
2939         // Validation for stsc / stco  happens earlier in mov_read_stsc + mov_read_trak.
2940         av_assert0(sc->stsc_data[index].first <= sc->chunk_count);
2941         chunk_count = sc->chunk_count - (sc->stsc_data[index].first - 1);
2942     }
2943 
2944     return sc->stsc_data[index].count * (int64_t)chunk_count;
2945 }
2946 
mov_read_stps(MOVContext * c,AVIOContext * pb,MOVAtom atom)2947 static int mov_read_stps(MOVContext *c, AVIOContext *pb, MOVAtom atom)
2948 {
2949     AVStream *st;
2950     MOVStreamContext *sc;
2951     unsigned i, entries;
2952 
2953     if (c->fc->nb_streams < 1)
2954         return 0;
2955     st = c->fc->streams[c->fc->nb_streams-1];
2956     sc = st->priv_data;
2957 
2958     avio_rb32(pb); // version + flags
2959 
2960     entries = avio_rb32(pb);
2961     if (sc->stps_data)
2962         av_log(c->fc, AV_LOG_WARNING, "Duplicated STPS atom\n");
2963     av_free(sc->stps_data);
2964     sc->stps_count = 0;
2965     sc->stps_data = av_malloc_array(entries, sizeof(*sc->stps_data));
2966     if (!sc->stps_data)
2967         return AVERROR(ENOMEM);
2968 
2969     for (i = 0; i < entries && !pb->eof_reached; i++) {
2970         sc->stps_data[i] = avio_rb32(pb);
2971     }
2972 
2973     sc->stps_count = i;
2974 
2975     if (pb->eof_reached) {
2976         av_log(c->fc, AV_LOG_WARNING, "reached eof, corrupted STPS atom\n");
2977         return AVERROR_EOF;
2978     }
2979 
2980     return 0;
2981 }
2982 
mov_read_stss(MOVContext * c,AVIOContext * pb,MOVAtom atom)2983 static int mov_read_stss(MOVContext *c, AVIOContext *pb, MOVAtom atom)
2984 {
2985     AVStream *st;
2986     FFStream *sti;
2987     MOVStreamContext *sc;
2988     unsigned int i, entries;
2989 
2990     if (c->fc->nb_streams < 1)
2991         return 0;
2992     st = c->fc->streams[c->fc->nb_streams-1];
2993     sti = ffstream(st);
2994     sc = st->priv_data;
2995 
2996     avio_r8(pb); /* version */
2997     avio_rb24(pb); /* flags */
2998 
2999     entries = avio_rb32(pb);
3000 
3001     av_log(c->fc, AV_LOG_TRACE, "keyframe_count = %u\n", entries);
3002 
3003     if (!entries) {
3004         sc->keyframe_absent = 1;
3005         if (!sti->need_parsing && st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO)
3006             sti->need_parsing = AVSTREAM_PARSE_HEADERS;
3007         return 0;
3008     }
3009     if (sc->keyframes)
3010         av_log(c->fc, AV_LOG_WARNING, "Duplicated STSS atom\n");
3011     if (entries >= UINT_MAX / sizeof(int))
3012         return AVERROR_INVALIDDATA;
3013     av_freep(&sc->keyframes);
3014     sc->keyframe_count = 0;
3015     sc->keyframes = av_malloc_array(entries, sizeof(*sc->keyframes));
3016     if (!sc->keyframes)
3017         return AVERROR(ENOMEM);
3018 
3019     for (i = 0; i < entries && !pb->eof_reached; i++) {
3020         sc->keyframes[i] = avio_rb32(pb);
3021     }
3022 
3023     sc->keyframe_count = i;
3024 
3025     if (pb->eof_reached) {
3026         av_log(c->fc, AV_LOG_WARNING, "reached eof, corrupted STSS atom\n");
3027         return AVERROR_EOF;
3028     }
3029 
3030     return 0;
3031 }
3032 
mov_read_stsz(MOVContext * c,AVIOContext * pb,MOVAtom atom)3033 static int mov_read_stsz(MOVContext *c, AVIOContext *pb, MOVAtom atom)
3034 {
3035     AVStream *st;
3036     MOVStreamContext *sc;
3037     unsigned int i, entries, sample_size, field_size, num_bytes;
3038     GetBitContext gb;
3039     unsigned char* buf;
3040     int ret;
3041 
3042     if (c->fc->nb_streams < 1)
3043         return 0;
3044     st = c->fc->streams[c->fc->nb_streams-1];
3045     sc = st->priv_data;
3046 
3047     avio_r8(pb); /* version */
3048     avio_rb24(pb); /* flags */
3049 
3050     if (atom.type == MKTAG('s','t','s','z')) {
3051         sample_size = avio_rb32(pb);
3052         if (!sc->sample_size) /* do not overwrite value computed in stsd */
3053             sc->sample_size = sample_size;
3054         sc->stsz_sample_size = sample_size;
3055         field_size = 32;
3056     } else {
3057         sample_size = 0;
3058         avio_rb24(pb); /* reserved */
3059         field_size = avio_r8(pb);
3060     }
3061     entries = avio_rb32(pb);
3062 
3063     av_log(c->fc, AV_LOG_TRACE, "sample_size = %u sample_count = %u\n", sc->sample_size, entries);
3064 
3065     sc->sample_count = entries;
3066     if (sample_size)
3067         return 0;
3068 
3069     if (field_size != 4 && field_size != 8 && field_size != 16 && field_size != 32) {
3070         av_log(c->fc, AV_LOG_ERROR, "Invalid sample field size %u\n", field_size);
3071         return AVERROR_INVALIDDATA;
3072     }
3073 
3074     if (!entries)
3075         return 0;
3076     if (entries >= (INT_MAX - 4 - 8 * AV_INPUT_BUFFER_PADDING_SIZE) / field_size)
3077         return AVERROR_INVALIDDATA;
3078     if (sc->sample_sizes)
3079         av_log(c->fc, AV_LOG_WARNING, "Duplicated STSZ atom\n");
3080     av_free(sc->sample_sizes);
3081     sc->sample_count = 0;
3082     sc->sample_sizes = av_malloc_array(entries, sizeof(*sc->sample_sizes));
3083     if (!sc->sample_sizes)
3084         return AVERROR(ENOMEM);
3085 
3086     num_bytes = (entries*field_size+4)>>3;
3087 
3088     buf = av_malloc(num_bytes+AV_INPUT_BUFFER_PADDING_SIZE);
3089     if (!buf) {
3090         av_freep(&sc->sample_sizes);
3091         return AVERROR(ENOMEM);
3092     }
3093 
3094     ret = ffio_read_size(pb, buf, num_bytes);
3095     if (ret < 0) {
3096         av_freep(&sc->sample_sizes);
3097         av_free(buf);
3098         av_log(c->fc, AV_LOG_WARNING, "STSZ atom truncated\n");
3099         return 0;
3100     }
3101 
3102     init_get_bits(&gb, buf, 8*num_bytes);
3103 
3104     for (i = 0; i < entries; i++) {
3105         sc->sample_sizes[i] = get_bits_long(&gb, field_size);
3106         if (sc->sample_sizes[i] < 0) {
3107             av_free(buf);
3108             av_log(c->fc, AV_LOG_ERROR, "Invalid sample size %d\n", sc->sample_sizes[i]);
3109             return AVERROR_INVALIDDATA;
3110         }
3111         sc->data_size += sc->sample_sizes[i];
3112     }
3113 
3114     sc->sample_count = i;
3115 
3116     av_free(buf);
3117 
3118     return 0;
3119 }
3120 
mov_read_stts(MOVContext * c,AVIOContext * pb,MOVAtom atom)3121 static int mov_read_stts(MOVContext *c, AVIOContext *pb, MOVAtom atom)
3122 {
3123     AVStream *st;
3124     MOVStreamContext *sc;
3125     unsigned int i, entries, alloc_size = 0;
3126     int64_t duration = 0;
3127     int64_t total_sample_count = 0;
3128     int64_t current_dts = 0;
3129     int64_t corrected_dts = 0;
3130 
3131     if (c->fc->nb_streams < 1)
3132         return 0;
3133     st = c->fc->streams[c->fc->nb_streams-1];
3134     sc = st->priv_data;
3135 
3136     avio_r8(pb); /* version */
3137     avio_rb24(pb); /* flags */
3138     entries = avio_rb32(pb);
3139 
3140     av_log(c->fc, AV_LOG_TRACE, "track[%u].stts.entries = %u\n",
3141             c->fc->nb_streams-1, entries);
3142 
3143     if (sc->stts_data)
3144         av_log(c->fc, AV_LOG_WARNING, "Duplicated STTS atom\n");
3145     av_freep(&sc->stts_data);
3146     sc->stts_count = 0;
3147     if (entries >= INT_MAX / sizeof(*sc->stts_data))
3148         return AVERROR(ENOMEM);
3149 
3150     for (i = 0; i < entries && !pb->eof_reached; i++) {
3151         unsigned int sample_duration;
3152         unsigned int sample_count;
3153         unsigned int min_entries = FFMIN(FFMAX(i + 1, 1024 * 1024), entries);
3154         MOVStts *stts_data = av_fast_realloc(sc->stts_data, &alloc_size,
3155                                              min_entries * sizeof(*sc->stts_data));
3156         if (!stts_data) {
3157             av_freep(&sc->stts_data);
3158             sc->stts_count = 0;
3159             return AVERROR(ENOMEM);
3160         }
3161         sc->stts_count = min_entries;
3162         sc->stts_data = stts_data;
3163 
3164         sample_count    = avio_rb32(pb);
3165         sample_duration = avio_rb32(pb);
3166 
3167         sc->stts_data[i].count= sample_count;
3168         sc->stts_data[i].duration= sample_duration;
3169 
3170         av_log(c->fc, AV_LOG_TRACE, "sample_count=%u, sample_duration=%u\n",
3171                 sample_count, sample_duration);
3172 
3173         /* STTS sample offsets are uint32 but some files store it as int32
3174          * with negative values used to correct DTS delays.
3175            There may be abnormally large values as well. */
3176         if (sample_duration > c->max_stts_delta) {
3177             // assume high delta is a correction if negative when cast as int32
3178             int32_t delta_magnitude = (int32_t)sample_duration;
3179             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",
3180                    sample_duration, i, sample_count, st->index);
3181             sc->stts_data[i].duration = 1;
3182             corrected_dts += (delta_magnitude < 0 ? (int64_t)delta_magnitude : 1) * sample_count;
3183         } else {
3184             corrected_dts += sample_duration * (int64_t)sample_count;
3185         }
3186 
3187         current_dts += sc->stts_data[i].duration * (int64_t)sample_count;
3188 
3189         if (current_dts > corrected_dts) {
3190             int64_t drift = (current_dts - corrected_dts)/FFMAX(sample_count, 1);
3191             uint32_t correction = (sc->stts_data[i].duration > drift) ? drift : sc->stts_data[i].duration - 1;
3192             current_dts -= correction * (uint64_t)sample_count;
3193             sc->stts_data[i].duration -= correction;
3194         }
3195 
3196         duration+=(int64_t)sc->stts_data[i].duration*(uint64_t)sc->stts_data[i].count;
3197         total_sample_count+=sc->stts_data[i].count;
3198     }
3199 
3200     sc->stts_count = i;
3201 
3202 #ifdef OHOS_EXPAND_MP4_INFO
3203     if (sc->stts_count > 0) {
3204         st->stts_count = sc->stts_count;
3205         st->stts_data = malloc(st->stts_count * sizeof(AVMOVStts));
3206         if (st->stts_data != NULL) {
3207             memcpy(st->stts_data, sc->stts_data, st->stts_count * sizeof(AVMOVStts));
3208         } else {
3209             av_log(c->fc, AV_LOG_WARNING, "st->stts_data malloc failed\n");
3210             st->stts_count = 0;
3211         }
3212     }
3213 #endif
3214 
3215     if (duration > 0 &&
3216         duration <= INT64_MAX - sc->duration_for_fps &&
3217         total_sample_count <= INT_MAX - sc->nb_frames_for_fps) {
3218         sc->duration_for_fps  += duration;
3219         sc->nb_frames_for_fps += total_sample_count;
3220     }
3221 
3222     if (pb->eof_reached) {
3223         av_log(c->fc, AV_LOG_WARNING, "reached eof, corrupted STTS atom\n");
3224         return AVERROR_EOF;
3225     }
3226 
3227     st->nb_frames= total_sample_count;
3228     if (duration)
3229         st->duration= FFMIN(st->duration, duration);
3230     sc->track_end = duration;
3231     return 0;
3232 }
3233 
mov_read_sdtp(MOVContext * c,AVIOContext * pb,MOVAtom atom)3234 static int mov_read_sdtp(MOVContext *c, AVIOContext *pb, MOVAtom atom)
3235 {
3236     AVStream *st;
3237     MOVStreamContext *sc;
3238     int64_t i, entries;
3239 
3240     if (c->fc->nb_streams < 1)
3241         return 0;
3242     st = c->fc->streams[c->fc->nb_streams - 1];
3243     sc = st->priv_data;
3244 
3245     avio_r8(pb); /* version */
3246     avio_rb24(pb); /* flags */
3247     entries = atom.size - 4;
3248 
3249     av_log(c->fc, AV_LOG_TRACE, "track[%u].sdtp.entries = %" PRId64 "\n",
3250            c->fc->nb_streams - 1, entries);
3251 
3252     if (sc->sdtp_data)
3253         av_log(c->fc, AV_LOG_WARNING, "Duplicated SDTP atom\n");
3254     av_freep(&sc->sdtp_data);
3255     sc->sdtp_count = 0;
3256 
3257     sc->sdtp_data = av_malloc(entries);
3258     if (!sc->sdtp_data)
3259         return AVERROR(ENOMEM);
3260 
3261     for (i = 0; i < entries && !pb->eof_reached; i++)
3262         sc->sdtp_data[i] = avio_r8(pb);
3263     sc->sdtp_count = i;
3264 
3265     return 0;
3266 }
3267 
mov_update_dts_shift(MOVStreamContext * sc,int duration,void * logctx)3268 static void mov_update_dts_shift(MOVStreamContext *sc, int duration, void *logctx)
3269 {
3270     if (duration < 0) {
3271         if (duration == INT_MIN) {
3272             av_log(logctx, AV_LOG_WARNING, "mov_update_dts_shift(): dts_shift set to %d\n", INT_MAX);
3273             duration++;
3274         }
3275         sc->dts_shift = FFMAX(sc->dts_shift, -duration);
3276     }
3277 }
3278 
mov_read_ctts(MOVContext * c,AVIOContext * pb,MOVAtom atom)3279 static int mov_read_ctts(MOVContext *c, AVIOContext *pb, MOVAtom atom)
3280 {
3281     AVStream *st;
3282     MOVStreamContext *sc;
3283     unsigned int i, entries, ctts_count = 0;
3284 
3285     if (c->fc->nb_streams < 1)
3286         return 0;
3287     st = c->fc->streams[c->fc->nb_streams-1];
3288     sc = st->priv_data;
3289 
3290     avio_r8(pb); /* version */
3291     avio_rb24(pb); /* flags */
3292     entries = avio_rb32(pb);
3293 
3294     av_log(c->fc, AV_LOG_TRACE, "track[%u].ctts.entries = %u\n", c->fc->nb_streams - 1, entries);
3295 
3296     if (!entries)
3297         return 0;
3298     if (entries >= UINT_MAX / sizeof(*sc->ctts_data))
3299         return AVERROR_INVALIDDATA;
3300     av_freep(&sc->ctts_data);
3301     sc->ctts_data = av_fast_realloc(NULL, &sc->ctts_allocated_size, entries * sizeof(*sc->ctts_data));
3302     if (!sc->ctts_data)
3303         return AVERROR(ENOMEM);
3304 
3305     for (i = 0; i < entries && !pb->eof_reached; i++) {
3306         int count    = avio_rb32(pb);
3307         int duration = avio_rb32(pb);
3308 
3309         if (count <= 0) {
3310             av_log(c->fc, AV_LOG_TRACE,
3311                    "ignoring CTTS entry with count=%d duration=%d\n",
3312                    count, duration);
3313             continue;
3314         }
3315 
3316         add_ctts_entry(&sc->ctts_data, &ctts_count, &sc->ctts_allocated_size,
3317                        count, duration);
3318 
3319         av_log(c->fc, AV_LOG_TRACE, "count=%d, duration=%d\n",
3320                 count, duration);
3321 
3322         if (FFNABS(duration) < -(1<<28) && i+2<entries) {
3323             av_log(c->fc, AV_LOG_WARNING, "CTTS invalid\n");
3324             av_freep(&sc->ctts_data);
3325             sc->ctts_count = 0;
3326             return 0;
3327         }
3328 
3329         if (i+2<entries)
3330             mov_update_dts_shift(sc, duration, c->fc);
3331     }
3332 
3333     sc->ctts_count = ctts_count;
3334 
3335 #ifdef OHOS_EXPAND_MP4_INFO
3336     if (sc->ctts_count > 0) {
3337         st->ctts_count = sc->ctts_count;
3338         st->ctts_data = malloc(st->ctts_count * sizeof(AVMOVCtts));
3339         if (st->ctts_data != NULL) {
3340             memcpy(st->ctts_data, sc->ctts_data, st->ctts_count * sizeof(AVMOVCtts));
3341         } else {
3342             av_log(c->fc, AV_LOG_WARNING, "st->ctts_data malloc failed\n");
3343             st->ctts_count = 0;
3344         }
3345     }
3346 #endif
3347 
3348     if (pb->eof_reached) {
3349         av_log(c->fc, AV_LOG_WARNING, "reached eof, corrupted CTTS atom\n");
3350         return AVERROR_EOF;
3351     }
3352 
3353     av_log(c->fc, AV_LOG_TRACE, "dts shift %d\n", sc->dts_shift);
3354 
3355     return 0;
3356 }
3357 
mov_read_sgpd(MOVContext * c,AVIOContext * pb,MOVAtom atom)3358 static int mov_read_sgpd(MOVContext *c, AVIOContext *pb, MOVAtom atom)
3359 {
3360     AVStream *st;
3361     MOVStreamContext *sc;
3362     uint8_t version;
3363     uint32_t grouping_type;
3364     uint32_t default_length;
3365     av_unused uint32_t default_group_description_index;
3366     uint32_t entry_count;
3367 
3368     if (c->fc->nb_streams < 1)
3369         return 0;
3370     st = c->fc->streams[c->fc->nb_streams - 1];
3371     sc = st->priv_data;
3372 
3373     version = avio_r8(pb); /* version */
3374     avio_rb24(pb); /* flags */
3375     grouping_type = avio_rl32(pb);
3376 
3377     /*
3378      * This function only supports "sync" boxes, but the code is able to parse
3379      * other boxes (such as "tscl", "tsas" and "stsa")
3380      */
3381     if (grouping_type != MKTAG('s','y','n','c'))
3382         return 0;
3383 
3384     default_length = version >= 1 ? avio_rb32(pb) : 0;
3385     default_group_description_index = version >= 2 ? avio_rb32(pb) : 0;
3386     entry_count = avio_rb32(pb);
3387 
3388     av_freep(&sc->sgpd_sync);
3389     sc->sgpd_sync_count = entry_count;
3390     sc->sgpd_sync = av_calloc(entry_count, sizeof(*sc->sgpd_sync));
3391     if (!sc->sgpd_sync)
3392         return AVERROR(ENOMEM);
3393 
3394     for (uint32_t i = 0; i < entry_count && !pb->eof_reached; i++) {
3395         uint32_t description_length = default_length;
3396         if (version >= 1 && default_length == 0)
3397             description_length = avio_rb32(pb);
3398         if (grouping_type == MKTAG('s','y','n','c')) {
3399             const uint8_t nal_unit_type = avio_r8(pb) & 0x3f;
3400             sc->sgpd_sync[i] = nal_unit_type;
3401             description_length -= 1;
3402         }
3403         avio_skip(pb, description_length);
3404     }
3405 
3406     if (pb->eof_reached) {
3407         av_log(c->fc, AV_LOG_WARNING, "reached eof, corrupted SGPD atom\n");
3408         return AVERROR_EOF;
3409     }
3410 
3411     return 0;
3412 }
3413 
mov_read_sbgp(MOVContext * c,AVIOContext * pb,MOVAtom atom)3414 static int mov_read_sbgp(MOVContext *c, AVIOContext *pb, MOVAtom atom)
3415 {
3416     AVStream *st;
3417     MOVStreamContext *sc;
3418     unsigned int i, entries;
3419     uint8_t version;
3420     uint32_t grouping_type;
3421     MOVSbgp *table, **tablep;
3422     int *table_count;
3423 
3424     if (c->fc->nb_streams < 1)
3425         return 0;
3426     st = c->fc->streams[c->fc->nb_streams-1];
3427     sc = st->priv_data;
3428 
3429     version = avio_r8(pb); /* version */
3430     avio_rb24(pb); /* flags */
3431     grouping_type = avio_rl32(pb);
3432 
3433     if (grouping_type == MKTAG('r','a','p',' ')) {
3434         tablep = &sc->rap_group;
3435         table_count = &sc->rap_group_count;
3436     } else if (grouping_type == MKTAG('s','y','n','c')) {
3437         tablep = &sc->sync_group;
3438         table_count = &sc->sync_group_count;
3439     } else {
3440         return 0;
3441     }
3442 
3443     if (version == 1)
3444         avio_rb32(pb); /* grouping_type_parameter */
3445 
3446     entries = avio_rb32(pb);
3447     if (!entries)
3448         return 0;
3449     if (*tablep)
3450         av_log(c->fc, AV_LOG_WARNING, "Duplicated SBGP %s atom\n", av_fourcc2str(grouping_type));
3451     av_freep(tablep);
3452     table = av_malloc_array(entries, sizeof(*table));
3453     if (!table)
3454         return AVERROR(ENOMEM);
3455     *tablep = table;
3456 
3457     for (i = 0; i < entries && !pb->eof_reached; i++) {
3458         table[i].count = avio_rb32(pb); /* sample_count */
3459         table[i].index = avio_rb32(pb); /* group_description_index */
3460     }
3461 
3462     *table_count = i;
3463 
3464     if (pb->eof_reached) {
3465         av_log(c->fc, AV_LOG_WARNING, "reached eof, corrupted SBGP atom\n");
3466         return AVERROR_EOF;
3467     }
3468 
3469     return 0;
3470 }
3471 
3472 /**
3473  * Get ith edit list entry (media time, duration).
3474  */
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)3475 static int get_edit_list_entry(MOVContext *mov,
3476                                const MOVStreamContext *msc,
3477                                unsigned int edit_list_index,
3478                                int64_t *edit_list_media_time,
3479                                int64_t *edit_list_duration,
3480                                int64_t global_timescale)
3481 {
3482     if (edit_list_index == msc->elst_count) {
3483         return 0;
3484     }
3485     *edit_list_media_time = msc->elst_data[edit_list_index].time;
3486     *edit_list_duration = msc->elst_data[edit_list_index].duration;
3487 
3488     /* duration is in global timescale units;convert to msc timescale */
3489     if (global_timescale == 0) {
3490       avpriv_request_sample(mov->fc, "Support for mvhd.timescale = 0 with editlists");
3491       return 0;
3492     }
3493     *edit_list_duration = av_rescale(*edit_list_duration, msc->time_scale,
3494                                      global_timescale);
3495 
3496     if (*edit_list_duration + (uint64_t)*edit_list_media_time > INT64_MAX)
3497         *edit_list_duration = 0;
3498 
3499     return 1;
3500 }
3501 
3502 /**
3503  * Find the closest previous frame to the timestamp_pts, in e_old index
3504  * entries. Searching for just any frame / just key frames can be controlled by
3505  * last argument 'flag'.
3506  * Note that if ctts_data is not NULL, we will always search for a key frame
3507  * irrespective of the value of 'flag'. If we don't find any keyframe, we will
3508  * return the first frame of the video.
3509  *
3510  * Here the timestamp_pts is considered to be a presentation timestamp and
3511  * the timestamp of index entries are considered to be decoding timestamps.
3512  *
3513  * Returns 0 if successful in finding a frame, else returns -1.
3514  * Places the found index corresponding output arg.
3515  *
3516  * If ctts_old is not NULL, then refines the searched entry by searching
3517  * backwards from the found timestamp, to find the frame with correct PTS.
3518  *
3519  * Places the found ctts_index and ctts_sample in corresponding output args.
3520  */
find_prev_closest_index(AVStream * st,AVIndexEntry * e_old,int nb_old,MOVCtts * ctts_data,int64_t ctts_count,int64_t timestamp_pts,int flag,int64_t * index,int64_t * ctts_index,int64_t * ctts_sample)3521 static int find_prev_closest_index(AVStream *st,
3522                                    AVIndexEntry *e_old,
3523                                    int nb_old,
3524                                    MOVCtts* ctts_data,
3525                                    int64_t ctts_count,
3526                                    int64_t timestamp_pts,
3527                                    int flag,
3528                                    int64_t* index,
3529                                    int64_t* ctts_index,
3530                                    int64_t* ctts_sample)
3531 {
3532     MOVStreamContext *msc = st->priv_data;
3533     FFStream *const sti = ffstream(st);
3534     AVIndexEntry *e_keep = sti->index_entries;
3535     int nb_keep = sti->nb_index_entries;
3536     int64_t i = 0;
3537     int64_t index_ctts_count;
3538 
3539     av_assert0(index);
3540 
3541     // If dts_shift > 0, then all the index timestamps will have to be offset by
3542     // at least dts_shift amount to obtain PTS.
3543     // Hence we decrement the searched timestamp_pts by dts_shift to find the closest index element.
3544     if (msc->dts_shift > 0) {
3545         timestamp_pts -= msc->dts_shift;
3546     }
3547 
3548     sti->index_entries    = e_old;
3549     sti->nb_index_entries = nb_old;
3550     *index = av_index_search_timestamp(st, timestamp_pts, flag | AVSEEK_FLAG_BACKWARD);
3551 
3552     // Keep going backwards in the index entries until the timestamp is the same.
3553     if (*index >= 0) {
3554         for (i = *index; i > 0 && e_old[i].timestamp == e_old[i - 1].timestamp;
3555              i--) {
3556             if ((flag & AVSEEK_FLAG_ANY) ||
3557                 (e_old[i - 1].flags & AVINDEX_KEYFRAME)) {
3558                 *index = i - 1;
3559             }
3560         }
3561     }
3562 
3563     // If we have CTTS then refine the search, by searching backwards over PTS
3564     // computed by adding corresponding CTTS durations to index timestamps.
3565     if (ctts_data && *index >= 0) {
3566         av_assert0(ctts_index);
3567         av_assert0(ctts_sample);
3568         // Find out the ctts_index for the found frame.
3569         *ctts_index = 0;
3570         *ctts_sample = 0;
3571         for (index_ctts_count = 0; index_ctts_count < *index; index_ctts_count++) {
3572             if (*ctts_index < ctts_count) {
3573                 (*ctts_sample)++;
3574                 if (ctts_data[*ctts_index].count == *ctts_sample) {
3575                     (*ctts_index)++;
3576                     *ctts_sample = 0;
3577                 }
3578             }
3579         }
3580 
3581         while (*index >= 0 && (*ctts_index) >= 0 && (*ctts_index) < ctts_count) {
3582             // Find a "key frame" with PTS <= timestamp_pts (So that we can decode B-frames correctly).
3583             // No need to add dts_shift to the timestamp here becase timestamp_pts has already been
3584             // compensated by dts_shift above.
3585             if ((e_old[*index].timestamp + ctts_data[*ctts_index].duration) <= timestamp_pts &&
3586                 (e_old[*index].flags & AVINDEX_KEYFRAME)) {
3587                 break;
3588             }
3589 
3590             (*index)--;
3591             if (*ctts_sample == 0) {
3592                 (*ctts_index)--;
3593                 if (*ctts_index >= 0)
3594                   *ctts_sample = ctts_data[*ctts_index].count - 1;
3595             } else {
3596                 (*ctts_sample)--;
3597             }
3598         }
3599     }
3600 
3601     /* restore AVStream state*/
3602     sti->index_entries    = e_keep;
3603     sti->nb_index_entries = nb_keep;
3604     return *index >= 0 ? 0 : -1;
3605 }
3606 
3607 /**
3608  * Add index entry with the given values, to the end of ffstream(st)->index_entries.
3609  * Returns the new size ffstream(st)->index_entries if successful, else returns -1.
3610  *
3611  * This function is similar to ff_add_index_entry in libavformat/utils.c
3612  * except that here we are always unconditionally adding an index entry to
3613  * the end, instead of searching the entries list and skipping the add if
3614  * there is an existing entry with the same timestamp.
3615  * This is needed because the mov_fix_index calls this func with the same
3616  * unincremented timestamp for successive discarded frames.
3617  */
add_index_entry(AVStream * st,int64_t pos,int64_t timestamp,int size,int distance,int flags)3618 static int64_t add_index_entry(AVStream *st, int64_t pos, int64_t timestamp,
3619                                int size, int distance, int flags)
3620 {
3621     FFStream *const sti = ffstream(st);
3622     AVIndexEntry *entries, *ie;
3623     int64_t index = -1;
3624     const size_t min_size_needed = (sti->nb_index_entries + 1) * sizeof(AVIndexEntry);
3625 
3626     // Double the allocation each time, to lower memory fragmentation.
3627     // Another difference from ff_add_index_entry function.
3628     const size_t requested_size =
3629         min_size_needed > sti->index_entries_allocated_size ?
3630         FFMAX(min_size_needed, 2 * sti->index_entries_allocated_size) :
3631         min_size_needed;
3632 
3633     if (sti->nb_index_entries + 1U >= UINT_MAX / sizeof(AVIndexEntry))
3634         return -1;
3635 
3636     entries = av_fast_realloc(sti->index_entries,
3637                               &sti->index_entries_allocated_size,
3638                               requested_size);
3639     if (!entries)
3640         return -1;
3641 
3642     sti->index_entries = entries;
3643 
3644     index = sti->nb_index_entries++;
3645     ie= &entries[index];
3646 
3647     ie->pos = pos;
3648     ie->timestamp = timestamp;
3649     ie->min_distance= distance;
3650     ie->size= size;
3651     ie->flags = flags;
3652     return index;
3653 }
3654 
3655 /**
3656  * Rewrite timestamps of index entries in the range [end_index - frame_duration_buffer_size, end_index)
3657  * by subtracting end_ts successively by the amounts given in frame_duration_buffer.
3658  */
fix_index_entry_timestamps(AVStream * st,int end_index,int64_t end_ts,int64_t * frame_duration_buffer,int frame_duration_buffer_size)3659 static void fix_index_entry_timestamps(AVStream* st, int end_index, int64_t end_ts,
3660                                        int64_t* frame_duration_buffer,
3661                                        int frame_duration_buffer_size) {
3662     FFStream *const sti = ffstream(st);
3663     int i = 0;
3664     av_assert0(end_index >= 0 && end_index <= sti->nb_index_entries);
3665     for (i = 0; i < frame_duration_buffer_size; i++) {
3666         end_ts -= frame_duration_buffer[frame_duration_buffer_size - 1 - i];
3667         sti->index_entries[end_index - 1 - i].timestamp = end_ts;
3668     }
3669 }
3670 
3671 /**
3672  * Append a new ctts entry to ctts_data.
3673  * Returns the new ctts_count if successful, else returns -1.
3674  */
add_ctts_entry(MOVCtts ** ctts_data,unsigned int * ctts_count,unsigned int * allocated_size,int count,int duration)3675 static int64_t add_ctts_entry(MOVCtts** ctts_data, unsigned int* ctts_count, unsigned int* allocated_size,
3676                               int count, int duration)
3677 {
3678     MOVCtts *ctts_buf_new;
3679     const size_t min_size_needed = (*ctts_count + 1) * sizeof(MOVCtts);
3680     const size_t requested_size =
3681         min_size_needed > *allocated_size ?
3682         FFMAX(min_size_needed, 2 * (*allocated_size)) :
3683         min_size_needed;
3684 
3685     if ((unsigned)(*ctts_count) >= UINT_MAX / sizeof(MOVCtts) - 1)
3686         return -1;
3687 
3688     ctts_buf_new = av_fast_realloc(*ctts_data, allocated_size, requested_size);
3689 
3690     if (!ctts_buf_new)
3691         return -1;
3692 
3693     *ctts_data = ctts_buf_new;
3694 
3695     ctts_buf_new[*ctts_count].count = count;
3696     ctts_buf_new[*ctts_count].duration = duration;
3697 
3698     *ctts_count = (*ctts_count) + 1;
3699     return *ctts_count;
3700 }
3701 
3702 #define MAX_REORDER_DELAY 16
mov_estimate_video_delay(MOVContext * c,AVStream * st)3703 static void mov_estimate_video_delay(MOVContext *c, AVStream* st)
3704 {
3705     MOVStreamContext *msc = st->priv_data;
3706     FFStream *const sti = ffstream(st);
3707     int ctts_ind = 0;
3708     int ctts_sample = 0;
3709     int64_t pts_buf[MAX_REORDER_DELAY + 1]; // Circular buffer to sort pts.
3710     int buf_start = 0;
3711     int j, r, num_swaps;
3712 
3713     for (j = 0; j < MAX_REORDER_DELAY + 1; j++)
3714         pts_buf[j] = INT64_MIN;
3715 
3716     if (st->codecpar->video_delay <= 0 && msc->ctts_data &&
3717         st->codecpar->codec_id == AV_CODEC_ID_H264) {
3718         st->codecpar->video_delay = 0;
3719         for (int ind = 0; ind < sti->nb_index_entries && ctts_ind < msc->ctts_count; ++ind) {
3720             // Point j to the last elem of the buffer and insert the current pts there.
3721             j = buf_start;
3722             buf_start = (buf_start + 1);
3723             if (buf_start == MAX_REORDER_DELAY + 1)
3724                 buf_start = 0;
3725 
3726             pts_buf[j] = sti->index_entries[ind].timestamp + msc->ctts_data[ctts_ind].duration;
3727 
3728             // The timestamps that are already in the sorted buffer, and are greater than the
3729             // current pts, are exactly the timestamps that need to be buffered to output PTS
3730             // in correct sorted order.
3731             // Hence the video delay (which is the buffer size used to sort DTS and output PTS),
3732             // can be computed as the maximum no. of swaps any particular timestamp needs to
3733             // go through, to keep this buffer in sorted order.
3734             num_swaps = 0;
3735             while (j != buf_start) {
3736                 r = j - 1;
3737                 if (r < 0) r = MAX_REORDER_DELAY;
3738                 if (pts_buf[j] < pts_buf[r]) {
3739                     FFSWAP(int64_t, pts_buf[j], pts_buf[r]);
3740                     ++num_swaps;
3741                 } else {
3742                     break;
3743                 }
3744                 j = r;
3745             }
3746             st->codecpar->video_delay = FFMAX(st->codecpar->video_delay, num_swaps);
3747 
3748             ctts_sample++;
3749             if (ctts_sample == msc->ctts_data[ctts_ind].count) {
3750                 ctts_ind++;
3751                 ctts_sample = 0;
3752             }
3753         }
3754         av_log(c->fc, AV_LOG_DEBUG, "Setting codecpar->delay to %d for stream st: %d\n",
3755                st->codecpar->video_delay, st->index);
3756     }
3757 }
3758 
mov_current_sample_inc(MOVStreamContext * sc)3759 static void mov_current_sample_inc(MOVStreamContext *sc)
3760 {
3761     sc->current_sample++;
3762     sc->current_index++;
3763     if (sc->index_ranges &&
3764         sc->current_index >= sc->current_index_range->end &&
3765         sc->current_index_range->end) {
3766         sc->current_index_range++;
3767         sc->current_index = sc->current_index_range->start;
3768     }
3769 }
3770 
mov_current_sample_dec(MOVStreamContext * sc)3771 static void mov_current_sample_dec(MOVStreamContext *sc)
3772 {
3773     sc->current_sample--;
3774     sc->current_index--;
3775     if (sc->index_ranges &&
3776         sc->current_index < sc->current_index_range->start &&
3777         sc->current_index_range > sc->index_ranges) {
3778         sc->current_index_range--;
3779         sc->current_index = sc->current_index_range->end - 1;
3780     }
3781 }
3782 
mov_current_sample_set(MOVStreamContext * sc,int current_sample)3783 static void mov_current_sample_set(MOVStreamContext *sc, int current_sample)
3784 {
3785     int64_t range_size;
3786 
3787     sc->current_sample = current_sample;
3788     sc->current_index = current_sample;
3789     if (!sc->index_ranges) {
3790         return;
3791     }
3792 
3793     for (sc->current_index_range = sc->index_ranges;
3794         sc->current_index_range->end;
3795         sc->current_index_range++) {
3796         range_size = sc->current_index_range->end - sc->current_index_range->start;
3797         if (range_size > current_sample) {
3798             sc->current_index = sc->current_index_range->start + current_sample;
3799             break;
3800         }
3801         current_sample -= range_size;
3802     }
3803 }
3804 
3805 /**
3806  * Fix ffstream(st)->index_entries, so that it contains only the entries (and the entries
3807  * which are needed to decode them) that fall in the edit list time ranges.
3808  * Also fixes the timestamps of the index entries to match the timeline
3809  * specified the edit lists.
3810  */
mov_fix_index(MOVContext * mov,AVStream * st)3811 static void mov_fix_index(MOVContext *mov, AVStream *st)
3812 {
3813     MOVStreamContext *msc = st->priv_data;
3814     FFStream *const sti = ffstream(st);
3815     AVIndexEntry *e_old = sti->index_entries;
3816     int nb_old = sti->nb_index_entries;
3817     const AVIndexEntry *e_old_end = e_old + nb_old;
3818     const AVIndexEntry *current = NULL;
3819     MOVCtts *ctts_data_old = msc->ctts_data;
3820     int64_t ctts_index_old = 0;
3821     int64_t ctts_sample_old = 0;
3822     int64_t ctts_count_old = msc->ctts_count;
3823     int64_t edit_list_media_time = 0;
3824     int64_t edit_list_duration = 0;
3825     int64_t frame_duration = 0;
3826     int64_t edit_list_dts_counter = 0;
3827     int64_t edit_list_dts_entry_end = 0;
3828     int64_t edit_list_start_ctts_sample = 0;
3829     int64_t curr_cts;
3830     int64_t curr_ctts = 0;
3831     int64_t empty_edits_sum_duration = 0;
3832     int64_t edit_list_index = 0;
3833     int64_t index;
3834     int flags;
3835     int64_t start_dts = 0;
3836     int64_t edit_list_start_encountered = 0;
3837     int64_t search_timestamp = 0;
3838     int64_t* frame_duration_buffer = NULL;
3839     int num_discarded_begin = 0;
3840     int first_non_zero_audio_edit = -1;
3841     int packet_skip_samples = 0;
3842     MOVIndexRange *current_index_range;
3843     int found_keyframe_after_edit = 0;
3844     int found_non_empty_edit = 0;
3845 
3846     if (!msc->elst_data || msc->elst_count <= 0 || nb_old <= 0) {
3847         return;
3848     }
3849 
3850     // allocate the index ranges array
3851     msc->index_ranges = av_malloc((msc->elst_count + 1) * sizeof(msc->index_ranges[0]));
3852     if (!msc->index_ranges) {
3853         av_log(mov->fc, AV_LOG_ERROR, "Cannot allocate index ranges buffer\n");
3854         return;
3855     }
3856     msc->current_index_range = msc->index_ranges;
3857     current_index_range = msc->index_ranges - 1;
3858 
3859     // Clean AVStream from traces of old index
3860     sti->index_entries = NULL;
3861     sti->index_entries_allocated_size = 0;
3862     sti->nb_index_entries = 0;
3863 
3864     // Clean ctts fields of MOVStreamContext
3865     msc->ctts_data = NULL;
3866     msc->ctts_count = 0;
3867     msc->ctts_index = 0;
3868     msc->ctts_sample = 0;
3869     msc->ctts_allocated_size = 0;
3870 
3871     // Reinitialize min_corrected_pts so that it can be computed again.
3872     msc->min_corrected_pts = -1;
3873 
3874     // If the dts_shift is positive (in case of negative ctts values in mov),
3875     // then negate the DTS by dts_shift
3876     if (msc->dts_shift > 0) {
3877         edit_list_dts_entry_end -= msc->dts_shift;
3878         av_log(mov->fc, AV_LOG_DEBUG, "Shifting DTS by %d because of negative CTTS.\n", msc->dts_shift);
3879     }
3880 
3881     start_dts = edit_list_dts_entry_end;
3882 
3883     while (get_edit_list_entry(mov, msc, edit_list_index, &edit_list_media_time,
3884                                &edit_list_duration, mov->time_scale)) {
3885         av_log(mov->fc, AV_LOG_DEBUG, "Processing st: %d, edit list %"PRId64" - media time: %"PRId64", duration: %"PRId64"\n",
3886                st->index, edit_list_index, edit_list_media_time, edit_list_duration);
3887         edit_list_index++;
3888         edit_list_dts_counter = edit_list_dts_entry_end;
3889         edit_list_dts_entry_end += edit_list_duration;
3890         num_discarded_begin = 0;
3891         if (!found_non_empty_edit && edit_list_media_time == -1) {
3892             empty_edits_sum_duration += edit_list_duration;
3893             continue;
3894         }
3895         found_non_empty_edit = 1;
3896 
3897         // If we encounter a non-negative edit list reset the skip_samples/start_pad fields and set them
3898         // according to the edit list below.
3899         if (st->codecpar->codec_type == AVMEDIA_TYPE_AUDIO) {
3900             if (first_non_zero_audio_edit < 0) {
3901                 first_non_zero_audio_edit = 1;
3902             } else {
3903                 first_non_zero_audio_edit = 0;
3904             }
3905 
3906             if (first_non_zero_audio_edit > 0)
3907                 sti->skip_samples = msc->start_pad = 0;
3908         }
3909 
3910         // While reordering frame index according to edit list we must handle properly
3911         // the scenario when edit list entry starts from none key frame.
3912         // We find closest previous key frame and preserve it and consequent frames in index.
3913         // All frames which are outside edit list entry time boundaries will be dropped after decoding.
3914         search_timestamp = edit_list_media_time;
3915         if (st->codecpar->codec_type == AVMEDIA_TYPE_AUDIO) {
3916             // Audio decoders like AAC need need a decoder delay samples previous to the current sample,
3917             // to correctly decode this frame. Hence for audio we seek to a frame 1 sec. before the
3918             // edit_list_media_time to cover the decoder delay.
3919             search_timestamp = FFMAX(search_timestamp - msc->time_scale, e_old[0].timestamp);
3920         }
3921 
3922         if (find_prev_closest_index(st, e_old, nb_old, ctts_data_old, ctts_count_old, search_timestamp, 0,
3923                                     &index, &ctts_index_old, &ctts_sample_old) < 0) {
3924             av_log(mov->fc, AV_LOG_WARNING,
3925                    "st: %d edit list: %"PRId64" Missing key frame while searching for timestamp: %"PRId64"\n",
3926                    st->index, edit_list_index, search_timestamp);
3927             if (find_prev_closest_index(st, e_old, nb_old, ctts_data_old, ctts_count_old, search_timestamp, AVSEEK_FLAG_ANY,
3928                                         &index, &ctts_index_old, &ctts_sample_old) < 0) {
3929                 av_log(mov->fc, AV_LOG_WARNING,
3930                        "st: %d edit list %"PRId64" Cannot find an index entry before timestamp: %"PRId64".\n",
3931                        st->index, edit_list_index, search_timestamp);
3932                 index = 0;
3933                 ctts_index_old = 0;
3934                 ctts_sample_old = 0;
3935             }
3936         }
3937         current = e_old + index;
3938         edit_list_start_ctts_sample = ctts_sample_old;
3939 
3940         // Iterate over index and arrange it according to edit list
3941         edit_list_start_encountered = 0;
3942         found_keyframe_after_edit = 0;
3943         for (; current < e_old_end; current++, index++) {
3944             // check  if frame outside edit list mark it for discard
3945             frame_duration = (current + 1 <  e_old_end) ?
3946                              ((current + 1)->timestamp - current->timestamp) : edit_list_duration;
3947 
3948             flags = current->flags;
3949 
3950             // frames (pts) before or after edit list
3951             curr_cts = current->timestamp + msc->dts_shift;
3952             curr_ctts = 0;
3953 
3954             if (ctts_data_old && ctts_index_old < ctts_count_old) {
3955                 curr_ctts = ctts_data_old[ctts_index_old].duration;
3956                 av_log(mov->fc, AV_LOG_TRACE, "stts: %"PRId64" ctts: %"PRId64", ctts_index: %"PRId64", ctts_count: %"PRId64"\n",
3957                        curr_cts, curr_ctts, ctts_index_old, ctts_count_old);
3958                 curr_cts += curr_ctts;
3959                 ctts_sample_old++;
3960                 if (ctts_sample_old == ctts_data_old[ctts_index_old].count) {
3961                     if (add_ctts_entry(&msc->ctts_data, &msc->ctts_count,
3962                                        &msc->ctts_allocated_size,
3963                                        ctts_data_old[ctts_index_old].count - edit_list_start_ctts_sample,
3964                                        ctts_data_old[ctts_index_old].duration) == -1) {
3965                         av_log(mov->fc, AV_LOG_ERROR, "Cannot add CTTS entry %"PRId64" - {%"PRId64", %d}\n",
3966                                ctts_index_old,
3967                                ctts_data_old[ctts_index_old].count - edit_list_start_ctts_sample,
3968                                ctts_data_old[ctts_index_old].duration);
3969                         break;
3970                     }
3971                     ctts_index_old++;
3972                     ctts_sample_old = 0;
3973                     edit_list_start_ctts_sample = 0;
3974                 }
3975             }
3976 
3977             if (curr_cts < edit_list_media_time || curr_cts >= (edit_list_duration + edit_list_media_time)) {
3978                 if (st->codecpar->codec_type == AVMEDIA_TYPE_AUDIO && st->codecpar->codec_id != AV_CODEC_ID_VORBIS &&
3979                     curr_cts < edit_list_media_time && curr_cts + frame_duration > edit_list_media_time &&
3980                     first_non_zero_audio_edit > 0) {
3981                     packet_skip_samples = edit_list_media_time - curr_cts;
3982                     sti->skip_samples += packet_skip_samples;
3983 
3984                     // Shift the index entry timestamp by packet_skip_samples to be correct.
3985                     edit_list_dts_counter -= packet_skip_samples;
3986                     if (edit_list_start_encountered == 0)  {
3987                         edit_list_start_encountered = 1;
3988                         // Make timestamps strictly monotonically increasing for audio, by rewriting timestamps for
3989                         // discarded packets.
3990                         if (frame_duration_buffer) {
3991                             fix_index_entry_timestamps(st, sti->nb_index_entries, edit_list_dts_counter,
3992                                                        frame_duration_buffer, num_discarded_begin);
3993                             av_freep(&frame_duration_buffer);
3994                         }
3995                     }
3996 
3997                     av_log(mov->fc, AV_LOG_DEBUG, "skip %d audio samples from curr_cts: %"PRId64"\n", packet_skip_samples, curr_cts);
3998                 } else {
3999                     flags |= AVINDEX_DISCARD_FRAME;
4000                     av_log(mov->fc, AV_LOG_DEBUG, "drop a frame at curr_cts: %"PRId64" @ %"PRId64"\n", curr_cts, index);
4001 
4002                     if (edit_list_start_encountered == 0) {
4003                         num_discarded_begin++;
4004                         frame_duration_buffer = av_realloc(frame_duration_buffer,
4005                                                            num_discarded_begin * sizeof(int64_t));
4006                         if (!frame_duration_buffer) {
4007                             av_log(mov->fc, AV_LOG_ERROR, "Cannot reallocate frame duration buffer\n");
4008                             break;
4009                         }
4010                         frame_duration_buffer[num_discarded_begin - 1] = frame_duration;
4011 
4012                         // Increment skip_samples for the first non-zero audio edit list
4013                         if (st->codecpar->codec_type == AVMEDIA_TYPE_AUDIO &&
4014                             first_non_zero_audio_edit > 0 && st->codecpar->codec_id != AV_CODEC_ID_VORBIS) {
4015                             sti->skip_samples += frame_duration;
4016                         }
4017                     }
4018                 }
4019             } else {
4020                 if (msc->min_corrected_pts < 0) {
4021                     msc->min_corrected_pts = edit_list_dts_counter + curr_ctts + msc->dts_shift;
4022                 } else {
4023                     msc->min_corrected_pts = FFMIN(msc->min_corrected_pts, edit_list_dts_counter + curr_ctts + msc->dts_shift);
4024                 }
4025                 if (edit_list_start_encountered == 0) {
4026                     edit_list_start_encountered = 1;
4027                     // Make timestamps strictly monotonically increasing by rewriting timestamps for
4028                     // discarded packets.
4029                     if (frame_duration_buffer) {
4030                         fix_index_entry_timestamps(st, sti->nb_index_entries, edit_list_dts_counter,
4031                                                    frame_duration_buffer, num_discarded_begin);
4032                         av_freep(&frame_duration_buffer);
4033                     }
4034                 }
4035             }
4036 
4037             if (add_index_entry(st, current->pos, edit_list_dts_counter, current->size,
4038                                 current->min_distance, flags) == -1) {
4039                 av_log(mov->fc, AV_LOG_ERROR, "Cannot add index entry\n");
4040                 break;
4041             }
4042 
4043             // Update the index ranges array
4044             if (current_index_range < msc->index_ranges || index != current_index_range->end) {
4045                 current_index_range++;
4046                 current_index_range->start = index;
4047             }
4048             current_index_range->end = index + 1;
4049 
4050             // Only start incrementing DTS in frame_duration amounts, when we encounter a frame in edit list.
4051             if (edit_list_start_encountered > 0) {
4052                 edit_list_dts_counter = edit_list_dts_counter + frame_duration;
4053             }
4054 
4055             // Break when found first key frame after edit entry completion
4056             if ((curr_cts + frame_duration >= (edit_list_duration + edit_list_media_time)) &&
4057                 ((flags & AVINDEX_KEYFRAME) || ((st->codecpar->codec_type == AVMEDIA_TYPE_AUDIO)))) {
4058                 if (ctts_data_old) {
4059                     // If we have CTTS and this is the first keyframe after edit elist,
4060                     // wait for one more, because there might be trailing B-frames after this I-frame
4061                     // that do belong to the edit.
4062                     if (st->codecpar->codec_type != AVMEDIA_TYPE_AUDIO && found_keyframe_after_edit == 0) {
4063                         found_keyframe_after_edit = 1;
4064                         continue;
4065                     }
4066                     if (ctts_sample_old != 0) {
4067                         if (add_ctts_entry(&msc->ctts_data, &msc->ctts_count,
4068                                            &msc->ctts_allocated_size,
4069                                            ctts_sample_old - edit_list_start_ctts_sample,
4070                                            ctts_data_old[ctts_index_old].duration) == -1) {
4071                             av_log(mov->fc, AV_LOG_ERROR, "Cannot add CTTS entry %"PRId64" - {%"PRId64", %d}\n",
4072                                    ctts_index_old, ctts_sample_old - edit_list_start_ctts_sample,
4073                                    ctts_data_old[ctts_index_old].duration);
4074                             break;
4075                         }
4076                     }
4077                 }
4078                 break;
4079             }
4080         }
4081     }
4082     // If there are empty edits, then msc->min_corrected_pts might be positive
4083     // intentionally. So we subtract the sum duration of emtpy edits here.
4084     msc->min_corrected_pts -= empty_edits_sum_duration;
4085 
4086     // If the minimum pts turns out to be greater than zero after fixing the index, then we subtract the
4087     // dts by that amount to make the first pts zero.
4088     if (st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO) {
4089         if (msc->min_corrected_pts > 0) {
4090             av_log(mov->fc, AV_LOG_DEBUG, "Offset DTS by %"PRId64" to make first pts zero.\n", msc->min_corrected_pts);
4091             for (int i = 0; i < sti->nb_index_entries; ++i)
4092                 sti->index_entries[i].timestamp -= msc->min_corrected_pts;
4093         }
4094     }
4095     // Start time should be equal to zero or the duration of any empty edits.
4096     st->start_time = empty_edits_sum_duration;
4097 
4098     // Update av stream length, if it ends up shorter than the track's media duration
4099     st->duration = FFMIN(st->duration, edit_list_dts_entry_end - start_dts);
4100     msc->start_pad = sti->skip_samples;
4101 
4102     // Free the old index and the old CTTS structures
4103     av_free(e_old);
4104     av_free(ctts_data_old);
4105     av_freep(&frame_duration_buffer);
4106 
4107     // Null terminate the index ranges array
4108     current_index_range++;
4109     current_index_range->start = 0;
4110     current_index_range->end = 0;
4111     msc->current_index = msc->index_ranges[0].start;
4112 }
4113 
get_sgpd_sync_index(const MOVStreamContext * sc,int nal_unit_type)4114 static uint32_t get_sgpd_sync_index(const MOVStreamContext *sc, int nal_unit_type)
4115 {
4116     for (uint32_t i = 0; i < sc->sgpd_sync_count; i++)
4117         if (sc->sgpd_sync[i] == HEVC_NAL_CRA_NUT)
4118             return i + 1;
4119     return 0;
4120 }
4121 
build_open_gop_key_points(AVStream * st)4122 static int build_open_gop_key_points(AVStream *st)
4123 {
4124     int k;
4125     int sample_id = 0;
4126     uint32_t cra_index;
4127     MOVStreamContext *sc = st->priv_data;
4128 
4129     if (st->codecpar->codec_id != AV_CODEC_ID_HEVC || !sc->sync_group_count)
4130         return 0;
4131 
4132     /* Build an unrolled index of the samples */
4133     sc->sample_offsets_count = 0;
4134     for (uint32_t i = 0; i < sc->ctts_count; i++) {
4135         if (sc->ctts_data[i].count > INT_MAX - sc->sample_offsets_count)
4136             return AVERROR(ENOMEM);
4137         sc->sample_offsets_count += sc->ctts_data[i].count;
4138     }
4139     av_freep(&sc->sample_offsets);
4140     sc->sample_offsets = av_calloc(sc->sample_offsets_count, sizeof(*sc->sample_offsets));
4141     if (!sc->sample_offsets)
4142         return AVERROR(ENOMEM);
4143     k = 0;
4144     for (uint32_t i = 0; i < sc->ctts_count; i++)
4145         for (int j = 0; j < sc->ctts_data[i].count; j++)
4146              sc->sample_offsets[k++] = sc->ctts_data[i].duration;
4147 
4148     /* The following HEVC NAL type reveal the use of open GOP sync points
4149      * (TODO: BLA types may also be concerned) */
4150     cra_index = get_sgpd_sync_index(sc, HEVC_NAL_CRA_NUT); /* Clean Random Access */
4151     if (!cra_index)
4152         return 0;
4153 
4154     /* Build a list of open-GOP key samples */
4155     sc->open_key_samples_count = 0;
4156     for (uint32_t i = 0; i < sc->sync_group_count; i++)
4157         if (sc->sync_group[i].index == cra_index) {
4158             if (sc->sync_group[i].count > INT_MAX - sc->open_key_samples_count)
4159                 return AVERROR(ENOMEM);
4160             sc->open_key_samples_count += sc->sync_group[i].count;
4161         }
4162     av_freep(&sc->open_key_samples);
4163     sc->open_key_samples = av_calloc(sc->open_key_samples_count, sizeof(*sc->open_key_samples));
4164     if (!sc->open_key_samples)
4165         return AVERROR(ENOMEM);
4166     k = 0;
4167     for (uint32_t i = 0; i < sc->sync_group_count; i++) {
4168         const MOVSbgp *sg = &sc->sync_group[i];
4169         if (sg->index == cra_index)
4170             for (uint32_t j = 0; j < sg->count; j++)
4171                 sc->open_key_samples[k++] = sample_id;
4172         if (sg->count > INT_MAX - sample_id)
4173             return AVERROR_PATCHWELCOME;
4174         sample_id += sg->count;
4175     }
4176 
4177     /* Identify the minimal time step between samples */
4178     sc->min_sample_duration = UINT_MAX;
4179     for (uint32_t i = 0; i < sc->stts_count; i++)
4180         sc->min_sample_duration = FFMIN(sc->min_sample_duration, sc->stts_data[i].duration);
4181 
4182     return 0;
4183 }
4184 
mov_build_index(MOVContext * mov,AVStream * st)4185 static void mov_build_index(MOVContext *mov, AVStream *st)
4186 {
4187     MOVStreamContext *sc = st->priv_data;
4188     FFStream *const sti = ffstream(st);
4189     int64_t current_offset;
4190     int64_t current_dts = 0;
4191     unsigned int stts_index = 0;
4192     unsigned int stsc_index = 0;
4193     unsigned int stss_index = 0;
4194     unsigned int stps_index = 0;
4195     unsigned int i, j;
4196     uint64_t stream_size = 0;
4197     MOVCtts *ctts_data_old = sc->ctts_data;
4198     unsigned int ctts_count_old = sc->ctts_count;
4199 
4200     int ret = build_open_gop_key_points(st);
4201     if (ret < 0)
4202         return;
4203 
4204     if (sc->elst_count) {
4205         int i, edit_start_index = 0, multiple_edits = 0;
4206         int64_t empty_duration = 0; // empty duration of the first edit list entry
4207         int64_t start_time = 0; // start time of the media
4208 
4209         for (i = 0; i < sc->elst_count; i++) {
4210             const MOVElst *e = &sc->elst_data[i];
4211             if (i == 0 && e->time == -1) {
4212                 /* if empty, the first entry is the start time of the stream
4213                  * relative to the presentation itself */
4214                 empty_duration = e->duration;
4215                 edit_start_index = 1;
4216             } else if (i == edit_start_index && e->time >= 0) {
4217                 start_time = e->time;
4218             } else {
4219                 multiple_edits = 1;
4220             }
4221         }
4222 
4223         if (multiple_edits && !mov->advanced_editlist)
4224             av_log(mov->fc, AV_LOG_WARNING, "multiple edit list entries, "
4225                    "Use -advanced_editlist to correctly decode otherwise "
4226                    "a/v desync might occur\n");
4227 
4228         /* adjust first dts according to edit list */
4229         if ((empty_duration || start_time) && mov->time_scale > 0) {
4230             if (empty_duration)
4231                 empty_duration = av_rescale(empty_duration, sc->time_scale, mov->time_scale);
4232 
4233             if (av_sat_sub64(start_time, empty_duration) != start_time - (uint64_t)empty_duration)
4234                 av_log(mov->fc, AV_LOG_WARNING, "start_time - empty_duration is not representable\n");
4235 
4236             sc->time_offset = start_time -  (uint64_t)empty_duration;
4237             sc->min_corrected_pts = start_time;
4238             if (!mov->advanced_editlist)
4239                 current_dts = -sc->time_offset;
4240         }
4241 
4242         if (!multiple_edits && !mov->advanced_editlist &&
4243             st->codecpar->codec_id == AV_CODEC_ID_AAC && start_time > 0)
4244             sc->start_pad = start_time;
4245     }
4246 
4247     /* only use old uncompressed audio chunk demuxing when stts specifies it */
4248     if (!(st->codecpar->codec_type == AVMEDIA_TYPE_AUDIO &&
4249           sc->stts_count == 1 && sc->stts_data[0].duration == 1)) {
4250         unsigned int current_sample = 0;
4251         unsigned int stts_sample = 0;
4252         unsigned int sample_size;
4253         unsigned int distance = 0;
4254         unsigned int rap_group_index = 0;
4255         unsigned int rap_group_sample = 0;
4256         int rap_group_present = sc->rap_group_count && sc->rap_group;
4257         int key_off = (sc->keyframe_count && sc->keyframes[0] > 0) || (sc->stps_count && sc->stps_data[0] > 0);
4258 
4259         current_dts -= sc->dts_shift;
4260 
4261         if (!sc->sample_count || sti->nb_index_entries)
4262             return;
4263         if (sc->sample_count >= UINT_MAX / sizeof(*sti->index_entries) - sti->nb_index_entries)
4264             return;
4265         if (av_reallocp_array(&sti->index_entries,
4266                               sti->nb_index_entries + sc->sample_count,
4267                               sizeof(*sti->index_entries)) < 0) {
4268             sti->nb_index_entries = 0;
4269             return;
4270         }
4271         sti->index_entries_allocated_size = (sti->nb_index_entries + sc->sample_count) * sizeof(*sti->index_entries);
4272 
4273         if (ctts_data_old) {
4274             // Expand ctts entries such that we have a 1-1 mapping with samples
4275             if (sc->sample_count >= UINT_MAX / sizeof(*sc->ctts_data))
4276                 return;
4277             sc->ctts_count = 0;
4278             sc->ctts_allocated_size = 0;
4279             sc->ctts_data = av_fast_realloc(NULL, &sc->ctts_allocated_size,
4280                                     sc->sample_count * sizeof(*sc->ctts_data));
4281             if (!sc->ctts_data) {
4282                 av_free(ctts_data_old);
4283                 return;
4284             }
4285 
4286             memset((uint8_t*)(sc->ctts_data), 0, sc->ctts_allocated_size);
4287 
4288             for (i = 0; i < ctts_count_old &&
4289                         sc->ctts_count < sc->sample_count; i++)
4290                 for (j = 0; j < ctts_data_old[i].count &&
4291                             sc->ctts_count < sc->sample_count; j++)
4292                     add_ctts_entry(&sc->ctts_data, &sc->ctts_count,
4293                                    &sc->ctts_allocated_size, 1,
4294                                    ctts_data_old[i].duration);
4295             av_free(ctts_data_old);
4296         }
4297 
4298         for (i = 0; i < sc->chunk_count; i++) {
4299             int64_t next_offset = i+1 < sc->chunk_count ? sc->chunk_offsets[i+1] : INT64_MAX;
4300             current_offset = sc->chunk_offsets[i];
4301             while (mov_stsc_index_valid(stsc_index, sc->stsc_count) &&
4302                 i + 1 == sc->stsc_data[stsc_index + 1].first)
4303                 stsc_index++;
4304 
4305             if (next_offset > current_offset && sc->sample_size>0 && sc->sample_size < sc->stsz_sample_size &&
4306                 sc->stsc_data[stsc_index].count * (int64_t)sc->stsz_sample_size > next_offset - current_offset) {
4307                 av_log(mov->fc, AV_LOG_WARNING, "STSZ sample size %d invalid (too large), ignoring\n", sc->stsz_sample_size);
4308                 sc->stsz_sample_size = sc->sample_size;
4309             }
4310             if (sc->stsz_sample_size>0 && sc->stsz_sample_size < sc->sample_size) {
4311                 av_log(mov->fc, AV_LOG_WARNING, "STSZ sample size %d invalid (too small), ignoring\n", sc->stsz_sample_size);
4312                 sc->stsz_sample_size = sc->sample_size;
4313             }
4314 
4315             for (j = 0; j < sc->stsc_data[stsc_index].count; j++) {
4316                 int keyframe = 0;
4317                 if (current_sample >= sc->sample_count) {
4318                     av_log(mov->fc, AV_LOG_ERROR, "wrong sample count\n");
4319                     return;
4320                 }
4321 
4322                 if (!sc->keyframe_absent && (!sc->keyframe_count || current_sample+key_off == sc->keyframes[stss_index])) {
4323                     keyframe = 1;
4324                     if (stss_index + 1 < sc->keyframe_count)
4325                         stss_index++;
4326                 } else if (sc->stps_count && current_sample+key_off == sc->stps_data[stps_index]) {
4327                     keyframe = 1;
4328                     if (stps_index + 1 < sc->stps_count)
4329                         stps_index++;
4330                 }
4331                 if (rap_group_present && rap_group_index < sc->rap_group_count) {
4332                     if (sc->rap_group[rap_group_index].index > 0)
4333                         keyframe = 1;
4334                     if (++rap_group_sample == sc->rap_group[rap_group_index].count) {
4335                         rap_group_sample = 0;
4336                         rap_group_index++;
4337                     }
4338                 }
4339                 if (sc->keyframe_absent
4340                     && !sc->stps_count
4341                     && !rap_group_present
4342                     && (st->codecpar->codec_type == AVMEDIA_TYPE_AUDIO || (i==0 && j==0)))
4343                      keyframe = 1;
4344                 if (keyframe)
4345                     distance = 0;
4346                 sample_size = sc->stsz_sample_size > 0 ? sc->stsz_sample_size : sc->sample_sizes[current_sample];
4347                 if (current_offset > INT64_MAX - sample_size) {
4348                     av_log(mov->fc, AV_LOG_ERROR, "Current offset %"PRId64" or sample size %u is too large\n",
4349                            current_offset,
4350                            sample_size);
4351                     return;
4352                 }
4353 
4354                 if (sc->pseudo_stream_id == -1 ||
4355                    sc->stsc_data[stsc_index].id - 1 == sc->pseudo_stream_id) {
4356                     AVIndexEntry *e;
4357                     if (sample_size > 0x3FFFFFFF) {
4358                         av_log(mov->fc, AV_LOG_ERROR, "Sample size %u is too large\n", sample_size);
4359                         return;
4360                     }
4361                     e = &sti->index_entries[sti->nb_index_entries++];
4362                     e->pos = current_offset;
4363                     e->timestamp = current_dts;
4364                     e->size = sample_size;
4365                     e->min_distance = distance;
4366                     e->flags = keyframe ? AVINDEX_KEYFRAME : 0;
4367                     av_log(mov->fc, AV_LOG_TRACE, "AVIndex stream %d, sample %u, offset %"PRIx64", dts %"PRId64", "
4368                             "size %u, distance %u, keyframe %d\n", st->index, current_sample,
4369                             current_offset, current_dts, sample_size, distance, keyframe);
4370                     if (st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO && sti->nb_index_entries < 100)
4371                         ff_rfps_add_frame(mov->fc, st, current_dts);
4372                 }
4373 
4374                 current_offset += sample_size;
4375                 stream_size += sample_size;
4376 
4377                 current_dts += sc->stts_data[stts_index].duration;
4378 
4379                 distance++;
4380                 stts_sample++;
4381                 current_sample++;
4382                 if (stts_index + 1 < sc->stts_count && stts_sample == sc->stts_data[stts_index].count) {
4383                     stts_sample = 0;
4384                     stts_index++;
4385                 }
4386             }
4387         }
4388         if (st->duration > 0)
4389             st->codecpar->bit_rate = stream_size*8*sc->time_scale/st->duration;
4390     } else {
4391         unsigned chunk_samples, total = 0;
4392 
4393         if (!sc->chunk_count)
4394             return;
4395 
4396         // compute total chunk count
4397         for (i = 0; i < sc->stsc_count; i++) {
4398             unsigned count, chunk_count;
4399 
4400             chunk_samples = sc->stsc_data[i].count;
4401             if (i != sc->stsc_count - 1 &&
4402                 sc->samples_per_frame && chunk_samples % sc->samples_per_frame) {
4403                 av_log(mov->fc, AV_LOG_ERROR, "error unaligned chunk\n");
4404                 return;
4405             }
4406 
4407             if (sc->samples_per_frame >= 160) { // gsm
4408                 count = chunk_samples / sc->samples_per_frame;
4409             } else if (sc->samples_per_frame > 1) {
4410                 unsigned samples = (1024/sc->samples_per_frame)*sc->samples_per_frame;
4411                 count = (chunk_samples+samples-1) / samples;
4412             } else {
4413                 count = (chunk_samples+1023) / 1024;
4414             }
4415 
4416             if (mov_stsc_index_valid(i, sc->stsc_count))
4417                 chunk_count = sc->stsc_data[i+1].first - sc->stsc_data[i].first;
4418             else
4419                 chunk_count = sc->chunk_count - (sc->stsc_data[i].first - 1);
4420             total += chunk_count * count;
4421         }
4422 
4423         av_log(mov->fc, AV_LOG_TRACE, "chunk count %u\n", total);
4424         if (total >= UINT_MAX / sizeof(*sti->index_entries) - sti->nb_index_entries)
4425             return;
4426         if (av_reallocp_array(&sti->index_entries,
4427                               sti->nb_index_entries + total,
4428                               sizeof(*sti->index_entries)) < 0) {
4429             sti->nb_index_entries = 0;
4430             return;
4431         }
4432         sti->index_entries_allocated_size = (sti->nb_index_entries + total) * sizeof(*sti->index_entries);
4433 
4434         // populate index
4435         for (i = 0; i < sc->chunk_count; i++) {
4436             current_offset = sc->chunk_offsets[i];
4437             if (mov_stsc_index_valid(stsc_index, sc->stsc_count) &&
4438                 i + 1 == sc->stsc_data[stsc_index + 1].first)
4439                 stsc_index++;
4440             chunk_samples = sc->stsc_data[stsc_index].count;
4441 
4442             while (chunk_samples > 0) {
4443                 AVIndexEntry *e;
4444                 unsigned size, samples;
4445 
4446                 if (sc->samples_per_frame > 1 && !sc->bytes_per_frame) {
4447                     avpriv_request_sample(mov->fc,
4448                            "Zero bytes per frame, but %d samples per frame",
4449                            sc->samples_per_frame);
4450                     return;
4451                 }
4452 
4453                 if (sc->samples_per_frame >= 160) { // gsm
4454                     samples = sc->samples_per_frame;
4455                     size = sc->bytes_per_frame;
4456                 } else {
4457                     if (sc->samples_per_frame > 1) {
4458                         samples = FFMIN((1024 / sc->samples_per_frame)*
4459                                         sc->samples_per_frame, chunk_samples);
4460                         size = (samples / sc->samples_per_frame) * sc->bytes_per_frame;
4461                     } else {
4462                         samples = FFMIN(1024, chunk_samples);
4463                         size = samples * sc->sample_size;
4464                     }
4465                 }
4466 
4467                 if (sti->nb_index_entries >= total) {
4468                     av_log(mov->fc, AV_LOG_ERROR, "wrong chunk count %u\n", total);
4469                     return;
4470                 }
4471                 if (size > 0x3FFFFFFF) {
4472                     av_log(mov->fc, AV_LOG_ERROR, "Sample size %u is too large\n", size);
4473                     return;
4474                 }
4475                 e = &sti->index_entries[sti->nb_index_entries++];
4476                 e->pos = current_offset;
4477                 e->timestamp = current_dts;
4478                 e->size = size;
4479                 e->min_distance = 0;
4480                 e->flags = AVINDEX_KEYFRAME;
4481                 av_log(mov->fc, AV_LOG_TRACE, "AVIndex stream %d, chunk %u, offset %"PRIx64", dts %"PRId64", "
4482                        "size %u, duration %u\n", st->index, i, current_offset, current_dts,
4483                        size, samples);
4484 
4485                 current_offset += size;
4486                 current_dts += samples;
4487                 chunk_samples -= samples;
4488             }
4489         }
4490     }
4491 
4492     if (!mov->ignore_editlist && mov->advanced_editlist) {
4493         // Fix index according to edit lists.
4494         mov_fix_index(mov, st);
4495     }
4496 
4497     // Update start time of the stream.
4498     if (st->start_time == AV_NOPTS_VALUE && st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO && sti->nb_index_entries > 0) {
4499         st->start_time = sti->index_entries[0].timestamp + sc->dts_shift;
4500         if (sc->ctts_data) {
4501             st->start_time += sc->ctts_data[0].duration;
4502         }
4503     }
4504 
4505     mov_estimate_video_delay(mov, st);
4506 }
4507 
test_same_origin(const char * src,const char * ref)4508 static int test_same_origin(const char *src, const char *ref) {
4509     char src_proto[64];
4510     char ref_proto[64];
4511     char src_auth[256];
4512     char ref_auth[256];
4513     char src_host[256];
4514     char ref_host[256];
4515     int src_port=-1;
4516     int ref_port=-1;
4517 
4518     av_url_split(src_proto, sizeof(src_proto), src_auth, sizeof(src_auth), src_host, sizeof(src_host), &src_port, NULL, 0, src);
4519     av_url_split(ref_proto, sizeof(ref_proto), ref_auth, sizeof(ref_auth), ref_host, sizeof(ref_host), &ref_port, NULL, 0, ref);
4520 
4521     if (strlen(src) == 0) {
4522         return -1;
4523     } else if (strlen(src_auth) + 1 >= sizeof(src_auth) ||
4524         strlen(ref_auth) + 1 >= sizeof(ref_auth) ||
4525         strlen(src_host) + 1 >= sizeof(src_host) ||
4526         strlen(ref_host) + 1 >= sizeof(ref_host)) {
4527         return 0;
4528     } else if (strcmp(src_proto, ref_proto) ||
4529                strcmp(src_auth, ref_auth) ||
4530                strcmp(src_host, ref_host) ||
4531                src_port != ref_port) {
4532         return 0;
4533     } else
4534         return 1;
4535 }
4536 
mov_open_dref(MOVContext * c,AVIOContext ** pb,const char * src,MOVDref * ref)4537 static int mov_open_dref(MOVContext *c, AVIOContext **pb, const char *src, MOVDref *ref)
4538 {
4539     /* try relative path, we do not try the absolute because it can leak information about our
4540        system to an attacker */
4541     if (ref->nlvl_to > 0 && ref->nlvl_from > 0) {
4542         char filename[1025];
4543         const char *src_path;
4544         int i, l;
4545 
4546         /* find a source dir */
4547         src_path = strrchr(src, '/');
4548         if (src_path)
4549             src_path++;
4550         else
4551             src_path = src;
4552 
4553         /* find a next level down to target */
4554         for (i = 0, l = strlen(ref->path) - 1; l >= 0; l--)
4555             if (ref->path[l] == '/') {
4556                 if (i == ref->nlvl_to - 1)
4557                     break;
4558                 else
4559                     i++;
4560             }
4561 
4562         /* compose filename if next level down to target was found */
4563         if (i == ref->nlvl_to - 1 && src_path - src  < sizeof(filename)) {
4564             memcpy(filename, src, src_path - src);
4565             filename[src_path - src] = 0;
4566 
4567             for (i = 1; i < ref->nlvl_from; i++)
4568                 av_strlcat(filename, "../", sizeof(filename));
4569 
4570             av_strlcat(filename, ref->path + l + 1, sizeof(filename));
4571             if (!c->use_absolute_path) {
4572                 int same_origin = test_same_origin(src, filename);
4573 
4574                 if (!same_origin) {
4575                     av_log(c->fc, AV_LOG_ERROR,
4576                         "Reference with mismatching origin, %s not tried for security reasons, "
4577                         "set demuxer option use_absolute_path to allow it anyway\n",
4578                         ref->path);
4579                     return AVERROR(ENOENT);
4580                 }
4581 
4582                 if (strstr(ref->path + l + 1, "..") ||
4583                     strstr(ref->path + l + 1, ":") ||
4584                     (ref->nlvl_from > 1 && same_origin < 0) ||
4585                     (filename[0] == '/' && src_path == src))
4586                     return AVERROR(ENOENT);
4587             }
4588 
4589             if (strlen(filename) + 1 == sizeof(filename))
4590                 return AVERROR(ENOENT);
4591             if (!c->fc->io_open(c->fc, pb, filename, AVIO_FLAG_READ, NULL))
4592                 return 0;
4593         }
4594     } else if (c->use_absolute_path) {
4595         av_log(c->fc, AV_LOG_WARNING, "Using absolute path on user request, "
4596                "this is a possible security issue\n");
4597         if (!c->fc->io_open(c->fc, pb, ref->path, AVIO_FLAG_READ, NULL))
4598             return 0;
4599     } else {
4600         av_log(c->fc, AV_LOG_ERROR,
4601                "Absolute path %s not tried for security reasons, "
4602                "set demuxer option use_absolute_path to allow absolute paths\n",
4603                ref->path);
4604     }
4605 
4606     return AVERROR(ENOENT);
4607 }
4608 
fix_timescale(MOVContext * c,MOVStreamContext * sc)4609 static void fix_timescale(MOVContext *c, MOVStreamContext *sc)
4610 {
4611     if (sc->time_scale <= 0) {
4612         av_log(c->fc, AV_LOG_WARNING, "stream %d, timescale not set\n", sc->ffindex);
4613         sc->time_scale = c->time_scale;
4614         if (sc->time_scale <= 0)
4615             sc->time_scale = 1;
4616     }
4617 }
4618 
mov_read_trak(MOVContext * c,AVIOContext * pb,MOVAtom atom)4619 static int mov_read_trak(MOVContext *c, AVIOContext *pb, MOVAtom atom)
4620 {
4621     AVStream *st;
4622     MOVStreamContext *sc;
4623     int ret;
4624 
4625     if (c->is_still_picture_avif) {
4626         return AVERROR_INVALIDDATA;
4627     }
4628 
4629     st = avformat_new_stream(c->fc, NULL);
4630     if (!st) return AVERROR(ENOMEM);
4631     st->id = -1;
4632     sc = av_mallocz(sizeof(MOVStreamContext));
4633     if (!sc) return AVERROR(ENOMEM);
4634 
4635     st->priv_data = sc;
4636     st->codecpar->codec_type = AVMEDIA_TYPE_DATA;
4637     sc->ffindex = st->index;
4638     c->trak_index = st->index;
4639 
4640     if ((ret = mov_read_default(c, pb, atom)) < 0)
4641         return ret;
4642 
4643     c->trak_index = -1;
4644 
4645     // Here stsc refers to a chunk not described in stco. This is technically invalid,
4646     // but we can overlook it (clearing stsc) whenever stts_count == 0 (indicating no samples).
4647     if (!sc->chunk_count && !sc->stts_count && sc->stsc_count) {
4648         sc->stsc_count = 0;
4649         av_freep(&sc->stsc_data);
4650     }
4651 
4652     /* sanity checks */
4653     if ((sc->chunk_count && (!sc->stts_count || !sc->stsc_count ||
4654                             (!sc->sample_size && !sc->sample_count))) ||
4655         (!sc->chunk_count && sc->sample_count)) {
4656         av_log(c->fc, AV_LOG_ERROR, "stream %d, missing mandatory atoms, broken header\n",
4657                st->index);
4658         return 0;
4659     }
4660     if (sc->stsc_count && sc->stsc_data[ sc->stsc_count - 1 ].first > sc->chunk_count) {
4661         av_log(c->fc, AV_LOG_ERROR, "stream %d, contradictionary STSC and STCO\n",
4662                st->index);
4663         return AVERROR_INVALIDDATA;
4664     }
4665 
4666     fix_timescale(c, sc);
4667 
4668     avpriv_set_pts_info(st, 64, 1, sc->time_scale);
4669 
4670     mov_build_index(c, st);
4671 
4672     if (sc->dref_id-1 < sc->drefs_count && sc->drefs[sc->dref_id-1].path) {
4673         MOVDref *dref = &sc->drefs[sc->dref_id - 1];
4674         if (c->enable_drefs) {
4675             if (mov_open_dref(c, &sc->pb, c->fc->url, dref) < 0)
4676                 av_log(c->fc, AV_LOG_ERROR,
4677                        "stream %d, error opening alias: path='%s', dir='%s', "
4678                        "filename='%s', volume='%s', nlvl_from=%d, nlvl_to=%d\n",
4679                        st->index, dref->path, dref->dir, dref->filename,
4680                        dref->volume, dref->nlvl_from, dref->nlvl_to);
4681         } else {
4682             av_log(c->fc, AV_LOG_WARNING,
4683                    "Skipped opening external track: "
4684                    "stream %d, alias: path='%s', dir='%s', "
4685                    "filename='%s', volume='%s', nlvl_from=%d, nlvl_to=%d."
4686                    "Set enable_drefs to allow this.\n",
4687                    st->index, dref->path, dref->dir, dref->filename,
4688                    dref->volume, dref->nlvl_from, dref->nlvl_to);
4689         }
4690     } else {
4691         sc->pb = c->fc->pb;
4692         sc->pb_is_copied = 1;
4693     }
4694 
4695     if (st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO) {
4696         if (!st->sample_aspect_ratio.num && st->codecpar->width && st->codecpar->height &&
4697             sc->height && sc->width &&
4698             (st->codecpar->width != sc->width || st->codecpar->height != sc->height)) {
4699             st->sample_aspect_ratio = av_d2q(((double)st->codecpar->height * sc->width) /
4700                                              ((double)st->codecpar->width * sc->height), INT_MAX);
4701         }
4702 
4703 #if FF_API_R_FRAME_RATE
4704         if (sc->stts_count == 1 || (sc->stts_count == 2 && sc->stts_data[1].count == 1))
4705             av_reduce(&st->r_frame_rate.num, &st->r_frame_rate.den,
4706                       sc->time_scale, sc->stts_data[0].duration, INT_MAX);
4707 #endif
4708     }
4709 
4710     // done for ai5q, ai52, ai55, ai1q, ai12 and ai15.
4711     if (!st->codecpar->extradata_size && st->codecpar->codec_id == AV_CODEC_ID_H264 &&
4712         TAG_IS_AVCI(st->codecpar->codec_tag)) {
4713         ret = ff_generate_avci_extradata(st);
4714         if (ret < 0)
4715             return ret;
4716     }
4717 
4718     switch (st->codecpar->codec_id) {
4719 #if CONFIG_H261_DECODER
4720     case AV_CODEC_ID_H261:
4721 #endif
4722 #if CONFIG_H263_DECODER
4723     case AV_CODEC_ID_H263:
4724 #endif
4725 #if CONFIG_MPEG4_DECODER
4726     case AV_CODEC_ID_MPEG4:
4727 #endif
4728         st->codecpar->width = 0; /* let decoder init width/height */
4729         st->codecpar->height= 0;
4730         break;
4731     }
4732 
4733     // If the duration of the mp3 packets is not constant, then they could need a parser
4734     if (st->codecpar->codec_id == AV_CODEC_ID_MP3
4735         && sc->stts_count > 3
4736         && sc->stts_count*10 > st->nb_frames
4737         && sc->time_scale == st->codecpar->sample_rate) {
4738             ffstream(st)->need_parsing = AVSTREAM_PARSE_FULL;
4739     }
4740     /* Do not need those anymore. */
4741     av_freep(&sc->chunk_offsets);
4742     av_freep(&sc->sample_sizes);
4743     av_freep(&sc->keyframes);
4744     av_freep(&sc->stts_data);
4745     av_freep(&sc->stps_data);
4746     av_freep(&sc->elst_data);
4747     av_freep(&sc->rap_group);
4748     av_freep(&sc->sync_group);
4749     av_freep(&sc->sgpd_sync);
4750 
4751     return 0;
4752 }
4753 
mov_read_ilst(MOVContext * c,AVIOContext * pb,MOVAtom atom)4754 static int mov_read_ilst(MOVContext *c, AVIOContext *pb, MOVAtom atom)
4755 {
4756     int ret;
4757     c->itunes_metadata = 1;
4758     ret = mov_read_default(c, pb, atom);
4759     c->itunes_metadata = 0;
4760     return ret;
4761 }
4762 
mov_read_keys(MOVContext * c,AVIOContext * pb,MOVAtom atom)4763 static int mov_read_keys(MOVContext *c, AVIOContext *pb, MOVAtom atom)
4764 {
4765     uint32_t count;
4766     uint32_t i;
4767 
4768     if (atom.size < 8)
4769         return 0;
4770 
4771     avio_skip(pb, 4);
4772     count = avio_rb32(pb);
4773     if (count > UINT_MAX / sizeof(*c->meta_keys) - 1) {
4774         av_log(c->fc, AV_LOG_ERROR,
4775                "The 'keys' atom with the invalid key count: %"PRIu32"\n", count);
4776         return AVERROR_INVALIDDATA;
4777     }
4778 
4779     c->meta_keys_count = count + 1;
4780     c->meta_keys = av_mallocz(c->meta_keys_count * sizeof(*c->meta_keys));
4781     if (!c->meta_keys)
4782         return AVERROR(ENOMEM);
4783 
4784     for (i = 1; i <= count; ++i) {
4785         uint32_t key_size = avio_rb32(pb);
4786         uint32_t type = avio_rl32(pb);
4787         if (key_size < 8) {
4788             av_log(c->fc, AV_LOG_ERROR,
4789                    "The key# %"PRIu32" in meta has invalid size:"
4790                    "%"PRIu32"\n", i, key_size);
4791             return AVERROR_INVALIDDATA;
4792         }
4793         key_size -= 8;
4794         if (type != MKTAG('m','d','t','a')) {
4795             avio_skip(pb, key_size);
4796         }
4797 #ifdef OHOS_MOOV_LEVEL_META
4798         char* tempKey = av_mallocz(key_size + 1);
4799         if (!tempKey) {
4800             return AVERROR(ENOMEM);
4801         }
4802         avio_read(pb, tempKey, key_size);
4803         c->meta_keys[i] = av_asprintf("%s%s", "moov_level_meta_key_", tempKey);
4804         av_freep(&tempKey);
4805 #else
4806         c->meta_keys[i] = av_mallocz(key_size + 1);
4807         if (!c->meta_keys[i])
4808             return AVERROR(ENOMEM);
4809         avio_read(pb, c->meta_keys[i], key_size);
4810 #endif
4811     }
4812 
4813     return 0;
4814 }
4815 
mov_read_custom(MOVContext * c,AVIOContext * pb,MOVAtom atom)4816 static int mov_read_custom(MOVContext *c, AVIOContext *pb, MOVAtom atom)
4817 {
4818     int64_t end = av_sat_add64(avio_tell(pb), atom.size);
4819     uint8_t *key = NULL, *val = NULL, *mean = NULL;
4820     int i;
4821     int ret = 0;
4822     AVStream *st;
4823     MOVStreamContext *sc;
4824 
4825     if (c->fc->nb_streams < 1)
4826         return 0;
4827     st = c->fc->streams[c->fc->nb_streams-1];
4828     sc = st->priv_data;
4829 
4830     for (i = 0; i < 3; i++) {
4831         uint8_t **p;
4832         uint32_t len, tag;
4833 
4834         if (end - avio_tell(pb) <= 12)
4835             break;
4836 
4837         len = avio_rb32(pb);
4838         tag = avio_rl32(pb);
4839         avio_skip(pb, 4); // flags
4840 
4841         if (len < 12 || len - 12 > end - avio_tell(pb))
4842             break;
4843         len -= 12;
4844 
4845         if (tag == MKTAG('m', 'e', 'a', 'n'))
4846             p = &mean;
4847         else if (tag == MKTAG('n', 'a', 'm', 'e'))
4848             p = &key;
4849         else if (tag == MKTAG('d', 'a', 't', 'a') && len > 4) {
4850             avio_skip(pb, 4);
4851             len -= 4;
4852             p = &val;
4853         } else
4854             break;
4855 
4856         if (*p)
4857             break;
4858 
4859         *p = av_malloc(len + 1);
4860         if (!*p) {
4861             ret = AVERROR(ENOMEM);
4862             break;
4863         }
4864         ret = ffio_read_size(pb, *p, len);
4865         if (ret < 0) {
4866             av_freep(p);
4867             break;
4868         }
4869         (*p)[len] = 0;
4870     }
4871 
4872     if (mean && key && val) {
4873         if (strcmp(key, "iTunSMPB") == 0) {
4874             int priming, remainder, samples;
4875             if(sscanf(val, "%*X %X %X %X", &priming, &remainder, &samples) == 3){
4876                 if(priming>0 && priming<16384)
4877                     sc->start_pad = priming;
4878             }
4879         }
4880         if (strcmp(key, "cdec") != 0) {
4881             av_dict_set(&c->fc->metadata, key, val,
4882                         AV_DICT_DONT_STRDUP_KEY | AV_DICT_DONT_STRDUP_VAL);
4883             key = val = NULL;
4884         }
4885     } else {
4886         av_log(c->fc, AV_LOG_VERBOSE,
4887                "Unhandled or malformed custom metadata of size %"PRId64"\n", atom.size);
4888     }
4889 
4890     avio_seek(pb, end, SEEK_SET);
4891     av_freep(&key);
4892     av_freep(&val);
4893     av_freep(&mean);
4894     return ret;
4895 }
4896 
mov_read_meta(MOVContext * c,AVIOContext * pb,MOVAtom atom)4897 static int mov_read_meta(MOVContext *c, AVIOContext *pb, MOVAtom atom)
4898 {
4899     while (atom.size > 8) {
4900         uint32_t tag;
4901         if (avio_feof(pb))
4902             return AVERROR_EOF;
4903         tag = avio_rl32(pb);
4904         atom.size -= 4;
4905         if (tag == MKTAG('h','d','l','r')) {
4906             avio_seek(pb, -8, SEEK_CUR);
4907             atom.size += 8;
4908             return mov_read_default(c, pb, atom);
4909         }
4910     }
4911     return 0;
4912 }
4913 
4914 // return 1 when matrix is identity, 0 otherwise
4915 #define IS_MATRIX_IDENT(matrix)            \
4916     ( (matrix)[0][0] == (1 << 16) &&       \
4917       (matrix)[1][1] == (1 << 16) &&       \
4918       (matrix)[2][2] == (1 << 30) &&       \
4919      !(matrix)[0][1] && !(matrix)[0][2] && \
4920      !(matrix)[1][0] && !(matrix)[1][2] && \
4921      !(matrix)[2][0] && !(matrix)[2][1])
4922 
mov_read_tkhd(MOVContext * c,AVIOContext * pb,MOVAtom atom)4923 static int mov_read_tkhd(MOVContext *c, AVIOContext *pb, MOVAtom atom)
4924 {
4925     int i, j, e;
4926     int width;
4927     int height;
4928     int display_matrix[3][3];
4929     int res_display_matrix[3][3] = { { 0 } };
4930     AVStream *st;
4931     MOVStreamContext *sc;
4932     int version;
4933     int flags;
4934 
4935     if (c->fc->nb_streams < 1)
4936         return 0;
4937     st = c->fc->streams[c->fc->nb_streams-1];
4938     sc = st->priv_data;
4939 
4940     // Each stream (trak) should have exactly 1 tkhd. This catches bad files and
4941     // avoids corrupting AVStreams mapped to an earlier tkhd.
4942     if (st->id != -1)
4943         return AVERROR_INVALIDDATA;
4944 
4945     version = avio_r8(pb);
4946     flags = avio_rb24(pb);
4947     st->disposition |= (flags & MOV_TKHD_FLAG_ENABLED) ? AV_DISPOSITION_DEFAULT : 0;
4948 
4949     if (version == 1) {
4950         avio_rb64(pb);
4951         avio_rb64(pb);
4952     } else {
4953         avio_rb32(pb); /* creation time */
4954         avio_rb32(pb); /* modification time */
4955     }
4956     st->id = (int)avio_rb32(pb); /* track id (NOT 0 !)*/
4957     avio_rb32(pb); /* reserved */
4958 
4959     /* highlevel (considering edits) duration in movie timebase */
4960     (version == 1) ? avio_rb64(pb) : avio_rb32(pb);
4961     avio_rb32(pb); /* reserved */
4962     avio_rb32(pb); /* reserved */
4963 
4964     avio_rb16(pb); /* layer */
4965     avio_rb16(pb); /* alternate group */
4966     avio_rb16(pb); /* volume */
4967     avio_rb16(pb); /* reserved */
4968 
4969     //read in the display matrix (outlined in ISO 14496-12, Section 6.2.2)
4970     // they're kept in fixed point format through all calculations
4971     // save u,v,z to store the whole matrix in the AV_PKT_DATA_DISPLAYMATRIX
4972     // side data, but the scale factor is not needed to calculate aspect ratio
4973     for (i = 0; i < 3; i++) {
4974         display_matrix[i][0] = avio_rb32(pb);   // 16.16 fixed point
4975         display_matrix[i][1] = avio_rb32(pb);   // 16.16 fixed point
4976         display_matrix[i][2] = avio_rb32(pb);   //  2.30 fixed point
4977     }
4978 
4979     width = avio_rb32(pb);       // 16.16 fixed point track width
4980     height = avio_rb32(pb);      // 16.16 fixed point track height
4981     sc->width = width >> 16;
4982     sc->height = height >> 16;
4983 
4984     // apply the moov display matrix (after the tkhd one)
4985     for (i = 0; i < 3; i++) {
4986         const int sh[3] = { 16, 16, 30 };
4987         for (j = 0; j < 3; j++) {
4988             for (e = 0; e < 3; e++) {
4989                 res_display_matrix[i][j] +=
4990                     ((int64_t) display_matrix[i][e] *
4991                      c->movie_display_matrix[e][j]) >> sh[e];
4992             }
4993         }
4994     }
4995 
4996     // save the matrix when it is not the default identity
4997     if (!IS_MATRIX_IDENT(res_display_matrix)) {
4998         av_freep(&sc->display_matrix);
4999         sc->display_matrix = av_malloc(sizeof(int32_t) * 9);
5000         if (!sc->display_matrix)
5001             return AVERROR(ENOMEM);
5002 
5003         for (i = 0; i < 3; i++)
5004             for (j = 0; j < 3; j++)
5005                 sc->display_matrix[i * 3 + j] = res_display_matrix[i][j];
5006     }
5007 
5008     // transform the display width/height according to the matrix
5009     // to keep the same scale, use [width height 1<<16]
5010     if (width && height && sc->display_matrix) {
5011         double disp_transform[2];
5012 
5013         for (i = 0; i < 2; i++)
5014             disp_transform[i] = hypot(sc->display_matrix[0 + i],
5015                                       sc->display_matrix[3 + i]);
5016 
5017         if (disp_transform[0] > 1       && disp_transform[1] > 1 &&
5018             disp_transform[0] < (1<<24) && disp_transform[1] < (1<<24) &&
5019             fabs((disp_transform[0] / disp_transform[1]) - 1.0) > 0.01)
5020             st->sample_aspect_ratio = av_d2q(
5021                 disp_transform[0] / disp_transform[1],
5022                 INT_MAX);
5023     }
5024     return 0;
5025 }
5026 
mov_read_tfhd(MOVContext * c,AVIOContext * pb,MOVAtom atom)5027 static int mov_read_tfhd(MOVContext *c, AVIOContext *pb, MOVAtom atom)
5028 {
5029     MOVFragment *frag = &c->fragment;
5030     MOVTrackExt *trex = NULL;
5031     int flags, track_id, i;
5032     MOVFragmentStreamInfo * frag_stream_info;
5033 
5034     avio_r8(pb); /* version */
5035     flags = avio_rb24(pb);
5036 
5037     track_id = avio_rb32(pb);
5038     if (!track_id)
5039         return AVERROR_INVALIDDATA;
5040     for (i = 0; i < c->trex_count; i++)
5041         if (c->trex_data[i].track_id == track_id) {
5042             trex = &c->trex_data[i];
5043             break;
5044         }
5045     if (!trex) {
5046         av_log(c->fc, AV_LOG_WARNING, "could not find corresponding trex (id %u)\n", track_id);
5047         return 0;
5048     }
5049     c->fragment.found_tfhd = 1;
5050     frag->track_id = track_id;
5051     set_frag_stream(&c->frag_index, track_id);
5052 
5053     frag->base_data_offset = flags & MOV_TFHD_BASE_DATA_OFFSET ?
5054                              avio_rb64(pb) : flags & MOV_TFHD_DEFAULT_BASE_IS_MOOF ?
5055                              frag->moof_offset : frag->implicit_offset;
5056     frag->stsd_id  = flags & MOV_TFHD_STSD_ID ? avio_rb32(pb) : trex->stsd_id;
5057 
5058     frag->duration = flags & MOV_TFHD_DEFAULT_DURATION ?
5059                      avio_rb32(pb) : trex->duration;
5060     frag->size     = flags & MOV_TFHD_DEFAULT_SIZE ?
5061                      avio_rb32(pb) : trex->size;
5062     frag->flags    = flags & MOV_TFHD_DEFAULT_FLAGS ?
5063                      avio_rb32(pb) : trex->flags;
5064     av_log(c->fc, AV_LOG_TRACE, "frag flags 0x%x\n", frag->flags);
5065 
5066     frag_stream_info = get_current_frag_stream_info(&c->frag_index);
5067     if (frag_stream_info)
5068         frag_stream_info->next_trun_dts = AV_NOPTS_VALUE;
5069 
5070     return 0;
5071 }
5072 
mov_read_chap(MOVContext * c,AVIOContext * pb,MOVAtom atom)5073 static int mov_read_chap(MOVContext *c, AVIOContext *pb, MOVAtom atom)
5074 {
5075     unsigned i, num;
5076     void *new_tracks;
5077 
5078     num = atom.size / 4;
5079     if (!(new_tracks = av_malloc_array(num, sizeof(int))))
5080         return AVERROR(ENOMEM);
5081 
5082     av_free(c->chapter_tracks);
5083     c->chapter_tracks = new_tracks;
5084     c->nb_chapter_tracks = num;
5085 
5086     for (i = 0; i < num && !pb->eof_reached; i++)
5087         c->chapter_tracks[i] = avio_rb32(pb);
5088 
5089     c->nb_chapter_tracks = i;
5090 
5091     return 0;
5092 }
5093 
mov_read_trex(MOVContext * c,AVIOContext * pb,MOVAtom atom)5094 static int mov_read_trex(MOVContext *c, AVIOContext *pb, MOVAtom atom)
5095 {
5096     MOVTrackExt *trex;
5097     int err;
5098 
5099     if ((uint64_t)c->trex_count+1 >= UINT_MAX / sizeof(*c->trex_data))
5100         return AVERROR_INVALIDDATA;
5101     if ((err = av_reallocp_array(&c->trex_data, c->trex_count + 1,
5102                                  sizeof(*c->trex_data))) < 0) {
5103         c->trex_count = 0;
5104         return err;
5105     }
5106 
5107     c->fc->duration = AV_NOPTS_VALUE; // the duration from mvhd is not representing the whole file when fragments are used.
5108 
5109     trex = &c->trex_data[c->trex_count++];
5110     avio_r8(pb); /* version */
5111     avio_rb24(pb); /* flags */
5112     trex->track_id = avio_rb32(pb);
5113     trex->stsd_id  = avio_rb32(pb);
5114     trex->duration = avio_rb32(pb);
5115     trex->size     = avio_rb32(pb);
5116     trex->flags    = avio_rb32(pb);
5117     return 0;
5118 }
5119 
mov_read_tfdt(MOVContext * c,AVIOContext * pb,MOVAtom atom)5120 static int mov_read_tfdt(MOVContext *c, AVIOContext *pb, MOVAtom atom)
5121 {
5122     MOVFragment *frag = &c->fragment;
5123     AVStream *st = NULL;
5124     MOVStreamContext *sc;
5125     int version, i;
5126     MOVFragmentStreamInfo * frag_stream_info;
5127     int64_t base_media_decode_time;
5128 
5129     for (i = 0; i < c->fc->nb_streams; i++) {
5130         if (c->fc->streams[i]->id == frag->track_id) {
5131             st = c->fc->streams[i];
5132             break;
5133         }
5134     }
5135     if (!st) {
5136         av_log(c->fc, AV_LOG_WARNING, "could not find corresponding track id %u\n", frag->track_id);
5137         return 0;
5138     }
5139     sc = st->priv_data;
5140     if (sc->pseudo_stream_id + 1 != frag->stsd_id && sc->pseudo_stream_id != -1)
5141         return 0;
5142     version = avio_r8(pb);
5143     avio_rb24(pb); /* flags */
5144     if (version) {
5145         base_media_decode_time = avio_rb64(pb);
5146     } else {
5147         base_media_decode_time = avio_rb32(pb);
5148     }
5149 
5150     frag_stream_info = get_current_frag_stream_info(&c->frag_index);
5151     if (frag_stream_info)
5152         frag_stream_info->tfdt_dts = base_media_decode_time;
5153     sc->track_end = base_media_decode_time;
5154 
5155     return 0;
5156 }
5157 
mov_read_trun(MOVContext * c,AVIOContext * pb,MOVAtom atom)5158 static int mov_read_trun(MOVContext *c, AVIOContext *pb, MOVAtom atom)
5159 {
5160     MOVFragment *frag = &c->fragment;
5161     AVStream *st = NULL;
5162     FFStream *sti = NULL;
5163     MOVStreamContext *sc;
5164     MOVCtts *ctts_data;
5165     uint64_t offset;
5166     int64_t dts, pts = AV_NOPTS_VALUE;
5167     int data_offset = 0;
5168     unsigned entries, first_sample_flags = frag->flags;
5169     int flags, distance, i;
5170     int64_t prev_dts = AV_NOPTS_VALUE;
5171     int next_frag_index = -1, index_entry_pos;
5172     size_t requested_size;
5173     size_t old_ctts_allocated_size;
5174     AVIndexEntry *new_entries;
5175     MOVFragmentStreamInfo * frag_stream_info;
5176 
5177     if (!frag->found_tfhd) {
5178         av_log(c->fc, AV_LOG_ERROR, "trun track id unknown, no tfhd was found\n");
5179         return AVERROR_INVALIDDATA;
5180     }
5181 
5182     for (i = 0; i < c->fc->nb_streams; i++) {
5183         if (c->fc->streams[i]->id == frag->track_id) {
5184             st = c->fc->streams[i];
5185             sti = ffstream(st);
5186             break;
5187         }
5188     }
5189     if (!st) {
5190         av_log(c->fc, AV_LOG_WARNING, "could not find corresponding track id %u\n", frag->track_id);
5191         return 0;
5192     }
5193     sc = st->priv_data;
5194     if (sc->pseudo_stream_id+1 != frag->stsd_id && sc->pseudo_stream_id != -1)
5195         return 0;
5196 
5197     // Find the next frag_index index that has a valid index_entry for
5198     // the current track_id.
5199     //
5200     // A valid index_entry means the trun for the fragment was read
5201     // and it's samples are in index_entries at the given position.
5202     // New index entries will be inserted before the index_entry found.
5203     index_entry_pos = sti->nb_index_entries;
5204     for (i = c->frag_index.current + 1; i < c->frag_index.nb_items; i++) {
5205         frag_stream_info = get_frag_stream_info(&c->frag_index, i, frag->track_id);
5206         if (frag_stream_info && frag_stream_info->index_entry >= 0) {
5207             next_frag_index = i;
5208             index_entry_pos = frag_stream_info->index_entry;
5209             break;
5210         }
5211     }
5212     av_assert0(index_entry_pos <= sti->nb_index_entries);
5213 
5214     avio_r8(pb); /* version */
5215     flags = avio_rb24(pb);
5216     entries = avio_rb32(pb);
5217     av_log(c->fc, AV_LOG_TRACE, "flags 0x%x entries %u\n", flags, entries);
5218 
5219     if ((uint64_t)entries+sc->ctts_count >= UINT_MAX/sizeof(*sc->ctts_data))
5220         return AVERROR_INVALIDDATA;
5221     if (flags & MOV_TRUN_DATA_OFFSET)        data_offset        = avio_rb32(pb);
5222     if (flags & MOV_TRUN_FIRST_SAMPLE_FLAGS) first_sample_flags = avio_rb32(pb);
5223 
5224     frag_stream_info = get_current_frag_stream_info(&c->frag_index);
5225     if (frag_stream_info) {
5226         if (frag_stream_info->next_trun_dts != AV_NOPTS_VALUE) {
5227             dts = frag_stream_info->next_trun_dts - sc->time_offset;
5228         } else if (frag_stream_info->first_tfra_pts != AV_NOPTS_VALUE &&
5229             c->use_mfra_for == FF_MOV_FLAG_MFRA_PTS) {
5230             pts = frag_stream_info->first_tfra_pts;
5231             av_log(c->fc, AV_LOG_DEBUG, "found mfra time %"PRId64
5232                     ", using it for pts\n", pts);
5233         } else if (frag_stream_info->first_tfra_pts != AV_NOPTS_VALUE &&
5234             c->use_mfra_for == FF_MOV_FLAG_MFRA_DTS) {
5235             dts = frag_stream_info->first_tfra_pts;
5236             av_log(c->fc, AV_LOG_DEBUG, "found mfra time %"PRId64
5237                     ", using it for dts\n", pts);
5238         } else {
5239             int has_tfdt = frag_stream_info->tfdt_dts != AV_NOPTS_VALUE;
5240             int has_sidx = frag_stream_info->sidx_pts != AV_NOPTS_VALUE;
5241             int fallback_tfdt = !c->use_tfdt && !has_sidx && has_tfdt;
5242             int fallback_sidx =  c->use_tfdt && !has_tfdt && has_sidx;
5243 
5244             if (fallback_sidx) {
5245                 av_log(c->fc, AV_LOG_DEBUG, "use_tfdt set but no tfdt found, using sidx instead\n");
5246             }
5247             if (fallback_tfdt) {
5248                 av_log(c->fc, AV_LOG_DEBUG, "use_tfdt not set but no sidx found, using tfdt instead\n");
5249             }
5250 
5251             if (has_tfdt && c->use_tfdt || fallback_tfdt) {
5252                 dts = frag_stream_info->tfdt_dts - sc->time_offset;
5253                 av_log(c->fc, AV_LOG_DEBUG, "found tfdt time %"PRId64
5254                         ", using it for dts\n", dts);
5255             } else if (has_sidx && !c->use_tfdt || fallback_sidx) {
5256                 // FIXME: sidx earliest_presentation_time is *PTS*, s.b.
5257                 // pts = frag_stream_info->sidx_pts;
5258                 dts = frag_stream_info->sidx_pts - sc->time_offset;
5259                 av_log(c->fc, AV_LOG_DEBUG, "found sidx time %"PRId64
5260                         ", using it for dts\n", frag_stream_info->sidx_pts);
5261             } else {
5262                 dts = sc->track_end - sc->time_offset;
5263                 av_log(c->fc, AV_LOG_DEBUG, "found track end time %"PRId64
5264                         ", using it for dts\n", dts);
5265             }
5266         }
5267     } else {
5268         dts = sc->track_end - sc->time_offset;
5269         av_log(c->fc, AV_LOG_DEBUG, "found track end time %"PRId64
5270                 ", using it for dts\n", dts);
5271     }
5272     offset   = frag->base_data_offset + data_offset;
5273     distance = 0;
5274     av_log(c->fc, AV_LOG_TRACE, "first sample flags 0x%x\n", first_sample_flags);
5275 
5276     // realloc space for new index entries
5277     if ((uint64_t)sti->nb_index_entries + entries >= UINT_MAX / sizeof(AVIndexEntry)) {
5278         entries = UINT_MAX / sizeof(AVIndexEntry) - sti->nb_index_entries;
5279         av_log(c->fc, AV_LOG_ERROR, "Failed to add index entry\n");
5280     }
5281     if (entries == 0)
5282         return 0;
5283 
5284     requested_size = (sti->nb_index_entries + entries) * sizeof(AVIndexEntry);
5285     new_entries = av_fast_realloc(sti->index_entries,
5286                                   &sti->index_entries_allocated_size,
5287                                   requested_size);
5288     if (!new_entries)
5289         return AVERROR(ENOMEM);
5290     sti->index_entries= new_entries;
5291 
5292     requested_size = (sti->nb_index_entries + entries) * sizeof(*sc->ctts_data);
5293     old_ctts_allocated_size = sc->ctts_allocated_size;
5294     ctts_data = av_fast_realloc(sc->ctts_data, &sc->ctts_allocated_size,
5295                                 requested_size);
5296     if (!ctts_data)
5297         return AVERROR(ENOMEM);
5298     sc->ctts_data = ctts_data;
5299 
5300     // In case there were samples without ctts entries, ensure they get
5301     // zero valued entries. This ensures clips which mix boxes with and
5302     // without ctts entries don't pickup uninitialized data.
5303     memset((uint8_t*)(sc->ctts_data) + old_ctts_allocated_size, 0,
5304            sc->ctts_allocated_size - old_ctts_allocated_size);
5305 
5306     if (index_entry_pos < sti->nb_index_entries) {
5307         // Make hole in index_entries and ctts_data for new samples
5308         memmove(sti->index_entries + index_entry_pos + entries,
5309                 sti->index_entries + index_entry_pos,
5310                 sizeof(*sti->index_entries) *
5311                 (sti->nb_index_entries - index_entry_pos));
5312         memmove(sc->ctts_data + index_entry_pos + entries,
5313                 sc->ctts_data + index_entry_pos,
5314                 sizeof(*sc->ctts_data) * (sc->ctts_count - index_entry_pos));
5315         if (index_entry_pos < sc->current_sample) {
5316             sc->current_sample += entries;
5317         }
5318     }
5319 
5320     sti->nb_index_entries += entries;
5321     sc->ctts_count = sti->nb_index_entries;
5322 
5323     // Record the index_entry position in frag_index of this fragment
5324     if (frag_stream_info)
5325         frag_stream_info->index_entry = index_entry_pos;
5326 
5327     if (index_entry_pos > 0)
5328         prev_dts = sti->index_entries[index_entry_pos-1].timestamp;
5329 
5330     for (i = 0; i < entries && !pb->eof_reached; i++) {
5331         unsigned sample_size = frag->size;
5332         int sample_flags = i ? frag->flags : first_sample_flags;
5333         unsigned sample_duration = frag->duration;
5334         unsigned ctts_duration = 0;
5335         int keyframe = 0;
5336         int index_entry_flags = 0;
5337 
5338         if (flags & MOV_TRUN_SAMPLE_DURATION) sample_duration = avio_rb32(pb);
5339         if (flags & MOV_TRUN_SAMPLE_SIZE)     sample_size     = avio_rb32(pb);
5340         if (flags & MOV_TRUN_SAMPLE_FLAGS)    sample_flags    = avio_rb32(pb);
5341         if (flags & MOV_TRUN_SAMPLE_CTS)      ctts_duration   = avio_rb32(pb);
5342 
5343         mov_update_dts_shift(sc, ctts_duration, c->fc);
5344         if (pts != AV_NOPTS_VALUE) {
5345             dts = pts - sc->dts_shift;
5346             if (flags & MOV_TRUN_SAMPLE_CTS) {
5347                 dts -= ctts_duration;
5348             } else {
5349                 dts -= sc->time_offset;
5350             }
5351             av_log(c->fc, AV_LOG_DEBUG,
5352                    "pts %"PRId64" calculated dts %"PRId64
5353                    " sc->dts_shift %d ctts.duration %d"
5354                    " sc->time_offset %"PRId64
5355                    " flags & MOV_TRUN_SAMPLE_CTS %d\n",
5356                    pts, dts,
5357                    sc->dts_shift, ctts_duration,
5358                    sc->time_offset, flags & MOV_TRUN_SAMPLE_CTS);
5359             pts = AV_NOPTS_VALUE;
5360         }
5361 
5362         if (st->codecpar->codec_type == AVMEDIA_TYPE_AUDIO)
5363             keyframe = 1;
5364         else
5365             keyframe =
5366                 !(sample_flags & (MOV_FRAG_SAMPLE_FLAG_IS_NON_SYNC |
5367                                   MOV_FRAG_SAMPLE_FLAG_DEPENDS_YES));
5368         if (keyframe) {
5369             distance = 0;
5370             index_entry_flags |= AVINDEX_KEYFRAME;
5371         }
5372         // Fragments can overlap in time.  Discard overlapping frames after
5373         // decoding.
5374         if (prev_dts >= dts)
5375             index_entry_flags |= AVINDEX_DISCARD_FRAME;
5376 
5377         sti->index_entries[index_entry_pos].pos   = offset;
5378         sti->index_entries[index_entry_pos].timestamp = dts;
5379         sti->index_entries[index_entry_pos].size  = sample_size;
5380         sti->index_entries[index_entry_pos].min_distance = distance;
5381         sti->index_entries[index_entry_pos].flags = index_entry_flags;
5382 
5383         sc->ctts_data[index_entry_pos].count = 1;
5384         sc->ctts_data[index_entry_pos].duration = ctts_duration;
5385         index_entry_pos++;
5386 
5387         av_log(c->fc, AV_LOG_TRACE, "AVIndex stream %d, sample %d, offset %"PRIx64", dts %"PRId64", "
5388                 "size %u, distance %d, keyframe %d\n", st->index,
5389                 index_entry_pos, offset, dts, sample_size, distance, keyframe);
5390         distance++;
5391         if (av_sat_add64(dts, sample_duration) != dts + (uint64_t)sample_duration)
5392             return AVERROR_INVALIDDATA;
5393         if (!sample_size)
5394             return AVERROR_INVALIDDATA;
5395         dts += sample_duration;
5396         offset += sample_size;
5397         sc->data_size += sample_size;
5398 
5399         if (sample_duration <= INT64_MAX - sc->duration_for_fps &&
5400             1 <= INT_MAX - sc->nb_frames_for_fps
5401         ) {
5402             sc->duration_for_fps += sample_duration;
5403             sc->nb_frames_for_fps ++;
5404         }
5405     }
5406     if (frag_stream_info)
5407         frag_stream_info->next_trun_dts = dts + sc->time_offset;
5408     if (i < entries) {
5409         // EOF found before reading all entries.  Fix the hole this would
5410         // leave in index_entries and ctts_data
5411         int gap = entries - i;
5412         memmove(sti->index_entries + index_entry_pos,
5413                 sti->index_entries + index_entry_pos + gap,
5414                 sizeof(*sti->index_entries) *
5415                 (sti->nb_index_entries - (index_entry_pos + gap)));
5416         memmove(sc->ctts_data + index_entry_pos,
5417                 sc->ctts_data + index_entry_pos + gap,
5418                 sizeof(*sc->ctts_data) *
5419                 (sc->ctts_count - (index_entry_pos + gap)));
5420 
5421         sti->nb_index_entries -= gap;
5422         sc->ctts_count -= gap;
5423         if (index_entry_pos < sc->current_sample) {
5424             sc->current_sample -= gap;
5425         }
5426         entries = i;
5427     }
5428 
5429     // The end of this new fragment may overlap in time with the start
5430     // of the next fragment in index_entries. Mark the samples in the next
5431     // fragment that overlap with AVINDEX_DISCARD_FRAME
5432     prev_dts = AV_NOPTS_VALUE;
5433     if (index_entry_pos > 0)
5434         prev_dts = sti->index_entries[index_entry_pos-1].timestamp;
5435     for (int i = index_entry_pos; i < sti->nb_index_entries; i++) {
5436         if (prev_dts < sti->index_entries[i].timestamp)
5437             break;
5438         sti->index_entries[i].flags |= AVINDEX_DISCARD_FRAME;
5439     }
5440 
5441     // If a hole was created to insert the new index_entries into,
5442     // the index_entry recorded for all subsequent moof must
5443     // be incremented by the number of entries inserted.
5444     fix_frag_index_entries(&c->frag_index, next_frag_index,
5445                            frag->track_id, entries);
5446 
5447     if (pb->eof_reached) {
5448         av_log(c->fc, AV_LOG_WARNING, "reached eof, corrupted TRUN atom\n");
5449         return AVERROR_EOF;
5450     }
5451 
5452     frag->implicit_offset = offset;
5453 
5454     sc->track_end = dts + sc->time_offset;
5455     if (st->duration < sc->track_end)
5456         st->duration = sc->track_end;
5457 
5458     return 0;
5459 }
5460 
mov_read_sidx(MOVContext * c,AVIOContext * pb,MOVAtom atom)5461 static int mov_read_sidx(MOVContext *c, AVIOContext *pb, MOVAtom atom)
5462 {
5463     int64_t stream_size = avio_size(pb);
5464     int64_t offset = av_sat_add64(avio_tell(pb), atom.size), pts, timestamp;
5465     uint8_t version, is_complete;
5466     int64_t offadd;
5467     unsigned i, j, track_id, item_count;
5468     AVStream *st = NULL;
5469     AVStream *ref_st = NULL;
5470     MOVStreamContext *sc, *ref_sc = NULL;
5471     AVRational timescale;
5472 
5473     version = avio_r8(pb);
5474     if (version > 1) {
5475         avpriv_request_sample(c->fc, "sidx version %u", version);
5476         return 0;
5477     }
5478 
5479     avio_rb24(pb); // flags
5480 
5481     track_id = avio_rb32(pb); // Reference ID
5482     for (i = 0; i < c->fc->nb_streams; i++) {
5483         if (c->fc->streams[i]->id == track_id) {
5484             st = c->fc->streams[i];
5485             break;
5486         }
5487     }
5488     if (!st) {
5489         av_log(c->fc, AV_LOG_WARNING, "could not find corresponding track id %d\n", track_id);
5490         return 0;
5491     }
5492 
5493     sc = st->priv_data;
5494 
5495     timescale = av_make_q(1, avio_rb32(pb));
5496 
5497     if (timescale.den <= 0) {
5498         av_log(c->fc, AV_LOG_ERROR, "Invalid sidx timescale 1/%d\n", timescale.den);
5499         return AVERROR_INVALIDDATA;
5500     }
5501 
5502     if (version == 0) {
5503         pts = avio_rb32(pb);
5504         offadd= avio_rb32(pb);
5505     } else {
5506         pts = avio_rb64(pb);
5507         offadd= avio_rb64(pb);
5508     }
5509     if (av_sat_add64(offset, offadd) != offset + (uint64_t)offadd)
5510         return AVERROR_INVALIDDATA;
5511 
5512     offset += (uint64_t)offadd;
5513 
5514     avio_rb16(pb); // reserved
5515 
5516     item_count = avio_rb16(pb);
5517     if (item_count == 0)
5518         return AVERROR_INVALIDDATA;
5519 
5520     for (i = 0; i < item_count; i++) {
5521         int index;
5522         MOVFragmentStreamInfo * frag_stream_info;
5523         uint32_t size = avio_rb32(pb);
5524         uint32_t duration = avio_rb32(pb);
5525         if (size & 0x80000000) {
5526             avpriv_request_sample(c->fc, "sidx reference_type 1");
5527             return AVERROR_PATCHWELCOME;
5528         }
5529         avio_rb32(pb); // sap_flags
5530         timestamp = av_rescale_q(pts, timescale, st->time_base);
5531 
5532         index = update_frag_index(c, offset);
5533         frag_stream_info = get_frag_stream_info(&c->frag_index, index, track_id);
5534         if (frag_stream_info)
5535             frag_stream_info->sidx_pts = timestamp;
5536 
5537         if (av_sat_add64(offset, size) != offset + (uint64_t)size ||
5538             av_sat_add64(pts, duration) != pts + (uint64_t)duration
5539         )
5540             return AVERROR_INVALIDDATA;
5541         offset += size;
5542         pts += duration;
5543     }
5544 
5545     st->duration = sc->track_end = pts;
5546 
5547     sc->has_sidx = 1;
5548 
5549     // See if the remaining bytes are just an mfra which we can ignore.
5550     is_complete = offset == stream_size;
5551     if (!is_complete && (pb->seekable & AVIO_SEEKABLE_NORMAL) && stream_size > 0 ) {
5552         int64_t ret;
5553         int64_t original_pos = avio_tell(pb);
5554         if (!c->have_read_mfra_size) {
5555             if ((ret = avio_seek(pb, stream_size - 4, SEEK_SET)) < 0)
5556                 return ret;
5557             c->mfra_size = avio_rb32(pb);
5558             c->have_read_mfra_size = 1;
5559             if ((ret = avio_seek(pb, original_pos, SEEK_SET)) < 0)
5560                 return ret;
5561         }
5562         if (offset == stream_size - c->mfra_size)
5563             is_complete = 1;
5564     }
5565 
5566     if (is_complete) {
5567         // Find first entry in fragment index that came from an sidx.
5568         // This will pretty much always be the first entry.
5569         for (i = 0; i < c->frag_index.nb_items; i++) {
5570             MOVFragmentIndexItem * item = &c->frag_index.item[i];
5571             for (j = 0; ref_st == NULL && j < item->nb_stream_info; j++) {
5572                 MOVFragmentStreamInfo * si;
5573                 si = &item->stream_info[j];
5574                 if (si->sidx_pts != AV_NOPTS_VALUE) {
5575                     ref_st = c->fc->streams[j];
5576                     ref_sc = ref_st->priv_data;
5577                     break;
5578                 }
5579             }
5580         }
5581         if (ref_st) for (i = 0; i < c->fc->nb_streams; i++) {
5582             st = c->fc->streams[i];
5583             sc = st->priv_data;
5584             if (!sc->has_sidx) {
5585                 st->duration = sc->track_end = av_rescale(ref_st->duration, sc->time_scale, ref_sc->time_scale);
5586             }
5587         }
5588 
5589         c->frag_index.complete = 1;
5590     }
5591 
5592     return 0;
5593 }
5594 
5595 /* this atom should be null (from specs), but some buggy files put the 'moov' atom inside it... */
5596 /* like the files created with Adobe Premiere 5.0, for samples see */
5597 /* http://graphics.tudelft.nl/~wouter/publications/soundtests/ */
mov_read_wide(MOVContext * c,AVIOContext * pb,MOVAtom atom)5598 static int mov_read_wide(MOVContext *c, AVIOContext *pb, MOVAtom atom)
5599 {
5600     int err;
5601 
5602     if (atom.size < 8)
5603         return 0; /* continue */
5604     if (avio_rb32(pb) != 0) { /* 0 sized mdat atom... use the 'wide' atom size */
5605         avio_skip(pb, atom.size - 4);
5606         return 0;
5607     }
5608     atom.type = avio_rl32(pb);
5609     atom.size -= 8;
5610     if (atom.type != MKTAG('m','d','a','t')) {
5611         avio_skip(pb, atom.size);
5612         return 0;
5613     }
5614     err = mov_read_mdat(c, pb, atom);
5615     return err;
5616 }
5617 
mov_read_cmov(MOVContext * c,AVIOContext * pb,MOVAtom atom)5618 static int mov_read_cmov(MOVContext *c, AVIOContext *pb, MOVAtom atom)
5619 {
5620 #if CONFIG_ZLIB
5621     FFIOContext ctx;
5622     uint8_t *cmov_data;
5623     uint8_t *moov_data; /* uncompressed data */
5624     long cmov_len, moov_len;
5625     int ret = -1;
5626 
5627     avio_rb32(pb); /* dcom atom */
5628     if (avio_rl32(pb) != MKTAG('d','c','o','m'))
5629         return AVERROR_INVALIDDATA;
5630     if (avio_rl32(pb) != MKTAG('z','l','i','b')) {
5631         av_log(c->fc, AV_LOG_ERROR, "unknown compression for cmov atom !\n");
5632         return AVERROR_INVALIDDATA;
5633     }
5634     avio_rb32(pb); /* cmvd atom */
5635     if (avio_rl32(pb) != MKTAG('c','m','v','d'))
5636         return AVERROR_INVALIDDATA;
5637     moov_len = avio_rb32(pb); /* uncompressed size */
5638     cmov_len = atom.size - 6 * 4;
5639 
5640     cmov_data = av_malloc(cmov_len);
5641     if (!cmov_data)
5642         return AVERROR(ENOMEM);
5643     moov_data = av_malloc(moov_len);
5644     if (!moov_data) {
5645         av_free(cmov_data);
5646         return AVERROR(ENOMEM);
5647     }
5648     ret = ffio_read_size(pb, cmov_data, cmov_len);
5649     if (ret < 0)
5650         goto free_and_return;
5651 
5652     ret = AVERROR_INVALIDDATA;
5653     if (uncompress (moov_data, (uLongf *) &moov_len, (const Bytef *)cmov_data, cmov_len) != Z_OK)
5654         goto free_and_return;
5655     ffio_init_context(&ctx, moov_data, moov_len, 0, NULL, NULL, NULL, NULL);
5656     ctx.pub.seekable = AVIO_SEEKABLE_NORMAL;
5657     atom.type = MKTAG('m','o','o','v');
5658     atom.size = moov_len;
5659     ret = mov_read_default(c, &ctx.pub, atom);
5660 free_and_return:
5661     av_free(moov_data);
5662     av_free(cmov_data);
5663     return ret;
5664 #else
5665     av_log(c->fc, AV_LOG_ERROR, "this file requires zlib support compiled in\n");
5666     return AVERROR(ENOSYS);
5667 #endif
5668 }
5669 
5670 /* edit list atom */
mov_read_elst(MOVContext * c,AVIOContext * pb,MOVAtom atom)5671 static int mov_read_elst(MOVContext *c, AVIOContext *pb, MOVAtom atom)
5672 {
5673     MOVStreamContext *sc;
5674     int i, edit_count, version;
5675     int64_t elst_entry_size;
5676 
5677     if (c->fc->nb_streams < 1 || c->ignore_editlist)
5678         return 0;
5679     sc = c->fc->streams[c->fc->nb_streams-1]->priv_data;
5680 
5681     version = avio_r8(pb); /* version */
5682     avio_rb24(pb); /* flags */
5683     edit_count = avio_rb32(pb); /* entries */
5684     atom.size -= 8;
5685 
5686     elst_entry_size = version == 1 ? 20 : 12;
5687     if (atom.size != edit_count * elst_entry_size) {
5688         if (c->fc->strict_std_compliance >= FF_COMPLIANCE_STRICT) {
5689             av_log(c->fc, AV_LOG_ERROR, "Invalid edit list entry_count: %d for elst atom of size: %"PRId64" bytes.\n",
5690                    edit_count, atom.size + 8);
5691             return AVERROR_INVALIDDATA;
5692         } else {
5693             edit_count = atom.size / elst_entry_size;
5694             if (edit_count * elst_entry_size != atom.size) {
5695                 av_log(c->fc, AV_LOG_WARNING, "ELST atom of %"PRId64" bytes, bigger than %d entries.\n", atom.size, edit_count);
5696             }
5697         }
5698     }
5699 
5700     if (!edit_count)
5701         return 0;
5702     if (sc->elst_data)
5703         av_log(c->fc, AV_LOG_WARNING, "Duplicated ELST atom\n");
5704     av_free(sc->elst_data);
5705     sc->elst_count = 0;
5706     sc->elst_data = av_malloc_array(edit_count, sizeof(*sc->elst_data));
5707     if (!sc->elst_data)
5708         return AVERROR(ENOMEM);
5709 
5710     av_log(c->fc, AV_LOG_TRACE, "track[%u].edit_count = %i\n", c->fc->nb_streams - 1, edit_count);
5711     for (i = 0; i < edit_count && atom.size > 0 && !pb->eof_reached; i++) {
5712         MOVElst *e = &sc->elst_data[i];
5713 
5714         if (version == 1) {
5715             e->duration = avio_rb64(pb);
5716             e->time     = avio_rb64(pb);
5717             atom.size -= 16;
5718         } else {
5719             e->duration = avio_rb32(pb); /* segment duration */
5720             e->time     = (int32_t)avio_rb32(pb); /* media time */
5721             atom.size -= 8;
5722         }
5723         e->rate = avio_rb32(pb) / 65536.0;
5724         atom.size -= 4;
5725         av_log(c->fc, AV_LOG_TRACE, "duration=%"PRId64" time=%"PRId64" rate=%f\n",
5726                e->duration, e->time, e->rate);
5727 
5728         if (e->time < 0 && e->time != -1 &&
5729             c->fc->strict_std_compliance >= FF_COMPLIANCE_STRICT) {
5730             av_log(c->fc, AV_LOG_ERROR, "Track %d, edit %d: Invalid edit list media time=%"PRId64"\n",
5731                    c->fc->nb_streams-1, i, e->time);
5732             return AVERROR_INVALIDDATA;
5733         }
5734     }
5735     sc->elst_count = i;
5736 
5737     return 0;
5738 }
5739 
mov_read_tmcd(MOVContext * c,AVIOContext * pb,MOVAtom atom)5740 static int mov_read_tmcd(MOVContext *c, AVIOContext *pb, MOVAtom atom)
5741 {
5742     MOVStreamContext *sc;
5743 
5744     if (c->fc->nb_streams < 1)
5745         return AVERROR_INVALIDDATA;
5746     sc = c->fc->streams[c->fc->nb_streams - 1]->priv_data;
5747     sc->timecode_track = avio_rb32(pb);
5748     return 0;
5749 }
5750 
mov_read_vpcc(MOVContext * c,AVIOContext * pb,MOVAtom atom)5751 static int mov_read_vpcc(MOVContext *c, AVIOContext *pb, MOVAtom atom)
5752 {
5753     AVStream *st;
5754     int version, color_range, color_primaries, color_trc, color_space;
5755 
5756     if (c->fc->nb_streams < 1)
5757         return 0;
5758     st = c->fc->streams[c->fc->nb_streams - 1];
5759 
5760     if (atom.size < 5) {
5761         av_log(c->fc, AV_LOG_ERROR, "Empty VP Codec Configuration box\n");
5762         return AVERROR_INVALIDDATA;
5763     }
5764 
5765     version = avio_r8(pb);
5766     if (version != 1) {
5767         av_log(c->fc, AV_LOG_WARNING, "Unsupported VP Codec Configuration box version %d\n", version);
5768         return 0;
5769     }
5770     avio_skip(pb, 3); /* flags */
5771 
5772     avio_skip(pb, 2); /* profile + level */
5773     color_range     = avio_r8(pb); /* bitDepth, chromaSubsampling, videoFullRangeFlag */
5774     color_primaries = avio_r8(pb);
5775     color_trc       = avio_r8(pb);
5776     color_space     = avio_r8(pb);
5777     if (avio_rb16(pb)) /* codecIntializationDataSize */
5778         return AVERROR_INVALIDDATA;
5779 
5780     if (!av_color_primaries_name(color_primaries))
5781         color_primaries = AVCOL_PRI_UNSPECIFIED;
5782     if (!av_color_transfer_name(color_trc))
5783         color_trc = AVCOL_TRC_UNSPECIFIED;
5784     if (!av_color_space_name(color_space))
5785         color_space = AVCOL_SPC_UNSPECIFIED;
5786 
5787     st->codecpar->color_range     = (color_range & 1) ? AVCOL_RANGE_JPEG : AVCOL_RANGE_MPEG;
5788     st->codecpar->color_primaries = color_primaries;
5789     st->codecpar->color_trc       = color_trc;
5790     st->codecpar->color_space     = color_space;
5791 
5792     return 0;
5793 }
5794 
mov_read_smdm(MOVContext * c,AVIOContext * pb,MOVAtom atom)5795 static int mov_read_smdm(MOVContext *c, AVIOContext *pb, MOVAtom atom)
5796 {
5797     MOVStreamContext *sc;
5798     int i, version;
5799 
5800     if (c->fc->nb_streams < 1)
5801         return AVERROR_INVALIDDATA;
5802 
5803     sc = c->fc->streams[c->fc->nb_streams - 1]->priv_data;
5804 
5805     if (atom.size < 5) {
5806         av_log(c->fc, AV_LOG_ERROR, "Empty Mastering Display Metadata box\n");
5807         return AVERROR_INVALIDDATA;
5808     }
5809 
5810     version = avio_r8(pb);
5811     if (version) {
5812         av_log(c->fc, AV_LOG_WARNING, "Unsupported Mastering Display Metadata box version %d\n", version);
5813         return 0;
5814     }
5815     if (sc->mastering)
5816         return AVERROR_INVALIDDATA;
5817 
5818     avio_skip(pb, 3); /* flags */
5819 
5820     sc->mastering = av_mastering_display_metadata_alloc();
5821     if (!sc->mastering)
5822         return AVERROR(ENOMEM);
5823 
5824     for (i = 0; i < 3; i++) {
5825         sc->mastering->display_primaries[i][0] = av_make_q(avio_rb16(pb), 1 << 16);
5826         sc->mastering->display_primaries[i][1] = av_make_q(avio_rb16(pb), 1 << 16);
5827     }
5828     sc->mastering->white_point[0] = av_make_q(avio_rb16(pb), 1 << 16);
5829     sc->mastering->white_point[1] = av_make_q(avio_rb16(pb), 1 << 16);
5830 
5831     sc->mastering->max_luminance = av_make_q(avio_rb32(pb), 1 << 8);
5832     sc->mastering->min_luminance = av_make_q(avio_rb32(pb), 1 << 14);
5833 
5834     sc->mastering->has_primaries = 1;
5835     sc->mastering->has_luminance = 1;
5836 
5837     return 0;
5838 }
5839 
mov_read_mdcv(MOVContext * c,AVIOContext * pb,MOVAtom atom)5840 static int mov_read_mdcv(MOVContext *c, AVIOContext *pb, MOVAtom atom)
5841 {
5842     MOVStreamContext *sc;
5843     const int mapping[3] = {1, 2, 0};
5844     const int chroma_den = 50000;
5845     const int luma_den = 10000;
5846     int i;
5847 
5848     if (c->fc->nb_streams < 1)
5849         return AVERROR_INVALIDDATA;
5850 
5851     sc = c->fc->streams[c->fc->nb_streams - 1]->priv_data;
5852 
5853     if (atom.size < 24 || sc->mastering) {
5854         av_log(c->fc, AV_LOG_ERROR, "Invalid Mastering Display Color Volume box\n");
5855         return AVERROR_INVALIDDATA;
5856     }
5857 
5858     sc->mastering = av_mastering_display_metadata_alloc();
5859     if (!sc->mastering)
5860         return AVERROR(ENOMEM);
5861 
5862     for (i = 0; i < 3; i++) {
5863         const int j = mapping[i];
5864         sc->mastering->display_primaries[j][0] = av_make_q(avio_rb16(pb), chroma_den);
5865         sc->mastering->display_primaries[j][1] = av_make_q(avio_rb16(pb), chroma_den);
5866     }
5867     sc->mastering->white_point[0] = av_make_q(avio_rb16(pb), chroma_den);
5868     sc->mastering->white_point[1] = av_make_q(avio_rb16(pb), chroma_den);
5869 
5870     sc->mastering->max_luminance = av_make_q(avio_rb32(pb), luma_den);
5871     sc->mastering->min_luminance = av_make_q(avio_rb32(pb), luma_den);
5872 
5873     sc->mastering->has_luminance = 1;
5874     sc->mastering->has_primaries = 1;
5875 
5876     return 0;
5877 }
5878 
mov_read_coll(MOVContext * c,AVIOContext * pb,MOVAtom atom)5879 static int mov_read_coll(MOVContext *c, AVIOContext *pb, MOVAtom atom)
5880 {
5881     MOVStreamContext *sc;
5882     int version;
5883 
5884     if (c->fc->nb_streams < 1)
5885         return AVERROR_INVALIDDATA;
5886 
5887     sc = c->fc->streams[c->fc->nb_streams - 1]->priv_data;
5888 
5889     if (atom.size < 5) {
5890         av_log(c->fc, AV_LOG_ERROR, "Empty Content Light Level box\n");
5891         return AVERROR_INVALIDDATA;
5892     }
5893 
5894     version = avio_r8(pb);
5895     if (version) {
5896         av_log(c->fc, AV_LOG_WARNING, "Unsupported Content Light Level box version %d\n", version);
5897         return 0;
5898     }
5899     avio_skip(pb, 3); /* flags */
5900 
5901     if (sc->coll){
5902         av_log(c->fc, AV_LOG_WARNING, "Ignoring duplicate COLL\n");
5903         return 0;
5904     }
5905 
5906     sc->coll = av_content_light_metadata_alloc(&sc->coll_size);
5907     if (!sc->coll)
5908         return AVERROR(ENOMEM);
5909 
5910     sc->coll->MaxCLL  = avio_rb16(pb);
5911     sc->coll->MaxFALL = avio_rb16(pb);
5912 
5913     return 0;
5914 }
5915 
mov_read_clli(MOVContext * c,AVIOContext * pb,MOVAtom atom)5916 static int mov_read_clli(MOVContext *c, AVIOContext *pb, MOVAtom atom)
5917 {
5918     MOVStreamContext *sc;
5919 
5920     if (c->fc->nb_streams < 1)
5921         return AVERROR_INVALIDDATA;
5922 
5923     sc = c->fc->streams[c->fc->nb_streams - 1]->priv_data;
5924 
5925     if (atom.size < 4) {
5926         av_log(c->fc, AV_LOG_ERROR, "Empty Content Light Level Info box\n");
5927         return AVERROR_INVALIDDATA;
5928     }
5929 
5930     if (sc->coll){
5931         av_log(c->fc, AV_LOG_WARNING, "Ignoring duplicate CLLI/COLL\n");
5932         return 0;
5933     }
5934 
5935     sc->coll = av_content_light_metadata_alloc(&sc->coll_size);
5936     if (!sc->coll)
5937         return AVERROR(ENOMEM);
5938 
5939     sc->coll->MaxCLL  = avio_rb16(pb);
5940     sc->coll->MaxFALL = avio_rb16(pb);
5941 
5942     return 0;
5943 }
5944 
mov_read_st3d(MOVContext * c,AVIOContext * pb,MOVAtom atom)5945 static int mov_read_st3d(MOVContext *c, AVIOContext *pb, MOVAtom atom)
5946 {
5947     AVStream *st;
5948     MOVStreamContext *sc;
5949     enum AVStereo3DType type;
5950     int mode;
5951 
5952     if (c->fc->nb_streams < 1)
5953         return 0;
5954 
5955     st = c->fc->streams[c->fc->nb_streams - 1];
5956     sc = st->priv_data;
5957 
5958     if (atom.size < 5) {
5959         av_log(c->fc, AV_LOG_ERROR, "Empty stereoscopic video box\n");
5960         return AVERROR_INVALIDDATA;
5961     }
5962 
5963     if (sc->stereo3d)
5964         return AVERROR_INVALIDDATA;
5965 
5966     avio_skip(pb, 4); /* version + flags */
5967 
5968     mode = avio_r8(pb);
5969     switch (mode) {
5970     case 0:
5971         type = AV_STEREO3D_2D;
5972         break;
5973     case 1:
5974         type = AV_STEREO3D_TOPBOTTOM;
5975         break;
5976     case 2:
5977         type = AV_STEREO3D_SIDEBYSIDE;
5978         break;
5979     default:
5980         av_log(c->fc, AV_LOG_WARNING, "Unknown st3d mode value %d\n", mode);
5981         return 0;
5982     }
5983 
5984     sc->stereo3d = av_stereo3d_alloc();
5985     if (!sc->stereo3d)
5986         return AVERROR(ENOMEM);
5987 
5988     sc->stereo3d->type = type;
5989     return 0;
5990 }
5991 
mov_read_sv3d(MOVContext * c,AVIOContext * pb,MOVAtom atom)5992 static int mov_read_sv3d(MOVContext *c, AVIOContext *pb, MOVAtom atom)
5993 {
5994     AVStream *st;
5995     MOVStreamContext *sc;
5996     int size, version, layout;
5997     int32_t yaw, pitch, roll;
5998     uint32_t l = 0, t = 0, r = 0, b = 0;
5999     uint32_t tag, padding = 0;
6000     enum AVSphericalProjection projection;
6001 
6002     if (c->fc->nb_streams < 1)
6003         return 0;
6004 
6005     st = c->fc->streams[c->fc->nb_streams - 1];
6006     sc = st->priv_data;
6007 
6008     if (atom.size < 8) {
6009         av_log(c->fc, AV_LOG_ERROR, "Empty spherical video box\n");
6010         return AVERROR_INVALIDDATA;
6011     }
6012 
6013     size = avio_rb32(pb);
6014     if (size <= 12 || size > atom.size)
6015         return AVERROR_INVALIDDATA;
6016 
6017     tag = avio_rl32(pb);
6018     if (tag != MKTAG('s','v','h','d')) {
6019         av_log(c->fc, AV_LOG_ERROR, "Missing spherical video header\n");
6020         return 0;
6021     }
6022     version = avio_r8(pb);
6023     if (version != 0) {
6024         av_log(c->fc, AV_LOG_WARNING, "Unknown spherical version %d\n",
6025                version);
6026         return 0;
6027     }
6028     avio_skip(pb, 3); /* flags */
6029     avio_skip(pb, size - 12); /* metadata_source */
6030 
6031     size = avio_rb32(pb);
6032     if (size > atom.size)
6033         return AVERROR_INVALIDDATA;
6034 
6035     tag = avio_rl32(pb);
6036     if (tag != MKTAG('p','r','o','j')) {
6037         av_log(c->fc, AV_LOG_ERROR, "Missing projection box\n");
6038         return 0;
6039     }
6040 
6041     size = avio_rb32(pb);
6042     if (size > atom.size)
6043         return AVERROR_INVALIDDATA;
6044 
6045     tag = avio_rl32(pb);
6046     if (tag != MKTAG('p','r','h','d')) {
6047         av_log(c->fc, AV_LOG_ERROR, "Missing projection header box\n");
6048         return 0;
6049     }
6050     version = avio_r8(pb);
6051     if (version != 0) {
6052         av_log(c->fc, AV_LOG_WARNING, "Unknown spherical version %d\n",
6053                version);
6054         return 0;
6055     }
6056     avio_skip(pb, 3); /* flags */
6057 
6058     /* 16.16 fixed point */
6059     yaw   = avio_rb32(pb);
6060     pitch = avio_rb32(pb);
6061     roll  = avio_rb32(pb);
6062 
6063     size = avio_rb32(pb);
6064     if (size > atom.size)
6065         return AVERROR_INVALIDDATA;
6066 
6067     tag = avio_rl32(pb);
6068     version = avio_r8(pb);
6069     if (version != 0) {
6070         av_log(c->fc, AV_LOG_WARNING, "Unknown spherical version %d\n",
6071                version);
6072         return 0;
6073     }
6074     avio_skip(pb, 3); /* flags */
6075     switch (tag) {
6076     case MKTAG('c','b','m','p'):
6077         layout = avio_rb32(pb);
6078         if (layout) {
6079             av_log(c->fc, AV_LOG_WARNING,
6080                    "Unsupported cubemap layout %d\n", layout);
6081             return 0;
6082         }
6083         projection = AV_SPHERICAL_CUBEMAP;
6084         padding = avio_rb32(pb);
6085         break;
6086     case MKTAG('e','q','u','i'):
6087         t = avio_rb32(pb);
6088         b = avio_rb32(pb);
6089         l = avio_rb32(pb);
6090         r = avio_rb32(pb);
6091 
6092         if (b >= UINT_MAX - t || r >= UINT_MAX - l) {
6093             av_log(c->fc, AV_LOG_ERROR,
6094                    "Invalid bounding rectangle coordinates "
6095                    "%"PRIu32",%"PRIu32",%"PRIu32",%"PRIu32"\n", l, t, r, b);
6096             return AVERROR_INVALIDDATA;
6097         }
6098 
6099         if (l || t || r || b)
6100             projection = AV_SPHERICAL_EQUIRECTANGULAR_TILE;
6101         else
6102             projection = AV_SPHERICAL_EQUIRECTANGULAR;
6103         break;
6104     default:
6105         av_log(c->fc, AV_LOG_ERROR, "Unknown projection type: %s\n", av_fourcc2str(tag));
6106         return 0;
6107     }
6108 
6109     sc->spherical = av_spherical_alloc(&sc->spherical_size);
6110     if (!sc->spherical)
6111         return AVERROR(ENOMEM);
6112 
6113     sc->spherical->projection = projection;
6114 
6115     sc->spherical->yaw   = yaw;
6116     sc->spherical->pitch = pitch;
6117     sc->spherical->roll  = roll;
6118 
6119     sc->spherical->padding = padding;
6120 
6121     sc->spherical->bound_left   = l;
6122     sc->spherical->bound_top    = t;
6123     sc->spherical->bound_right  = r;
6124     sc->spherical->bound_bottom = b;
6125 
6126     return 0;
6127 }
6128 
mov_parse_uuid_spherical(MOVStreamContext * sc,AVIOContext * pb,size_t len)6129 static int mov_parse_uuid_spherical(MOVStreamContext *sc, AVIOContext *pb, size_t len)
6130 {
6131     int ret = 0;
6132     uint8_t *buffer = av_malloc(len + 1);
6133     const char *val;
6134 
6135     if (!buffer)
6136         return AVERROR(ENOMEM);
6137     buffer[len] = '\0';
6138 
6139     ret = ffio_read_size(pb, buffer, len);
6140     if (ret < 0)
6141         goto out;
6142 
6143     /* Check for mandatory keys and values, try to support XML as best-effort */
6144     if (!sc->spherical &&
6145         av_stristr(buffer, "<GSpherical:StitchingSoftware>") &&
6146         (val = av_stristr(buffer, "<GSpherical:Spherical>")) &&
6147         av_stristr(val, "true") &&
6148         (val = av_stristr(buffer, "<GSpherical:Stitched>")) &&
6149         av_stristr(val, "true") &&
6150         (val = av_stristr(buffer, "<GSpherical:ProjectionType>")) &&
6151         av_stristr(val, "equirectangular")) {
6152         sc->spherical = av_spherical_alloc(&sc->spherical_size);
6153         if (!sc->spherical)
6154             goto out;
6155 
6156         sc->spherical->projection = AV_SPHERICAL_EQUIRECTANGULAR;
6157 
6158         if (av_stristr(buffer, "<GSpherical:StereoMode>") && !sc->stereo3d) {
6159             enum AVStereo3DType mode;
6160 
6161             if (av_stristr(buffer, "left-right"))
6162                 mode = AV_STEREO3D_SIDEBYSIDE;
6163             else if (av_stristr(buffer, "top-bottom"))
6164                 mode = AV_STEREO3D_TOPBOTTOM;
6165             else
6166                 mode = AV_STEREO3D_2D;
6167 
6168             sc->stereo3d = av_stereo3d_alloc();
6169             if (!sc->stereo3d)
6170                 goto out;
6171 
6172             sc->stereo3d->type = mode;
6173         }
6174 
6175         /* orientation */
6176         val = av_stristr(buffer, "<GSpherical:InitialViewHeadingDegrees>");
6177         if (val)
6178             sc->spherical->yaw = strtol(val, NULL, 10) * (1 << 16);
6179         val = av_stristr(buffer, "<GSpherical:InitialViewPitchDegrees>");
6180         if (val)
6181             sc->spherical->pitch = strtol(val, NULL, 10) * (1 << 16);
6182         val = av_stristr(buffer, "<GSpherical:InitialViewRollDegrees>");
6183         if (val)
6184             sc->spherical->roll = strtol(val, NULL, 10) * (1 << 16);
6185     }
6186 
6187 out:
6188     av_free(buffer);
6189     return ret;
6190 }
6191 
mov_read_uuid(MOVContext * c,AVIOContext * pb,MOVAtom atom)6192 static int mov_read_uuid(MOVContext *c, AVIOContext *pb, MOVAtom atom)
6193 {
6194     AVStream *st;
6195     MOVStreamContext *sc;
6196     int64_t ret;
6197     AVUUID uuid;
6198     static const AVUUID uuid_isml_manifest = {
6199         0xa5, 0xd4, 0x0b, 0x30, 0xe8, 0x14, 0x11, 0xdd,
6200         0xba, 0x2f, 0x08, 0x00, 0x20, 0x0c, 0x9a, 0x66
6201     };
6202     static const AVUUID uuid_xmp = {
6203         0xbe, 0x7a, 0xcf, 0xcb, 0x97, 0xa9, 0x42, 0xe8,
6204         0x9c, 0x71, 0x99, 0x94, 0x91, 0xe3, 0xaf, 0xac
6205     };
6206     static const AVUUID uuid_spherical = {
6207         0xff, 0xcc, 0x82, 0x63, 0xf8, 0x55, 0x4a, 0x93,
6208         0x88, 0x14, 0x58, 0x7a, 0x02, 0x52, 0x1f, 0xdd,
6209     };
6210 
6211     if (atom.size < AV_UUID_LEN || atom.size >= FFMIN(INT_MAX, SIZE_MAX))
6212         return AVERROR_INVALIDDATA;
6213 
6214     if (c->fc->nb_streams < 1)
6215         return 0;
6216     st = c->fc->streams[c->fc->nb_streams - 1];
6217     sc = st->priv_data;
6218 
6219     ret = ffio_read_size(pb, uuid, AV_UUID_LEN);
6220     if (ret < 0)
6221         return ret;
6222     if (av_uuid_equal(uuid, uuid_isml_manifest)) {
6223         uint8_t *buffer, *ptr;
6224         char *endptr;
6225         size_t len = atom.size - AV_UUID_LEN;
6226 
6227         if (len < 4) {
6228             return AVERROR_INVALIDDATA;
6229         }
6230         ret = avio_skip(pb, 4); // zeroes
6231         len -= 4;
6232 
6233         buffer = av_mallocz(len + 1);
6234         if (!buffer) {
6235             return AVERROR(ENOMEM);
6236         }
6237         ret = ffio_read_size(pb, buffer, len);
6238         if (ret < 0) {
6239             av_free(buffer);
6240             return ret;
6241         }
6242 
6243         ptr = buffer;
6244         while ((ptr = av_stristr(ptr, "systemBitrate=\""))) {
6245             ptr += sizeof("systemBitrate=\"") - 1;
6246             c->bitrates_count++;
6247             c->bitrates = av_realloc_f(c->bitrates, c->bitrates_count, sizeof(*c->bitrates));
6248             if (!c->bitrates) {
6249                 c->bitrates_count = 0;
6250                 av_free(buffer);
6251                 return AVERROR(ENOMEM);
6252             }
6253             errno = 0;
6254             ret = strtol(ptr, &endptr, 10);
6255             if (ret < 0 || errno || *endptr != '"') {
6256                 c->bitrates[c->bitrates_count - 1] = 0;
6257             } else {
6258                 c->bitrates[c->bitrates_count - 1] = ret;
6259             }
6260         }
6261 
6262         av_free(buffer);
6263     } else if (av_uuid_equal(uuid, uuid_xmp)) {
6264         uint8_t *buffer;
6265         size_t len = atom.size - AV_UUID_LEN;
6266         if (c->export_xmp) {
6267             buffer = av_mallocz(len + 1);
6268             if (!buffer) {
6269                 return AVERROR(ENOMEM);
6270             }
6271             ret = ffio_read_size(pb, buffer, len);
6272             if (ret < 0) {
6273                 av_free(buffer);
6274                 return ret;
6275             }
6276             buffer[len] = '\0';
6277             av_dict_set(&c->fc->metadata, "xmp",
6278                         buffer, AV_DICT_DONT_STRDUP_VAL);
6279         } else {
6280             // skip all uuid atom, which makes it fast for long uuid-xmp file
6281             ret = avio_skip(pb, len);
6282             if (ret < 0)
6283                 return ret;
6284         }
6285     } else if (av_uuid_equal(uuid, uuid_spherical)) {
6286         size_t len = atom.size - AV_UUID_LEN;
6287         ret = mov_parse_uuid_spherical(sc, pb, len);
6288         if (ret < 0)
6289             return ret;
6290         if (!sc->spherical)
6291             av_log(c->fc, AV_LOG_WARNING, "Invalid spherical metadata found\n");
6292     }
6293 
6294     return 0;
6295 }
6296 
mov_read_free(MOVContext * c,AVIOContext * pb,MOVAtom atom)6297 static int mov_read_free(MOVContext *c, AVIOContext *pb, MOVAtom atom)
6298 {
6299     int ret;
6300     uint8_t content[16];
6301 
6302     if (atom.size < 8)
6303         return 0;
6304 
6305     ret = ffio_read_size(pb, content, FFMIN(sizeof(content), atom.size));
6306     if (ret < 0)
6307         return ret;
6308 
6309     if (   !c->found_moov
6310         && !c->found_mdat
6311         && !memcmp(content, "Anevia\x1A\x1A", 8)
6312         && c->use_mfra_for == FF_MOV_FLAG_MFRA_AUTO) {
6313         c->use_mfra_for = FF_MOV_FLAG_MFRA_PTS;
6314     }
6315 
6316     return 0;
6317 }
6318 
mov_read_frma(MOVContext * c,AVIOContext * pb,MOVAtom atom)6319 static int mov_read_frma(MOVContext *c, AVIOContext *pb, MOVAtom atom)
6320 {
6321     uint32_t format = avio_rl32(pb);
6322     MOVStreamContext *sc;
6323     enum AVCodecID id;
6324     AVStream *st;
6325 
6326     if (c->fc->nb_streams < 1)
6327         return 0;
6328     st = c->fc->streams[c->fc->nb_streams - 1];
6329     sc = st->priv_data;
6330 
6331     switch (sc->format)
6332     {
6333     case MKTAG('e','n','c','v'):        // encrypted video
6334     case MKTAG('e','n','c','a'):        // encrypted audio
6335         id = mov_codec_id(st, format);
6336         if (st->codecpar->codec_id != AV_CODEC_ID_NONE &&
6337             st->codecpar->codec_id != id) {
6338             av_log(c->fc, AV_LOG_WARNING,
6339                    "ignoring 'frma' atom of '%.4s', stream has codec id %d\n",
6340                    (char*)&format, st->codecpar->codec_id);
6341             break;
6342         }
6343 
6344         st->codecpar->codec_id = id;
6345         sc->format = format;
6346         break;
6347 
6348     default:
6349         if (format != sc->format) {
6350             av_log(c->fc, AV_LOG_WARNING,
6351                    "ignoring 'frma' atom of '%.4s', stream format is '%.4s'\n",
6352                    (char*)&format, (char*)&sc->format);
6353         }
6354         break;
6355     }
6356 
6357     return 0;
6358 }
6359 
6360 /**
6361  * Gets the current encryption info and associated current stream context.  If
6362  * we are parsing a track fragment, this will return the specific encryption
6363  * info for this fragment; otherwise this will return the global encryption
6364  * info for the current stream.
6365  */
get_current_encryption_info(MOVContext * c,MOVEncryptionIndex ** encryption_index,MOVStreamContext ** sc)6366 static int get_current_encryption_info(MOVContext *c, MOVEncryptionIndex **encryption_index, MOVStreamContext **sc)
6367 {
6368     MOVFragmentStreamInfo *frag_stream_info;
6369     AVStream *st;
6370     int i;
6371 
6372     frag_stream_info = get_current_frag_stream_info(&c->frag_index);
6373     if (frag_stream_info) {
6374         for (i = 0; i < c->fc->nb_streams; i++) {
6375             if (c->fc->streams[i]->id == frag_stream_info->id) {
6376               st = c->fc->streams[i];
6377               break;
6378             }
6379         }
6380         if (i == c->fc->nb_streams)
6381             return 0;
6382         *sc = st->priv_data;
6383 
6384         if (!frag_stream_info->encryption_index) {
6385             // If this stream isn't encrypted, don't create the index.
6386             if (!(*sc)->cenc.default_encrypted_sample)
6387                 return 0;
6388             frag_stream_info->encryption_index = av_mallocz(sizeof(*frag_stream_info->encryption_index));
6389             if (!frag_stream_info->encryption_index)
6390                 return AVERROR(ENOMEM);
6391         }
6392         *encryption_index = frag_stream_info->encryption_index;
6393         return 1;
6394     } else {
6395         // No current track fragment, using stream level encryption info.
6396 
6397         if (c->fc->nb_streams < 1)
6398             return 0;
6399         st = c->fc->streams[c->fc->nb_streams - 1];
6400         *sc = st->priv_data;
6401 
6402         if (!(*sc)->cenc.encryption_index) {
6403             // If this stream isn't encrypted, don't create the index.
6404             if (!(*sc)->cenc.default_encrypted_sample)
6405                 return 0;
6406             (*sc)->cenc.encryption_index = av_mallocz(sizeof(*frag_stream_info->encryption_index));
6407             if (!(*sc)->cenc.encryption_index)
6408                 return AVERROR(ENOMEM);
6409         }
6410 
6411         *encryption_index = (*sc)->cenc.encryption_index;
6412         return 1;
6413     }
6414 }
6415 
mov_read_sample_encryption_info(MOVContext * c,AVIOContext * pb,MOVStreamContext * sc,AVEncryptionInfo ** sample,int use_subsamples)6416 static int mov_read_sample_encryption_info(MOVContext *c, AVIOContext *pb, MOVStreamContext *sc, AVEncryptionInfo **sample, int use_subsamples)
6417 {
6418     int i, ret;
6419     unsigned int subsample_count;
6420     AVSubsampleEncryptionInfo *subsamples;
6421 
6422     if (!sc->cenc.default_encrypted_sample) {
6423         av_log(c->fc, AV_LOG_ERROR, "Missing schm or tenc\n");
6424         return AVERROR_INVALIDDATA;
6425     }
6426 
6427     *sample = av_encryption_info_clone(sc->cenc.default_encrypted_sample);
6428     if (!*sample)
6429         return AVERROR(ENOMEM);
6430 
6431     if (sc->cenc.per_sample_iv_size != 0) {
6432         if ((ret = ffio_read_size(pb, (*sample)->iv, sc->cenc.per_sample_iv_size)) < 0) {
6433             av_log(c->fc, AV_LOG_ERROR, "failed to read the initialization vector\n");
6434             av_encryption_info_free(*sample);
6435             *sample = NULL;
6436             return ret;
6437         }
6438     }
6439 
6440     if (use_subsamples) {
6441         subsample_count = avio_rb16(pb);
6442         av_free((*sample)->subsamples);
6443         (*sample)->subsamples = av_calloc(subsample_count, sizeof(*subsamples));
6444         if (!(*sample)->subsamples) {
6445             av_encryption_info_free(*sample);
6446             *sample = NULL;
6447             return AVERROR(ENOMEM);
6448         }
6449 
6450         for (i = 0; i < subsample_count && !pb->eof_reached; i++) {
6451             (*sample)->subsamples[i].bytes_of_clear_data = avio_rb16(pb);
6452             (*sample)->subsamples[i].bytes_of_protected_data = avio_rb32(pb);
6453         }
6454 
6455         if (pb->eof_reached) {
6456             av_log(c->fc, AV_LOG_ERROR, "hit EOF while reading sub-sample encryption info\n");
6457             av_encryption_info_free(*sample);
6458             *sample = NULL;
6459             return AVERROR_INVALIDDATA;
6460         }
6461         (*sample)->subsample_count = subsample_count;
6462     }
6463 
6464     return 0;
6465 }
6466 
mov_read_senc(MOVContext * c,AVIOContext * pb,MOVAtom atom)6467 static int mov_read_senc(MOVContext *c, AVIOContext *pb, MOVAtom atom)
6468 {
6469     AVEncryptionInfo **encrypted_samples;
6470     MOVEncryptionIndex *encryption_index;
6471     MOVStreamContext *sc;
6472     int use_subsamples, ret;
6473     unsigned int sample_count, i, alloc_size = 0;
6474 
6475     ret = get_current_encryption_info(c, &encryption_index, &sc);
6476     if (ret != 1)
6477         return ret;
6478 
6479     if (encryption_index->nb_encrypted_samples) {
6480         // This can happen if we have both saio/saiz and senc atoms.
6481         av_log(c->fc, AV_LOG_DEBUG, "Ignoring duplicate encryption info in senc\n");
6482         return 0;
6483     }
6484 
6485     avio_r8(pb); /* version */
6486     use_subsamples = avio_rb24(pb) & 0x02; /* flags */
6487 
6488     sample_count = avio_rb32(pb);
6489     if (sample_count >= INT_MAX / sizeof(*encrypted_samples))
6490         return AVERROR(ENOMEM);
6491 
6492     for (i = 0; i < sample_count; i++) {
6493         unsigned int min_samples = FFMIN(FFMAX(i + 1, 1024 * 1024), sample_count);
6494         encrypted_samples = av_fast_realloc(encryption_index->encrypted_samples, &alloc_size,
6495                                             min_samples * sizeof(*encrypted_samples));
6496         if (encrypted_samples) {
6497             encryption_index->encrypted_samples = encrypted_samples;
6498 
6499             ret = mov_read_sample_encryption_info(
6500                 c, pb, sc, &encryption_index->encrypted_samples[i], use_subsamples);
6501         } else {
6502             ret = AVERROR(ENOMEM);
6503         }
6504         if (pb->eof_reached) {
6505             av_log(c->fc, AV_LOG_ERROR, "Hit EOF while reading senc\n");
6506             if (ret >= 0)
6507                 av_encryption_info_free(encryption_index->encrypted_samples[i]);
6508             ret = AVERROR_INVALIDDATA;
6509         }
6510 
6511         if (ret < 0) {
6512             for (; i > 0; i--)
6513                 av_encryption_info_free(encryption_index->encrypted_samples[i - 1]);
6514             av_freep(&encryption_index->encrypted_samples);
6515             return ret;
6516         }
6517     }
6518     encryption_index->nb_encrypted_samples = sample_count;
6519 
6520     return 0;
6521 }
6522 
mov_parse_auxiliary_info(MOVContext * c,MOVStreamContext * sc,AVIOContext * pb,MOVEncryptionIndex * encryption_index)6523 static int mov_parse_auxiliary_info(MOVContext *c, MOVStreamContext *sc, AVIOContext *pb, MOVEncryptionIndex *encryption_index)
6524 {
6525     AVEncryptionInfo **sample, **encrypted_samples;
6526     int64_t prev_pos;
6527     size_t sample_count, sample_info_size, i;
6528     int ret = 0;
6529     unsigned int alloc_size = 0;
6530 
6531     if (encryption_index->nb_encrypted_samples)
6532         return 0;
6533     sample_count = encryption_index->auxiliary_info_sample_count;
6534     if (encryption_index->auxiliary_offsets_count != 1) {
6535         av_log(c->fc, AV_LOG_ERROR, "Multiple auxiliary info chunks are not supported\n");
6536         return AVERROR_PATCHWELCOME;
6537     }
6538     if (sample_count >= INT_MAX / sizeof(*encrypted_samples))
6539         return AVERROR(ENOMEM);
6540 
6541     prev_pos = avio_tell(pb);
6542     if (!(pb->seekable & AVIO_SEEKABLE_NORMAL) ||
6543         avio_seek(pb, encryption_index->auxiliary_offsets[0], SEEK_SET) != encryption_index->auxiliary_offsets[0]) {
6544         av_log(c->fc, AV_LOG_INFO, "Failed to seek for auxiliary info, will only parse senc atoms for encryption info\n");
6545         goto finish;
6546     }
6547 
6548     for (i = 0; i < sample_count && !pb->eof_reached; i++) {
6549         unsigned int min_samples = FFMIN(FFMAX(i + 1, 1024 * 1024), sample_count);
6550         encrypted_samples = av_fast_realloc(encryption_index->encrypted_samples, &alloc_size,
6551                                             min_samples * sizeof(*encrypted_samples));
6552         if (!encrypted_samples) {
6553             ret = AVERROR(ENOMEM);
6554             goto finish;
6555         }
6556         encryption_index->encrypted_samples = encrypted_samples;
6557 
6558         sample = &encryption_index->encrypted_samples[i];
6559         sample_info_size = encryption_index->auxiliary_info_default_size
6560                                ? encryption_index->auxiliary_info_default_size
6561                                : encryption_index->auxiliary_info_sizes[i];
6562 
6563         ret = mov_read_sample_encryption_info(c, pb, sc, sample, sample_info_size > sc->cenc.per_sample_iv_size);
6564         if (ret < 0)
6565             goto finish;
6566     }
6567     if (pb->eof_reached) {
6568         av_log(c->fc, AV_LOG_ERROR, "Hit EOF while reading auxiliary info\n");
6569         ret = AVERROR_INVALIDDATA;
6570     } else {
6571         encryption_index->nb_encrypted_samples = sample_count;
6572     }
6573 
6574 finish:
6575     avio_seek(pb, prev_pos, SEEK_SET);
6576     if (ret < 0) {
6577         for (; i > 0; i--) {
6578             av_encryption_info_free(encryption_index->encrypted_samples[i - 1]);
6579         }
6580         av_freep(&encryption_index->encrypted_samples);
6581     }
6582     return ret;
6583 }
6584 
6585 /**
6586  * Tries to read the given number of bytes from the stream and puts it in a
6587  * newly allocated buffer.  This reads in small chunks to avoid allocating large
6588  * memory if the file contains an invalid/malicious size value.
6589  */
mov_try_read_block(AVIOContext * pb,size_t size,uint8_t ** data)6590 static int mov_try_read_block(AVIOContext *pb, size_t size, uint8_t **data)
6591 {
6592     const unsigned int block_size = 1024 * 1024;
6593     uint8_t *buffer = NULL;
6594     unsigned int alloc_size = 0, offset = 0;
6595     while (offset < size) {
6596         unsigned int new_size =
6597             alloc_size >= INT_MAX - block_size ? INT_MAX : alloc_size + block_size;
6598         uint8_t *new_buffer = av_fast_realloc(buffer, &alloc_size, new_size);
6599         unsigned int to_read = FFMIN(size, alloc_size) - offset;
6600         if (!new_buffer) {
6601             av_free(buffer);
6602             return AVERROR(ENOMEM);
6603         }
6604         buffer = new_buffer;
6605 
6606         if (avio_read(pb, buffer + offset, to_read) != to_read) {
6607             av_free(buffer);
6608             return AVERROR_INVALIDDATA;
6609         }
6610         offset += to_read;
6611     }
6612 
6613     *data = buffer;
6614     return 0;
6615 }
6616 
mov_read_saiz(MOVContext * c,AVIOContext * pb,MOVAtom atom)6617 static int mov_read_saiz(MOVContext *c, AVIOContext *pb, MOVAtom atom)
6618 {
6619     MOVEncryptionIndex *encryption_index;
6620     MOVStreamContext *sc;
6621     int ret;
6622     unsigned int sample_count, aux_info_type, aux_info_param;
6623 
6624     ret = get_current_encryption_info(c, &encryption_index, &sc);
6625     if (ret != 1)
6626         return ret;
6627 
6628     if (encryption_index->nb_encrypted_samples) {
6629         // This can happen if we have both saio/saiz and senc atoms.
6630         av_log(c->fc, AV_LOG_DEBUG, "Ignoring duplicate encryption info in saiz\n");
6631         return 0;
6632     }
6633 
6634     if (encryption_index->auxiliary_info_sample_count) {
6635         av_log(c->fc, AV_LOG_ERROR, "Duplicate saiz atom\n");
6636         return AVERROR_INVALIDDATA;
6637     }
6638 
6639     avio_r8(pb); /* version */
6640     if (avio_rb24(pb) & 0x01) {  /* flags */
6641         aux_info_type = avio_rb32(pb);
6642         aux_info_param = avio_rb32(pb);
6643         if (sc->cenc.default_encrypted_sample) {
6644             if (aux_info_type != sc->cenc.default_encrypted_sample->scheme) {
6645                 av_log(c->fc, AV_LOG_DEBUG, "Ignoring saiz box with non-zero aux_info_type\n");
6646                 return 0;
6647             }
6648             if (aux_info_param != 0) {
6649                 av_log(c->fc, AV_LOG_DEBUG, "Ignoring saiz box with non-zero aux_info_type_parameter\n");
6650                 return 0;
6651             }
6652         } else {
6653             // Didn't see 'schm' or 'tenc', so this isn't encrypted.
6654             if ((aux_info_type == MKBETAG('c','e','n','c') ||
6655                  aux_info_type == MKBETAG('c','e','n','s') ||
6656                  aux_info_type == MKBETAG('c','b','c','1') ||
6657                  aux_info_type == MKBETAG('c','b','c','s')) &&
6658                 aux_info_param == 0) {
6659                 av_log(c->fc, AV_LOG_ERROR, "Saw encrypted saiz without schm/tenc\n");
6660                 return AVERROR_INVALIDDATA;
6661             } else {
6662                 return 0;
6663             }
6664         }
6665     } else if (!sc->cenc.default_encrypted_sample) {
6666         // Didn't see 'schm' or 'tenc', so this isn't encrypted.
6667         return 0;
6668     }
6669 
6670     encryption_index->auxiliary_info_default_size = avio_r8(pb);
6671     sample_count = avio_rb32(pb);
6672     encryption_index->auxiliary_info_sample_count = sample_count;
6673 
6674     if (encryption_index->auxiliary_info_default_size == 0) {
6675         ret = mov_try_read_block(pb, sample_count, &encryption_index->auxiliary_info_sizes);
6676         if (ret < 0) {
6677             av_log(c->fc, AV_LOG_ERROR, "Failed to read the auxiliary info\n");
6678             return ret;
6679         }
6680     }
6681 
6682     if (encryption_index->auxiliary_offsets_count) {
6683         return mov_parse_auxiliary_info(c, sc, pb, encryption_index);
6684     }
6685 
6686     return 0;
6687 }
6688 
mov_read_saio(MOVContext * c,AVIOContext * pb,MOVAtom atom)6689 static int mov_read_saio(MOVContext *c, AVIOContext *pb, MOVAtom atom)
6690 {
6691     uint64_t *auxiliary_offsets;
6692     MOVEncryptionIndex *encryption_index;
6693     MOVStreamContext *sc;
6694     int i, ret;
6695     unsigned int version, entry_count, aux_info_type, aux_info_param;
6696     unsigned int alloc_size = 0;
6697 
6698     ret = get_current_encryption_info(c, &encryption_index, &sc);
6699     if (ret != 1)
6700         return ret;
6701 
6702     if (encryption_index->nb_encrypted_samples) {
6703         // This can happen if we have both saio/saiz and senc atoms.
6704         av_log(c->fc, AV_LOG_DEBUG, "Ignoring duplicate encryption info in saio\n");
6705         return 0;
6706     }
6707 
6708     if (encryption_index->auxiliary_offsets_count) {
6709         av_log(c->fc, AV_LOG_ERROR, "Duplicate saio atom\n");
6710         return AVERROR_INVALIDDATA;
6711     }
6712 
6713     version = avio_r8(pb); /* version */
6714     if (avio_rb24(pb) & 0x01) {  /* flags */
6715         aux_info_type = avio_rb32(pb);
6716         aux_info_param = avio_rb32(pb);
6717         if (sc->cenc.default_encrypted_sample) {
6718             if (aux_info_type != sc->cenc.default_encrypted_sample->scheme) {
6719                 av_log(c->fc, AV_LOG_DEBUG, "Ignoring saio box with non-zero aux_info_type\n");
6720                 return 0;
6721             }
6722             if (aux_info_param != 0) {
6723                 av_log(c->fc, AV_LOG_DEBUG, "Ignoring saio box with non-zero aux_info_type_parameter\n");
6724                 return 0;
6725             }
6726         } else {
6727             // Didn't see 'schm' or 'tenc', so this isn't encrypted.
6728             if ((aux_info_type == MKBETAG('c','e','n','c') ||
6729                  aux_info_type == MKBETAG('c','e','n','s') ||
6730                  aux_info_type == MKBETAG('c','b','c','1') ||
6731                  aux_info_type == MKBETAG('c','b','c','s')) &&
6732                 aux_info_param == 0) {
6733                 av_log(c->fc, AV_LOG_ERROR, "Saw encrypted saio without schm/tenc\n");
6734                 return AVERROR_INVALIDDATA;
6735             } else {
6736                 return 0;
6737             }
6738         }
6739     } else if (!sc->cenc.default_encrypted_sample) {
6740         // Didn't see 'schm' or 'tenc', so this isn't encrypted.
6741         return 0;
6742     }
6743 
6744     entry_count = avio_rb32(pb);
6745     if (entry_count >= INT_MAX / sizeof(*auxiliary_offsets))
6746         return AVERROR(ENOMEM);
6747 
6748     for (i = 0; i < entry_count && !pb->eof_reached; i++) {
6749         unsigned int min_offsets = FFMIN(FFMAX(i + 1, 1024), entry_count);
6750         auxiliary_offsets = av_fast_realloc(
6751             encryption_index->auxiliary_offsets, &alloc_size,
6752             min_offsets * sizeof(*auxiliary_offsets));
6753         if (!auxiliary_offsets) {
6754             av_freep(&encryption_index->auxiliary_offsets);
6755             return AVERROR(ENOMEM);
6756         }
6757         encryption_index->auxiliary_offsets = auxiliary_offsets;
6758 
6759         if (version == 0) {
6760             encryption_index->auxiliary_offsets[i] = avio_rb32(pb);
6761         } else {
6762             encryption_index->auxiliary_offsets[i] = avio_rb64(pb);
6763         }
6764         if (c->frag_index.current >= 0) {
6765             encryption_index->auxiliary_offsets[i] += c->fragment.base_data_offset;
6766         }
6767     }
6768 
6769     if (pb->eof_reached) {
6770         av_log(c->fc, AV_LOG_ERROR, "Hit EOF while reading saio\n");
6771         av_freep(&encryption_index->auxiliary_offsets);
6772         return AVERROR_INVALIDDATA;
6773     }
6774 
6775     encryption_index->auxiliary_offsets_count = entry_count;
6776 
6777     if (encryption_index->auxiliary_info_sample_count) {
6778         return mov_parse_auxiliary_info(c, sc, pb, encryption_index);
6779     }
6780 
6781     return 0;
6782 }
6783 
6784 #ifdef OHOS_DRM
mov_set_drm_info(const uint8_t * pssh_buf,uint32_t pssh_buf_size,AV_DrmInfo * side_data)6785 static int mov_set_drm_info(const uint8_t *pssh_buf, uint32_t pssh_buf_size, AV_DrmInfo *side_data)
6786 {
6787     if (pssh_buf_size < (AV_DRM_UUID_OFFSET + AV_DRM_MAX_DRM_UUID_LEN)) {
6788         return AVERROR_INVALIDDATA;
6789     }
6790     side_data->uuid_len = AV_DRM_MAX_DRM_UUID_LEN;
6791     memcpy(side_data->uuid, pssh_buf + AV_DRM_UUID_OFFSET, AV_DRM_MAX_DRM_UUID_LEN);
6792     side_data->pssh_len = pssh_buf_size;
6793     memcpy(side_data->pssh, pssh_buf, pssh_buf_size);
6794     return 0;
6795 }
6796 
mov_is_exist_pssh(const AV_DrmInfo * old_side_data,uint32_t count,AV_DrmInfo side_data_node)6797 static int mov_is_exist_pssh(const AV_DrmInfo *old_side_data, uint32_t count, AV_DrmInfo side_data_node)
6798 {
6799     uint32_t i = 0;
6800     if (count == 0) {
6801         return 0;
6802     }
6803     for (; i < count; i++) {
6804         if ((old_side_data[i].pssh_len == side_data_node.pssh_len) &&
6805             (old_side_data[i].uuid_len == side_data_node.uuid_len)) {
6806             if ((memcmp(old_side_data[i].pssh, side_data_node.pssh, old_side_data[i].pssh_len) == 0) &&
6807                 (memcmp(old_side_data[i].uuid, side_data_node.uuid, old_side_data[i].uuid_len) == 0)) {
6808                 return 1;
6809             }
6810         }
6811     }
6812     return 0;
6813 }
6814 
mov_copy_drm_info(AV_DrmInfo * new_side_data,const AV_DrmInfo * old_side_data,uint32_t old_side_data_count,AV_DrmInfo side_data_node)6815 static void mov_copy_drm_info(AV_DrmInfo *new_side_data, const AV_DrmInfo *old_side_data,
6816     uint32_t old_side_data_count, AV_DrmInfo side_data_node)
6817 {
6818     uint32_t i = 0;
6819     for (; i < old_side_data_count; i++) {
6820         new_side_data[i].uuid_len = old_side_data[i].uuid_len;
6821         memcpy(new_side_data[i].uuid, old_side_data[i].uuid, old_side_data[i].uuid_len);
6822         new_side_data[i].pssh_len = old_side_data[i].pssh_len;
6823         memcpy(new_side_data[i].pssh, old_side_data[i].pssh, old_side_data[i].pssh_len);
6824     }
6825     new_side_data[i].uuid_len = side_data_node.uuid_len;
6826     memcpy(new_side_data[i].uuid, side_data_node.uuid, side_data_node.uuid_len);
6827     new_side_data[i].pssh_len = side_data_node.pssh_len;
6828     memcpy(new_side_data[i].pssh, side_data_node.pssh, side_data_node.pssh_len);
6829     return;
6830 }
6831 
mov_read_pssh_ex(MOVContext * c,AVIOContext * pb,MOVAtom atom)6832 static int mov_read_pssh_ex(MOVContext *c, AVIOContext *pb, MOVAtom atom)
6833 {
6834     int ret = 0;
6835     AVStream *st;
6836     AV_DrmInfo side_data_node;
6837     AV_DrmInfo *old_side_data = NULL;
6838     AV_DrmInfo *new_side_data = NULL;
6839     uint8_t pssh_buf[AV_DRM_MAX_DRM_PSSH_LEN];
6840     size_t old_side_data_size = 0;
6841     uint32_t old_side_data_count = 0;
6842     int pssh_exist_flag = 0;
6843     if ((c == NULL) || (c->fc == NULL) || (c->fc->nb_streams < 1) || (c->fc->streams == NULL) || (pb == NULL) ||
6844         (atom.size > (AV_DRM_MAX_DRM_PSSH_LEN - MOV_DRM_PSSH_TITLE_LEN)) || (atom.size <= 0)) {
6845         return 0;
6846     }
6847     st = c->fc->streams[c->fc->nb_streams-1];
6848     if (st == NULL) {
6849         return 0;
6850     }
6851 
6852     memset(pssh_buf, 0, sizeof(pssh_buf));
6853     AV_WB32(pssh_buf, (atom.size + MOV_DRM_PSSH_TITLE_LEN));
6854     memcpy(pssh_buf + sizeof(uint32_t), g_pssh_title_buf, sizeof(g_pssh_title_buf));
6855 
6856     if ((ret = ffio_read_size(pb, pssh_buf + MOV_DRM_PSSH_TITLE_LEN, atom.size)) < 0) {
6857         av_log(c->fc, AV_LOG_ERROR, "Failed to read the pssh data\n");
6858         return 0;
6859     }
6860     if ((ret = mov_set_drm_info(pssh_buf, (uint32_t)(atom.size + MOV_DRM_PSSH_TITLE_LEN), &side_data_node)) != 0) {
6861         av_log(c->fc, AV_LOG_ERROR, "Failed to set drm info\n");
6862         return 0;
6863     }
6864 
6865     old_side_data = (AV_DrmInfo *)av_stream_get_side_data(st, AV_PKT_DATA_ENCRYPTION_INIT_INFO, &old_side_data_size);
6866     if ((old_side_data != NULL) && (old_side_data_size != 0)) {
6867         old_side_data_count = old_side_data_size / sizeof(AV_DrmInfo);
6868         pssh_exist_flag = mov_is_exist_pssh(old_side_data, old_side_data_count, side_data_node);
6869     }
6870     if (pssh_exist_flag == 0) {
6871         new_side_data = (AV_DrmInfo *)av_mallocz(sizeof(AV_DrmInfo) * (old_side_data_count + 1));
6872         if (new_side_data != NULL) {
6873             mov_copy_drm_info(new_side_data, old_side_data, old_side_data_count, side_data_node);
6874             ret = av_stream_add_side_data(st, AV_PKT_DATA_ENCRYPTION_INIT_INFO, (uint8_t *)new_side_data,
6875                 (size_t)(sizeof(AV_DrmInfo) * (old_side_data_count + 1)));
6876             if (ret < 0)
6877                 av_free(new_side_data);
6878         }
6879     }
6880     return 0;
6881 }
6882 #endif
6883 
mov_read_pssh(MOVContext * c,AVIOContext * pb,MOVAtom atom)6884 static int mov_read_pssh(MOVContext *c, AVIOContext *pb, MOVAtom atom)
6885 {
6886     AVEncryptionInitInfo *info, *old_init_info;
6887     uint8_t **key_ids;
6888     AVStream *st;
6889     uint8_t *side_data, *extra_data, *old_side_data;
6890     size_t side_data_size, old_side_data_size;
6891     int ret = 0;
6892     unsigned int version, kid_count, extra_data_size, alloc_size = 0;
6893 
6894     if (c->fc->nb_streams < 1)
6895         return 0;
6896     st = c->fc->streams[c->fc->nb_streams-1];
6897 
6898     version = avio_r8(pb); /* version */
6899     avio_rb24(pb);  /* flags */
6900 
6901     info = av_encryption_init_info_alloc(/* system_id_size */ 16, /* num_key_ids */ 0,
6902                                          /* key_id_size */ 16, /* data_size */ 0);
6903     if (!info)
6904         return AVERROR(ENOMEM);
6905 
6906     if ((ret = ffio_read_size(pb, info->system_id, 16)) < 0) {
6907         av_log(c->fc, AV_LOG_ERROR, "Failed to read the system id\n");
6908         goto finish;
6909     }
6910 
6911     if (version > 0) {
6912         kid_count = avio_rb32(pb);
6913         if (kid_count >= INT_MAX / sizeof(*key_ids)) {
6914             ret = AVERROR(ENOMEM);
6915             goto finish;
6916         }
6917 
6918         for (unsigned int i = 0; i < kid_count && !pb->eof_reached; i++) {
6919             unsigned int min_kid_count = FFMIN(FFMAX(i + 1, 1024), kid_count);
6920             key_ids = av_fast_realloc(info->key_ids, &alloc_size,
6921                                       min_kid_count * sizeof(*key_ids));
6922             if (!key_ids) {
6923                 ret = AVERROR(ENOMEM);
6924                 goto finish;
6925             }
6926             info->key_ids = key_ids;
6927 
6928             info->key_ids[i] = av_mallocz(16);
6929             if (!info->key_ids[i]) {
6930                 ret = AVERROR(ENOMEM);
6931                 goto finish;
6932             }
6933             info->num_key_ids = i + 1;
6934 
6935             if ((ret = ffio_read_size(pb, info->key_ids[i], 16)) < 0) {
6936                 av_log(c->fc, AV_LOG_ERROR, "Failed to read the key id\n");
6937                 goto finish;
6938             }
6939         }
6940 
6941         if (pb->eof_reached) {
6942             av_log(c->fc, AV_LOG_ERROR, "Hit EOF while reading pssh\n");
6943             ret = AVERROR_INVALIDDATA;
6944             goto finish;
6945         }
6946     }
6947 
6948     extra_data_size = avio_rb32(pb);
6949     ret = mov_try_read_block(pb, extra_data_size, &extra_data);
6950     if (ret < 0)
6951         goto finish;
6952 
6953     av_freep(&info->data);  // malloc(0) may still allocate something.
6954     info->data = extra_data;
6955     info->data_size = extra_data_size;
6956 
6957     // If there is existing initialization data, append to the list.
6958     old_side_data = av_stream_get_side_data(st, AV_PKT_DATA_ENCRYPTION_INIT_INFO, &old_side_data_size);
6959     if (old_side_data) {
6960         old_init_info = av_encryption_init_info_get_side_data(old_side_data, old_side_data_size);
6961         if (old_init_info) {
6962             // Append to the end of the list.
6963             for (AVEncryptionInitInfo *cur = old_init_info;; cur = cur->next) {
6964                 if (!cur->next) {
6965                     cur->next = info;
6966                     break;
6967                 }
6968             }
6969             info = old_init_info;
6970         } else {
6971             // Assume existing side-data will be valid, so the only error we could get is OOM.
6972             ret = AVERROR(ENOMEM);
6973             goto finish;
6974         }
6975     }
6976 
6977     side_data = av_encryption_init_info_add_side_data(info, &side_data_size);
6978     if (!side_data) {
6979         ret = AVERROR(ENOMEM);
6980         goto finish;
6981     }
6982     ret = av_stream_add_side_data(st, AV_PKT_DATA_ENCRYPTION_INIT_INFO,
6983                                   side_data, side_data_size);
6984     if (ret < 0)
6985         av_free(side_data);
6986 
6987 finish:
6988     av_encryption_init_info_free(info);
6989     return ret;
6990 }
6991 
mov_read_schm(MOVContext * c,AVIOContext * pb,MOVAtom atom)6992 static int mov_read_schm(MOVContext *c, AVIOContext *pb, MOVAtom atom)
6993 {
6994     AVStream *st;
6995     MOVStreamContext *sc;
6996 
6997     if (c->fc->nb_streams < 1)
6998         return 0;
6999     st = c->fc->streams[c->fc->nb_streams-1];
7000     sc = st->priv_data;
7001 
7002     if (sc->pseudo_stream_id != 0) {
7003         av_log(c->fc, AV_LOG_ERROR, "schm boxes are only supported in first sample descriptor\n");
7004         return AVERROR_PATCHWELCOME;
7005     }
7006 
7007     if (atom.size < 8)
7008         return AVERROR_INVALIDDATA;
7009 
7010     avio_rb32(pb); /* version and flags */
7011 
7012     if (!sc->cenc.default_encrypted_sample) {
7013         sc->cenc.default_encrypted_sample = av_encryption_info_alloc(0, 16, 16);
7014         if (!sc->cenc.default_encrypted_sample) {
7015             return AVERROR(ENOMEM);
7016         }
7017     }
7018 
7019     sc->cenc.default_encrypted_sample->scheme = avio_rb32(pb);
7020     return 0;
7021 }
7022 
mov_read_tenc(MOVContext * c,AVIOContext * pb,MOVAtom atom)7023 static int mov_read_tenc(MOVContext *c, AVIOContext *pb, MOVAtom atom)
7024 {
7025     AVStream *st;
7026     MOVStreamContext *sc;
7027     unsigned int version, pattern, is_protected, iv_size;
7028 
7029     if (c->fc->nb_streams < 1)
7030         return 0;
7031     st = c->fc->streams[c->fc->nb_streams-1];
7032     sc = st->priv_data;
7033 
7034     if (sc->pseudo_stream_id != 0) {
7035         av_log(c->fc, AV_LOG_ERROR, "tenc atom are only supported in first sample descriptor\n");
7036         return AVERROR_PATCHWELCOME;
7037     }
7038 
7039     if (!sc->cenc.default_encrypted_sample) {
7040         sc->cenc.default_encrypted_sample = av_encryption_info_alloc(0, 16, 16);
7041         if (!sc->cenc.default_encrypted_sample) {
7042             return AVERROR(ENOMEM);
7043         }
7044     }
7045 
7046     if (atom.size < 20)
7047         return AVERROR_INVALIDDATA;
7048 
7049     version = avio_r8(pb); /* version */
7050     avio_rb24(pb); /* flags */
7051 
7052     avio_r8(pb); /* reserved */
7053     pattern = avio_r8(pb);
7054 
7055     if (version > 0) {
7056         sc->cenc.default_encrypted_sample->crypt_byte_block = pattern >> 4;
7057         sc->cenc.default_encrypted_sample->skip_byte_block = pattern & 0xf;
7058     }
7059 
7060     is_protected = avio_r8(pb);
7061     if (is_protected && !sc->cenc.encryption_index) {
7062         // The whole stream should be by-default encrypted.
7063         sc->cenc.encryption_index = av_mallocz(sizeof(MOVEncryptionIndex));
7064         if (!sc->cenc.encryption_index)
7065             return AVERROR(ENOMEM);
7066     }
7067     sc->cenc.per_sample_iv_size = avio_r8(pb);
7068     if (sc->cenc.per_sample_iv_size != 0 && sc->cenc.per_sample_iv_size != 8 &&
7069         sc->cenc.per_sample_iv_size != 16) {
7070         av_log(c->fc, AV_LOG_ERROR, "invalid per-sample IV size value\n");
7071         return AVERROR_INVALIDDATA;
7072     }
7073     if (avio_read(pb, sc->cenc.default_encrypted_sample->key_id, 16) != 16) {
7074         av_log(c->fc, AV_LOG_ERROR, "failed to read the default key ID\n");
7075         return AVERROR_INVALIDDATA;
7076     }
7077 
7078     if (is_protected && !sc->cenc.per_sample_iv_size) {
7079         iv_size = avio_r8(pb);
7080         if (iv_size != 8 && iv_size != 16) {
7081             av_log(c->fc, AV_LOG_ERROR, "invalid default_constant_IV_size in tenc atom\n");
7082             return AVERROR_INVALIDDATA;
7083         }
7084 
7085         if (avio_read(pb, sc->cenc.default_encrypted_sample->iv, iv_size) != iv_size) {
7086             av_log(c->fc, AV_LOG_ERROR, "failed to read the default IV\n");
7087             return AVERROR_INVALIDDATA;
7088         }
7089     }
7090 
7091     return 0;
7092 }
7093 
mov_read_dfla(MOVContext * c,AVIOContext * pb,MOVAtom atom)7094 static int mov_read_dfla(MOVContext *c, AVIOContext *pb, MOVAtom atom)
7095 {
7096     AVStream *st;
7097     int last, type, size, ret;
7098     uint8_t buf[4];
7099 
7100     if (c->fc->nb_streams < 1)
7101         return 0;
7102     st = c->fc->streams[c->fc->nb_streams-1];
7103 
7104     if ((uint64_t)atom.size > (1<<30) || atom.size < 42)
7105         return AVERROR_INVALIDDATA;
7106 
7107     /* Check FlacSpecificBox version. */
7108     if (avio_r8(pb) != 0)
7109         return AVERROR_INVALIDDATA;
7110 
7111     avio_rb24(pb); /* Flags */
7112 
7113     if (avio_read(pb, buf, sizeof(buf)) != sizeof(buf)) {
7114         av_log(c->fc, AV_LOG_ERROR, "failed to read FLAC metadata block header\n");
7115         return pb->error < 0 ? pb->error : AVERROR_INVALIDDATA;
7116     }
7117     flac_parse_block_header(buf, &last, &type, &size);
7118 
7119     if (type != FLAC_METADATA_TYPE_STREAMINFO || size != FLAC_STREAMINFO_SIZE) {
7120         av_log(c->fc, AV_LOG_ERROR, "STREAMINFO must be first FLACMetadataBlock\n");
7121         return AVERROR_INVALIDDATA;
7122     }
7123 
7124     ret = ff_get_extradata(c->fc, st->codecpar, pb, size);
7125     if (ret < 0)
7126         return ret;
7127 
7128     if (!last)
7129         av_log(c->fc, AV_LOG_WARNING, "non-STREAMINFO FLACMetadataBlock(s) ignored\n");
7130 
7131     return 0;
7132 }
7133 
cenc_scheme_decrypt(MOVContext * c,MOVStreamContext * sc,AVEncryptionInfo * sample,uint8_t * input,int size)7134 static int cenc_scheme_decrypt(MOVContext *c, MOVStreamContext *sc, AVEncryptionInfo *sample, uint8_t *input, int size)
7135 {
7136     int i, ret;
7137     int bytes_of_protected_data;
7138 
7139     if (!sc->cenc.aes_ctr) {
7140         /* initialize the cipher */
7141         sc->cenc.aes_ctr = av_aes_ctr_alloc();
7142         if (!sc->cenc.aes_ctr) {
7143             return AVERROR(ENOMEM);
7144         }
7145 
7146         ret = av_aes_ctr_init(sc->cenc.aes_ctr, c->decryption_key);
7147         if (ret < 0) {
7148             return ret;
7149         }
7150     }
7151 
7152     av_aes_ctr_set_full_iv(sc->cenc.aes_ctr, sample->iv);
7153 
7154     if (!sample->subsample_count) {
7155         /* decrypt the whole packet */
7156         av_aes_ctr_crypt(sc->cenc.aes_ctr, input, input, size);
7157         return 0;
7158     }
7159 
7160     for (i = 0; i < sample->subsample_count; i++) {
7161         if (sample->subsamples[i].bytes_of_clear_data + sample->subsamples[i].bytes_of_protected_data > size) {
7162             av_log(c->fc, AV_LOG_ERROR, "subsample size exceeds the packet size left\n");
7163             return AVERROR_INVALIDDATA;
7164         }
7165 
7166         /* skip the clear bytes */
7167         input += sample->subsamples[i].bytes_of_clear_data;
7168         size -= sample->subsamples[i].bytes_of_clear_data;
7169 
7170         /* decrypt the encrypted bytes */
7171 
7172         bytes_of_protected_data = sample->subsamples[i].bytes_of_protected_data;
7173         av_aes_ctr_crypt(sc->cenc.aes_ctr, input, input, bytes_of_protected_data);
7174 
7175         input += bytes_of_protected_data;
7176         size -= bytes_of_protected_data;
7177     }
7178 
7179     if (size > 0) {
7180         av_log(c->fc, AV_LOG_ERROR, "leftover packet bytes after subsample processing\n");
7181         return AVERROR_INVALIDDATA;
7182     }
7183 
7184     return 0;
7185 }
7186 
cbc1_scheme_decrypt(MOVContext * c,MOVStreamContext * sc,AVEncryptionInfo * sample,uint8_t * input,int size)7187 static int cbc1_scheme_decrypt(MOVContext *c, MOVStreamContext *sc, AVEncryptionInfo *sample, uint8_t *input, int size)
7188 {
7189     int i, ret;
7190     int num_of_encrypted_blocks;
7191     uint8_t iv[16];
7192 
7193     if (!sc->cenc.aes_ctx) {
7194         /* initialize the cipher */
7195         sc->cenc.aes_ctx = av_aes_alloc();
7196         if (!sc->cenc.aes_ctx) {
7197             return AVERROR(ENOMEM);
7198         }
7199 
7200         ret = av_aes_init(sc->cenc.aes_ctx, c->decryption_key, 16 * 8, 1);
7201         if (ret < 0) {
7202             return ret;
7203         }
7204     }
7205 
7206     memcpy(iv, sample->iv, 16);
7207 
7208     /* whole-block full sample encryption */
7209     if (!sample->subsample_count) {
7210         /* decrypt the whole packet */
7211         av_aes_crypt(sc->cenc.aes_ctx, input, input, size/16, iv, 1);
7212         return 0;
7213     }
7214 
7215     for (i = 0; i < sample->subsample_count; i++) {
7216         if (sample->subsamples[i].bytes_of_clear_data + sample->subsamples[i].bytes_of_protected_data > size) {
7217             av_log(c->fc, AV_LOG_ERROR, "subsample size exceeds the packet size left\n");
7218             return AVERROR_INVALIDDATA;
7219         }
7220 
7221         if (sample->subsamples[i].bytes_of_protected_data % 16) {
7222             av_log(c->fc, AV_LOG_ERROR, "subsample BytesOfProtectedData is not a multiple of 16\n");
7223             return AVERROR_INVALIDDATA;
7224         }
7225 
7226         /* skip the clear bytes */
7227         input += sample->subsamples[i].bytes_of_clear_data;
7228         size -= sample->subsamples[i].bytes_of_clear_data;
7229 
7230         /* decrypt the encrypted bytes */
7231         num_of_encrypted_blocks = sample->subsamples[i].bytes_of_protected_data/16;
7232         if (num_of_encrypted_blocks > 0) {
7233             av_aes_crypt(sc->cenc.aes_ctx, input, input, num_of_encrypted_blocks, iv, 1);
7234         }
7235         input += sample->subsamples[i].bytes_of_protected_data;
7236         size -= sample->subsamples[i].bytes_of_protected_data;
7237     }
7238 
7239     if (size > 0) {
7240         av_log(c->fc, AV_LOG_ERROR, "leftover packet bytes after subsample processing\n");
7241         return AVERROR_INVALIDDATA;
7242     }
7243 
7244     return 0;
7245 }
7246 
cens_scheme_decrypt(MOVContext * c,MOVStreamContext * sc,AVEncryptionInfo * sample,uint8_t * input,int size)7247 static int cens_scheme_decrypt(MOVContext *c, MOVStreamContext *sc, AVEncryptionInfo *sample, uint8_t *input, int size)
7248 {
7249     int i, ret, rem_bytes;
7250     uint8_t *data;
7251 
7252     if (!sc->cenc.aes_ctr) {
7253         /* initialize the cipher */
7254         sc->cenc.aes_ctr = av_aes_ctr_alloc();
7255         if (!sc->cenc.aes_ctr) {
7256             return AVERROR(ENOMEM);
7257         }
7258 
7259         ret = av_aes_ctr_init(sc->cenc.aes_ctr, c->decryption_key);
7260         if (ret < 0) {
7261             return ret;
7262         }
7263     }
7264 
7265     av_aes_ctr_set_full_iv(sc->cenc.aes_ctr, sample->iv);
7266 
7267     /* whole-block full sample encryption */
7268     if (!sample->subsample_count) {
7269         /* decrypt the whole packet */
7270         av_aes_ctr_crypt(sc->cenc.aes_ctr, input, input, size);
7271         return 0;
7272     } else if (!sample->crypt_byte_block && !sample->skip_byte_block) {
7273         av_log(c->fc, AV_LOG_ERROR, "pattern encryption is not present in 'cens' scheme\n");
7274         return AVERROR_INVALIDDATA;
7275     }
7276 
7277     for (i = 0; i < sample->subsample_count; i++) {
7278         if (sample->subsamples[i].bytes_of_clear_data + sample->subsamples[i].bytes_of_protected_data > size) {
7279             av_log(c->fc, AV_LOG_ERROR, "subsample size exceeds the packet size left\n");
7280             return AVERROR_INVALIDDATA;
7281         }
7282 
7283         /* skip the clear bytes */
7284         input += sample->subsamples[i].bytes_of_clear_data;
7285         size -= sample->subsamples[i].bytes_of_clear_data;
7286 
7287         /* decrypt the encrypted bytes */
7288         data = input;
7289         rem_bytes = sample->subsamples[i].bytes_of_protected_data;
7290         while (rem_bytes > 0) {
7291             if (rem_bytes < 16*sample->crypt_byte_block) {
7292                 break;
7293             }
7294             av_aes_ctr_crypt(sc->cenc.aes_ctr, data, data, 16*sample->crypt_byte_block);
7295             data += 16*sample->crypt_byte_block;
7296             rem_bytes -= 16*sample->crypt_byte_block;
7297             data += FFMIN(16*sample->skip_byte_block, rem_bytes);
7298             rem_bytes -= FFMIN(16*sample->skip_byte_block, rem_bytes);
7299         }
7300         input += sample->subsamples[i].bytes_of_protected_data;
7301         size -= sample->subsamples[i].bytes_of_protected_data;
7302     }
7303 
7304     if (size > 0) {
7305         av_log(c->fc, AV_LOG_ERROR, "leftover packet bytes after subsample processing\n");
7306         return AVERROR_INVALIDDATA;
7307     }
7308 
7309     return 0;
7310 }
7311 
cbcs_scheme_decrypt(MOVContext * c,MOVStreamContext * sc,AVEncryptionInfo * sample,uint8_t * input,int size)7312 static int cbcs_scheme_decrypt(MOVContext *c, MOVStreamContext *sc, AVEncryptionInfo *sample, uint8_t *input, int size)
7313 {
7314     int i, ret, rem_bytes;
7315     uint8_t iv[16];
7316     uint8_t *data;
7317 
7318     if (!sc->cenc.aes_ctx) {
7319         /* initialize the cipher */
7320         sc->cenc.aes_ctx = av_aes_alloc();
7321         if (!sc->cenc.aes_ctx) {
7322             return AVERROR(ENOMEM);
7323         }
7324 
7325         ret = av_aes_init(sc->cenc.aes_ctx, c->decryption_key, 16 * 8, 1);
7326         if (ret < 0) {
7327             return ret;
7328         }
7329     }
7330 
7331     /* whole-block full sample encryption */
7332     if (!sample->subsample_count) {
7333         /* decrypt the whole packet */
7334         memcpy(iv, sample->iv, 16);
7335         av_aes_crypt(sc->cenc.aes_ctx, input, input, size/16, iv, 1);
7336         return 0;
7337     } else if (!sample->crypt_byte_block && !sample->skip_byte_block) {
7338         av_log(c->fc, AV_LOG_ERROR, "pattern encryption is not present in 'cbcs' scheme\n");
7339         return AVERROR_INVALIDDATA;
7340     }
7341 
7342     for (i = 0; i < sample->subsample_count; i++) {
7343         if (sample->subsamples[i].bytes_of_clear_data + sample->subsamples[i].bytes_of_protected_data > size) {
7344             av_log(c->fc, AV_LOG_ERROR, "subsample size exceeds the packet size left\n");
7345             return AVERROR_INVALIDDATA;
7346         }
7347 
7348         /* skip the clear bytes */
7349         input += sample->subsamples[i].bytes_of_clear_data;
7350         size -= sample->subsamples[i].bytes_of_clear_data;
7351 
7352         /* decrypt the encrypted bytes */
7353         memcpy(iv, sample->iv, 16);
7354         data = input;
7355         rem_bytes = sample->subsamples[i].bytes_of_protected_data;
7356         while (rem_bytes > 0) {
7357             if (rem_bytes < 16*sample->crypt_byte_block) {
7358                 break;
7359             }
7360             av_aes_crypt(sc->cenc.aes_ctx, data, data, sample->crypt_byte_block, iv, 1);
7361             data += 16*sample->crypt_byte_block;
7362             rem_bytes -= 16*sample->crypt_byte_block;
7363             data += FFMIN(16*sample->skip_byte_block, rem_bytes);
7364             rem_bytes -= FFMIN(16*sample->skip_byte_block, rem_bytes);
7365         }
7366         input += sample->subsamples[i].bytes_of_protected_data;
7367         size -= sample->subsamples[i].bytes_of_protected_data;
7368     }
7369 
7370     if (size > 0) {
7371         av_log(c->fc, AV_LOG_ERROR, "leftover packet bytes after subsample processing\n");
7372         return AVERROR_INVALIDDATA;
7373     }
7374 
7375     return 0;
7376 }
7377 
cenc_decrypt(MOVContext * c,MOVStreamContext * sc,AVEncryptionInfo * sample,uint8_t * input,int size)7378 static int cenc_decrypt(MOVContext *c, MOVStreamContext *sc, AVEncryptionInfo *sample, uint8_t *input, int size)
7379 {
7380     if (sample->scheme == MKBETAG('c','e','n','c') && !sample->crypt_byte_block && !sample->skip_byte_block) {
7381         return cenc_scheme_decrypt(c, sc, sample, input, size);
7382     } else if (sample->scheme == MKBETAG('c','b','c','1') && !sample->crypt_byte_block && !sample->skip_byte_block) {
7383         return cbc1_scheme_decrypt(c, sc, sample, input, size);
7384     } else if (sample->scheme == MKBETAG('c','e','n','s')) {
7385         return cens_scheme_decrypt(c, sc, sample, input, size);
7386     } else if (sample->scheme == MKBETAG('c','b','c','s')) {
7387         return cbcs_scheme_decrypt(c, sc, sample, input, size);
7388     } else {
7389         av_log(c->fc, AV_LOG_ERROR, "invalid encryption scheme\n");
7390         return AVERROR_INVALIDDATA;
7391     }
7392 }
7393 
cenc_filter(MOVContext * mov,AVStream * st,MOVStreamContext * sc,AVPacket * pkt,int current_index)7394 static int cenc_filter(MOVContext *mov, AVStream* st, MOVStreamContext *sc, AVPacket *pkt, int current_index)
7395 {
7396     MOVFragmentStreamInfo *frag_stream_info;
7397     MOVEncryptionIndex *encryption_index;
7398     AVEncryptionInfo *encrypted_sample;
7399     int encrypted_index, ret;
7400 
7401     frag_stream_info = get_frag_stream_info(&mov->frag_index, mov->frag_index.current, st->id);
7402     encrypted_index = current_index;
7403     encryption_index = NULL;
7404     if (frag_stream_info) {
7405         // Note this only supports encryption info in the first sample descriptor.
7406         if (mov->fragment.stsd_id == 1) {
7407             if (frag_stream_info->encryption_index) {
7408                 if (!current_index && frag_stream_info->index_entry)
7409                     sc->cenc.frag_index_entry_base = frag_stream_info->index_entry;
7410                 encrypted_index = current_index - (frag_stream_info->index_entry - sc->cenc.frag_index_entry_base);
7411                 encryption_index = frag_stream_info->encryption_index;
7412             } else {
7413                 encryption_index = sc->cenc.encryption_index;
7414             }
7415         }
7416     } else {
7417         encryption_index = sc->cenc.encryption_index;
7418     }
7419 
7420     if (encryption_index) {
7421         if (encryption_index->auxiliary_info_sample_count &&
7422             !encryption_index->nb_encrypted_samples) {
7423             av_log(mov->fc, AV_LOG_ERROR, "saiz atom found without saio\n");
7424             return AVERROR_INVALIDDATA;
7425         }
7426         if (encryption_index->auxiliary_offsets_count &&
7427             !encryption_index->nb_encrypted_samples) {
7428             av_log(mov->fc, AV_LOG_ERROR, "saio atom found without saiz\n");
7429             return AVERROR_INVALIDDATA;
7430         }
7431 
7432         if (!encryption_index->nb_encrypted_samples) {
7433             // Full-sample encryption with default settings.
7434             encrypted_sample = sc->cenc.default_encrypted_sample;
7435         } else if (encrypted_index >= 0 && encrypted_index < encryption_index->nb_encrypted_samples) {
7436             // Per-sample setting override.
7437             encrypted_sample = encryption_index->encrypted_samples[encrypted_index];
7438         } else {
7439             av_log(mov->fc, AV_LOG_ERROR, "Incorrect number of samples in encryption info\n");
7440             return AVERROR_INVALIDDATA;
7441         }
7442 
7443         if (mov->decryption_key) {
7444             return cenc_decrypt(mov, sc, encrypted_sample, pkt->data, pkt->size);
7445         } else {
7446             size_t size;
7447 #ifdef OHOS_DRM
7448             AV_DrmCencInfo *side_data = NULL;
7449             side_data = av_encryption_info_add_side_data_ex(encrypted_sample, &size, side_data, pkt->size);
7450 #else
7451             uint8_t *side_data = av_encryption_info_add_side_data(encrypted_sample, &size);
7452 #endif
7453             if (!side_data)
7454                 return AVERROR(ENOMEM);
7455 #ifdef OHOS_DRM
7456             ret = av_packet_add_side_data(pkt, AV_PKT_DATA_ENCRYPTION_INFO, (uint8_t *)side_data, size);
7457 #else
7458             ret = av_packet_add_side_data(pkt, AV_PKT_DATA_ENCRYPTION_INFO, side_data, size);
7459 #endif
7460             if (ret < 0)
7461                 av_free(side_data);
7462             return ret;
7463         }
7464     }
7465 
7466     return 0;
7467 }
7468 
mov_read_dops(MOVContext * c,AVIOContext * pb,MOVAtom atom)7469 static int mov_read_dops(MOVContext *c, AVIOContext *pb, MOVAtom atom)
7470 {
7471     const int OPUS_SEEK_PREROLL_MS = 80;
7472     int ret;
7473     AVStream *st;
7474     size_t size;
7475     uint16_t pre_skip;
7476 
7477     if (c->fc->nb_streams < 1)
7478         return 0;
7479     st = c->fc->streams[c->fc->nb_streams-1];
7480 
7481     if ((uint64_t)atom.size > (1<<30) || atom.size < 11)
7482         return AVERROR_INVALIDDATA;
7483 
7484     /* Check OpusSpecificBox version. */
7485     if (avio_r8(pb) != 0) {
7486         av_log(c->fc, AV_LOG_ERROR, "unsupported OpusSpecificBox version\n");
7487         return AVERROR_INVALIDDATA;
7488     }
7489 
7490     /* OpusSpecificBox size plus magic for Ogg OpusHead header. */
7491     size = atom.size + 8;
7492 
7493     if ((ret = ff_alloc_extradata(st->codecpar, size)) < 0)
7494         return ret;
7495 
7496     AV_WL32(st->codecpar->extradata, MKTAG('O','p','u','s'));
7497     AV_WL32(st->codecpar->extradata + 4, MKTAG('H','e','a','d'));
7498     AV_WB8(st->codecpar->extradata + 8, 1); /* OpusHead version */
7499     avio_read(pb, st->codecpar->extradata + 9, size - 9);
7500 
7501     /* OpusSpecificBox is stored in big-endian, but OpusHead is
7502        little-endian; aside from the preceeding magic and version they're
7503        otherwise currently identical.  Data after output gain at offset 16
7504        doesn't need to be bytewapped. */
7505     pre_skip = AV_RB16(st->codecpar->extradata + 10);
7506     AV_WL16(st->codecpar->extradata + 10, pre_skip);
7507     AV_WL32(st->codecpar->extradata + 12, AV_RB32(st->codecpar->extradata + 12));
7508     AV_WL16(st->codecpar->extradata + 16, AV_RB16(st->codecpar->extradata + 16));
7509 
7510     st->codecpar->initial_padding = pre_skip;
7511     st->codecpar->seek_preroll = av_rescale_q(OPUS_SEEK_PREROLL_MS,
7512                                               (AVRational){1, 1000},
7513                                               (AVRational){1, 48000});
7514 
7515     return 0;
7516 }
7517 
mov_read_dmlp(MOVContext * c,AVIOContext * pb,MOVAtom atom)7518 static int mov_read_dmlp(MOVContext *c, AVIOContext *pb, MOVAtom atom)
7519 {
7520     AVStream *st;
7521     unsigned format_info;
7522     int channel_assignment, channel_assignment1, channel_assignment2;
7523     int ratebits;
7524     uint64_t chmask;
7525 
7526     if (c->fc->nb_streams < 1)
7527         return 0;
7528     st = c->fc->streams[c->fc->nb_streams-1];
7529 
7530     if (atom.size < 10)
7531         return AVERROR_INVALIDDATA;
7532 
7533     format_info = avio_rb32(pb);
7534 
7535     ratebits            = (format_info >> 28) & 0xF;
7536     channel_assignment1 = (format_info >> 15) & 0x1F;
7537     channel_assignment2 = format_info & 0x1FFF;
7538     if (channel_assignment2)
7539         channel_assignment = channel_assignment2;
7540     else
7541         channel_assignment = channel_assignment1;
7542 
7543     st->codecpar->frame_size = 40 << (ratebits & 0x7);
7544     st->codecpar->sample_rate = mlp_samplerate(ratebits);
7545 
7546     av_channel_layout_uninit(&st->codecpar->ch_layout);
7547     chmask = truehd_layout(channel_assignment);
7548     av_channel_layout_from_mask(&st->codecpar->ch_layout, chmask);
7549 
7550     return 0;
7551 }
7552 
mov_read_dvcc_dvvc(MOVContext * c,AVIOContext * pb,MOVAtom atom)7553 static int mov_read_dvcc_dvvc(MOVContext *c, AVIOContext *pb, MOVAtom atom)
7554 {
7555     AVStream *st;
7556     uint8_t buf[ISOM_DVCC_DVVC_SIZE];
7557     int ret;
7558     int64_t read_size = atom.size;
7559 
7560     if (c->fc->nb_streams < 1)
7561         return 0;
7562     st = c->fc->streams[c->fc->nb_streams-1];
7563 
7564     // At most 24 bytes
7565     read_size = FFMIN(read_size, ISOM_DVCC_DVVC_SIZE);
7566 
7567     if ((ret = ffio_read_size(pb, buf, read_size)) < 0)
7568         return ret;
7569 
7570     return ff_isom_parse_dvcc_dvvc(c->fc, st, buf, read_size);
7571 }
7572 
mov_read_kind(MOVContext * c,AVIOContext * pb,MOVAtom atom)7573 static int mov_read_kind(MOVContext *c, AVIOContext *pb, MOVAtom atom)
7574 {
7575     AVFormatContext *ctx = c->fc;
7576     AVStream *st = NULL;
7577     AVBPrint scheme_buf, value_buf;
7578     int64_t scheme_str_len = 0, value_str_len = 0;
7579     int version, flags, ret = AVERROR_BUG;
7580     int64_t size = atom.size;
7581 
7582     if (atom.size < 6)
7583         // 4 bytes for version + flags, 2x 1 byte for null
7584         return AVERROR_INVALIDDATA;
7585 
7586     if (c->fc->nb_streams < 1)
7587         return 0;
7588     st = c->fc->streams[c->fc->nb_streams-1];
7589 
7590     version = avio_r8(pb);
7591     flags   = avio_rb24(pb);
7592     size   -= 4;
7593 
7594     if (version != 0 || flags != 0) {
7595         av_log(ctx, AV_LOG_ERROR,
7596                "Unsupported 'kind' box with version %d, flags: %x",
7597                version, flags);
7598         return AVERROR_INVALIDDATA;
7599     }
7600 
7601     av_bprint_init(&scheme_buf, 0, AV_BPRINT_SIZE_UNLIMITED);
7602     av_bprint_init(&value_buf,  0, AV_BPRINT_SIZE_UNLIMITED);
7603 
7604     if ((scheme_str_len = ff_read_string_to_bprint_overwrite(pb, &scheme_buf,
7605                                                              size)) < 0) {
7606         ret = scheme_str_len;
7607         goto cleanup;
7608     }
7609 
7610     if (scheme_str_len + 1 >= size) {
7611         // we need to have another string, even if nullptr.
7612         // we check with + 1 since we expect that if size was not hit,
7613         // an additional null was read.
7614         ret = AVERROR_INVALIDDATA;
7615         goto cleanup;
7616     }
7617 
7618     size -= scheme_str_len + 1;
7619 
7620     if ((value_str_len = ff_read_string_to_bprint_overwrite(pb, &value_buf,
7621                                                             size)) < 0) {
7622         ret = value_str_len;
7623         goto cleanup;
7624     }
7625 
7626     if (value_str_len == size) {
7627         // in case of no trailing null, box is not valid.
7628         ret = AVERROR_INVALIDDATA;
7629         goto cleanup;
7630     }
7631 
7632     av_log(ctx, AV_LOG_TRACE,
7633            "%s stream %d KindBox(scheme: %s, value: %s)\n",
7634            av_get_media_type_string(st->codecpar->codec_type),
7635            st->index,
7636            scheme_buf.str, value_buf.str);
7637 
7638     for (int i = 0; ff_mov_track_kind_table[i].scheme_uri; i++) {
7639         const struct MP4TrackKindMapping map = ff_mov_track_kind_table[i];
7640         if (!av_strstart(scheme_buf.str, map.scheme_uri, NULL))
7641             continue;
7642 
7643         for (int j = 0; map.value_maps[j].disposition; j++) {
7644             const struct MP4TrackKindValueMapping value_map = map.value_maps[j];
7645             if (!av_strstart(value_buf.str, value_map.value, NULL))
7646                 continue;
7647 
7648             st->disposition |= value_map.disposition;
7649         }
7650     }
7651 
7652     ret = 0;
7653 
7654 cleanup:
7655 
7656     av_bprint_finalize(&scheme_buf, NULL);
7657     av_bprint_finalize(&value_buf,  NULL);
7658 
7659     return ret;
7660 }
7661 
mov_read_SA3D(MOVContext * c,AVIOContext * pb,MOVAtom atom)7662 static int mov_read_SA3D(MOVContext *c, AVIOContext *pb, MOVAtom atom)
7663 {
7664     AVStream *st;
7665     int i, version, type;
7666     int ambisonic_order, channel_order, normalization, channel_count;
7667 
7668     if (c->fc->nb_streams < 1)
7669         return 0;
7670 
7671     st = c->fc->streams[c->fc->nb_streams - 1];
7672 
7673     if (atom.size < 16) {
7674         av_log(c->fc, AV_LOG_ERROR, "SA3D audio box too small\n");
7675         return AVERROR_INVALIDDATA;
7676     }
7677 
7678     version = avio_r8(pb);
7679     if (version) {
7680         av_log(c->fc, AV_LOG_WARNING, "Unsupported SA3D box version %d\n", version);
7681         return 0;
7682     }
7683 
7684     type = avio_r8(pb);
7685     if (type) {
7686         av_log(c->fc, AV_LOG_WARNING,
7687                "Unsupported ambisonic type %d\n", type);
7688         return 0;
7689     }
7690 
7691     ambisonic_order = avio_rb32(pb);
7692 
7693     channel_order = avio_r8(pb);
7694     if (channel_order) {
7695         av_log(c->fc, AV_LOG_WARNING,
7696                "Unsupported channel_order %d\n", channel_order);
7697         return 0;
7698     }
7699 
7700     normalization = avio_r8(pb);
7701     if (normalization) {
7702         av_log(c->fc, AV_LOG_WARNING,
7703                "Unsupported normalization %d\n", normalization);
7704         return 0;
7705     }
7706 
7707     channel_count = avio_rb32(pb);
7708     if (ambisonic_order < 0 || channel_count != (ambisonic_order + 1LL) * (ambisonic_order + 1LL)) {
7709         av_log(c->fc, AV_LOG_ERROR,
7710                "Invalid number of channels (%d / %d)\n",
7711                channel_count, ambisonic_order);
7712         return 0;
7713     }
7714 
7715     for (i = 0; i < channel_count; i++) {
7716         if (i != avio_rb32(pb)) {
7717             av_log(c->fc, AV_LOG_WARNING,
7718                    "Ambisonic channel reordering is not supported\n");
7719             return 0;
7720         }
7721     }
7722 
7723     av_channel_layout_uninit(&st->codecpar->ch_layout);
7724     st->codecpar->ch_layout.order = AV_CHANNEL_ORDER_AMBISONIC;
7725     st->codecpar->ch_layout.nb_channels = channel_count;
7726 
7727     return 0;
7728 }
7729 
mov_read_SAND(MOVContext * c,AVIOContext * pb,MOVAtom atom)7730 static int mov_read_SAND(MOVContext *c, AVIOContext *pb, MOVAtom atom)
7731 {
7732     AVStream *st;
7733     int version;
7734 
7735     if (c->fc->nb_streams < 1)
7736         return 0;
7737 
7738     st = c->fc->streams[c->fc->nb_streams - 1];
7739 
7740     if (atom.size < 5) {
7741         av_log(c->fc, AV_LOG_ERROR, "Empty SAND audio box\n");
7742         return AVERROR_INVALIDDATA;
7743     }
7744 
7745     version = avio_r8(pb);
7746     if (version) {
7747         av_log(c->fc, AV_LOG_WARNING, "Unsupported SAND box version %d\n", version);
7748         return 0;
7749     }
7750 
7751     st->disposition |= AV_DISPOSITION_NON_DIEGETIC;
7752 
7753     return 0;
7754 }
7755 
rb_size(AVIOContext * pb,uint64_t * value,int size)7756 static int rb_size(AVIOContext *pb, uint64_t* value, int size)
7757 {
7758     if (size == 0)
7759         *value = 0;
7760     else if (size == 1)
7761         *value = avio_r8(pb);
7762     else if (size == 2)
7763         *value = avio_rb16(pb);
7764     else if (size == 4)
7765         *value = avio_rb32(pb);
7766     else if (size == 8)
7767         *value = avio_rb64(pb);
7768     else
7769         return -1;
7770     return size;
7771 }
7772 
mov_read_pitm(MOVContext * c,AVIOContext * pb,MOVAtom atom)7773 static int mov_read_pitm(MOVContext *c, AVIOContext *pb, MOVAtom atom)
7774 {
7775     avio_rb32(pb);  // version & flags.
7776     c->primary_item_id = avio_rb16(pb);
7777     return atom.size;
7778 }
7779 
mov_read_iloc(MOVContext * c,AVIOContext * pb,MOVAtom atom)7780 static int mov_read_iloc(MOVContext *c, AVIOContext *pb, MOVAtom atom)
7781 {
7782     int version, offset_size, length_size, base_offset_size, index_size;
7783     int item_count, extent_count;
7784     uint64_t base_offset, extent_offset, extent_length;
7785     uint8_t value;
7786     AVStream *st;
7787     MOVStreamContext *sc;
7788 
7789     if (!c->is_still_picture_avif) {
7790         // * For non-avif, we simply ignore the iloc box.
7791         // * For animated avif, we don't care about the iloc box as all the
7792         //   necessary information can be found in the moov box.
7793         return 0;
7794     }
7795 
7796     if (c->fc->nb_streams) {
7797         av_log(c->fc, AV_LOG_INFO, "Duplicate iloc box found\n");
7798         return 0;
7799     }
7800 
7801     st = avformat_new_stream(c->fc, NULL);
7802     if (!st)
7803         return AVERROR(ENOMEM);
7804     st->id = c->fc->nb_streams;
7805     sc = av_mallocz(sizeof(MOVStreamContext));
7806     if (!sc)
7807         return AVERROR(ENOMEM);
7808 
7809     st->priv_data = sc;
7810     st->codecpar->codec_type = AVMEDIA_TYPE_VIDEO;
7811     st->codecpar->codec_id = AV_CODEC_ID_AV1;
7812     sc->ffindex = st->index;
7813     c->trak_index = st->index;
7814     st->avg_frame_rate.num = st->avg_frame_rate.den = 1;
7815     st->time_base.num = st->time_base.den = 1;
7816     st->nb_frames = 1;
7817     sc->time_scale = 1;
7818     sc = st->priv_data;
7819     sc->pb = c->fc->pb;
7820     sc->pb_is_copied = 1;
7821 
7822     version = avio_r8(pb);
7823     avio_rb24(pb);  // flags.
7824 
7825     value = avio_r8(pb);
7826     offset_size = (value >> 4) & 0xF;
7827     length_size = value & 0xF;
7828     value = avio_r8(pb);
7829     base_offset_size = (value >> 4) & 0xF;
7830     index_size = !version ? 0 : (value & 0xF);
7831     if (index_size) {
7832         av_log(c->fc, AV_LOG_ERROR, "iloc: index_size != 0 not supported.\n");
7833         return AVERROR_PATCHWELCOME;
7834     }
7835     item_count = (version < 2) ? avio_rb16(pb) : avio_rb32(pb);
7836 
7837     // Populate the necessary fields used by mov_build_index.
7838     sc->stsc_count = 1;
7839     sc->stsc_data = av_malloc_array(1, sizeof(*sc->stsc_data));
7840     if (!sc->stsc_data)
7841         return AVERROR(ENOMEM);
7842     sc->stsc_data[0].first = 1;
7843     sc->stsc_data[0].count = 1;
7844     sc->stsc_data[0].id = 1;
7845     sc->chunk_count = 1;
7846     sc->chunk_offsets = av_malloc_array(1, sizeof(*sc->chunk_offsets));
7847     if (!sc->chunk_offsets)
7848         return AVERROR(ENOMEM);
7849     sc->sample_count = 1;
7850     sc->sample_sizes = av_malloc_array(1, sizeof(*sc->sample_sizes));
7851     if (!sc->sample_sizes)
7852         return AVERROR(ENOMEM);
7853     sc->stts_count = 1;
7854     sc->stts_data = av_malloc_array(1, sizeof(*sc->stts_data));
7855     if (!sc->stts_data)
7856         return AVERROR(ENOMEM);
7857     sc->stts_data[0].count = 1;
7858     // Not used for still images. But needed by mov_build_index.
7859     sc->stts_data[0].duration = 0;
7860 
7861     for (int i = 0; i < item_count; i++) {
7862         int item_id = (version < 2) ? avio_rb16(pb) : avio_rb32(pb);
7863         if (avio_feof(pb))
7864             return AVERROR_INVALIDDATA;
7865         if (version > 0)
7866             avio_rb16(pb);  // construction_method.
7867         avio_rb16(pb);  // data_reference_index.
7868         if (rb_size(pb, &base_offset, base_offset_size) < 0)
7869             return AVERROR_INVALIDDATA;
7870         extent_count = avio_rb16(pb);
7871         if (extent_count > 1) {
7872             // For still AVIF images, we only support one extent item.
7873             av_log(c->fc, AV_LOG_ERROR, "iloc: extent_count > 1 not supported.\n");
7874             return AVERROR_PATCHWELCOME;
7875         }
7876         for (int j = 0; j < extent_count; j++) {
7877             if (rb_size(pb, &extent_offset, offset_size) < 0 ||
7878                 rb_size(pb, &extent_length, length_size) < 0 ||
7879                 base_offset > INT64_MAX - extent_offset)
7880                 return AVERROR_INVALIDDATA;
7881             if (item_id == c->primary_item_id) {
7882                 sc->sample_sizes[0] = extent_length;
7883                 sc->chunk_offsets[0] = base_offset + extent_offset;
7884             }
7885         }
7886     }
7887 
7888     mov_build_index(c, st);
7889 
7890     // For still AVIF images, the iloc box contains all the necessary
7891     // information that would generally be provided by the moov box. So simply
7892     // mark that we have found the moov box so that parsing can continue.
7893     c->found_moov = 1;
7894 
7895     return atom.size;
7896 }
7897 
7898 
7899 #ifdef OHOS_MOOV_LEVEL_META
mov_read_gnre(MOVContext * c,AVIOContext * pb,MOVAtom atom)7900 static int mov_read_gnre(MOVContext *c, AVIOContext *pb, MOVAtom atom)
7901 {
7902     int32_t i = 0;
7903     if (atom.size > 0) {
7904         if (atom.size > FFMIN(INT_MAX, SIZE_MAX - 1))
7905             return AVERROR_INVALIDDATA;
7906         char* genre = av_mallocz(atom.size + 1); /* Add null terminator */
7907         if (!genre)
7908             return AVERROR(ENOMEM);
7909 
7910         int ret = ffio_read_size(pb, genre, atom.size);
7911         if (ret < 0) {
7912             av_freep(&genre);
7913             return ret;
7914         }
7915         /* skip zero at head of genre from dual frame video */
7916         for (i = 0; i < atom.size; ++i) {
7917             if (genre[i] != 0) {
7918 	            break;
7919             }
7920         }
7921         av_dict_set(&c->fc->metadata, "genre", genre + i, AV_DICT_DONT_OVERWRITE);
7922         av_freep(&genre);
7923     }
7924     return 0;
7925 }
7926 #endif
7927 
7928 static const MOVParseTableEntry mov_default_parse_table[] = {
7929 { MKTAG('A','C','L','R'), mov_read_aclr },
7930 { MKTAG('A','P','R','G'), mov_read_avid },
7931 { MKTAG('A','A','L','P'), mov_read_avid },
7932 { MKTAG('A','R','E','S'), mov_read_ares },
7933 { MKTAG('a','v','s','s'), mov_read_avss },
7934 { MKTAG('a','v','1','C'), mov_read_glbl },
7935 { MKTAG('c','h','p','l'), mov_read_chpl },
7936 { MKTAG('c','o','6','4'), mov_read_stco },
7937 { MKTAG('c','o','l','r'), mov_read_colr },
7938 { MKTAG('c','t','t','s'), mov_read_ctts }, /* composition time to sample */
7939 { MKTAG('d','i','n','f'), mov_read_default },
7940 { MKTAG('D','p','x','E'), mov_read_dpxe },
7941 { MKTAG('d','r','e','f'), mov_read_dref },
7942 { MKTAG('e','d','t','s'), mov_read_default },
7943 { MKTAG('e','l','s','t'), mov_read_elst },
7944 { MKTAG('e','n','d','a'), mov_read_enda },
7945 { MKTAG('f','i','e','l'), mov_read_fiel },
7946 { MKTAG('a','d','r','m'), mov_read_adrm },
7947 { MKTAG('f','t','y','p'), mov_read_ftyp },
7948 { MKTAG('g','l','b','l'), mov_read_glbl },
7949 { MKTAG('h','d','l','r'), mov_read_hdlr },
7950 { MKTAG('i','l','s','t'), mov_read_ilst },
7951 { MKTAG('j','p','2','h'), mov_read_jp2h },
7952 { MKTAG('m','d','a','t'), mov_read_mdat },
7953 { MKTAG('m','d','h','d'), mov_read_mdhd },
7954 { MKTAG('m','d','i','a'), mov_read_default },
7955 { MKTAG('m','e','t','a'), mov_read_meta },
7956 { MKTAG('m','i','n','f'), mov_read_default },
7957 { MKTAG('m','o','o','f'), mov_read_moof },
7958 { MKTAG('m','o','o','v'), mov_read_moov },
7959 { MKTAG('m','v','e','x'), mov_read_default },
7960 { MKTAG('m','v','h','d'), mov_read_mvhd },
7961 { MKTAG('S','M','I',' '), mov_read_svq3 },
7962 { MKTAG('a','l','a','c'), mov_read_alac }, /* alac specific atom */
7963 { MKTAG('a','v','c','C'), mov_read_glbl },
7964 { MKTAG('p','a','s','p'), mov_read_pasp },
7965 { MKTAG('s','i','d','x'), mov_read_sidx },
7966 { MKTAG('s','t','b','l'), mov_read_default },
7967 { MKTAG('s','t','c','o'), mov_read_stco },
7968 { MKTAG('s','t','p','s'), mov_read_stps },
7969 { MKTAG('s','t','r','f'), mov_read_strf },
7970 { MKTAG('s','t','s','c'), mov_read_stsc },
7971 { MKTAG('s','t','s','d'), mov_read_stsd }, /* sample description */
7972 { MKTAG('s','t','s','s'), mov_read_stss }, /* sync sample */
7973 { MKTAG('s','t','s','z'), mov_read_stsz }, /* sample size */
7974 { MKTAG('s','t','t','s'), mov_read_stts },
7975 { MKTAG('s','t','z','2'), mov_read_stsz }, /* compact sample size */
7976 { MKTAG('s','d','t','p'), mov_read_sdtp }, /* independent and disposable samples */
7977 { MKTAG('t','k','h','d'), mov_read_tkhd }, /* track header */
7978 { MKTAG('t','f','d','t'), mov_read_tfdt },
7979 { MKTAG('t','f','h','d'), mov_read_tfhd }, /* track fragment header */
7980 { MKTAG('t','r','a','k'), mov_read_trak },
7981 { MKTAG('t','r','a','f'), mov_read_default },
7982 { MKTAG('t','r','e','f'), mov_read_default },
7983 { MKTAG('t','m','c','d'), mov_read_tmcd },
7984 { MKTAG('c','h','a','p'), mov_read_chap },
7985 { MKTAG('t','r','e','x'), mov_read_trex },
7986 { MKTAG('t','r','u','n'), mov_read_trun },
7987 { MKTAG('u','d','t','a'), mov_read_default },
7988 { MKTAG('w','a','v','e'), mov_read_wave },
7989 { MKTAG('e','s','d','s'), mov_read_esds },
7990 { MKTAG('d','a','c','3'), mov_read_dac3 }, /* AC-3 info */
7991 { MKTAG('d','e','c','3'), mov_read_dec3 }, /* EAC-3 info */
7992 { MKTAG('d','d','t','s'), mov_read_ddts }, /* DTS audio descriptor */
7993 { MKTAG('w','i','d','e'), mov_read_wide }, /* place holder */
7994 { MKTAG('w','f','e','x'), mov_read_wfex },
7995 { MKTAG('c','m','o','v'), mov_read_cmov },
7996 { MKTAG('c','h','a','n'), mov_read_chan }, /* channel layout */
7997 { MKTAG('d','v','c','1'), mov_read_dvc1 },
7998 { MKTAG('s','g','p','d'), mov_read_sgpd },
7999 { MKTAG('s','b','g','p'), mov_read_sbgp },
8000 { MKTAG('h','v','c','C'), mov_read_glbl },
8001 #ifdef OHOS_OPT_COMPAT
8002 { MKTAG('v','v','c','C'), mov_read_glbl },
8003 #endif
8004 { MKTAG('u','u','i','d'), mov_read_uuid },
8005 { MKTAG('C','i','n', 0x8e), mov_read_targa_y216 },
8006 { MKTAG('f','r','e','e'), mov_read_free },
8007 { MKTAG('-','-','-','-'), mov_read_custom },
8008 { MKTAG('s','i','n','f'), mov_read_default },
8009 { MKTAG('f','r','m','a'), mov_read_frma },
8010 { MKTAG('s','e','n','c'), mov_read_senc },
8011 { MKTAG('s','a','i','z'), mov_read_saiz },
8012 { MKTAG('s','a','i','o'), mov_read_saio },
8013 #ifdef OHOS_DRM
8014 { MKTAG('p','s','s','h'), mov_read_pssh_ex },
8015 #else
8016 { MKTAG('p','s','s','h'), mov_read_pssh },
8017 #endif
8018 { MKTAG('s','c','h','m'), mov_read_schm },
8019 { MKTAG('s','c','h','i'), mov_read_default },
8020 { MKTAG('t','e','n','c'), mov_read_tenc },
8021 { MKTAG('d','f','L','a'), mov_read_dfla },
8022 { MKTAG('s','t','3','d'), mov_read_st3d }, /* stereoscopic 3D video box */
8023 { MKTAG('s','v','3','d'), mov_read_sv3d }, /* spherical video box */
8024 { MKTAG('d','O','p','s'), mov_read_dops },
8025 { MKTAG('d','m','l','p'), mov_read_dmlp },
8026 { MKTAG('S','m','D','m'), mov_read_smdm },
8027 { MKTAG('C','o','L','L'), mov_read_coll },
8028 { MKTAG('v','p','c','C'), mov_read_vpcc },
8029 { MKTAG('m','d','c','v'), mov_read_mdcv },
8030 { MKTAG('c','l','l','i'), mov_read_clli },
8031 { MKTAG('d','v','c','C'), mov_read_dvcc_dvvc },
8032 { MKTAG('d','v','v','C'), mov_read_dvcc_dvvc },
8033 { MKTAG('d','v','w','C'), mov_read_dvcc_dvvc },
8034 { MKTAG('k','i','n','d'), mov_read_kind },
8035 { MKTAG('S','A','3','D'), mov_read_SA3D }, /* ambisonic audio box */
8036 { MKTAG('S','A','N','D'), mov_read_SAND }, /* non diegetic audio box */
8037 { MKTAG('i','l','o','c'), mov_read_iloc },
8038 { MKTAG('p','c','m','C'), mov_read_pcmc }, /* PCM configuration box */
8039 { MKTAG('p','i','t','m'), mov_read_pitm },
8040 #ifdef OHOS_TIMED_META_TRACK
8041 { MKTAG('c','d','s','c'), mov_read_cdsc },
8042 #endif
8043 { 0, NULL }
8044 };
8045 
mov_read_default(MOVContext * c,AVIOContext * pb,MOVAtom atom)8046 static int mov_read_default(MOVContext *c, AVIOContext *pb, MOVAtom atom)
8047 {
8048     int64_t total_size = 0;
8049     MOVAtom a;
8050     int i;
8051 
8052     if (c->atom_depth > 10) {
8053         av_log(c->fc, AV_LOG_ERROR, "Atoms too deeply nested\n");
8054         return AVERROR_INVALIDDATA;
8055     }
8056     c->atom_depth ++;
8057 
8058     if (atom.size < 0)
8059         atom.size = INT64_MAX;
8060     while (total_size <= atom.size - 8) {
8061         int (*parse)(MOVContext*, AVIOContext*, MOVAtom) = NULL;
8062         a.size = avio_rb32(pb);
8063         a.type = avio_rl32(pb);
8064         if (avio_feof(pb))
8065             break;
8066         if (((a.type == MKTAG('f','r','e','e') && c->moov_retry) ||
8067               a.type == MKTAG('h','o','o','v')) &&
8068             a.size >= 8 &&
8069             c->fc->strict_std_compliance < FF_COMPLIANCE_STRICT) {
8070                 uint32_t type;
8071                 avio_skip(pb, 4);
8072                 type = avio_rl32(pb);
8073                 if (avio_feof(pb))
8074                     break;
8075                 avio_seek(pb, -8, SEEK_CUR);
8076                 if (type == MKTAG('m','v','h','d') ||
8077                     type == MKTAG('c','m','o','v')) {
8078                     av_log(c->fc, AV_LOG_ERROR, "Detected moov in a free or hoov atom.\n");
8079                     a.type = MKTAG('m','o','o','v');
8080                 }
8081         }
8082         if (atom.type != MKTAG('r','o','o','t') &&
8083             atom.type != MKTAG('m','o','o','v')) {
8084             if (a.type == MKTAG('t','r','a','k') ||
8085                 a.type == MKTAG('m','d','a','t')) {
8086                 av_log(c->fc, AV_LOG_ERROR, "Broken file, trak/mdat not at top-level\n");
8087                 avio_skip(pb, -8);
8088                 c->atom_depth --;
8089                 return 0;
8090             }
8091         }
8092         total_size += 8;
8093         if (a.size == 1 && total_size + 8 <= atom.size) { /* 64 bit extended size */
8094             a.size = avio_rb64(pb) - 8;
8095             total_size += 8;
8096         }
8097         av_log(c->fc, AV_LOG_TRACE, "type:'%s' parent:'%s' sz: %"PRId64" %"PRId64" %"PRId64"\n",
8098                av_fourcc2str(a.type), av_fourcc2str(atom.type), a.size, total_size, atom.size);
8099         if (a.size == 0) {
8100             a.size = atom.size - total_size + 8;
8101         }
8102         if (a.size < 0)
8103             break;
8104         a.size -= 8;
8105         if (a.size < 0)
8106             break;
8107         a.size = FFMIN(a.size, atom.size - total_size);
8108 
8109         for (i = 0; mov_default_parse_table[i].type; i++)
8110             if (mov_default_parse_table[i].type == a.type) {
8111                 parse = mov_default_parse_table[i].parse;
8112                 break;
8113             }
8114 
8115         // container is user data
8116         if (!parse && (atom.type == MKTAG('u','d','t','a') ||
8117                        atom.type == MKTAG('i','l','s','t')))
8118             parse = mov_read_udta_string;
8119 
8120 #ifdef OHOS_MOOV_LEVEL_META
8121         // support moov gnre info
8122         if (!parse && a.type == MKTAG('g','n','r','e')) {
8123             parse = mov_read_gnre;
8124         }
8125 #endif
8126 
8127         // Supports parsing the QuickTime Metadata Keys.
8128         // https://developer.apple.com/library/mac/documentation/QuickTime/QTFF/Metadata/Metadata.html
8129         if (!parse && c->found_hdlr_mdta &&
8130             atom.type == MKTAG('m','e','t','a') &&
8131             a.type == MKTAG('k','e','y','s') &&
8132             c->meta_keys_count == 0) {
8133             parse = mov_read_keys;
8134         }
8135 
8136         if (!parse) { /* skip leaf atoms data */
8137             avio_skip(pb, a.size);
8138         } else {
8139             int64_t start_pos = avio_tell(pb);
8140             int64_t left;
8141             int err = parse(c, pb, a);
8142             if (err < 0) {
8143                 c->atom_depth --;
8144                 return err;
8145             }
8146             if (c->found_moov && c->found_mdat && a.size <= INT64_MAX - start_pos &&
8147                 ((!(pb->seekable & AVIO_SEEKABLE_NORMAL) || c->fc->flags & AVFMT_FLAG_IGNIDX || c->frag_index.complete) ||
8148                  start_pos + a.size == avio_size(pb))) {
8149                 if (!(pb->seekable & AVIO_SEEKABLE_NORMAL) || c->fc->flags & AVFMT_FLAG_IGNIDX || c->frag_index.complete)
8150                     c->next_root_atom = start_pos + a.size;
8151                 c->atom_depth --;
8152                 return 0;
8153             }
8154             left = a.size - avio_tell(pb) + start_pos;
8155             if (left > 0) /* skip garbage at atom end */
8156                 avio_skip(pb, left);
8157             else if (left < 0) {
8158                 av_log(c->fc, AV_LOG_WARNING,
8159                        "overread end of atom '%s' by %"PRId64" bytes\n",
8160                        av_fourcc2str(a.type), -left);
8161                 avio_seek(pb, left, SEEK_CUR);
8162             }
8163         }
8164 
8165         total_size += a.size;
8166     }
8167 
8168     if (total_size < atom.size && atom.size < 0x7ffff)
8169         avio_skip(pb, atom.size - total_size);
8170 
8171     c->atom_depth --;
8172     return 0;
8173 }
8174 
mov_probe(const AVProbeData * p)8175 static int mov_probe(const AVProbeData *p)
8176 {
8177     int64_t offset;
8178     uint32_t tag;
8179     int score = 0;
8180     int moov_offset = -1;
8181 
8182     /* check file header */
8183     offset = 0;
8184     for (;;) {
8185         int64_t size;
8186         int minsize = 8;
8187         /* ignore invalid offset */
8188         if ((offset + 8ULL) > (unsigned int)p->buf_size)
8189             break;
8190         size = AV_RB32(p->buf + offset);
8191         if (size == 1 && offset + 16 <= (unsigned int)p->buf_size) {
8192             size = AV_RB64(p->buf+offset + 8);
8193             minsize = 16;
8194         } else if (size == 0) {
8195             size = p->buf_size - offset;
8196         }
8197         if (size < minsize) {
8198             offset += 4;
8199             continue;
8200         }
8201         tag = AV_RL32(p->buf + offset + 4);
8202         switch(tag) {
8203         /* check for obvious tags */
8204         case MKTAG('m','o','o','v'):
8205             moov_offset = offset + 4;
8206         case MKTAG('m','d','a','t'):
8207         case MKTAG('p','n','o','t'): /* detect movs with preview pics like ew.mov and april.mov */
8208         case MKTAG('u','d','t','a'): /* Packet Video PVAuthor adds this and a lot of more junk */
8209         case MKTAG('f','t','y','p'):
8210             if (tag == MKTAG('f','t','y','p') &&
8211                        (   AV_RL32(p->buf + offset + 8) == MKTAG('j','p','2',' ')
8212                         || AV_RL32(p->buf + offset + 8) == MKTAG('j','p','x',' ')
8213                         || AV_RL32(p->buf + offset + 8) == MKTAG('j','x','l',' ')
8214                     )) {
8215                 score = FFMAX(score, 5);
8216             } else {
8217                 score = AVPROBE_SCORE_MAX;
8218             }
8219             break;
8220         /* those are more common words, so rate then a bit less */
8221         case MKTAG('e','d','i','w'): /* xdcam files have reverted first tags */
8222         case MKTAG('w','i','d','e'):
8223         case MKTAG('f','r','e','e'):
8224         case MKTAG('j','u','n','k'):
8225         case MKTAG('p','i','c','t'):
8226             score  = FFMAX(score, AVPROBE_SCORE_MAX - 5);
8227             break;
8228         case MKTAG(0x82,0x82,0x7f,0x7d):
8229         case MKTAG('s','k','i','p'):
8230         case MKTAG('u','u','i','d'):
8231         case MKTAG('p','r','f','l'):
8232             /* if we only find those cause probedata is too small at least rate them */
8233             score  = FFMAX(score, AVPROBE_SCORE_EXTENSION);
8234             break;
8235         }
8236         if (size > INT64_MAX - offset)
8237             break;
8238         offset += size;
8239     }
8240     if (score > AVPROBE_SCORE_MAX - 50 && moov_offset != -1) {
8241         /* moov atom in the header - we should make sure that this is not a
8242          * MOV-packed MPEG-PS */
8243         offset = moov_offset;
8244 
8245         while (offset < (p->buf_size - 16)) { /* Sufficient space */
8246                /* We found an actual hdlr atom */
8247             if (AV_RL32(p->buf + offset     ) == MKTAG('h','d','l','r') &&
8248                 AV_RL32(p->buf + offset +  8) == MKTAG('m','h','l','r') &&
8249                 AV_RL32(p->buf + offset + 12) == MKTAG('M','P','E','G')) {
8250                 av_log(NULL, AV_LOG_WARNING, "Found media data tag MPEG indicating this is a MOV-packed MPEG-PS.\n");
8251                 /* We found a media handler reference atom describing an
8252                  * MPEG-PS-in-MOV, return a
8253                  * low score to force expanding the probe window until
8254                  * mpegps_probe finds what it needs */
8255                 return 5;
8256             } else {
8257                 /* Keep looking */
8258                 offset += 2;
8259             }
8260         }
8261     }
8262 
8263     return score;
8264 }
8265 
8266 // must be done after parsing all trak because there's no order requirement
mov_read_chapters(AVFormatContext * s)8267 static void mov_read_chapters(AVFormatContext *s)
8268 {
8269     MOVContext *mov = s->priv_data;
8270     MOVStreamContext *sc;
8271     int64_t cur_pos;
8272     int i, j;
8273     int chapter_track;
8274 
8275     for (j = 0; j < mov->nb_chapter_tracks; j++) {
8276         AVStream *st = NULL;
8277         FFStream *sti = NULL;
8278         chapter_track = mov->chapter_tracks[j];
8279         for (i = 0; i < s->nb_streams; i++)
8280             if (s->streams[i]->id == chapter_track) {
8281                 st = s->streams[i];
8282                 break;
8283             }
8284         if (!st) {
8285             av_log(s, AV_LOG_ERROR, "Referenced QT chapter track not found\n");
8286             continue;
8287         }
8288         sti = ffstream(st);
8289 
8290         sc = st->priv_data;
8291         cur_pos = avio_tell(sc->pb);
8292 
8293         if (st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO) {
8294             st->disposition |= AV_DISPOSITION_ATTACHED_PIC | AV_DISPOSITION_TIMED_THUMBNAILS;
8295             if (sti->nb_index_entries) {
8296                 // Retrieve the first frame, if possible
8297                 AVIndexEntry *sample = &sti->index_entries[0];
8298                 if (avio_seek(sc->pb, sample->pos, SEEK_SET) != sample->pos) {
8299                     av_log(s, AV_LOG_ERROR, "Failed to retrieve first frame\n");
8300                     goto finish;
8301                 }
8302 
8303                 if (ff_add_attached_pic(s, st, sc->pb, NULL, sample->size) < 0)
8304                     goto finish;
8305             }
8306         } else {
8307             st->codecpar->codec_type = AVMEDIA_TYPE_DATA;
8308             st->codecpar->codec_id = AV_CODEC_ID_BIN_DATA;
8309             st->discard = AVDISCARD_ALL;
8310             for (int i = 0; i < sti->nb_index_entries; i++) {
8311                 AVIndexEntry *sample = &sti->index_entries[i];
8312                 int64_t end = i+1 < sti->nb_index_entries ? sti->index_entries[i+1].timestamp : st->duration;
8313                 uint8_t *title;
8314                 uint16_t ch;
8315                 int len, title_len;
8316 
8317                 if (end < sample->timestamp) {
8318                     av_log(s, AV_LOG_WARNING, "ignoring stream duration which is shorter than chapters\n");
8319                     end = AV_NOPTS_VALUE;
8320                 }
8321 
8322                 if (avio_seek(sc->pb, sample->pos, SEEK_SET) != sample->pos) {
8323                     av_log(s, AV_LOG_ERROR, "Chapter %d not found in file\n", i);
8324                     goto finish;
8325                 }
8326 
8327                 // the first two bytes are the length of the title
8328                 len = avio_rb16(sc->pb);
8329                 if (len > sample->size-2)
8330                     continue;
8331                 title_len = 2*len + 1;
8332                 if (!(title = av_mallocz(title_len)))
8333                     goto finish;
8334 
8335                 // The samples could theoretically be in any encoding if there's an encd
8336                 // atom following, but in practice are only utf-8 or utf-16, distinguished
8337                 // instead by the presence of a BOM
8338                 if (!len) {
8339                     title[0] = 0;
8340                 } else {
8341                     ch = avio_rb16(sc->pb);
8342                     if (ch == 0xfeff)
8343                         avio_get_str16be(sc->pb, len, title, title_len);
8344                     else if (ch == 0xfffe)
8345                         avio_get_str16le(sc->pb, len, title, title_len);
8346                     else {
8347                         AV_WB16(title, ch);
8348                         if (len == 1 || len == 2)
8349                             title[len] = 0;
8350                         else
8351                             avio_get_str(sc->pb, INT_MAX, title + 2, len - 1);
8352                     }
8353                 }
8354 
8355                 avpriv_new_chapter(s, i, st->time_base, sample->timestamp, end, title);
8356                 av_freep(&title);
8357             }
8358         }
8359 finish:
8360         avio_seek(sc->pb, cur_pos, SEEK_SET);
8361     }
8362 }
8363 
parse_timecode_in_framenum_format(AVFormatContext * s,AVStream * st,int64_t value,int flags)8364 static int parse_timecode_in_framenum_format(AVFormatContext *s, AVStream *st,
8365                                              int64_t value, int flags)
8366 {
8367     AVTimecode tc;
8368     char buf[AV_TIMECODE_STR_SIZE];
8369     AVRational rate = st->avg_frame_rate;
8370     int ret = av_timecode_init(&tc, rate, flags, 0, s);
8371     if (ret < 0)
8372         return ret;
8373     av_dict_set(&st->metadata, "timecode",
8374                 av_timecode_make_string(&tc, buf, value), 0);
8375     return 0;
8376 }
8377 
mov_read_rtmd_track(AVFormatContext * s,AVStream * st)8378 static int mov_read_rtmd_track(AVFormatContext *s, AVStream *st)
8379 {
8380     MOVStreamContext *sc = st->priv_data;
8381     FFStream *const sti = ffstream(st);
8382     char buf[AV_TIMECODE_STR_SIZE];
8383     int64_t cur_pos = avio_tell(sc->pb);
8384     int hh, mm, ss, ff, drop;
8385 
8386     if (!sti->nb_index_entries)
8387         return -1;
8388 
8389     avio_seek(sc->pb, sti->index_entries->pos, SEEK_SET);
8390     avio_skip(s->pb, 13);
8391     hh = avio_r8(s->pb);
8392     mm = avio_r8(s->pb);
8393     ss = avio_r8(s->pb);
8394     drop = avio_r8(s->pb);
8395     ff = avio_r8(s->pb);
8396     snprintf(buf, AV_TIMECODE_STR_SIZE, "%02d:%02d:%02d%c%02d",
8397              hh, mm, ss, drop ? ';' : ':', ff);
8398     av_dict_set(&st->metadata, "timecode", buf, 0);
8399 
8400     avio_seek(sc->pb, cur_pos, SEEK_SET);
8401     return 0;
8402 }
8403 
mov_read_timecode_track(AVFormatContext * s,AVStream * st)8404 static int mov_read_timecode_track(AVFormatContext *s, AVStream *st)
8405 {
8406     MOVStreamContext *sc = st->priv_data;
8407     FFStream *const sti = ffstream(st);
8408     int flags = 0;
8409     int64_t cur_pos = avio_tell(sc->pb);
8410     int64_t value;
8411     AVRational tc_rate = st->avg_frame_rate;
8412     int tmcd_nb_frames = sc->tmcd_nb_frames;
8413     int rounded_tc_rate;
8414 
8415     if (!sti->nb_index_entries)
8416         return -1;
8417 
8418     if (!tc_rate.num || !tc_rate.den || !tmcd_nb_frames)
8419         return -1;
8420 
8421     avio_seek(sc->pb, sti->index_entries->pos, SEEK_SET);
8422     value = avio_rb32(s->pb);
8423 
8424     if (sc->tmcd_flags & 0x0001) flags |= AV_TIMECODE_FLAG_DROPFRAME;
8425     if (sc->tmcd_flags & 0x0002) flags |= AV_TIMECODE_FLAG_24HOURSMAX;
8426     if (sc->tmcd_flags & 0x0004) flags |= AV_TIMECODE_FLAG_ALLOWNEGATIVE;
8427 
8428     /* Assume Counter flag is set to 1 in tmcd track (even though it is likely
8429      * not the case) and thus assume "frame number format" instead of QT one.
8430      * No sample with tmcd track can be found with a QT timecode at the moment,
8431      * despite what the tmcd track "suggests" (Counter flag set to 0 means QT
8432      * format). */
8433 
8434     /* 60 fps content have tmcd_nb_frames set to 30 but tc_rate set to 60, so
8435      * we multiply the frame number with the quotient.
8436      * See tickets #9492, #9710. */
8437     rounded_tc_rate = (tc_rate.num + tc_rate.den / 2) / tc_rate.den;
8438     /* Work around files where tmcd_nb_frames is rounded down from frame rate
8439      * instead of up. See ticket #5978. */
8440     if (tmcd_nb_frames == tc_rate.num / tc_rate.den &&
8441         s->strict_std_compliance < FF_COMPLIANCE_STRICT)
8442         tmcd_nb_frames = rounded_tc_rate;
8443     value = av_rescale(value, rounded_tc_rate, tmcd_nb_frames);
8444 
8445     parse_timecode_in_framenum_format(s, st, value, flags);
8446 
8447     avio_seek(sc->pb, cur_pos, SEEK_SET);
8448     return 0;
8449 }
8450 
mov_free_encryption_index(MOVEncryptionIndex ** index)8451 static void mov_free_encryption_index(MOVEncryptionIndex **index) {
8452     int i;
8453     if (!index || !*index) return;
8454     for (i = 0; i < (*index)->nb_encrypted_samples; i++) {
8455         av_encryption_info_free((*index)->encrypted_samples[i]);
8456     }
8457     av_freep(&(*index)->encrypted_samples);
8458     av_freep(&(*index)->auxiliary_info_sizes);
8459     av_freep(&(*index)->auxiliary_offsets);
8460     av_freep(index);
8461 }
8462 
mov_read_close(AVFormatContext * s)8463 static int mov_read_close(AVFormatContext *s)
8464 {
8465     MOVContext *mov = s->priv_data;
8466     int i, j;
8467 
8468     for (i = 0; i < s->nb_streams; i++) {
8469         AVStream *st = s->streams[i];
8470         MOVStreamContext *sc = st->priv_data;
8471 
8472 #ifdef OHOS_EXPAND_MP4_INFO
8473         if (st->stts_data != NULL) {
8474              free(st->stts_data);
8475              st->stts_data = NULL;
8476         }
8477 
8478         if (st->ctts_data != NULL) {
8479              free(st->ctts_data);
8480              st->ctts_data = NULL;
8481         }
8482 #endif
8483 
8484         if (!sc)
8485             continue;
8486 
8487         av_freep(&sc->ctts_data);
8488         for (j = 0; j < sc->drefs_count; j++) {
8489             av_freep(&sc->drefs[j].path);
8490             av_freep(&sc->drefs[j].dir);
8491         }
8492         av_freep(&sc->drefs);
8493 
8494         sc->drefs_count = 0;
8495 
8496         if (!sc->pb_is_copied)
8497             ff_format_io_close(s, &sc->pb);
8498 
8499         sc->pb = NULL;
8500         av_freep(&sc->chunk_offsets);
8501         av_freep(&sc->stsc_data);
8502         av_freep(&sc->sample_sizes);
8503         av_freep(&sc->keyframes);
8504         av_freep(&sc->stts_data);
8505         av_freep(&sc->sdtp_data);
8506         av_freep(&sc->stps_data);
8507         av_freep(&sc->elst_data);
8508         av_freep(&sc->rap_group);
8509         av_freep(&sc->sync_group);
8510         av_freep(&sc->sgpd_sync);
8511         av_freep(&sc->sample_offsets);
8512         av_freep(&sc->open_key_samples);
8513         av_freep(&sc->display_matrix);
8514         av_freep(&sc->index_ranges);
8515 
8516         if (sc->extradata)
8517             for (j = 0; j < sc->stsd_count; j++)
8518                 av_free(sc->extradata[j]);
8519         av_freep(&sc->extradata);
8520         av_freep(&sc->extradata_size);
8521 
8522         mov_free_encryption_index(&sc->cenc.encryption_index);
8523         av_encryption_info_free(sc->cenc.default_encrypted_sample);
8524         av_aes_ctr_free(sc->cenc.aes_ctr);
8525 
8526         av_freep(&sc->stereo3d);
8527         av_freep(&sc->spherical);
8528         av_freep(&sc->mastering);
8529         av_freep(&sc->coll);
8530     }
8531 
8532     av_freep(&mov->dv_demux);
8533     avformat_free_context(mov->dv_fctx);
8534     mov->dv_fctx = NULL;
8535 
8536     if (mov->meta_keys) {
8537         for (i = 1; i < mov->meta_keys_count; i++) {
8538             av_freep(&mov->meta_keys[i]);
8539         }
8540         av_freep(&mov->meta_keys);
8541     }
8542 
8543     av_freep(&mov->trex_data);
8544     av_freep(&mov->bitrates);
8545 
8546     for (i = 0; i < mov->frag_index.nb_items; i++) {
8547         MOVFragmentStreamInfo *frag = mov->frag_index.item[i].stream_info;
8548         for (j = 0; j < mov->frag_index.item[i].nb_stream_info; j++) {
8549             mov_free_encryption_index(&frag[j].encryption_index);
8550         }
8551         av_freep(&mov->frag_index.item[i].stream_info);
8552     }
8553     av_freep(&mov->frag_index.item);
8554 
8555     av_freep(&mov->aes_decrypt);
8556     av_freep(&mov->chapter_tracks);
8557 
8558     return 0;
8559 }
8560 
tmcd_is_referenced(AVFormatContext * s,int tmcd_id)8561 static int tmcd_is_referenced(AVFormatContext *s, int tmcd_id)
8562 {
8563     int i;
8564 
8565     for (i = 0; i < s->nb_streams; i++) {
8566         AVStream *st = s->streams[i];
8567         MOVStreamContext *sc = st->priv_data;
8568 
8569         if (st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO &&
8570             sc->timecode_track == tmcd_id)
8571             return 1;
8572     }
8573     return 0;
8574 }
8575 
8576 /* look for a tmcd track not referenced by any video track, and export it globally */
export_orphan_timecode(AVFormatContext * s)8577 static void export_orphan_timecode(AVFormatContext *s)
8578 {
8579     int i;
8580 
8581     for (i = 0; i < s->nb_streams; i++) {
8582         AVStream *st = s->streams[i];
8583 
8584         if (st->codecpar->codec_tag  == MKTAG('t','m','c','d') &&
8585             !tmcd_is_referenced(s, i + 1)) {
8586             AVDictionaryEntry *tcr = av_dict_get(st->metadata, "timecode", NULL, 0);
8587             if (tcr) {
8588                 av_dict_set(&s->metadata, "timecode", tcr->value, 0);
8589                 break;
8590             }
8591         }
8592     }
8593 }
8594 
read_tfra(MOVContext * mov,AVIOContext * f)8595 static int read_tfra(MOVContext *mov, AVIOContext *f)
8596 {
8597     int version, fieldlength, i, j;
8598     int64_t pos = avio_tell(f);
8599     uint32_t size = avio_rb32(f);
8600     unsigned track_id, item_count;
8601 
8602     if (avio_rb32(f) != MKBETAG('t', 'f', 'r', 'a')) {
8603         return 1;
8604     }
8605     av_log(mov->fc, AV_LOG_VERBOSE, "found tfra\n");
8606 
8607     version = avio_r8(f);
8608     avio_rb24(f);
8609     track_id = avio_rb32(f);
8610     fieldlength = avio_rb32(f);
8611     item_count = avio_rb32(f);
8612     for (i = 0; i < item_count; i++) {
8613         int64_t time, offset;
8614         int index;
8615         MOVFragmentStreamInfo * frag_stream_info;
8616 
8617         if (avio_feof(f)) {
8618             return AVERROR_INVALIDDATA;
8619         }
8620 
8621         if (version == 1) {
8622             time   = avio_rb64(f);
8623             offset = avio_rb64(f);
8624         } else {
8625             time   = avio_rb32(f);
8626             offset = avio_rb32(f);
8627         }
8628 
8629         // The first sample of each stream in a fragment is always a random
8630         // access sample.  So it's entry in the tfra can be used as the
8631         // initial PTS of the fragment.
8632         index = update_frag_index(mov, offset);
8633         frag_stream_info = get_frag_stream_info(&mov->frag_index, index, track_id);
8634         if (frag_stream_info &&
8635             frag_stream_info->first_tfra_pts == AV_NOPTS_VALUE)
8636             frag_stream_info->first_tfra_pts = time;
8637 
8638         for (j = 0; j < ((fieldlength >> 4) & 3) + 1; j++)
8639             avio_r8(f);
8640         for (j = 0; j < ((fieldlength >> 2) & 3) + 1; j++)
8641             avio_r8(f);
8642         for (j = 0; j < ((fieldlength >> 0) & 3) + 1; j++)
8643             avio_r8(f);
8644     }
8645 
8646     avio_seek(f, pos + size, SEEK_SET);
8647     return 0;
8648 }
8649 
mov_read_mfra(MOVContext * c,AVIOContext * f)8650 static int mov_read_mfra(MOVContext *c, AVIOContext *f)
8651 {
8652     int64_t stream_size = avio_size(f);
8653     int64_t original_pos = avio_tell(f);
8654     int64_t seek_ret;
8655     int ret = -1;
8656     if ((seek_ret = avio_seek(f, stream_size - 4, SEEK_SET)) < 0) {
8657         ret = seek_ret;
8658         goto fail;
8659     }
8660     c->mfra_size = avio_rb32(f);
8661     c->have_read_mfra_size = 1;
8662     if (!c->mfra_size || c->mfra_size > stream_size) {
8663         av_log(c->fc, AV_LOG_DEBUG, "doesn't look like mfra (unreasonable size)\n");
8664         goto fail;
8665     }
8666     if ((seek_ret = avio_seek(f, -((int64_t) c->mfra_size), SEEK_CUR)) < 0) {
8667         ret = seek_ret;
8668         goto fail;
8669     }
8670     if (avio_rb32(f) != c->mfra_size) {
8671         av_log(c->fc, AV_LOG_DEBUG, "doesn't look like mfra (size mismatch)\n");
8672         goto fail;
8673     }
8674     if (avio_rb32(f) != MKBETAG('m', 'f', 'r', 'a')) {
8675         av_log(c->fc, AV_LOG_DEBUG, "doesn't look like mfra (tag mismatch)\n");
8676         goto fail;
8677     }
8678     av_log(c->fc, AV_LOG_VERBOSE, "stream has mfra\n");
8679     do {
8680         ret = read_tfra(c, f);
8681         if (ret < 0)
8682             goto fail;
8683     } while (!ret);
8684     ret = 0;
8685     c->frag_index.complete = 1;
8686 fail:
8687     seek_ret = avio_seek(f, original_pos, SEEK_SET);
8688     if (seek_ret < 0) {
8689         av_log(c->fc, AV_LOG_ERROR,
8690                "failed to seek back after looking for mfra\n");
8691         ret = seek_ret;
8692     }
8693     return ret;
8694 }
8695 
mov_read_header(AVFormatContext * s)8696 static int mov_read_header(AVFormatContext *s)
8697 {
8698     MOVContext *mov = s->priv_data;
8699     AVIOContext *pb = s->pb;
8700     int j, err;
8701     MOVAtom atom = { AV_RL32("root") };
8702     int i;
8703 
8704     if (mov->decryption_key_len != 0 && mov->decryption_key_len != AES_CTR_KEY_SIZE) {
8705         av_log(s, AV_LOG_ERROR, "Invalid decryption key len %d expected %d\n",
8706             mov->decryption_key_len, AES_CTR_KEY_SIZE);
8707         return AVERROR(EINVAL);
8708     }
8709 
8710     mov->fc = s;
8711     mov->trak_index = -1;
8712     /* .mov and .mp4 aren't streamable anyway (only progressive download if moov is before mdat) */
8713     if (pb->seekable & AVIO_SEEKABLE_NORMAL)
8714         atom.size = avio_size(pb);
8715     else
8716         atom.size = INT64_MAX;
8717 
8718     /* check MOV header */
8719     do {
8720         if (mov->moov_retry)
8721             avio_seek(pb, 0, SEEK_SET);
8722         if ((err = mov_read_default(mov, pb, atom)) < 0) {
8723             av_log(s, AV_LOG_ERROR, "error reading header\n");
8724             return err;
8725         }
8726     } while ((pb->seekable & AVIO_SEEKABLE_NORMAL) && !mov->found_moov && !mov->moov_retry++);
8727     if (!mov->found_moov) {
8728         av_log(s, AV_LOG_ERROR, "moov atom not found\n");
8729         return AVERROR_INVALIDDATA;
8730     }
8731     av_log(mov->fc, AV_LOG_TRACE, "on_parse_exit_offset=%"PRId64"\n", avio_tell(pb));
8732 
8733     if (pb->seekable & AVIO_SEEKABLE_NORMAL) {
8734         if (mov->nb_chapter_tracks > 0 && !mov->ignore_chapters)
8735             mov_read_chapters(s);
8736         for (i = 0; i < s->nb_streams; i++)
8737             if (s->streams[i]->codecpar->codec_tag == AV_RL32("tmcd")) {
8738                 mov_read_timecode_track(s, s->streams[i]);
8739             } else if (s->streams[i]->codecpar->codec_tag == AV_RL32("rtmd")) {
8740                 mov_read_rtmd_track(s, s->streams[i]);
8741             }
8742     }
8743 
8744     /* copy timecode metadata from tmcd tracks to the related video streams */
8745     for (i = 0; i < s->nb_streams; i++) {
8746         AVStream *st = s->streams[i];
8747         MOVStreamContext *sc = st->priv_data;
8748         if (sc->timecode_track > 0) {
8749             AVDictionaryEntry *tcr;
8750             int tmcd_st_id = -1;
8751 
8752             for (j = 0; j < s->nb_streams; j++)
8753                 if (s->streams[j]->id == sc->timecode_track)
8754                     tmcd_st_id = j;
8755 
8756             if (tmcd_st_id < 0 || tmcd_st_id == i)
8757                 continue;
8758             tcr = av_dict_get(s->streams[tmcd_st_id]->metadata, "timecode", NULL, 0);
8759             if (tcr)
8760                 av_dict_set(&st->metadata, "timecode", tcr->value, 0);
8761         }
8762     }
8763     export_orphan_timecode(s);
8764 
8765     for (i = 0; i < s->nb_streams; i++) {
8766         AVStream *st = s->streams[i];
8767         FFStream *const sti = ffstream(st);
8768         MOVStreamContext *sc = st->priv_data;
8769         fix_timescale(mov, sc);
8770         if (st->codecpar->codec_type == AVMEDIA_TYPE_AUDIO &&
8771             st->codecpar->codec_id   == AV_CODEC_ID_AAC) {
8772             sti->skip_samples = sc->start_pad;
8773         }
8774         if (st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO && sc->nb_frames_for_fps > 0 && sc->duration_for_fps > 0)
8775             av_reduce(&st->avg_frame_rate.num, &st->avg_frame_rate.den,
8776                       sc->time_scale*(int64_t)sc->nb_frames_for_fps, sc->duration_for_fps, INT_MAX);
8777         if (st->codecpar->codec_type == AVMEDIA_TYPE_SUBTITLE) {
8778             if (st->codecpar->width <= 0 || st->codecpar->height <= 0) {
8779                 st->codecpar->width  = sc->width;
8780                 st->codecpar->height = sc->height;
8781             }
8782             if (st->codecpar->codec_id == AV_CODEC_ID_DVD_SUBTITLE) {
8783                 if ((err = mov_rewrite_dvd_sub_extradata(st)) < 0)
8784                     return err;
8785             }
8786         }
8787         if (mov->handbrake_version &&
8788             mov->handbrake_version <= 1000000*0 + 1000*10 + 2 &&  // 0.10.2
8789             st->codecpar->codec_id == AV_CODEC_ID_MP3) {
8790             av_log(s, AV_LOG_VERBOSE, "Forcing full parsing for mp3 stream\n");
8791             sti->need_parsing = AVSTREAM_PARSE_FULL;
8792         }
8793     }
8794 
8795     if (mov->trex_data) {
8796         for (i = 0; i < s->nb_streams; i++) {
8797             AVStream *st = s->streams[i];
8798             MOVStreamContext *sc = st->priv_data;
8799             if (st->duration > 0) {
8800                 /* Akin to sc->data_size * 8 * sc->time_scale / st->duration but accounting for overflows. */
8801                 st->codecpar->bit_rate = av_rescale(sc->data_size, ((int64_t) sc->time_scale) * 8, st->duration);
8802                 if (st->codecpar->bit_rate == INT64_MIN) {
8803                     av_log(s, AV_LOG_WARNING, "Overflow during bit rate calculation %"PRId64" * 8 * %d\n",
8804                            sc->data_size, sc->time_scale);
8805                     st->codecpar->bit_rate = 0;
8806                     if (s->error_recognition & AV_EF_EXPLODE)
8807                         return AVERROR_INVALIDDATA;
8808                 }
8809             }
8810         }
8811     }
8812 
8813     if (mov->use_mfra_for > 0) {
8814         for (i = 0; i < s->nb_streams; i++) {
8815             AVStream *st = s->streams[i];
8816             MOVStreamContext *sc = st->priv_data;
8817             if (sc->duration_for_fps > 0) {
8818                 /* Akin to sc->data_size * 8 * sc->time_scale / sc->duration_for_fps but accounting for overflows. */
8819                 st->codecpar->bit_rate = av_rescale(sc->data_size, ((int64_t) sc->time_scale) * 8, sc->duration_for_fps);
8820                 if (st->codecpar->bit_rate == INT64_MIN) {
8821                     av_log(s, AV_LOG_WARNING, "Overflow during bit rate calculation %"PRId64" * 8 * %d\n",
8822                            sc->data_size, sc->time_scale);
8823                     st->codecpar->bit_rate = 0;
8824                     if (s->error_recognition & AV_EF_EXPLODE)
8825                         return AVERROR_INVALIDDATA;
8826                 }
8827             }
8828         }
8829     }
8830 
8831     for (i = 0; i < mov->bitrates_count && i < s->nb_streams; i++) {
8832         if (mov->bitrates[i]) {
8833             s->streams[i]->codecpar->bit_rate = mov->bitrates[i];
8834         }
8835     }
8836 
8837     ff_rfps_calculate(s);
8838 
8839     for (i = 0; i < s->nb_streams; i++) {
8840         AVStream *st = s->streams[i];
8841         MOVStreamContext *sc = st->priv_data;
8842 
8843         switch (st->codecpar->codec_type) {
8844         case AVMEDIA_TYPE_AUDIO:
8845             err = ff_replaygain_export(st, s->metadata);
8846             if (err < 0)
8847                 return err;
8848             break;
8849         case AVMEDIA_TYPE_VIDEO:
8850             if (sc->display_matrix) {
8851                 err = av_stream_add_side_data(st, AV_PKT_DATA_DISPLAYMATRIX, (uint8_t*)sc->display_matrix,
8852                                               sizeof(int32_t) * 9);
8853                 if (err < 0)
8854                     return err;
8855 
8856                 sc->display_matrix = NULL;
8857             }
8858             if (sc->stereo3d) {
8859                 err = av_stream_add_side_data(st, AV_PKT_DATA_STEREO3D,
8860                                               (uint8_t *)sc->stereo3d,
8861                                               sizeof(*sc->stereo3d));
8862                 if (err < 0)
8863                     return err;
8864 
8865                 sc->stereo3d = NULL;
8866             }
8867             if (sc->spherical) {
8868                 err = av_stream_add_side_data(st, AV_PKT_DATA_SPHERICAL,
8869                                               (uint8_t *)sc->spherical,
8870                                               sc->spherical_size);
8871                 if (err < 0)
8872                     return err;
8873 
8874                 sc->spherical = NULL;
8875             }
8876             if (sc->mastering) {
8877                 err = av_stream_add_side_data(st, AV_PKT_DATA_MASTERING_DISPLAY_METADATA,
8878                                               (uint8_t *)sc->mastering,
8879                                               sizeof(*sc->mastering));
8880                 if (err < 0)
8881                     return err;
8882 
8883                 sc->mastering = NULL;
8884             }
8885             if (sc->coll) {
8886                 err = av_stream_add_side_data(st, AV_PKT_DATA_CONTENT_LIGHT_LEVEL,
8887                                               (uint8_t *)sc->coll,
8888                                               sc->coll_size);
8889                 if (err < 0)
8890                     return err;
8891 
8892                 sc->coll = NULL;
8893             }
8894             break;
8895         }
8896     }
8897     ff_configure_buffers_for_index(s, AV_TIME_BASE);
8898 
8899     for (i = 0; i < mov->frag_index.nb_items; i++)
8900         if (mov->frag_index.item[i].moof_offset <= mov->fragment.moof_offset)
8901             mov->frag_index.item[i].headers_read = 1;
8902 
8903     return 0;
8904 }
8905 
mov_find_next_sample(AVFormatContext * s,AVStream ** st)8906 static AVIndexEntry *mov_find_next_sample(AVFormatContext *s, AVStream **st)
8907 {
8908     AVIndexEntry *sample = NULL;
8909     int64_t best_dts = INT64_MAX;
8910     int i;
8911     for (i = 0; i < s->nb_streams; i++) {
8912         AVStream *avst = s->streams[i];
8913         FFStream *const avsti = ffstream(avst);
8914         MOVStreamContext *msc = avst->priv_data;
8915         if (msc->pb && msc->current_sample < avsti->nb_index_entries) {
8916             AVIndexEntry *current_sample = &avsti->index_entries[msc->current_sample];
8917             int64_t dts = av_rescale(current_sample->timestamp, AV_TIME_BASE, msc->time_scale);
8918             uint64_t dtsdiff = best_dts > dts ? best_dts - (uint64_t)dts : ((uint64_t)dts - best_dts);
8919             av_log(s, AV_LOG_TRACE, "stream %d, sample %d, dts %"PRId64"\n", i, msc->current_sample, dts);
8920             if (!sample || (!(s->pb->seekable & AVIO_SEEKABLE_NORMAL) && current_sample->pos < sample->pos) ||
8921                 ((s->pb->seekable & AVIO_SEEKABLE_NORMAL) &&
8922                  ((msc->pb != s->pb && dts < best_dts) || (msc->pb == s->pb && dts != AV_NOPTS_VALUE &&
8923                  ((dtsdiff <= AV_TIME_BASE && current_sample->pos < sample->pos) ||
8924                   (dtsdiff > AV_TIME_BASE && dts < best_dts)))))) {
8925                 sample = current_sample;
8926                 best_dts = dts;
8927                 *st = avst;
8928             }
8929         }
8930     }
8931     return sample;
8932 }
8933 
should_retry(AVIOContext * pb,int error_code)8934 static int should_retry(AVIOContext *pb, int error_code) {
8935     if (error_code == AVERROR_EOF || avio_feof(pb))
8936         return 0;
8937 
8938     return 1;
8939 }
8940 
mov_switch_root(AVFormatContext * s,int64_t target,int index)8941 static int mov_switch_root(AVFormatContext *s, int64_t target, int index)
8942 {
8943     int ret;
8944     MOVContext *mov = s->priv_data;
8945 
8946     if (index >= 0 && index < mov->frag_index.nb_items)
8947         target = mov->frag_index.item[index].moof_offset;
8948     if (avio_seek(s->pb, target, SEEK_SET) != target) {
8949         av_log(mov->fc, AV_LOG_ERROR, "root atom offset 0x%"PRIx64": partial file\n", target);
8950         return AVERROR_INVALIDDATA;
8951     }
8952 
8953     mov->next_root_atom = 0;
8954     if (index < 0 || index >= mov->frag_index.nb_items)
8955         index = search_frag_moof_offset(&mov->frag_index, target);
8956     if (index < mov->frag_index.nb_items &&
8957         mov->frag_index.item[index].moof_offset == target) {
8958         if (index + 1 < mov->frag_index.nb_items)
8959             mov->next_root_atom = mov->frag_index.item[index + 1].moof_offset;
8960         if (mov->frag_index.item[index].headers_read)
8961             return 0;
8962         mov->frag_index.item[index].headers_read = 1;
8963     }
8964 
8965     mov->found_mdat = 0;
8966 
8967     ret = mov_read_default(mov, s->pb, (MOVAtom){ AV_RL32("root"), INT64_MAX });
8968     if (ret < 0)
8969         return ret;
8970     if (avio_feof(s->pb))
8971         return AVERROR_EOF;
8972     av_log(s, AV_LOG_TRACE, "read fragments, offset 0x%"PRIx64"\n", avio_tell(s->pb));
8973 
8974     return 1;
8975 }
8976 
mov_change_extradata(MOVStreamContext * sc,AVPacket * pkt)8977 static int mov_change_extradata(MOVStreamContext *sc, AVPacket *pkt)
8978 {
8979     uint8_t *side, *extradata;
8980     int extradata_size;
8981 
8982     /* Save the current index. */
8983     sc->last_stsd_index = sc->stsc_data[sc->stsc_index].id - 1;
8984 
8985     /* Notify the decoder that extradata changed. */
8986     extradata_size = sc->extradata_size[sc->last_stsd_index];
8987     extradata = sc->extradata[sc->last_stsd_index];
8988     if (extradata_size > 0 && extradata) {
8989         side = av_packet_new_side_data(pkt,
8990                                        AV_PKT_DATA_NEW_EXTRADATA,
8991                                        extradata_size);
8992         if (!side)
8993             return AVERROR(ENOMEM);
8994         memcpy(side, extradata, extradata_size);
8995     }
8996 
8997     return 0;
8998 }
8999 
get_eia608_packet(AVIOContext * pb,AVPacket * pkt,int size)9000 static int get_eia608_packet(AVIOContext *pb, AVPacket *pkt, int size)
9001 {
9002     int new_size, ret;
9003 
9004     if (size <= 8)
9005         return AVERROR_INVALIDDATA;
9006     new_size = ((size - 8) / 2) * 3;
9007     ret = av_new_packet(pkt, new_size);
9008     if (ret < 0)
9009         return ret;
9010 
9011     avio_skip(pb, 8);
9012     for (int j = 0; j < new_size; j += 3) {
9013         pkt->data[j] = 0xFC;
9014         pkt->data[j+1] = avio_r8(pb);
9015         pkt->data[j+2] = avio_r8(pb);
9016     }
9017 
9018     return 0;
9019 }
9020 
mov_read_packet(AVFormatContext * s,AVPacket * pkt)9021 static int mov_read_packet(AVFormatContext *s, AVPacket *pkt)
9022 {
9023     MOVContext *mov = s->priv_data;
9024     MOVStreamContext *sc;
9025     AVIndexEntry *sample;
9026     AVStream *st = NULL;
9027     int64_t current_index;
9028     int ret;
9029     mov->fc = s;
9030  retry:
9031     sample = mov_find_next_sample(s, &st);
9032     if (!sample || (mov->next_root_atom && sample->pos > mov->next_root_atom)) {
9033         if (!mov->next_root_atom)
9034             return AVERROR_EOF;
9035         if ((ret = mov_switch_root(s, mov->next_root_atom, -1)) < 0)
9036             return ret;
9037         goto retry;
9038     }
9039     sc = st->priv_data;
9040     /* must be done just before reading, to avoid infinite loop on sample */
9041     current_index = sc->current_index;
9042     mov_current_sample_inc(sc);
9043 
9044     if (mov->next_root_atom) {
9045         sample->pos = FFMIN(sample->pos, mov->next_root_atom);
9046         sample->size = FFMIN(sample->size, (mov->next_root_atom - sample->pos));
9047     }
9048 
9049     if (st->discard != AVDISCARD_ALL) {
9050         int64_t ret64 = avio_seek(sc->pb, sample->pos, SEEK_SET);
9051         if (ret64 != sample->pos) {
9052             av_log(mov->fc, AV_LOG_ERROR, "stream %d, offset 0x%"PRIx64": partial file\n",
9053                    sc->ffindex, sample->pos);
9054             if (should_retry(sc->pb, ret64)) {
9055                 mov_current_sample_dec(sc);
9056             } else if (ret64 < 0) {
9057                 return (int)ret64;
9058             }
9059             return AVERROR_INVALIDDATA;
9060         }
9061 
9062         if (st->discard == AVDISCARD_NONKEY && !(sample->flags & AVINDEX_KEYFRAME)) {
9063             av_log(mov->fc, AV_LOG_DEBUG, "Nonkey frame from stream %d discarded due to AVDISCARD_NONKEY\n", sc->ffindex);
9064             goto retry;
9065         }
9066 
9067         if (st->codecpar->codec_id == AV_CODEC_ID_EIA_608 && sample->size > 8)
9068             ret = get_eia608_packet(sc->pb, pkt, sample->size);
9069         else
9070             ret = av_get_packet(sc->pb, pkt, sample->size);
9071         if (ret < 0) {
9072             if (should_retry(sc->pb, ret)) {
9073                 mov_current_sample_dec(sc);
9074             }
9075             return ret;
9076         }
9077 #ifdef OHOS_SUBTITLE_DEMUXER
9078         if (st->codecpar->codec_id == AV_CODEC_ID_WEBVTT) {
9079             if (pkt->size >= 8) {
9080                 uint32_t type = AV_RL32(pkt->data + 4);
9081                 int payload_size = pkt->size - 8;
9082                 if (type == MKTAG('v', 't', 't', 'e')) {
9083                     pkt->size = 0;
9084                 } else if (type == MKTAG('v', 't', 't', 'c')) {
9085                     uint8_t *payload_data = pkt->data + 8;
9086                     while (payload_size >= 8) {
9087                         int64_t temp_size = AV_RB32(payload_data);
9088                         uint32_t temp_type = AV_RL32(payload_data + 4);
9089                         if (temp_type == MKTAG('p', 'a', 'y', 'l')) {
9090                             payload_data += 8;
9091                             payload_size -= 8;
9092                             int move_size = payload_size;
9093                             if (pkt->size < move_size) {
9094                                 move_size = pkt->size;
9095                             }
9096                             memmove(pkt->data, payload_data, move_size);
9097                             pkt->size = payload_size;
9098                             pkt->data[pkt->size] = '\0';
9099                             break;
9100                         } else {
9101                             if (temp_size > payload_size) {
9102                                 break;
9103                             }
9104                             payload_data += temp_size;
9105                             payload_size -= temp_size;
9106                         }
9107                     }
9108                 }
9109             }
9110         }
9111 #endif
9112 #if CONFIG_DV_DEMUXER
9113         if (mov->dv_demux && sc->dv_audio_container) {
9114             ret = avpriv_dv_produce_packet(mov->dv_demux, pkt, pkt->data, pkt->size, pkt->pos);
9115             av_packet_unref(pkt);
9116             if (ret < 0)
9117                 return ret;
9118             ret = avpriv_dv_get_packet(mov->dv_demux, pkt);
9119             if (ret < 0)
9120                 return ret;
9121         }
9122 #endif
9123         if (sc->has_palette) {
9124             uint8_t *pal;
9125 
9126             pal = av_packet_new_side_data(pkt, AV_PKT_DATA_PALETTE, AVPALETTE_SIZE);
9127             if (!pal) {
9128                 av_log(mov->fc, AV_LOG_ERROR, "Cannot append palette to packet\n");
9129             } else {
9130                 memcpy(pal, sc->palette, AVPALETTE_SIZE);
9131                 sc->has_palette = 0;
9132             }
9133         }
9134         if (st->codecpar->codec_id == AV_CODEC_ID_MP3 && !ffstream(st)->need_parsing && pkt->size > 4) {
9135             if (ff_mpa_check_header(AV_RB32(pkt->data)) < 0)
9136                 ffstream(st)->need_parsing = AVSTREAM_PARSE_FULL;
9137         }
9138     }
9139 
9140     pkt->stream_index = sc->ffindex;
9141     pkt->dts = sample->timestamp;
9142     if (sample->flags & AVINDEX_DISCARD_FRAME) {
9143         pkt->flags |= AV_PKT_FLAG_DISCARD;
9144     }
9145     if (sc->ctts_data && sc->ctts_index < sc->ctts_count) {
9146         pkt->pts = pkt->dts + sc->dts_shift + sc->ctts_data[sc->ctts_index].duration;
9147         /* update ctts context */
9148         sc->ctts_sample++;
9149         if (sc->ctts_index < sc->ctts_count &&
9150             sc->ctts_data[sc->ctts_index].count == sc->ctts_sample) {
9151             sc->ctts_index++;
9152             sc->ctts_sample = 0;
9153         }
9154     } else {
9155         int64_t next_dts = (sc->current_sample < ffstream(st)->nb_index_entries) ?
9156             ffstream(st)->index_entries[sc->current_sample].timestamp : st->duration;
9157 
9158         if (next_dts >= pkt->dts)
9159             pkt->duration = next_dts - pkt->dts;
9160         pkt->pts = pkt->dts;
9161     }
9162     if (st->discard == AVDISCARD_ALL)
9163         goto retry;
9164     if (sc->sdtp_data && sc->current_sample <= sc->sdtp_count) {
9165         uint8_t sample_flags = sc->sdtp_data[sc->current_sample - 1];
9166         uint8_t sample_is_depended_on = (sample_flags >> 2) & 0x3;
9167         pkt->flags |= sample_is_depended_on == MOV_SAMPLE_DEPENDENCY_NO ? AV_PKT_FLAG_DISPOSABLE : 0;
9168     }
9169     pkt->flags |= sample->flags & AVINDEX_KEYFRAME ? AV_PKT_FLAG_KEY : 0;
9170     pkt->pos = sample->pos;
9171 
9172     /* Multiple stsd handling. */
9173     if (sc->stsc_data) {
9174         if (sc->stsc_data[sc->stsc_index].id > 0 &&
9175             sc->stsc_data[sc->stsc_index].id - 1 < sc->stsd_count &&
9176             sc->stsc_data[sc->stsc_index].id - 1 != sc->last_stsd_index) {
9177             ret = mov_change_extradata(sc, pkt);
9178             if (ret < 0)
9179                 return ret;
9180         }
9181 
9182         /* Update the stsc index for the next sample */
9183         sc->stsc_sample++;
9184         if (mov_stsc_index_valid(sc->stsc_index, sc->stsc_count) &&
9185             mov_get_stsc_samples(sc, sc->stsc_index) == sc->stsc_sample) {
9186             sc->stsc_index++;
9187             sc->stsc_sample = 0;
9188         }
9189     }
9190 
9191     if (mov->aax_mode)
9192         aax_filter(pkt->data, pkt->size, mov);
9193 
9194     ret = cenc_filter(mov, st, sc, pkt, current_index);
9195     if (ret < 0) {
9196         return ret;
9197     }
9198 
9199     return 0;
9200 }
9201 
mov_seek_fragment(AVFormatContext * s,AVStream * st,int64_t timestamp)9202 static int mov_seek_fragment(AVFormatContext *s, AVStream *st, int64_t timestamp)
9203 {
9204     MOVContext *mov = s->priv_data;
9205     int index;
9206 
9207     if (!mov->frag_index.complete)
9208         return 0;
9209 
9210     index = search_frag_timestamp(&mov->frag_index, st, timestamp);
9211     if (index < 0)
9212         index = 0;
9213     if (!mov->frag_index.item[index].headers_read)
9214         return mov_switch_root(s, -1, index);
9215     if (index + 1 < mov->frag_index.nb_items)
9216         mov->next_root_atom = mov->frag_index.item[index + 1].moof_offset;
9217 
9218     return 0;
9219 }
9220 
is_open_key_sample(const MOVStreamContext * sc,int sample)9221 static int is_open_key_sample(const MOVStreamContext *sc, int sample)
9222 {
9223     // TODO: a bisect search would scale much better
9224     for (int i = 0; i < sc->open_key_samples_count; i++) {
9225         const int oks = sc->open_key_samples[i];
9226         if (oks == sample)
9227             return 1;
9228         if (oks > sample) /* list is monotically increasing so we can stop early */
9229             break;
9230     }
9231     return 0;
9232 }
9233 
9234 /*
9235  * Some key sample may be key frames but not IDR frames, so a random access to
9236  * them may not be allowed.
9237  */
can_seek_to_key_sample(AVStream * st,int sample,int64_t requested_pts)9238 static int can_seek_to_key_sample(AVStream *st, int sample, int64_t requested_pts)
9239 {
9240     MOVStreamContext *sc = st->priv_data;
9241     FFStream *const sti = ffstream(st);
9242     int64_t key_sample_dts, key_sample_pts;
9243 
9244     if (st->codecpar->codec_id != AV_CODEC_ID_HEVC)
9245         return 1;
9246 
9247     if (sample >= sc->sample_offsets_count)
9248         return 1;
9249 
9250     key_sample_dts = sti->index_entries[sample].timestamp;
9251     key_sample_pts = key_sample_dts + sc->sample_offsets[sample] + sc->dts_shift;
9252 
9253     /*
9254      * If the sample needs to be presented before an open key sample, they may
9255      * not be decodable properly, even though they come after in decoding
9256      * order.
9257      */
9258     if (is_open_key_sample(sc, sample) && key_sample_pts > requested_pts)
9259         return 0;
9260 
9261     return 1;
9262 }
9263 
mov_seek_stream(AVFormatContext * s,AVStream * st,int64_t timestamp,int flags)9264 static int mov_seek_stream(AVFormatContext *s, AVStream *st, int64_t timestamp, int flags)
9265 {
9266     MOVStreamContext *sc = st->priv_data;
9267     FFStream *const sti = ffstream(st);
9268     int sample, time_sample, ret;
9269     unsigned int i;
9270 
9271     // Here we consider timestamp to be PTS, hence try to offset it so that we
9272     // can search over the DTS timeline.
9273     timestamp -= (sc->min_corrected_pts + sc->dts_shift);
9274 
9275     ret = mov_seek_fragment(s, st, timestamp);
9276     if (ret < 0)
9277         return ret;
9278 
9279     for (;;) {
9280         sample = av_index_search_timestamp(st, timestamp, flags);
9281         av_log(s, AV_LOG_TRACE, "stream %d, timestamp %"PRId64", sample %d\n", st->index, timestamp, sample);
9282         if (sample < 0 && sti->nb_index_entries && timestamp < sti->index_entries[0].timestamp)
9283             sample = 0;
9284         if (sample < 0) /* not sure what to do */
9285             return AVERROR_INVALIDDATA;
9286 
9287         if (!sample || can_seek_to_key_sample(st, sample, timestamp))
9288             break;
9289         timestamp -= FFMAX(sc->min_sample_duration, 1);
9290     }
9291 
9292     mov_current_sample_set(sc, sample);
9293     av_log(s, AV_LOG_TRACE, "stream %d, found sample %d\n", st->index, sc->current_sample);
9294     /* adjust ctts index */
9295     if (sc->ctts_data) {
9296         time_sample = 0;
9297         for (i = 0; i < sc->ctts_count; i++) {
9298             int next = time_sample + sc->ctts_data[i].count;
9299             if (next > sc->current_sample) {
9300                 sc->ctts_index = i;
9301                 sc->ctts_sample = sc->current_sample - time_sample;
9302                 break;
9303             }
9304             time_sample = next;
9305         }
9306     }
9307 
9308     /* adjust stsd index */
9309     if (sc->chunk_count) {
9310         time_sample = 0;
9311         for (i = 0; i < sc->stsc_count; i++) {
9312             int64_t next = time_sample + mov_get_stsc_samples(sc, i);
9313             if (next > sc->current_sample) {
9314                 sc->stsc_index = i;
9315                 sc->stsc_sample = sc->current_sample - time_sample;
9316                 break;
9317             }
9318             av_assert0(next == (int)next);
9319             time_sample = next;
9320         }
9321     }
9322 
9323     return sample;
9324 }
9325 
mov_get_skip_samples(AVStream * st,int sample)9326 static int64_t mov_get_skip_samples(AVStream *st, int sample)
9327 {
9328     MOVStreamContext *sc = st->priv_data;
9329     FFStream *const sti = ffstream(st);
9330     int64_t first_ts = sti->index_entries[0].timestamp;
9331     int64_t ts = sti->index_entries[sample].timestamp;
9332     int64_t off;
9333 
9334     if (st->codecpar->codec_type != AVMEDIA_TYPE_AUDIO)
9335         return 0;
9336 
9337     /* compute skip samples according to stream start_pad, seek ts and first ts */
9338     off = av_rescale_q(ts - first_ts, st->time_base,
9339                        (AVRational){1, st->codecpar->sample_rate});
9340     return FFMAX(sc->start_pad - off, 0);
9341 }
9342 
mov_read_seek(AVFormatContext * s,int stream_index,int64_t sample_time,int flags)9343 static int mov_read_seek(AVFormatContext *s, int stream_index, int64_t sample_time, int flags)
9344 {
9345     MOVContext *mc = s->priv_data;
9346     AVStream *st;
9347     FFStream *sti;
9348     int sample;
9349     int i;
9350 
9351     if (stream_index >= s->nb_streams)
9352         return AVERROR_INVALIDDATA;
9353 
9354     st = s->streams[stream_index];
9355     sti = ffstream(st);
9356     sample = mov_seek_stream(s, st, sample_time, flags);
9357     if (sample < 0)
9358         return sample;
9359 
9360     if (mc->seek_individually) {
9361         /* adjust seek timestamp to found sample timestamp */
9362         int64_t seek_timestamp = sti->index_entries[sample].timestamp;
9363         sti->skip_samples = mov_get_skip_samples(st, sample);
9364 
9365         for (i = 0; i < s->nb_streams; i++) {
9366             AVStream *const st  = s->streams[i];
9367             FFStream *const sti = ffstream(st);
9368             int64_t timestamp;
9369 
9370             if (stream_index == i)
9371                 continue;
9372 
9373             timestamp = av_rescale_q(seek_timestamp, s->streams[stream_index]->time_base, st->time_base);
9374             sample = mov_seek_stream(s, st, timestamp, flags);
9375             if (sample >= 0)
9376                 sti->skip_samples = mov_get_skip_samples(st, sample);
9377         }
9378     } else {
9379         for (i = 0; i < s->nb_streams; i++) {
9380             MOVStreamContext *sc;
9381             st = s->streams[i];
9382             sc = st->priv_data;
9383             mov_current_sample_set(sc, 0);
9384         }
9385         while (1) {
9386             MOVStreamContext *sc;
9387             AVIndexEntry *entry = mov_find_next_sample(s, &st);
9388             if (!entry)
9389                 return AVERROR_INVALIDDATA;
9390             sc = st->priv_data;
9391             if (sc->ffindex == stream_index && sc->current_sample == sample)
9392                 break;
9393             mov_current_sample_inc(sc);
9394         }
9395     }
9396     return 0;
9397 }
9398 
9399 #define OFFSET(x) offsetof(MOVContext, x)
9400 #define FLAGS AV_OPT_FLAG_VIDEO_PARAM | AV_OPT_FLAG_DECODING_PARAM
9401 static const AVOption mov_options[] = {
9402     {"use_absolute_path",
9403         "allow using absolute path when opening alias, this is a possible security issue",
9404         OFFSET(use_absolute_path), AV_OPT_TYPE_BOOL, {.i64 = 0},
9405         0, 1, FLAGS},
9406     {"seek_streams_individually",
9407         "Seek each stream individually to the closest point",
9408         OFFSET(seek_individually), AV_OPT_TYPE_BOOL, { .i64 = 1 },
9409         0, 1, FLAGS},
9410     {"ignore_editlist", "Ignore the edit list atom.", OFFSET(ignore_editlist), AV_OPT_TYPE_BOOL, {.i64 = 0},
9411         0, 1, FLAGS},
9412     {"advanced_editlist",
9413         "Modify the AVIndex according to the editlists. Use this option to decode in the order specified by the edits.",
9414         OFFSET(advanced_editlist), AV_OPT_TYPE_BOOL, {.i64 = 1},
9415         0, 1, FLAGS},
9416     {"ignore_chapters", "", OFFSET(ignore_chapters), AV_OPT_TYPE_BOOL, {.i64 = 0},
9417         0, 1, FLAGS},
9418     {"use_mfra_for",
9419         "use mfra for fragment timestamps",
9420         OFFSET(use_mfra_for), AV_OPT_TYPE_INT, {.i64 = FF_MOV_FLAG_MFRA_AUTO},
9421         -1, FF_MOV_FLAG_MFRA_PTS, FLAGS,
9422         "use_mfra_for"},
9423     {"auto", "auto", 0, AV_OPT_TYPE_CONST, {.i64 = FF_MOV_FLAG_MFRA_AUTO}, 0, 0,
9424         FLAGS, "use_mfra_for" },
9425     {"dts", "dts", 0, AV_OPT_TYPE_CONST, {.i64 = FF_MOV_FLAG_MFRA_DTS}, 0, 0,
9426         FLAGS, "use_mfra_for" },
9427     {"pts", "pts", 0, AV_OPT_TYPE_CONST, {.i64 = FF_MOV_FLAG_MFRA_PTS}, 0, 0,
9428         FLAGS, "use_mfra_for" },
9429     {"use_tfdt", "use tfdt for fragment timestamps", OFFSET(use_tfdt), AV_OPT_TYPE_BOOL, {.i64 = 1},
9430         0, 1, FLAGS},
9431     { "export_all", "Export unrecognized metadata entries", OFFSET(export_all),
9432         AV_OPT_TYPE_BOOL, { .i64 = 0 }, 0, 1, .flags = FLAGS },
9433     { "export_xmp", "Export full XMP metadata", OFFSET(export_xmp),
9434         AV_OPT_TYPE_BOOL, { .i64 = 0 }, 0, 1, .flags = FLAGS },
9435     { "activation_bytes", "Secret bytes for Audible AAX files", OFFSET(activation_bytes),
9436         AV_OPT_TYPE_BINARY, .flags = AV_OPT_FLAG_DECODING_PARAM },
9437     { "audible_key", "AES-128 Key for Audible AAXC files", OFFSET(audible_key),
9438         AV_OPT_TYPE_BINARY, .flags = AV_OPT_FLAG_DECODING_PARAM },
9439     { "audible_iv", "AES-128 IV for Audible AAXC files", OFFSET(audible_iv),
9440         AV_OPT_TYPE_BINARY, .flags = AV_OPT_FLAG_DECODING_PARAM },
9441     { "audible_fixed_key", // extracted from libAAX_SDK.so and AAXSDKWin.dll files!
9442         "Fixed key used for handling Audible AAX files", OFFSET(audible_fixed_key),
9443         AV_OPT_TYPE_BINARY, {.str="77214d4b196a87cd520045fd20a51d67"},
9444         .flags = AV_OPT_FLAG_DECODING_PARAM },
9445     { "decryption_key", "The media decryption key (hex)", OFFSET(decryption_key), AV_OPT_TYPE_BINARY, .flags = AV_OPT_FLAG_DECODING_PARAM },
9446     { "enable_drefs", "Enable external track support.", OFFSET(enable_drefs), AV_OPT_TYPE_BOOL,
9447         {.i64 = 0}, 0, 1, FLAGS },
9448     { "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 },
9449 
9450     { NULL },
9451 };
9452 
9453 static const AVClass mov_class = {
9454     .class_name = "mov,mp4,m4a,3gp,3g2,mj2",
9455     .item_name  = av_default_item_name,
9456     .option     = mov_options,
9457     .version    = LIBAVUTIL_VERSION_INT,
9458 };
9459 
9460 const AVInputFormat ff_mov_demuxer = {
9461     .name           = "mov,mp4,m4a,3gp,3g2,mj2",
9462     .long_name      = NULL_IF_CONFIG_SMALL("QuickTime / MOV"),
9463     .priv_class     = &mov_class,
9464     .priv_data_size = sizeof(MOVContext),
9465     .extensions     = "mov,mp4,m4a,3gp,3g2,mj2,psp,m4b,ism,ismv,isma,f4v,avif",
9466     .flags_internal = FF_FMT_INIT_CLEANUP,
9467     .read_probe     = mov_probe,
9468     .read_header    = mov_read_header,
9469     .read_packet    = mov_read_packet,
9470     .read_close     = mov_read_close,
9471     .read_seek      = mov_read_seek,
9472     .flags          = AVFMT_NO_BYTE_SEEK | AVFMT_SEEK_TO_PTS | AVFMT_SHOW_IDS,
9473 };