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