chromium/third_party/ffmpeg/libavformat/mov.c

/*
 * MOV demuxer
 * Copyright (c) 2001 Fabrice Bellard
 * Copyright (c) 2009 Baptiste Coudurier <baptiste dot coudurier at gmail dot com>
 *
 * first version by Francois Revol <[email protected]>
 * seek function by Gael Chardon <[email protected]>
 *
 * This file is part of FFmpeg.
 *
 * FFmpeg is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * FFmpeg is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with FFmpeg; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
 */

#include "config_components.h"

#include <inttypes.h>
#include <limits.h>
#include <stdint.h>

#include "libavutil/attributes.h"
#include "libavutil/bprint.h"
#include "libavutil/channel_layout.h"
#include "libavutil/dict_internal.h"
#include "libavutil/internal.h"
#include "libavutil/intreadwrite.h"
#include "libavutil/intfloat.h"
#include "libavutil/mathematics.h"
#include "libavutil/avassert.h"
#include "libavutil/avstring.h"
#include "libavutil/dict.h"
#include "libavutil/mem.h"
#include "libavutil/opt.h"
#include "libavutil/aes.h"
#include "libavutil/aes_ctr.h"
#include "libavutil/pixdesc.h"
#include "libavutil/sha.h"
#include "libavutil/spherical.h"
#include "libavutil/stereo3d.h"
#include "libavutil/timecode.h"
#include "libavutil/uuid.h"
#include "libavcodec/ac3tab.h"
#include "libavcodec/flac.h"
#include "libavcodec/hevc.h"
#include "libavcodec/mpegaudiodecheader.h"
#include "libavcodec/mlp_parse.h"
#include "avformat.h"
#include "internal.h"
#include "avio_internal.h"
#include "demux.h"
#include "iamf_parse.h"
#include "iamf_reader.h"
#include "dovi_isom.h"
#include "riff.h"
#include "isom.h"
#include "libavcodec/get_bits.h"
#include "id3v1.h"
#include "mov_chan.h"
#include "replaygain.h"

#if CONFIG_ZLIB
#include <zlib.h>
#endif

#include "qtpalette.h"

/* those functions parse an atom */
/* links atom IDs to parse functions */
MOVParseTableEntry;

static int mov_read_default(MOVContext *c, AVIOContext *pb, MOVAtom atom);
static int mov_read_mfra(MOVContext *c, AVIOContext *f);
static void mov_free_stream_context(AVFormatContext *s, AVStream *st);
static int64_t add_ctts_entry(MOVCtts** ctts_data, unsigned int* ctts_count, unsigned int* allocated_size,
                              int count, int duration);

static int mov_metadata_track_or_disc_number(MOVContext *c, AVIOContext *pb,
                                             unsigned len, const char *key)
{}

static int mov_metadata_int8_bypass_padding(MOVContext *c, AVIOContext *pb,
                                            unsigned len, const char *key)
{}

static int mov_metadata_int8_no_padding(MOVContext *c, AVIOContext *pb,
                                        unsigned len, const char *key)
{}

static int mov_metadata_gnre(MOVContext *c, AVIOContext *pb,
                             unsigned len, const char *key)
{}

static const uint32_t mac_to_unicode[128] =;

static int mov_read_mac_string(MOVContext *c, AVIOContext *pb, int len,
                               char *dst, int dstlen)
{}

static AVStream *get_curr_st(MOVContext *c)
{}

static int mov_read_covr(MOVContext *c, AVIOContext *pb, int type, int len)
{}

// 3GPP TS 26.244
static int mov_metadata_loci(MOVContext *c, AVIOContext *pb, unsigned len)
{}

static int mov_metadata_hmmt(MOVContext *c, AVIOContext *pb, unsigned len)
{}

static int mov_read_udta_string(MOVContext *c, AVIOContext *pb, MOVAtom atom)
{}

static int mov_read_chpl(MOVContext *c, AVIOContext *pb, MOVAtom atom)
{}

#define MIN_DATA_ENTRY_BOX_SIZE
static int mov_read_dref(MOVContext *c, AVIOContext *pb, MOVAtom atom)
{}

static int mov_read_hdlr(MOVContext *c, AVIOContext *pb, MOVAtom atom)
{}

static int mov_read_esds(MOVContext *c, AVIOContext *pb, MOVAtom atom)
{}

static int mov_read_dac3(MOVContext *c, AVIOContext *pb, MOVAtom atom)
{}

#if CONFIG_IAMFDEC
static int mov_read_iacb(MOVContext *c, AVIOContext *pb, MOVAtom atom)
{
    AVStream *st;
    MOVStreamContext *sc;
    FFIOContext b;
    AVIOContext *descriptor_pb;
    AVDictionary *metadata;
    IAMFContext *iamf;
    int64_t start_time, duration;
    unsigned descriptors_size;
    int nb_frames, disposition;
    int version, ret;

    if (atom.size < 5)
        return AVERROR_INVALIDDATA;

    if (c->fc->nb_streams < 1)
        return 0;

    version = avio_r8(pb);
    if (version != 1) {
        av_log(c->fc, AV_LOG_ERROR, "%s configurationVersion %d",
               version < 1 ? "invalid" : "unsupported", version);
        return AVERROR_INVALIDDATA;
    }

    descriptors_size = ffio_read_leb(pb);
    if (!descriptors_size || descriptors_size > INT_MAX)
        return AVERROR_INVALIDDATA;

    st = c->fc->streams[c->fc->nb_streams - 1];
    sc = st->priv_data;

    sc->iamf = av_mallocz(sizeof(*sc->iamf));
    if (!sc->iamf)
        return AVERROR(ENOMEM);
    iamf = &sc->iamf->iamf;

    st->codecpar->extradata = av_malloc(descriptors_size);
    if (!st->codecpar->extradata)
        return AVERROR(ENOMEM);
    st->codecpar->extradata_size = descriptors_size;

    ret = avio_read(pb, st->codecpar->extradata, descriptors_size);
    if (ret != descriptors_size)
        return ret < 0 ? ret : AVERROR_INVALIDDATA;

    ffio_init_read_context(&b, st->codecpar->extradata, descriptors_size);
    descriptor_pb = &b.pub;

    ret = ff_iamfdec_read_descriptors(iamf, descriptor_pb, descriptors_size, c->fc);
    if (ret < 0)
        return ret;

    metadata = st->metadata;
    st->metadata = NULL;
    start_time = st->start_time;
    nb_frames = st->nb_frames;
    duration = st->duration;
    disposition = st->disposition;

    for (int i = 0; i < iamf->nb_audio_elements; i++) {
        IAMFAudioElement *audio_element = iamf->audio_elements[i];
        const AVIAMFAudioElement *element;
        AVStreamGroup *stg =
            avformat_stream_group_create(c->fc, AV_STREAM_GROUP_PARAMS_IAMF_AUDIO_ELEMENT, NULL);

        if (!stg) {
            ret = AVERROR(ENOMEM);
            goto fail;
        }

        av_iamf_audio_element_free(&stg->params.iamf_audio_element);
        stg->id = audio_element->audio_element_id;
        /* Transfer ownership */
        element = stg->params.iamf_audio_element = audio_element->element;
        audio_element->element = NULL;

        for (int j = 0; j < audio_element->nb_substreams; j++) {
            IAMFSubStream *substream = &audio_element->substreams[j];
            AVStream *stream;

            if (!i && !j) {
                if (audio_element->layers[0].substream_count != 1)
                    disposition &= ~AV_DISPOSITION_DEFAULT;
                stream = st;
            } else
                stream = avformat_new_stream(c->fc, NULL);
            if (!stream) {
                ret = AVERROR(ENOMEM);
                goto fail;
            }

            stream->start_time = start_time;
            stream->nb_frames = nb_frames;
            stream->duration = duration;
            stream->disposition = disposition;
            if (stream != st) {
                stream->priv_data = sc;
                sc->refcount++;
            }

            if (element->audio_element_type == AV_IAMF_AUDIO_ELEMENT_TYPE_SCENE)
                stream->disposition |= AV_DISPOSITION_DEPENDENT;
            if (i || j) {
                stream->disposition |= AV_DISPOSITION_DEPENDENT;
                if (audio_element->layers[0].substream_count == 1)
                    stream->disposition &= ~AV_DISPOSITION_DEFAULT;
            }

            ret = avcodec_parameters_copy(stream->codecpar, substream->codecpar);
            if (ret < 0)
                goto fail;

            stream->id = substream->audio_substream_id;

            avpriv_set_pts_info(st, 64, 1, sc->time_scale);

            ret = avformat_stream_group_add_stream(stg, stream);
            if (ret < 0)
                goto fail;
        }

        ret = av_dict_copy(&stg->metadata, metadata, 0);
        if (ret < 0)
            goto fail;
    }

    for (int i = 0; i < iamf->nb_mix_presentations; i++) {
        IAMFMixPresentation *mix_presentation = iamf->mix_presentations[i];
        const AVIAMFMixPresentation *mix = mix_presentation->cmix;
        AVStreamGroup *stg =
            avformat_stream_group_create(c->fc, AV_STREAM_GROUP_PARAMS_IAMF_MIX_PRESENTATION, NULL);

        if (!stg) {
            ret = AVERROR(ENOMEM);
            goto fail;
        }

        av_iamf_mix_presentation_free(&stg->params.iamf_mix_presentation);
        stg->id = mix_presentation->mix_presentation_id;
        /* Transfer ownership */
        stg->params.iamf_mix_presentation = mix_presentation->mix;
        mix_presentation->mix = NULL;

        for (int j = 0; j < mix->nb_submixes; j++) {
            const AVIAMFSubmix *submix = mix->submixes[j];

            for (int k = 0; k < submix->nb_elements; k++) {
                const AVIAMFSubmixElement *submix_element = submix->elements[k];
                const AVStreamGroup *audio_element = NULL;

                for (int l = 0; l < c->fc->nb_stream_groups; l++)
                    if (c->fc->stream_groups[l]->type == AV_STREAM_GROUP_PARAMS_IAMF_AUDIO_ELEMENT &&
                        c->fc->stream_groups[l]->id   == submix_element->audio_element_id) {
                        audio_element = c->fc->stream_groups[l];
                        break;
                    }
                av_assert0(audio_element);

                for (int l = 0; l < audio_element->nb_streams; l++) {
                    ret = avformat_stream_group_add_stream(stg, audio_element->streams[l]);
                    if (ret < 0 && ret != AVERROR(EEXIST))
                        goto fail;
                }
            }
        }

        ret = av_dict_copy(&stg->metadata, metadata, 0);
        if (ret < 0)
            goto fail;
    }

    ret = 0;
fail:
    av_dict_free(&metadata);

    return ret;
}
#endif

static int mov_read_dec3(MOVContext *c, AVIOContext *pb, MOVAtom atom)
{}

static int mov_read_ddts(MOVContext *c, AVIOContext *pb, MOVAtom atom)
{}

static int mov_read_chan(MOVContext *c, AVIOContext *pb, MOVAtom atom)
{}

static int mov_read_chnl(MOVContext *c, AVIOContext *pb, MOVAtom atom)
{}

static int mov_read_wfex(MOVContext *c, AVIOContext *pb, MOVAtom atom)
{}

/* This atom overrides any previously set aspect ratio */
static int mov_read_pasp(MOVContext *c, AVIOContext *pb, MOVAtom atom)
{}

/* this atom contains actual media data */
static int mov_read_mdat(MOVContext *c, AVIOContext *pb, MOVAtom atom)
{}

#define DRM_BLOB_SIZE

static int mov_read_adrm(MOVContext *c, AVIOContext *pb, MOVAtom atom)
{}

static int mov_aaxc_crypto(MOVContext *c)
{}

// Audible AAX (and AAX+) bytestream decryption
static int aax_filter(uint8_t *input, int size, MOVContext *c)
{}

/* read major brand, minor version and compatible brands and store them as metadata */
static int mov_read_ftyp(MOVContext *c, AVIOContext *pb, MOVAtom atom)
{}

/* this atom should contain all header atoms */
static int mov_read_moov(MOVContext *c, AVIOContext *pb, MOVAtom atom)
{}

static MOVFragmentStreamInfo * get_frag_stream_info(
    MOVFragmentIndex *frag_index,
    int index,
    int id)
{}

static void set_frag_stream(MOVFragmentIndex *frag_index, int id)
{}

static MOVFragmentStreamInfo * get_current_frag_stream_info(
    MOVFragmentIndex *frag_index)
{}

static int search_frag_moof_offset(MOVFragmentIndex *frag_index, int64_t offset)
{}

static int64_t get_stream_info_time(MOVFragmentStreamInfo * frag_stream_info)
{}

static int64_t get_frag_time(AVFormatContext *s, AVStream *dst_st,
                             MOVFragmentIndex *frag_index, int index)
{}

static int search_frag_timestamp(AVFormatContext *s, MOVFragmentIndex *frag_index,
                                 AVStream *st, int64_t timestamp)
{}

static int update_frag_index(MOVContext *c, int64_t offset)
{}

static void fix_frag_index_entries(MOVFragmentIndex *frag_index, int index,
                                   int id, int entries)
{}

static int mov_read_moof(MOVContext *c, AVIOContext *pb, MOVAtom atom)
{}

static void mov_metadata_creation_time(MOVContext *c, AVIOContext *pb, AVDictionary **metadata, int version)
{}

static int mov_read_mdhd(MOVContext *c, AVIOContext *pb, MOVAtom atom)
{}

static int mov_read_mvhd(MOVContext *c, AVIOContext *pb, MOVAtom atom)
{}

static void set_last_stream_little_endian(AVFormatContext *fc)
{}

static int mov_read_enda(MOVContext *c, AVIOContext *pb, MOVAtom atom)
{}

static int mov_read_pcmc(MOVContext *c, AVIOContext *pb, MOVAtom atom)
{}

static int mov_read_colr(MOVContext *c, AVIOContext *pb, MOVAtom atom)
{}

static int mov_read_fiel(MOVContext *c, AVIOContext *pb, MOVAtom atom)
{}

static int mov_realloc_extradata(AVCodecParameters *par, MOVAtom atom)
{}

/* Read a whole atom into the extradata return the size of the atom read, possibly truncated if != atom.size */
static int64_t mov_read_atom_into_extradata(MOVContext *c, AVIOContext *pb, MOVAtom atom,
                                        AVCodecParameters *par, uint8_t *buf)
{}

/* FIXME modify QDM2/SVQ3/H.264 decoders to take full atom as extradata */
static int mov_read_extradata(MOVContext *c, AVIOContext *pb, MOVAtom atom,
                              enum AVCodecID codec_id)
{}

/* wrapper functions for reading ALAC/AVS/MJPEG/MJPEG2000 extradata atoms only for those codecs */
static int mov_read_alac(MOVContext *c, AVIOContext *pb, MOVAtom atom)
{}

static int mov_read_avss(MOVContext *c, AVIOContext *pb, MOVAtom atom)
{}

static int mov_read_jp2h(MOVContext *c, AVIOContext *pb, MOVAtom atom)
{}

static int mov_read_dpxe(MOVContext *c, AVIOContext *pb, MOVAtom atom)
{}

static int mov_read_avid(MOVContext *c, AVIOContext *pb, MOVAtom atom)
{}

static int mov_read_targa_y216(MOVContext *c, AVIOContext *pb, MOVAtom atom)
{}

static int mov_read_ares(MOVContext *c, AVIOContext *pb, MOVAtom atom)
{}

static int mov_read_aclr(MOVContext *c, AVIOContext *pb, MOVAtom atom)
{}

static int mov_read_svq3(MOVContext *c, AVIOContext *pb, MOVAtom atom)
{}

static int mov_read_wave(MOVContext *c, AVIOContext *pb, MOVAtom atom)
{}

/**
 * This function reads atom content and puts data in extradata without tag
 * nor size unlike mov_read_extradata.
 */
static int mov_read_glbl(MOVContext *c, AVIOContext *pb, MOVAtom atom)
{}

static int mov_read_dvc1(MOVContext *c, AVIOContext *pb, MOVAtom atom)
{}

/**
 * An strf atom is a BITMAPINFOHEADER struct. This struct is 40 bytes itself,
 * but can have extradata appended at the end after the 40 bytes belonging
 * to the struct.
 */
static int mov_read_strf(MOVContext *c, AVIOContext *pb, MOVAtom atom)
{}

static int mov_read_stco(MOVContext *c, AVIOContext *pb, MOVAtom atom)
{}

static int mov_codec_id(AVStream *st, uint32_t format)
{}

static void mov_parse_stsd_video(MOVContext *c, AVIOContext *pb,
                                 AVStream *st, MOVStreamContext *sc)
{}

static void mov_parse_stsd_audio(MOVContext *c, AVIOContext *pb,
                                 AVStream *st, MOVStreamContext *sc)
{}

static void mov_parse_stsd_subtitle(MOVContext *c, AVIOContext *pb,
                                    AVStream *st, MOVStreamContext *sc,
                                    int64_t size)
{}

static uint32_t yuv_to_rgba(uint32_t ycbcr)
{}

static int mov_rewrite_dvd_sub_extradata(AVStream *st)
{}

static int mov_parse_stsd_data(MOVContext *c, AVIOContext *pb,
                                AVStream *st, MOVStreamContext *sc,
                                int64_t size)
{}

static int mov_finalize_stsd_codec(MOVContext *c, AVIOContext *pb,
                                   AVStream *st, MOVStreamContext *sc)
{}

static int mov_skip_multiple_stsd(MOVContext *c, AVIOContext *pb,
                                  int codec_tag, int format,
                                  int64_t size)
{}

int ff_mov_read_stsd_entries(MOVContext *c, AVIOContext *pb, int entries)
{}

static int mov_read_stsd(MOVContext *c, AVIOContext *pb, MOVAtom atom)
{}

static int mov_read_stsc(MOVContext *c, AVIOContext *pb, MOVAtom atom)
{}

static inline int mov_stsc_index_valid(unsigned int index, unsigned int count)
{}

/* Compute the samples value for the stsc entry at the given index. */
static inline int64_t mov_get_stsc_samples(MOVStreamContext *sc, unsigned int index)
{}

static int mov_read_stps(MOVContext *c, AVIOContext *pb, MOVAtom atom)
{}

static int mov_read_stss(MOVContext *c, AVIOContext *pb, MOVAtom atom)
{}

static int mov_read_stsz(MOVContext *c, AVIOContext *pb, MOVAtom atom)
{}

static int mov_read_stts(MOVContext *c, AVIOContext *pb, MOVAtom atom)
{}

static int mov_read_sdtp(MOVContext *c, AVIOContext *pb, MOVAtom atom)
{}

static void mov_update_dts_shift(MOVStreamContext *sc, int duration, void *logctx)
{}

static int mov_read_ctts(MOVContext *c, AVIOContext *pb, MOVAtom atom)
{}

static int mov_read_sgpd(MOVContext *c, AVIOContext *pb, MOVAtom atom)
{}

static int mov_read_sbgp(MOVContext *c, AVIOContext *pb, MOVAtom atom)
{}

/**
 * Get ith edit list entry (media time, duration).
 */
static int get_edit_list_entry(MOVContext *mov,
                               const MOVStreamContext *msc,
                               unsigned int edit_list_index,
                               int64_t *edit_list_media_time,
                               int64_t *edit_list_duration,
                               int64_t global_timescale)
{}

/**
 * Find the closest previous frame to the timestamp_pts, in e_old index
 * entries. Searching for just any frame / just key frames can be controlled by
 * last argument 'flag'.
 * Note that if ctts_data is not NULL, we will always search for a key frame
 * irrespective of the value of 'flag'. If we don't find any keyframe, we will
 * return the first frame of the video.
 *
 * Here the timestamp_pts is considered to be a presentation timestamp and
 * the timestamp of index entries are considered to be decoding timestamps.
 *
 * Returns 0 if successful in finding a frame, else returns -1.
 * Places the found index corresponding output arg.
 *
 * If ctts_old is not NULL, then refines the searched entry by searching
 * backwards from the found timestamp, to find the frame with correct PTS.
 *
 * Places the found ctts_index and ctts_sample in corresponding output args.
 */
static int find_prev_closest_index(AVStream *st,
                                   AVIndexEntry *e_old,
                                   int nb_old,
                                   MOVCtts* ctts_data,
                                   int64_t ctts_count,
                                   int64_t timestamp_pts,
                                   int flag,
                                   int64_t* index,
                                   int64_t* ctts_index,
                                   int64_t* ctts_sample)
{}

/**
 * Add index entry with the given values, to the end of ffstream(st)->index_entries.
 * Returns the new size ffstream(st)->index_entries if successful, else returns -1.
 *
 * This function is similar to ff_add_index_entry in libavformat/utils.c
 * except that here we are always unconditionally adding an index entry to
 * the end, instead of searching the entries list and skipping the add if
 * there is an existing entry with the same timestamp.
 * This is needed because the mov_fix_index calls this func with the same
 * unincremented timestamp for successive discarded frames.
 */
static int64_t add_index_entry(AVStream *st, int64_t pos, int64_t timestamp,
                               int size, int distance, int flags)
{}

/**
 * Rewrite timestamps of index entries in the range [end_index - frame_duration_buffer_size, end_index)
 * by subtracting end_ts successively by the amounts given in frame_duration_buffer.
 */
static void fix_index_entry_timestamps(AVStream* st, int end_index, int64_t end_ts,
                                       int64_t* frame_duration_buffer,
                                       int frame_duration_buffer_size) {}

/**
 * Append a new ctts entry to ctts_data.
 * Returns the new ctts_count if successful, else returns -1.
 */
static int64_t add_ctts_entry(MOVCtts** ctts_data, unsigned int* ctts_count, unsigned int* allocated_size,
                              int count, int duration)
{}

#define MAX_REORDER_DELAY
static void mov_estimate_video_delay(MOVContext *c, AVStream* st)
{}

static void mov_current_sample_inc(MOVStreamContext *sc)
{}

static void mov_current_sample_dec(MOVStreamContext *sc)
{}

static void mov_current_sample_set(MOVStreamContext *sc, int current_sample)
{}

/**
 * Fix ffstream(st)->index_entries, so that it contains only the entries (and the entries
 * which are needed to decode them) that fall in the edit list time ranges.
 * Also fixes the timestamps of the index entries to match the timeline
 * specified the edit lists.
 */
static void mov_fix_index(MOVContext *mov, AVStream *st)
{}

static uint32_t get_sgpd_sync_index(const MOVStreamContext *sc, int nal_unit_type)
{}

static int build_open_gop_key_points(AVStream *st)
{}

static void mov_build_index(MOVContext *mov, AVStream *st)
{}

static int test_same_origin(const char *src, const char *ref) {}

static int mov_open_dref(MOVContext *c, AVIOContext **pb, const char *src, MOVDref *ref)
{}

static void fix_timescale(MOVContext *c, MOVStreamContext *sc)
{}

#if CONFIG_IAMFDEC
static int mov_update_iamf_streams(MOVContext *c, const AVStream *st)
{
    const MOVStreamContext *sc = st->priv_data;
    const IAMFContext *iamf = &sc->iamf->iamf;

    for (int i = 0; i < iamf->nb_audio_elements; i++) {
        const AVStreamGroup *stg = NULL;

        for (int j = 0; j < c->fc->nb_stream_groups; j++)
            if (c->fc->stream_groups[j]->id == iamf->audio_elements[i]->audio_element_id)
                stg = c->fc->stream_groups[j];
        av_assert0(stg);

        for (int j = 0; j < stg->nb_streams; j++) {
            const FFStream *sti = cffstream(st);
            AVStream *out = stg->streams[j];
            FFStream *out_sti = ffstream(stg->streams[j]);

            out->codecpar->bit_rate = 0;

            if (out == st)
                continue;

            out->time_base           = st->time_base;
            out->start_time          = st->start_time;
            out->duration            = st->duration;
            out->nb_frames           = st->nb_frames;
            out->discard             = st->discard;

            av_assert0(!out_sti->index_entries);
            out_sti->index_entries = av_malloc(sti->index_entries_allocated_size);
            if (!out_sti->index_entries)
                return AVERROR(ENOMEM);

            out_sti->index_entries_allocated_size = sti->index_entries_allocated_size;
            out_sti->nb_index_entries = sti->nb_index_entries;
            out_sti->skip_samples = sti->skip_samples;
            memcpy(out_sti->index_entries, sti->index_entries, sti->index_entries_allocated_size);
        }
    }

    return 0;
}
#endif

static int mov_read_trak(MOVContext *c, AVIOContext *pb, MOVAtom atom)
{}

static int mov_read_ilst(MOVContext *c, AVIOContext *pb, MOVAtom atom)
{}

static int mov_read_keys(MOVContext *c, AVIOContext *pb, MOVAtom atom)
{}

static int mov_read_custom(MOVContext *c, AVIOContext *pb, MOVAtom atom)
{}

static int heif_add_stream(MOVContext *c, HEIFItem *item)
{}

static int mov_read_meta(MOVContext *c, AVIOContext *pb, MOVAtom atom)
{}

// return 1 when matrix is identity, 0 otherwise
#define IS_MATRIX_IDENT(matrix)

static int mov_read_tkhd(MOVContext *c, AVIOContext *pb, MOVAtom atom)
{}

static int mov_read_tfhd(MOVContext *c, AVIOContext *pb, MOVAtom atom)
{}

static int mov_read_chap(MOVContext *c, AVIOContext *pb, MOVAtom atom)
{}

static int mov_read_trex(MOVContext *c, AVIOContext *pb, MOVAtom atom)
{}

static int mov_read_tfdt(MOVContext *c, AVIOContext *pb, MOVAtom atom)
{}

static int mov_read_trun(MOVContext *c, AVIOContext *pb, MOVAtom atom)
{}

static int mov_read_sidx(MOVContext *c, AVIOContext *pb, MOVAtom atom)
{}

/* this atom should be null (from specs), but some buggy files put the 'moov' atom inside it... */
/* like the files created with Adobe Premiere 5.0, for samples see */
/* http://graphics.tudelft.nl/~wouter/publications/soundtests/ */
static int mov_read_wide(MOVContext *c, AVIOContext *pb, MOVAtom atom)
{}

static int mov_read_cmov(MOVContext *c, AVIOContext *pb, MOVAtom atom)
{}

/* edit list atom */
static int mov_read_elst(MOVContext *c, AVIOContext *pb, MOVAtom atom)
{}

static int mov_read_tmcd(MOVContext *c, AVIOContext *pb, MOVAtom atom)
{}

static int mov_read_vpcc(MOVContext *c, AVIOContext *pb, MOVAtom atom)
{}

static int mov_read_smdm(MOVContext *c, AVIOContext *pb, MOVAtom atom)
{}

static int mov_read_mdcv(MOVContext *c, AVIOContext *pb, MOVAtom atom)
{}

static int mov_read_coll(MOVContext *c, AVIOContext *pb, MOVAtom atom)
{}

static int mov_read_clli(MOVContext *c, AVIOContext *pb, MOVAtom atom)
{}

static int mov_read_amve(MOVContext *c, AVIOContext *pb, MOVAtom atom)
{}

static int mov_read_st3d(MOVContext *c, AVIOContext *pb, MOVAtom atom)
{}

static int mov_read_sv3d(MOVContext *c, AVIOContext *pb, MOVAtom atom)
{}

static int mov_parse_uuid_spherical(MOVStreamContext *sc, AVIOContext *pb, size_t len)
{}

static int mov_read_uuid(MOVContext *c, AVIOContext *pb, MOVAtom atom)
{}

static int mov_read_free(MOVContext *c, AVIOContext *pb, MOVAtom atom)
{}

static int mov_read_frma(MOVContext *c, AVIOContext *pb, MOVAtom atom)
{}

/**
 * Gets the current encryption info and associated current stream context.  If
 * we are parsing a track fragment, this will return the specific encryption
 * info for this fragment; otherwise this will return the global encryption
 * info for the current stream.
 */
static int get_current_encryption_info(MOVContext *c, MOVEncryptionIndex **encryption_index, MOVStreamContext **sc)
{}

static int mov_read_sample_encryption_info(MOVContext *c, AVIOContext *pb, MOVStreamContext *sc, AVEncryptionInfo **sample, int use_subsamples)
{}

static int mov_read_senc(MOVContext *c, AVIOContext *pb, MOVAtom atom)
{}

static int mov_parse_auxiliary_info(MOVContext *c, MOVStreamContext *sc, AVIOContext *pb, MOVEncryptionIndex *encryption_index)
{}

static int mov_read_saiz(MOVContext *c, AVIOContext *pb, MOVAtom atom)
{}

static int mov_read_saio(MOVContext *c, AVIOContext *pb, MOVAtom atom)
{}

static int mov_read_pssh(MOVContext *c, AVIOContext *pb, MOVAtom atom)
{}

static int mov_read_schm(MOVContext *c, AVIOContext *pb, MOVAtom atom)
{}

static int mov_read_tenc(MOVContext *c, AVIOContext *pb, MOVAtom atom)
{}

static int mov_read_dfla(MOVContext *c, AVIOContext *pb, MOVAtom atom)
{}

static int cenc_scheme_decrypt(MOVContext *c, MOVStreamContext *sc, AVEncryptionInfo *sample, uint8_t *input, int size)
{}

static int cbc1_scheme_decrypt(MOVContext *c, MOVStreamContext *sc, AVEncryptionInfo *sample, uint8_t *input, int size)
{}

static int cens_scheme_decrypt(MOVContext *c, MOVStreamContext *sc, AVEncryptionInfo *sample, uint8_t *input, int size)
{}

static int cbcs_scheme_decrypt(MOVContext *c, MOVStreamContext *sc, AVEncryptionInfo *sample, uint8_t *input, int size)
{}

static int cenc_decrypt(MOVContext *c, MOVStreamContext *sc, AVEncryptionInfo *sample, uint8_t *input, int size)
{}

static MOVFragmentStreamInfo *get_frag_stream_info_from_pkt(MOVFragmentIndex *frag_index, AVPacket *pkt, int id)
{}

static int cenc_filter(MOVContext *mov, AVStream* st, MOVStreamContext *sc, AVPacket *pkt, int current_index)
{}

static int mov_read_dops(MOVContext *c, AVIOContext *pb, MOVAtom atom)
{}

static int mov_read_dmlp(MOVContext *c, AVIOContext *pb, MOVAtom atom)
{}

static int mov_read_dvcc_dvvc(MOVContext *c, AVIOContext *pb, MOVAtom atom)
{}

static int mov_read_kind(MOVContext *c, AVIOContext *pb, MOVAtom atom)
{}

static int mov_read_SA3D(MOVContext *c, AVIOContext *pb, MOVAtom atom)
{}

static int mov_read_SAND(MOVContext *c, AVIOContext *pb, MOVAtom atom)
{}

static int rb_size(AVIOContext *pb, uint64_t* value, int size)
{}

static int mov_read_pitm(MOVContext *c, AVIOContext *pb, MOVAtom atom)
{}

static int mov_read_idat(MOVContext *c, AVIOContext *pb, MOVAtom atom)
{}

static int mov_read_iloc(MOVContext *c, AVIOContext *pb, MOVAtom atom)
{}

static int mov_read_infe(MOVContext *c, AVIOContext *pb, MOVAtom atom, int idx)
{}

static int mov_read_iinf(MOVContext *c, AVIOContext *pb, MOVAtom atom)
{}

static int mov_read_iref_dimg(MOVContext *c, AVIOContext *pb, int version)
{}

static int mov_read_iref_thmb(MOVContext *c, AVIOContext *pb, int version)
{}

static int mov_read_iref(MOVContext *c, AVIOContext *pb, MOVAtom atom)
{}

static int mov_read_ispe(MOVContext *c, AVIOContext *pb, MOVAtom atom)
{}

static int mov_read_iprp(MOVContext *c, AVIOContext *pb, MOVAtom atom)
{}

static const MOVParseTableEntry mov_default_parse_table[] =;

static int mov_read_default(MOVContext *c, AVIOContext *pb, MOVAtom atom)
{}

static int mov_probe(const AVProbeData *p)
{}

// must be done after parsing all trak because there's no order requirement
static void mov_read_chapters(AVFormatContext *s)
{}

static int parse_timecode_in_framenum_format(AVFormatContext *s, AVStream *st,
                                             int64_t value, int flags)
{}

static int mov_read_rtmd_track(AVFormatContext *s, AVStream *st)
{}

static int mov_read_timecode_track(AVFormatContext *s, AVStream *st)
{}

static void mov_free_encryption_index(MOVEncryptionIndex **index) {}

static void mov_free_stream_context(AVFormatContext *s, AVStream *st)
{}

static int mov_read_close(AVFormatContext *s)
{}

static int tmcd_is_referenced(AVFormatContext *s, int tmcd_id)
{}

/* look for a tmcd track not referenced by any video track, and export it globally */
static void export_orphan_timecode(AVFormatContext *s)
{}

static int read_tfra(MOVContext *mov, AVIOContext *f)
{}

static int mov_read_mfra(MOVContext *c, AVIOContext *f)
{}

static int read_image_grid(AVFormatContext *s, const HEIFGrid *grid,
                           AVStreamGroupTileGrid *tile_grid)
{}

static int read_image_iovl(AVFormatContext *s, const HEIFGrid *grid,
                           AVStreamGroupTileGrid *tile_grid)
{}

static int mov_parse_tiles(AVFormatContext *s)
{}

static int mov_read_header(AVFormatContext *s)
{}

static AVIndexEntry *mov_find_next_sample(AVFormatContext *s, AVStream **st)
{}

static int should_retry(AVIOContext *pb, int error_code) {}

static int mov_switch_root(AVFormatContext *s, int64_t target, int index)
{}

static int mov_change_extradata(AVStream *st, AVPacket *pkt)
{}

static int get_eia608_packet(AVIOContext *pb, AVPacket *pkt, int size)
{}

static int mov_finalize_packet(AVFormatContext *s, AVStream *st, AVIndexEntry *sample,
                                int64_t current_index, AVPacket *pkt)
{}

static int mov_read_packet(AVFormatContext *s, AVPacket *pkt)
{}

static int mov_seek_fragment(AVFormatContext *s, AVStream *st, int64_t timestamp)
{}

static int is_open_key_sample(const MOVStreamContext *sc, int sample)
{}

/*
 * Some key sample may be key frames but not IDR frames, so a random access to
 * them may not be allowed.
 */
static int can_seek_to_key_sample(AVStream *st, int sample, int64_t requested_pts)
{}

static int mov_seek_stream(AVFormatContext *s, AVStream *st, int64_t timestamp, int flags)
{}

static int64_t mov_get_skip_samples(AVStream *st, int sample)
{}

static int mov_read_seek(AVFormatContext *s, int stream_index, int64_t sample_time, int flags)
{}

#define OFFSET(x)
#define FLAGS
static const AVOption mov_options[] =;

static const AVClass mov_class =;

const FFInputFormat ff_mov_demuxer =;