LCOV - code coverage report
Current view: top level - libavformat - mov.c (source / functions) Hit Total Coverage
Test: coverage.info Lines: 2815 4588 61.4 %
Date: 2018-05-20 11:54:08 Functions: 120 153 78.4 %

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

Generated by: LCOV version 1.13