static int mov_init(AVFormatContext *s)

{

    MOVMuxContext *mov = s->priv_data;

    AVDictionaryEntry *global_tcr = av_dict_get(s->metadata, "timecode", NULL, 0);

    int i, ret;



    mov->fc = s;



    /* Default mode == MP4 */

    mov->mode = MODE_MP4;



    if (s->oformat) {

        if (!strcmp("3gp", s->oformat->name)) mov->mode = MODE_3GP;

        else if (!strcmp("3g2", s->oformat->name)) mov->mode = MODE_3GP|MODE_3G2;

        else if (!strcmp("mov", s->oformat->name)) mov->mode = MODE_MOV;

        else if (!strcmp("psp", s->oformat->name)) mov->mode = MODE_PSP;

        else if (!strcmp("ipod",s->oformat->name)) mov->mode = MODE_IPOD;

        else if (!strcmp("ismv",s->oformat->name)) mov->mode = MODE_ISM;

        else if (!strcmp("f4v", s->oformat->name)) mov->mode = MODE_F4V;

    }



    if (mov->flags & FF_MOV_FLAG_DELAY_MOOV)

        mov->flags |= FF_MOV_FLAG_EMPTY_MOOV;



    /* Set the FRAGMENT flag if any of the fragmentation methods are

     * enabled. */

    if (mov->max_fragment_duration || mov->max_fragment_size ||

        mov->flags & (FF_MOV_FLAG_EMPTY_MOOV |

                      FF_MOV_FLAG_FRAG_KEYFRAME |

                      FF_MOV_FLAG_FRAG_CUSTOM))

        mov->flags |= FF_MOV_FLAG_FRAGMENT;



    /* Set other implicit flags immediately */

    if (mov->mode == MODE_ISM)

        mov->flags |= FF_MOV_FLAG_EMPTY_MOOV | FF_MOV_FLAG_SEPARATE_MOOF |

                      FF_MOV_FLAG_FRAGMENT;

    if (mov->flags & FF_MOV_FLAG_DASH)

        mov->flags |= FF_MOV_FLAG_FRAGMENT | FF_MOV_FLAG_EMPTY_MOOV |

                      FF_MOV_FLAG_DEFAULT_BASE_MOOF;



    if (mov->flags & FF_MOV_FLAG_EMPTY_MOOV && s->flags & AVFMT_FLAG_AUTO_BSF) {

        av_log(s, AV_LOG_VERBOSE, "Empty MOOV enabled; disabling automatic bitstream filtering\n");

        s->flags &= ~AVFMT_FLAG_AUTO_BSF;

    }



    if (mov->flags & FF_MOV_FLAG_FASTSTART) {

        mov->reserved_moov_size = -1;

    }



    if (mov->use_editlist < 0) {

        mov->use_editlist = 1;

        if (mov->flags & FF_MOV_FLAG_FRAGMENT &&

            !(mov->flags & FF_MOV_FLAG_DELAY_MOOV)) {

            // If we can avoid needing an edit list by shifting the

            // tracks, prefer that over (trying to) write edit lists

            // in fragmented output.

            if (s->avoid_negative_ts == AVFMT_AVOID_NEG_TS_AUTO ||

                s->avoid_negative_ts == AVFMT_AVOID_NEG_TS_MAKE_ZERO)

                mov->use_editlist = 0;

        }

    }

    if (mov->flags & FF_MOV_FLAG_EMPTY_MOOV &&

        !(mov->flags & FF_MOV_FLAG_DELAY_MOOV) && mov->use_editlist)

        av_log(s, AV_LOG_WARNING, "No meaningful edit list will be written when using empty_moov without delay_moov\n");



    if (!mov->use_editlist && s->avoid_negative_ts == AVFMT_AVOID_NEG_TS_AUTO)

        s->avoid_negative_ts = AVFMT_AVOID_NEG_TS_MAKE_ZERO;



    /* Clear the omit_tfhd_offset flag if default_base_moof is set;

     * if the latter is set that's enough and omit_tfhd_offset doesn't

     * add anything extra on top of that. */

    if (mov->flags & FF_MOV_FLAG_OMIT_TFHD_OFFSET &&

        mov->flags & FF_MOV_FLAG_DEFAULT_BASE_MOOF)

        mov->flags &= ~FF_MOV_FLAG_OMIT_TFHD_OFFSET;



    if (mov->frag_interleave &&

        mov->flags & (FF_MOV_FLAG_OMIT_TFHD_OFFSET | FF_MOV_FLAG_SEPARATE_MOOF)) {

        av_log(s, AV_LOG_ERROR,

               "Sample interleaving in fragments is mutually exclusive with "

               "omit_tfhd_offset and separate_moof\n");

        return AVERROR(EINVAL);

    }



    /* Non-seekable output is ok if using fragmentation. If ism_lookahead

     * is enabled, we don't support non-seekable output at all. */

    if (!(s->pb->seekable & AVIO_SEEKABLE_NORMAL) &&

        (!(mov->flags & FF_MOV_FLAG_FRAGMENT) || mov->ism_lookahead)) {

        av_log(s, AV_LOG_ERROR, "muxer does not support non seekable output\n");

        return AVERROR(EINVAL);

    }



    mov->nb_streams = s->nb_streams;

    if (mov->mode & (MODE_MP4|MODE_MOV|MODE_IPOD) && s->nb_chapters)

        mov->chapter_track = mov->nb_streams++;



    if (mov->flags & FF_MOV_FLAG_RTP_HINT) {

        /* Add hint tracks for each audio and video stream */

        for (i = 0; i < s->nb_streams; i++) {

            AVStream *st = s->streams[i];

            if (st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO ||

                st->codecpar->codec_type == AVMEDIA_TYPE_AUDIO) {

                mov->nb_streams++;

            }

        }

    }



    if (   mov->write_tmcd == -1 && (mov->mode == MODE_MOV || mov->mode == MODE_MP4)

        || mov->write_tmcd == 1) {

        /* +1 tmcd track for each video stream with a timecode */

        for (i = 0; i < s->nb_streams; i++) {

            AVStream *st = s->streams[i];

            AVDictionaryEntry *t = global_tcr;

            if (st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO &&

                (t || (t=av_dict_get(st->metadata, "timecode", NULL, 0)))) {

                AVTimecode tc;

                ret = mov_check_timecode_track(s, &tc, i, t->value);

                if (ret >= 0)

                    mov->nb_meta_tmcd++;

            }

        }



        /* check if there is already a tmcd track to remux */

        if (mov->nb_meta_tmcd) {

            for (i = 0; i < s->nb_streams; i++) {

                AVStream *st = s->streams[i];

                if (st->codecpar->codec_tag == MKTAG('t','m','c','d')) {

                    av_log(s, AV_LOG_WARNING, "You requested a copy of the original timecode track "

                           "so timecode metadata are now ignored\n");

                    mov->nb_meta_tmcd = 0;

                }

            }

        }



        mov->nb_streams += mov->nb_meta_tmcd;

    }



    // Reserve an extra stream for chapters for the case where chapters

    // are written in the trailer

    mov->tracks = av_mallocz_array((mov->nb_streams + 1), sizeof(*mov->tracks));

    if (!mov->tracks)

        return AVERROR(ENOMEM);



    if (mov->encryption_scheme_str != NULL && strcmp(mov->encryption_scheme_str, "none") != 0) {

        if (strcmp(mov->encryption_scheme_str, "cenc-aes-ctr") == 0) {

            mov->encryption_scheme = MOV_ENC_CENC_AES_CTR;



            if (mov->encryption_key_len != AES_CTR_KEY_SIZE) {

                av_log(s, AV_LOG_ERROR, "Invalid encryption key len %d expected %d\n",

                    mov->encryption_key_len, AES_CTR_KEY_SIZE);

                return AVERROR(EINVAL);

            }



            if (mov->encryption_kid_len != CENC_KID_SIZE) {

                av_log(s, AV_LOG_ERROR, "Invalid encryption kid len %d expected %d\n",

                    mov->encryption_kid_len, CENC_KID_SIZE);

                return AVERROR(EINVAL);

            }

        } else {

            av_log(s, AV_LOG_ERROR, "unsupported encryption scheme %s\n",

                mov->encryption_scheme_str);

            return AVERROR(EINVAL);

        }

    }



    for (i = 0; i < s->nb_streams; i++) {

        AVStream *st= s->streams[i];

        MOVTrack *track= &mov->tracks[i];

        AVDictionaryEntry *lang = av_dict_get(st->metadata, "language", NULL,0);



        track->st  = st;

        track->par = st->codecpar;

        track->language = ff_mov_iso639_to_lang(lang?lang->value:"und", mov->mode!=MODE_MOV);

        if (track->language < 0)

            track->language = 0;

        track->mode = mov->mode;

        track->tag  = mov_find_codec_tag(s, track);

        if (!track->tag) {

            av_log(s, AV_LOG_ERROR, "Could not find tag for codec %s in stream #%d, "

                   "codec not currently supported in container\n",

                   avcodec_get_name(st->codecpar->codec_id), i);

            return AVERROR(EINVAL);

        }

        /* If hinting of this track is enabled by a later hint track,

         * this is updated. */

        track->hint_track = -1;

        track->start_dts  = AV_NOPTS_VALUE;

        track->start_cts  = AV_NOPTS_VALUE;

        track->end_pts    = AV_NOPTS_VALUE;

        if (st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO) {

            if (track->tag == MKTAG('m','x','3','p') || track->tag == MKTAG('m','x','3','n') ||

                track->tag == MKTAG('m','x','4','p') || track->tag == MKTAG('m','x','4','n') ||

                track->tag == MKTAG('m','x','5','p') || track->tag == MKTAG('m','x','5','n')) {

                if (st->codecpar->width != 720 || (st->codecpar->height != 608 && st->codecpar->height != 512)) {

                    av_log(s, AV_LOG_ERROR, "D-10/IMX must use 720x608 or 720x512 video resolution\n");

                    return AVERROR(EINVAL);

                }

                track->height = track->tag >> 24 == 'n' ? 486 : 576;

            }

            if (mov->video_track_timescale) {

                track->timescale = mov->video_track_timescale;

            } else {

                track->timescale = st->time_base.den;

                while(track->timescale < 10000)

                    track->timescale *= 2;

            }

            if (st->codecpar->width > 65535 || st->codecpar->height > 65535) {

                av_log(s, AV_LOG_ERROR, "Resolution %dx%d too large for mov/mp4\n", st->codecpar->width, st->codecpar->height);

                return AVERROR(EINVAL);

            }

            if (track->mode == MODE_MOV && track->timescale > 100000)

                av_log(s, AV_LOG_WARNING,

                       "WARNING codec timebase is very high. If duration is too long,\n"

                       "file may not be playable by quicktime. Specify a shorter timebase\n"

                       "or choose different container.\n");

            if (track->mode == MODE_MOV &&

                track->par->codec_id == AV_CODEC_ID_RAWVIDEO &&

                track->tag == MKTAG('r','a','w',' ')) {

                enum AVPixelFormat pix_fmt = track->par->format;

                if (pix_fmt == AV_PIX_FMT_NONE && track->par->bits_per_coded_sample == 1)

                    pix_fmt = AV_PIX_FMT_MONOWHITE;

                track->is_unaligned_qt_rgb =

                        pix_fmt == AV_PIX_FMT_RGB24 ||

                        pix_fmt == AV_PIX_FMT_BGR24 ||

                        pix_fmt == AV_PIX_FMT_PAL8 ||

                        pix_fmt == AV_PIX_FMT_GRAY8 ||

                        pix_fmt == AV_PIX_FMT_MONOWHITE ||

                        pix_fmt == AV_PIX_FMT_MONOBLACK;

            }

            if (track->par->codec_id == AV_CODEC_ID_VP9) {

                if (track->mode != MODE_MP4) {

                    av_log(s, AV_LOG_ERROR, "VP9 only supported in MP4.\n");

                    return AVERROR(EINVAL);

                }

                if (s->strict_std_compliance > FF_COMPLIANCE_EXPERIMENTAL) {

                    av_log(s, AV_LOG_ERROR,

                           "VP9 in MP4 support is experimental, add "

                           "'-strict %d' if you want to use it.\n",

                           FF_COMPLIANCE_EXPERIMENTAL);

                    return AVERROR_EXPERIMENTAL;

                }

            }

        } else if (st->codecpar->codec_type == AVMEDIA_TYPE_AUDIO) {

            track->timescale = st->codecpar->sample_rate;

            if (!st->codecpar->frame_size && !av_get_bits_per_sample(st->codecpar->codec_id)) {

                av_log(s, AV_LOG_WARNING, "track %d: codec frame size is not set\n", i);

                track->audio_vbr = 1;

            }else if (st->codecpar->codec_id == AV_CODEC_ID_ADPCM_MS ||

                     st->codecpar->codec_id == AV_CODEC_ID_ADPCM_IMA_WAV ||

                     st->codecpar->codec_id == AV_CODEC_ID_ILBC){

                if (!st->codecpar->block_align) {

                    av_log(s, AV_LOG_ERROR, "track %d: codec block align is not set for adpcm\n", i);

                    return AVERROR(EINVAL);

                }

                track->sample_size = st->codecpar->block_align;

            }else if (st->codecpar->frame_size > 1){ /* assume compressed audio */

                track->audio_vbr = 1;

            }else{

                track->sample_size = (av_get_bits_per_sample(st->codecpar->codec_id) >> 3) * st->codecpar->channels;

            }

            if (st->codecpar->codec_id == AV_CODEC_ID_ILBC ||

                st->codecpar->codec_id == AV_CODEC_ID_ADPCM_IMA_QT) {

                track->audio_vbr = 1;

            }

            if (track->mode != MODE_MOV &&

                track->par->codec_id == AV_CODEC_ID_MP3 && track->timescale < 16000) {

                if (s->strict_std_compliance >= FF_COMPLIANCE_NORMAL) {

                    av_log(s, AV_LOG_ERROR, "track %d: muxing mp3 at %dhz is not standard, to mux anyway set strict to -1\n",

                        i, track->par->sample_rate);

                    return AVERROR(EINVAL);

                } else {

                    av_log(s, AV_LOG_WARNING, "track %d: muxing mp3 at %dhz is not standard in MP4\n",

                           i, track->par->sample_rate);

                }

            }

            if (track->par->codec_id == AV_CODEC_ID_FLAC ||

                track->par->codec_id == AV_CODEC_ID_OPUS) {

                if (track->mode != MODE_MP4) {

                    av_log(s, AV_LOG_ERROR, "%s only supported in MP4.\n", avcodec_get_name(track->par->codec_id));

                    return AVERROR(EINVAL);

                }

                if (s->strict_std_compliance > FF_COMPLIANCE_EXPERIMENTAL) {

                    av_log(s, AV_LOG_ERROR,

                           "%s in MP4 support is experimental, add "

                           "'-strict %d' if you want to use it.\n",

                           avcodec_get_name(track->par->codec_id), FF_COMPLIANCE_EXPERIMENTAL);

                    return AVERROR_EXPERIMENTAL;

                }

            }

        } else if (st->codecpar->codec_type == AVMEDIA_TYPE_SUBTITLE) {

            track->timescale = st->time_base.den;

        } else if (st->codecpar->codec_type == AVMEDIA_TYPE_DATA) {

            track->timescale = st->time_base.den;

        } else {

            track->timescale = MOV_TIMESCALE;

        }

        if (!track->height)

            track->height = st->codecpar->height;

        /* The ism specific timescale isn't mandatory, but is assumed by

         * some tools, such as mp4split. */

        if (mov->mode == MODE_ISM)

            track->timescale = 10000000;



        avpriv_set_pts_info(st, 64, 1, track->timescale);



        if (mov->encryption_scheme == MOV_ENC_CENC_AES_CTR) {

            ret = ff_mov_cenc_init(&track->cenc, mov->encryption_key,

                track->par->codec_id == AV_CODEC_ID_H264, s->flags & AVFMT_FLAG_BITEXACT);

            if (ret)

                return ret;

        }

    }



    enable_tracks(s);

    return 0;

}

static int mov_init(AVFormatContext *s)

{

    MOVMuxContext *mov = s->priv_data;

    AVDictionaryEntry *global_tcr = av_dict_get(s->metadata, "timecode", NULL, 0);

    int i, ret;



    mov->fc = s;



    

    mov->mode = MODE_MP4;



    if (s->oformat) {

        if (!strcmp("3gp", s->oformat->name)) mov->mode = MODE_3GP;

        else if (!strcmp("3g2", s->oformat->name)) mov->mode = MODE_3GP|MODE_3G2;

        else if (!strcmp("mov", s->oformat->name)) mov->mode = MODE_MOV;

        else if (!strcmp("psp", s->oformat->name)) mov->mode = MODE_PSP;

        else if (!strcmp("ipod",s->oformat->name)) mov->mode = MODE_IPOD;

        else if (!strcmp("ismv",s->oformat->name)) mov->mode = MODE_ISM;

        else if (!strcmp("f4v", s->oformat->name)) mov->mode = MODE_F4V;

    }



    if (mov->flags & FF_MOV_FLAG_DELAY_MOOV)

        mov->flags |= FF_MOV_FLAG_EMPTY_MOOV;



    



    if (mov->max_fragment_duration || mov->max_fragment_size ||

        mov->flags & (FF_MOV_FLAG_EMPTY_MOOV |

                      FF_MOV_FLAG_FRAG_KEYFRAME |

                      FF_MOV_FLAG_FRAG_CUSTOM))

        mov->flags |= FF_MOV_FLAG_FRAGMENT;



    

    if (mov->mode == MODE_ISM)

        mov->flags |= FF_MOV_FLAG_EMPTY_MOOV | FF_MOV_FLAG_SEPARATE_MOOF |

                      FF_MOV_FLAG_FRAGMENT;

    if (mov->flags & FF_MOV_FLAG_DASH)

        mov->flags |= FF_MOV_FLAG_FRAGMENT | FF_MOV_FLAG_EMPTY_MOOV |

                      FF_MOV_FLAG_DEFAULT_BASE_MOOF;



    if (mov->flags & FF_MOV_FLAG_EMPTY_MOOV && s->flags & AVFMT_FLAG_AUTO_BSF) {

        av_log(s, AV_LOG_VERBOSE, "Empty MOOV enabled; disabling automatic bitstream filtering\n");

        s->flags &= ~AVFMT_FLAG_AUTO_BSF;

    }



    if (mov->flags & FF_MOV_FLAG_FASTSTART) {

        mov->reserved_moov_size = -1;

    }



    if (mov->use_editlist < 0) {

        mov->use_editlist = 1;

        if (mov->flags & FF_MOV_FLAG_FRAGMENT &&

            !(mov->flags & FF_MOV_FLAG_DELAY_MOOV)) {

            

            

            

            if (s->avoid_negative_ts == AVFMT_AVOID_NEG_TS_AUTO ||

                s->avoid_negative_ts == AVFMT_AVOID_NEG_TS_MAKE_ZERO)

                mov->use_editlist = 0;

        }

    }

    if (mov->flags & FF_MOV_FLAG_EMPTY_MOOV &&

        !(mov->flags & FF_MOV_FLAG_DELAY_MOOV) && mov->use_editlist)

        av_log(s, AV_LOG_WARNING, "No meaningful edit list will be written when using empty_moov without delay_moov\n");



    if (!mov->use_editlist && s->avoid_negative_ts == AVFMT_AVOID_NEG_TS_AUTO)

        s->avoid_negative_ts = AVFMT_AVOID_NEG_TS_MAKE_ZERO;



    





    if (mov->flags & FF_MOV_FLAG_OMIT_TFHD_OFFSET &&

        mov->flags & FF_MOV_FLAG_DEFAULT_BASE_MOOF)

        mov->flags &= ~FF_MOV_FLAG_OMIT_TFHD_OFFSET;



    if (mov->frag_interleave &&

        mov->flags & (FF_MOV_FLAG_OMIT_TFHD_OFFSET | FF_MOV_FLAG_SEPARATE_MOOF)) {

        av_log(s, AV_LOG_ERROR,

               "Sample interleaving in fragments is mutually exclusive with "

               "omit_tfhd_offset and separate_moof\n");

        return AVERROR(EINVAL);

    }



    



    if (!(s->pb->seekable & AVIO_SEEKABLE_NORMAL) &&

        (!(mov->flags & FF_MOV_FLAG_FRAGMENT) || mov->ism_lookahead)) {

        av_log(s, AV_LOG_ERROR, "muxer does not support non seekable output\n");

        return AVERROR(EINVAL);

    }



    mov->nb_streams = s->nb_streams;

    if (mov->mode & (MODE_MP4|MODE_MOV|MODE_IPOD) && s->nb_chapters)

        mov->chapter_track = mov->nb_streams++;



    if (mov->flags & FF_MOV_FLAG_RTP_HINT) {

        

        for (i = 0; i < s->nb_streams; i++) {

            AVStream *st = s->streams[i];

            if (st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO ||

                st->codecpar->codec_type == AVMEDIA_TYPE_AUDIO) {

                mov->nb_streams++;

            }

        }

    }



    if (   mov->write_tmcd == -1 && (mov->mode == MODE_MOV || mov->mode == MODE_MP4)

        || mov->write_tmcd == 1) {

        

        for (i = 0; i < s->nb_streams; i++) {

            AVStream *st = s->streams[i];

            AVDictionaryEntry *t = global_tcr;

            if (st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO &&

                (t || (t=av_dict_get(st->metadata, "timecode", NULL, 0)))) {

                AVTimecode tc;

                ret = mov_check_timecode_track(s, &tc, i, t->value);

                if (ret >= 0)

                    mov->nb_meta_tmcd++;

            }

        }



        

        if (mov->nb_meta_tmcd) {

            for (i = 0; i < s->nb_streams; i++) {

                AVStream *st = s->streams[i];

                if (st->codecpar->codec_tag == MKTAG('t','m','c','d')) {

                    av_log(s, AV_LOG_WARNING, "You requested a copy of the original timecode track "

                           "so timecode metadata are now ignored\n");

                    mov->nb_meta_tmcd = 0;

                }

            }

        }



        mov->nb_streams += mov->nb_meta_tmcd;

    }



    

    

    mov->tracks = av_mallocz_array((mov->nb_streams + 1), sizeof(*mov->tracks));

    if (!mov->tracks)

        return AVERROR(ENOMEM);



    if (mov->encryption_scheme_str != NULL && strcmp(mov->encryption_scheme_str, "none") != 0) {

        if (strcmp(mov->encryption_scheme_str, "cenc-aes-ctr") == 0) {

            mov->encryption_scheme = MOV_ENC_CENC_AES_CTR;



            if (mov->encryption_key_len != AES_CTR_KEY_SIZE) {

                av_log(s, AV_LOG_ERROR, "Invalid encryption key len %d expected %d\n",

                    mov->encryption_key_len, AES_CTR_KEY_SIZE);

                return AVERROR(EINVAL);

            }



            if (mov->encryption_kid_len != CENC_KID_SIZE) {

                av_log(s, AV_LOG_ERROR, "Invalid encryption kid len %d expected %d\n",

                    mov->encryption_kid_len, CENC_KID_SIZE);

                return AVERROR(EINVAL);

            }

        } else {

            av_log(s, AV_LOG_ERROR, "unsupported encryption scheme %s\n",

                mov->encryption_scheme_str);

            return AVERROR(EINVAL);

        }

    }



    for (i = 0; i < s->nb_streams; i++) {

        AVStream *st= s->streams[i];

        MOVTrack *track= &mov->tracks[i];

        AVDictionaryEntry *lang = av_dict_get(st->metadata, "language", NULL,0);



        track->st  = st;

        track->par = st->codecpar;

        track->language = ff_mov_iso639_to_lang(lang?lang->value:"und", mov->mode!=MODE_MOV);

        if (track->language < 0)

            track->language = 0;

        track->mode = mov->mode;

        track->tag  = mov_find_codec_tag(s, track);

        if (!track->tag) {

            av_log(s, AV_LOG_ERROR, "Could not find tag for codec %s in stream #%d, "

                   "codec not currently supported in container\n",

                   avcodec_get_name(st->codecpar->codec_id), i);

            return AVERROR(EINVAL);

        }

        



        track->hint_track = -1;

        track->start_dts  = AV_NOPTS_VALUE;

        track->start_cts  = AV_NOPTS_VALUE;

        track->end_pts    = AV_NOPTS_VALUE;

        if (st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO) {

            if (track->tag == MKTAG('m','x','3','p') || track->tag == MKTAG('m','x','3','n') ||

                track->tag == MKTAG('m','x','4','p') || track->tag == MKTAG('m','x','4','n') ||

                track->tag == MKTAG('m','x','5','p') || track->tag == MKTAG('m','x','5','n')) {

                if (st->codecpar->width != 720 || (st->codecpar->height != 608 && st->codecpar->height != 512)) {

                    av_log(s, AV_LOG_ERROR, "D-10/IMX must use 720x608 or 720x512 video resolution\n");

                    return AVERROR(EINVAL);

                }

                track->height = track->tag >> 24 == 'n' ? 486 : 576;

            }

            if (mov->video_track_timescale) {

                track->timescale = mov->video_track_timescale;

            } else {

                track->timescale = st->time_base.den;

                while(track->timescale < 10000)

                    track->timescale *= 2;

            }

            if (st->codecpar->width > 65535 || st->codecpar->height > 65535) {

                av_log(s, AV_LOG_ERROR, "Resolution %dx%d too large for mov/mp4\n", st->codecpar->width, st->codecpar->height);

                return AVERROR(EINVAL);

            }

            if (track->mode == MODE_MOV && track->timescale > 100000)

                av_log(s, AV_LOG_WARNING,

                       "WARNING codec timebase is very high. If duration is too long,\n"

                       "file may not be playable by quicktime. Specify a shorter timebase\n"

                       "or choose different container.\n");

            if (track->mode == MODE_MOV &&

                track->par->codec_id == AV_CODEC_ID_RAWVIDEO &&

                track->tag == MKTAG('r','a','w',' ')) {

                enum AVPixelFormat pix_fmt = track->par->format;

                if (pix_fmt == AV_PIX_FMT_NONE && track->par->bits_per_coded_sample == 1)

                    pix_fmt = AV_PIX_FMT_MONOWHITE;

                track->is_unaligned_qt_rgb =

                        pix_fmt == AV_PIX_FMT_RGB24 ||

                        pix_fmt == AV_PIX_FMT_BGR24 ||

                        pix_fmt == AV_PIX_FMT_PAL8 ||

                        pix_fmt == AV_PIX_FMT_GRAY8 ||

                        pix_fmt == AV_PIX_FMT_MONOWHITE ||

                        pix_fmt == AV_PIX_FMT_MONOBLACK;

            }

            if (track->par->codec_id == AV_CODEC_ID_VP9) {

                if (track->mode != MODE_MP4) {

                    av_log(s, AV_LOG_ERROR, "VP9 only supported in MP4.\n");

                    return AVERROR(EINVAL);

                }

                if (s->strict_std_compliance > FF_COMPLIANCE_EXPERIMENTAL) {

                    av_log(s, AV_LOG_ERROR,

                           "VP9 in MP4 support is experimental, add "

                           "'-strict %d' if you want to use it.\n",

                           FF_COMPLIANCE_EXPERIMENTAL);

                    return AVERROR_EXPERIMENTAL;

                }

            }

        } else if (st->codecpar->codec_type == AVMEDIA_TYPE_AUDIO) {

            track->timescale = st->codecpar->sample_rate;

            if (!st->codecpar->frame_size && !av_get_bits_per_sample(st->codecpar->codec_id)) {

                av_log(s, AV_LOG_WARNING, "track %d: codec frame size is not set\n", i);

                track->audio_vbr = 1;

            }else if (st->codecpar->codec_id == AV_CODEC_ID_ADPCM_MS ||

                     st->codecpar->codec_id == AV_CODEC_ID_ADPCM_IMA_WAV ||

                     st->codecpar->codec_id == AV_CODEC_ID_ILBC){

                if (!st->codecpar->block_align) {

                    av_log(s, AV_LOG_ERROR, "track %d: codec block align is not set for adpcm\n", i);

                    return AVERROR(EINVAL);

                }

                track->sample_size = st->codecpar->block_align;

            }else if (st->codecpar->frame_size > 1){ 

                track->audio_vbr = 1;

            }else{

                track->sample_size = (av_get_bits_per_sample(st->codecpar->codec_id) >> 3) * st->codecpar->channels;

            }

            if (st->codecpar->codec_id == AV_CODEC_ID_ILBC ||

                st->codecpar->codec_id == AV_CODEC_ID_ADPCM_IMA_QT) {

                track->audio_vbr = 1;

            }

            if (track->mode != MODE_MOV &&

                track->par->codec_id == AV_CODEC_ID_MP3 && track->timescale < 16000) {

                if (s->strict_std_compliance >= FF_COMPLIANCE_NORMAL) {

                    av_log(s, AV_LOG_ERROR, "track %d: muxing mp3 at %dhz is not standard, to mux anyway set strict to -1\n",

                        i, track->par->sample_rate);

                    return AVERROR(EINVAL);

                } else {

                    av_log(s, AV_LOG_WARNING, "track %d: muxing mp3 at %dhz is not standard in MP4\n",

                           i, track->par->sample_rate);

                }

            }

            if (track->par->codec_id == AV_CODEC_ID_FLAC ||

                track->par->codec_id == AV_CODEC_ID_OPUS) {

                if (track->mode != MODE_MP4) {

                    av_log(s, AV_LOG_ERROR, "%s only supported in MP4.\n", avcodec_get_name(track->par->codec_id));

                    return AVERROR(EINVAL);

                }

                if (s->strict_std_compliance > FF_COMPLIANCE_EXPERIMENTAL) {

                    av_log(s, AV_LOG_ERROR,

                           "%s in MP4 support is experimental, add "

                           "'-strict %d' if you want to use it.\n",

                           avcodec_get_name(track->par->codec_id), FF_COMPLIANCE_EXPERIMENTAL);

                    return AVERROR_EXPERIMENTAL;

                }

            }

        } else if (st->codecpar->codec_type == AVMEDIA_TYPE_SUBTITLE) {

            track->timescale = st->time_base.den;

        } else if (st->codecpar->codec_type == AVMEDIA_TYPE_DATA) {

            track->timescale = st->time_base.den;

        } else {

            track->timescale = MOV_TIMESCALE;

        }

        if (!track->height)

            track->height = st->codecpar->height;

        



        if (mov->mode == MODE_ISM)

            track->timescale = 10000000;



        avpriv_set_pts_info(st, 64, 1, track->timescale);



        if (mov->encryption_scheme == MOV_ENC_CENC_AES_CTR) {

            ret = ff_mov_cenc_init(&track->cenc, mov->encryption_key,

                track->par->codec_id == AV_CODEC_ID_H264, s->flags & AVFMT_FLAG_BITEXACT);

            if (ret)

                return ret;

        }

    }



    enable_tracks(s);

    return 0;

}

static int FUNC_0(AVFormatContext *VAR_0)

{

    MOVMuxContext *mov = VAR_0->priv_data;

    AVDictionaryEntry *global_tcr = av_dict_get(VAR_0->metadata, "timecode", NULL, 0);

    int VAR_1, VAR_2;



    mov->fc = VAR_0;



    

    mov->mode = MODE_MP4;



    if (VAR_0->oformat) {

        if (!strcmp("3gp", VAR_0->oformat->name)) mov->mode = MODE_3GP;

        else if (!strcmp("3g2", VAR_0->oformat->name)) mov->mode = MODE_3GP|MODE_3G2;

        else if (!strcmp("mov", VAR_0->oformat->name)) mov->mode = MODE_MOV;

        else if (!strcmp("psp", VAR_0->oformat->name)) mov->mode = MODE_PSP;

        else if (!strcmp("ipod",VAR_0->oformat->name)) mov->mode = MODE_IPOD;

        else if (!strcmp("ismv",VAR_0->oformat->name)) mov->mode = MODE_ISM;

        else if (!strcmp("f4v", VAR_0->oformat->name)) mov->mode = MODE_F4V;

    }



    if (mov->flags & FF_MOV_FLAG_DELAY_MOOV)

        mov->flags |= FF_MOV_FLAG_EMPTY_MOOV;



    



    if (mov->max_fragment_duration || mov->max_fragment_size ||

        mov->flags & (FF_MOV_FLAG_EMPTY_MOOV |

                      FF_MOV_FLAG_FRAG_KEYFRAME |

                      FF_MOV_FLAG_FRAG_CUSTOM))

        mov->flags |= FF_MOV_FLAG_FRAGMENT;



    

    if (mov->mode == MODE_ISM)

        mov->flags |= FF_MOV_FLAG_EMPTY_MOOV | FF_MOV_FLAG_SEPARATE_MOOF |

                      FF_MOV_FLAG_FRAGMENT;

    if (mov->flags & FF_MOV_FLAG_DASH)

        mov->flags |= FF_MOV_FLAG_FRAGMENT | FF_MOV_FLAG_EMPTY_MOOV |

                      FF_MOV_FLAG_DEFAULT_BASE_MOOF;



    if (mov->flags & FF_MOV_FLAG_EMPTY_MOOV && VAR_0->flags & AVFMT_FLAG_AUTO_BSF) {

        av_log(VAR_0, AV_LOG_VERBOSE, "Empty MOOV enabled; disabling automatic bitstream filtering\n");

        VAR_0->flags &= ~AVFMT_FLAG_AUTO_BSF;

    }



    if (mov->flags & FF_MOV_FLAG_FASTSTART) {

        mov->reserved_moov_size = -1;

    }



    if (mov->use_editlist < 0) {

        mov->use_editlist = 1;

        if (mov->flags & FF_MOV_FLAG_FRAGMENT &&

            !(mov->flags & FF_MOV_FLAG_DELAY_MOOV)) {

            

            

            

            if (VAR_0->avoid_negative_ts == AVFMT_AVOID_NEG_TS_AUTO ||

                VAR_0->avoid_negative_ts == AVFMT_AVOID_NEG_TS_MAKE_ZERO)

                mov->use_editlist = 0;

        }

    }

    if (mov->flags & FF_MOV_FLAG_EMPTY_MOOV &&

        !(mov->flags & FF_MOV_FLAG_DELAY_MOOV) && mov->use_editlist)

        av_log(VAR_0, AV_LOG_WARNING, "No meaningful edit list will be written when using empty_moov without delay_moov\n");



    if (!mov->use_editlist && VAR_0->avoid_negative_ts == AVFMT_AVOID_NEG_TS_AUTO)

        VAR_0->avoid_negative_ts = AVFMT_AVOID_NEG_TS_MAKE_ZERO;



    





    if (mov->flags & FF_MOV_FLAG_OMIT_TFHD_OFFSET &&

        mov->flags & FF_MOV_FLAG_DEFAULT_BASE_MOOF)

        mov->flags &= ~FF_MOV_FLAG_OMIT_TFHD_OFFSET;



    if (mov->frag_interleave &&

        mov->flags & (FF_MOV_FLAG_OMIT_TFHD_OFFSET | FF_MOV_FLAG_SEPARATE_MOOF)) {

        av_log(VAR_0, AV_LOG_ERROR,

               "Sample interleaving in fragments is mutually exclusive with "

               "omit_tfhd_offset and separate_moof\n");

        return AVERROR(EINVAL);

    }



    



    if (!(VAR_0->pb->seekable & AVIO_SEEKABLE_NORMAL) &&

        (!(mov->flags & FF_MOV_FLAG_FRAGMENT) || mov->ism_lookahead)) {

        av_log(VAR_0, AV_LOG_ERROR, "muxer does not support non seekable output\n");

        return AVERROR(EINVAL);

    }



    mov->nb_streams = VAR_0->nb_streams;

    if (mov->mode & (MODE_MP4|MODE_MOV|MODE_IPOD) && VAR_0->nb_chapters)

        mov->chapter_track = mov->nb_streams++;



    if (mov->flags & FF_MOV_FLAG_RTP_HINT) {

        

        for (VAR_1 = 0; VAR_1 < VAR_0->nb_streams; VAR_1++) {

            AVStream *st = VAR_0->streams[VAR_1];

            if (st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO ||

                st->codecpar->codec_type == AVMEDIA_TYPE_AUDIO) {

                mov->nb_streams++;

            }

        }

    }



    if (   mov->write_tmcd == -1 && (mov->mode == MODE_MOV || mov->mode == MODE_MP4)

        || mov->write_tmcd == 1) {

        

        for (VAR_1 = 0; VAR_1 < VAR_0->nb_streams; VAR_1++) {

            AVStream *st = VAR_0->streams[VAR_1];

            AVDictionaryEntry *t = global_tcr;

            if (st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO &&

                (t || (t=av_dict_get(st->metadata, "timecode", NULL, 0)))) {

                AVTimecode tc;

                VAR_2 = mov_check_timecode_track(VAR_0, &tc, VAR_1, t->value);

                if (VAR_2 >= 0)

                    mov->nb_meta_tmcd++;

            }

        }



        

        if (mov->nb_meta_tmcd) {

            for (VAR_1 = 0; VAR_1 < VAR_0->nb_streams; VAR_1++) {

                AVStream *st = VAR_0->streams[VAR_1];

                if (st->codecpar->codec_tag == MKTAG('t','m','c','d')) {

                    av_log(VAR_0, AV_LOG_WARNING, "You requested a copy of the original timecode track "

                           "so timecode metadata are now ignored\n");

                    mov->nb_meta_tmcd = 0;

                }

            }

        }



        mov->nb_streams += mov->nb_meta_tmcd;

    }



    

    

    mov->tracks = av_mallocz_array((mov->nb_streams + 1), sizeof(*mov->tracks));

    if (!mov->tracks)

        return AVERROR(ENOMEM);



    if (mov->encryption_scheme_str != NULL && strcmp(mov->encryption_scheme_str, "none") != 0) {

        if (strcmp(mov->encryption_scheme_str, "cenc-aes-ctr") == 0) {

            mov->encryption_scheme = MOV_ENC_CENC_AES_CTR;



            if (mov->encryption_key_len != AES_CTR_KEY_SIZE) {

                av_log(VAR_0, AV_LOG_ERROR, "Invalid encryption key len %d expected %d\n",

                    mov->encryption_key_len, AES_CTR_KEY_SIZE);

                return AVERROR(EINVAL);

            }



            if (mov->encryption_kid_len != CENC_KID_SIZE) {

                av_log(VAR_0, AV_LOG_ERROR, "Invalid encryption kid len %d expected %d\n",

                    mov->encryption_kid_len, CENC_KID_SIZE);

                return AVERROR(EINVAL);

            }

        } else {

            av_log(VAR_0, AV_LOG_ERROR, "unsupported encryption scheme %VAR_0\n",

                mov->encryption_scheme_str);

            return AVERROR(EINVAL);

        }

    }



    for (VAR_1 = 0; VAR_1 < VAR_0->nb_streams; VAR_1++) {

        AVStream *st= VAR_0->streams[VAR_1];

        MOVTrack *track= &mov->tracks[VAR_1];

        AVDictionaryEntry *lang = av_dict_get(st->metadata, "language", NULL,0);



        track->st  = st;

        track->par = st->codecpar;

        track->language = ff_mov_iso639_to_lang(lang?lang->value:"und", mov->mode!=MODE_MOV);

        if (track->language < 0)

            track->language = 0;

        track->mode = mov->mode;

        track->tag  = mov_find_codec_tag(VAR_0, track);

        if (!track->tag) {

            av_log(VAR_0, AV_LOG_ERROR, "Could not find tag for codec %VAR_0 in stream #%d, "

                   "codec not currently supported in container\n",

                   avcodec_get_name(st->codecpar->codec_id), VAR_1);

            return AVERROR(EINVAL);

        }

        



        track->hint_track = -1;

        track->start_dts  = AV_NOPTS_VALUE;

        track->start_cts  = AV_NOPTS_VALUE;

        track->end_pts    = AV_NOPTS_VALUE;

        if (st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO) {

            if (track->tag == MKTAG('m','x','3','p') || track->tag == MKTAG('m','x','3','n') ||

                track->tag == MKTAG('m','x','4','p') || track->tag == MKTAG('m','x','4','n') ||

                track->tag == MKTAG('m','x','5','p') || track->tag == MKTAG('m','x','5','n')) {

                if (st->codecpar->width != 720 || (st->codecpar->height != 608 && st->codecpar->height != 512)) {

                    av_log(VAR_0, AV_LOG_ERROR, "D-10/IMX must use 720x608 or 720x512 video resolution\n");

                    return AVERROR(EINVAL);

                }

                track->height = track->tag >> 24 == 'n' ? 486 : 576;

            }

            if (mov->video_track_timescale) {

                track->timescale = mov->video_track_timescale;

            } else {

                track->timescale = st->time_base.den;

                while(track->timescale < 10000)

                    track->timescale *= 2;

            }

            if (st->codecpar->width > 65535 || st->codecpar->height > 65535) {

                av_log(VAR_0, AV_LOG_ERROR, "Resolution %dx%d too large for mov/mp4\n", st->codecpar->width, st->codecpar->height);

                return AVERROR(EINVAL);

            }

            if (track->mode == MODE_MOV && track->timescale > 100000)

                av_log(VAR_0, AV_LOG_WARNING,

                       "WARNING codec timebase is very high. If duration is too long,\n"

                       "file may not be playable by quicktime. Specify a shorter timebase\n"

                       "or choose different container.\n");

            if (track->mode == MODE_MOV &&

                track->par->codec_id == AV_CODEC_ID_RAWVIDEO &&

                track->tag == MKTAG('r','a','w',' ')) {

                enum AVPixelFormat pix_fmt = track->par->format;

                if (pix_fmt == AV_PIX_FMT_NONE && track->par->bits_per_coded_sample == 1)

                    pix_fmt = AV_PIX_FMT_MONOWHITE;

                track->is_unaligned_qt_rgb =

                        pix_fmt == AV_PIX_FMT_RGB24 ||

                        pix_fmt == AV_PIX_FMT_BGR24 ||

                        pix_fmt == AV_PIX_FMT_PAL8 ||

                        pix_fmt == AV_PIX_FMT_GRAY8 ||

                        pix_fmt == AV_PIX_FMT_MONOWHITE ||

                        pix_fmt == AV_PIX_FMT_MONOBLACK;

            }

            if (track->par->codec_id == AV_CODEC_ID_VP9) {

                if (track->mode != MODE_MP4) {

                    av_log(VAR_0, AV_LOG_ERROR, "VP9 only supported in MP4.\n");

                    return AVERROR(EINVAL);

                }

                if (VAR_0->strict_std_compliance > FF_COMPLIANCE_EXPERIMENTAL) {

                    av_log(VAR_0, AV_LOG_ERROR,

                           "VP9 in MP4 support is experimental, add "

                           "'-strict %d' if you want to use it.\n",

                           FF_COMPLIANCE_EXPERIMENTAL);

                    return AVERROR_EXPERIMENTAL;

                }

            }

        } else if (st->codecpar->codec_type == AVMEDIA_TYPE_AUDIO) {

            track->timescale = st->codecpar->sample_rate;

            if (!st->codecpar->frame_size && !av_get_bits_per_sample(st->codecpar->codec_id)) {

                av_log(VAR_0, AV_LOG_WARNING, "track %d: codec frame size is not set\n", VAR_1);

                track->audio_vbr = 1;

            }else if (st->codecpar->codec_id == AV_CODEC_ID_ADPCM_MS ||

                     st->codecpar->codec_id == AV_CODEC_ID_ADPCM_IMA_WAV ||

                     st->codecpar->codec_id == AV_CODEC_ID_ILBC){

                if (!st->codecpar->block_align) {

                    av_log(VAR_0, AV_LOG_ERROR, "track %d: codec block align is not set for adpcm\n", VAR_1);

                    return AVERROR(EINVAL);

                }

                track->sample_size = st->codecpar->block_align;

            }else if (st->codecpar->frame_size > 1){ 

                track->audio_vbr = 1;

            }else{

                track->sample_size = (av_get_bits_per_sample(st->codecpar->codec_id) >> 3) * st->codecpar->channels;

            }

            if (st->codecpar->codec_id == AV_CODEC_ID_ILBC ||

                st->codecpar->codec_id == AV_CODEC_ID_ADPCM_IMA_QT) {

                track->audio_vbr = 1;

            }

            if (track->mode != MODE_MOV &&

                track->par->codec_id == AV_CODEC_ID_MP3 && track->timescale < 16000) {

                if (VAR_0->strict_std_compliance >= FF_COMPLIANCE_NORMAL) {

                    av_log(VAR_0, AV_LOG_ERROR, "track %d: muxing mp3 at %dhz is not standard, to mux anyway set strict to -1\n",

                        VAR_1, track->par->sample_rate);

                    return AVERROR(EINVAL);

                } else {

                    av_log(VAR_0, AV_LOG_WARNING, "track %d: muxing mp3 at %dhz is not standard in MP4\n",

                           VAR_1, track->par->sample_rate);

                }

            }

            if (track->par->codec_id == AV_CODEC_ID_FLAC ||

                track->par->codec_id == AV_CODEC_ID_OPUS) {

                if (track->mode != MODE_MP4) {

                    av_log(VAR_0, AV_LOG_ERROR, "%VAR_0 only supported in MP4.\n", avcodec_get_name(track->par->codec_id));

                    return AVERROR(EINVAL);

                }

                if (VAR_0->strict_std_compliance > FF_COMPLIANCE_EXPERIMENTAL) {

                    av_log(VAR_0, AV_LOG_ERROR,

                           "%VAR_0 in MP4 support is experimental, add "

                           "'-strict %d' if you want to use it.\n",

                           avcodec_get_name(track->par->codec_id), FF_COMPLIANCE_EXPERIMENTAL);

                    return AVERROR_EXPERIMENTAL;

                }

            }

        } else if (st->codecpar->codec_type == AVMEDIA_TYPE_SUBTITLE) {

            track->timescale = st->time_base.den;

        } else if (st->codecpar->codec_type == AVMEDIA_TYPE_DATA) {

            track->timescale = st->time_base.den;

        } else {

            track->timescale = MOV_TIMESCALE;

        }

        if (!track->height)

            track->height = st->codecpar->height;

        



        if (mov->mode == MODE_ISM)

            track->timescale = 10000000;



        avpriv_set_pts_info(st, 64, 1, track->timescale);



        if (mov->encryption_scheme == MOV_ENC_CENC_AES_CTR) {

            VAR_2 = ff_mov_cenc_init(&track->cenc, mov->encryption_key,

                track->par->codec_id == AV_CODEC_ID_H264, VAR_0->flags & AVFMT_FLAG_BITEXACT);

            if (VAR_2)

                return VAR_2;

        }

    }



    enable_tracks(VAR_0);

    return 0;

}

static int FUNC_0(AVFormatContext *VAR_0)
{ MOVMuxContext *mov = VAR_0->priv_data; AVDictionaryEntry *global_tcr = av_dict_get(VAR_0->metadata, "timecode", NULL, 0); int VAR_1, VAR_2; mov->fc = VAR_0; mov->mode = MODE_MP4; if (VAR_0->oformat) { if (!strcmp("3gp", VAR_0->oformat->name)) mov->mode = MODE_3GP; else if (!strcmp("3g2", VAR_0->oformat->name)) mov->mode = MODE_3GP|MODE_3G2; else if (!strcmp("mov", VAR_0->oformat->name)) mov->mode = MODE_MOV; else if (!strcmp("psp", VAR_0->oformat->name)) mov->mode = MODE_PSP; else if (!strcmp("ipod",VAR_0->oformat->name)) mov->mode = MODE_IPOD; else if (!strcmp("ismv",VAR_0->oformat->name)) mov->mode = MODE_ISM; else if (!strcmp("f4v", VAR_0->oformat->name)) mov->mode = MODE_F4V; } if (mov->flags & FF_MOV_FLAG_DELAY_MOOV)
mov->flags |= FF_MOV_FLAG_EMPTY_MOOV; if (mov->max_fragment_duration || mov->max_fragment_size ||
mov->flags & (FF_MOV_FLAG_EMPTY_MOOV |
FF_MOV_FLAG_FRAG_KEYFRAME |
FF_MOV_FLAG_FRAG_CUSTOM))
mov->flags |= FF_MOV_FLAG_FRAGMENT; if (mov->mode == MODE_ISM)
mov->flags |= FF_MOV_FLAG_EMPTY_MOOV | FF_MOV_FLAG_SEPARATE_MOOF |
FF_MOV_FLAG_FRAGMENT; if (mov->flags & FF_MOV_FLAG_DASH)
mov->flags |= FF_MOV_FLAG_FRAGMENT | FF_MOV_FLAG_EMPTY_MOOV |
FF_MOV_FLAG_DEFAULT_BASE_MOOF; if (mov->flags & FF_MOV_FLAG_EMPTY_MOOV && VAR_0->flags & AVFMT_FLAG_AUTO_BSF) { av_log(VAR_0, AV_LOG_VERBOSE, "Empty MOOV enabled; disabling automatic bitstream filtering\n"); VAR_0->flags &= ~AVFMT_FLAG_AUTO_BSF; } if (mov->flags & FF_MOV_FLAG_FASTSTART) { mov->reserved_moov_size = -1; } if (mov->use_editlist < 0) { mov->use_editlist = 1; if (mov->flags & FF_MOV_FLAG_FRAGMENT &&
!(mov->flags & FF_MOV_FLAG_DELAY_MOOV)) { if (VAR_0->avoid_negative_ts == AVFMT_AVOID_NEG_TS_AUTO ||
VAR_0->avoid_negative_ts == AVFMT_AVOID_NEG_TS_MAKE_ZERO)
mov->use_editlist = 0; } } if (mov->flags & FF_MOV_FLAG_EMPTY_MOOV &&
!(mov->flags & FF_MOV_FLAG_DELAY_MOOV) && mov->use_editlist)
av_log(VAR_0, AV_LOG_WARNING, "No meaningful edit list will be written when using empty_moov without delay_moov\n"); if (!mov->use_editlist && VAR_0->avoid_negative_ts == AVFMT_AVOID_NEG_TS_AUTO)
VAR_0->avoid_negative_ts = AVFMT_AVOID_NEG_TS_MAKE_ZERO; if (mov->flags & FF_MOV_FLAG_OMIT_TFHD_OFFSET &&
mov->flags & FF_MOV_FLAG_DEFAULT_BASE_MOOF)
mov->flags &= ~FF_MOV_FLAG_OMIT_TFHD_OFFSET; if (mov->frag_interleave &&
mov->flags & (FF_MOV_FLAG_OMIT_TFHD_OFFSET | FF_MOV_FLAG_SEPARATE_MOOF)) { av_log(VAR_0, AV_LOG_ERROR,
"Sample interleaving in fragments is mutually exclusive with "
"omit_tfhd_offset and separate_moof\n"); return AVERROR(EINVAL); } if (!(VAR_0->pb->seekable & AVIO_SEEKABLE_NORMAL) &&
(!(mov->flags & FF_MOV_FLAG_FRAGMENT) || mov->ism_lookahead)) { av_log(VAR_0, AV_LOG_ERROR, "muxer does not support non seekable output\n"); return AVERROR(EINVAL); } mov->nb_streams = VAR_0->nb_streams; if (mov->mode & (MODE_MP4|MODE_MOV|MODE_IPOD) && VAR_0->nb_chapters)
mov->chapter_track = mov->nb_streams++; if (mov->flags & FF_MOV_FLAG_RTP_HINT) { for (VAR_1 = 0; VAR_1 < VAR_0->nb_streams; VAR_1++) { AVStream *st = VAR_0->streams[VAR_1]; if (st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO ||
st->codecpar->codec_type == AVMEDIA_TYPE_AUDIO) { mov->nb_streams++; } } } if (   mov->write_tmcd == -1 && (mov->mode == MODE_MOV || mov->mode == MODE_MP4)
|| mov->write_tmcd == 1) { for (VAR_1 = 0; VAR_1 < VAR_0->nb_streams; VAR_1++) { AVStream *st = VAR_0->streams[VAR_1]; AVDictionaryEntry *t = global_tcr; if (st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO &&
(t || (t=av_dict_get(st->metadata, "timecode", NULL, 0)))) { AVTimecode tc; VAR_2 = mov_check_timecode_track(VAR_0, &tc, VAR_1, t->value); if (VAR_2 >= 0)
mov->nb_meta_tmcd++; } } if (mov->nb_meta_tmcd) { for (VAR_1 = 0; VAR_1 < VAR_0->nb_streams; VAR_1++) { AVStream *st = VAR_0->streams[VAR_1]; if (st->codecpar->codec_tag == MKTAG('t','m','c','d')) { av_log(VAR_0, AV_LOG_WARNING, "You requested a copy of the original timecode track "
"so timecode metadata are now ignored\n"); mov->nb_meta_tmcd = 0; } } } mov->nb_streams += mov->nb_meta_tmcd; } mov->tracks = av_mallocz_array((mov->nb_streams + 1), sizeof(*mov->tracks)); if (!mov->tracks)
return AVERROR(ENOMEM); if (mov->encryption_scheme_str != NULL && strcmp(mov->encryption_scheme_str, "none") != 0) { if (strcmp(mov->encryption_scheme_str, "cenc-aes-ctr") == 0) { mov->encryption_scheme = MOV_ENC_CENC_AES_CTR; if (mov->encryption_key_len != AES_CTR_KEY_SIZE) { av_log(VAR_0, AV_LOG_ERROR, "Invalid encryption key len %d expected %d\n",
mov->encryption_key_len, AES_CTR_KEY_SIZE); return AVERROR(EINVAL); } if (mov->encryption_kid_len != CENC_KID_SIZE) { av_log(VAR_0, AV_LOG_ERROR, "Invalid encryption kid len %d expected %d\n",
mov->encryption_kid_len, CENC_KID_SIZE); return AVERROR(EINVAL); } } else { av_log(VAR_0, AV_LOG_ERROR, "unsupported encryption scheme %VAR_0\n",
mov->encryption_scheme_str); return AVERROR(EINVAL); } } for (VAR_1 = 0; VAR_1 < VAR_0->nb_streams; VAR_1++) { AVStream *st= VAR_0->streams[VAR_1]; MOVTrack *track= &mov->tracks[VAR_1]; AVDictionaryEntry *lang = av_dict_get(st->metadata, "language", NULL,0); track->st  = st; track->par = st->codecpar; track->language = ff_mov_iso639_to_lang(lang?lang->value:"und", mov->mode!=MODE_MOV); if (track->language < 0)
track->language = 0; track->mode = mov->mode; track->tag  = mov_find_codec_tag(VAR_0, track); if (!track->tag) { av_log(VAR_0, AV_LOG_ERROR, "Could not find tag for codec %VAR_0 in stream #%d, "
"codec not currently supported in container\n",
avcodec_get_name(st->codecpar->codec_id), VAR_1); return AVERROR(EINVAL); } track->hint_track = -1; track->start_dts  = AV_NOPTS_VALUE; track->start_cts  = AV_NOPTS_VALUE; track->end_pts    = AV_NOPTS_VALUE; if (st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO) { if (track->tag == MKTAG('m','x','3','p') || track->tag == MKTAG('m','x','3','n') ||
track->tag == MKTAG('m','x','4','p') || track->tag == MKTAG('m','x','4','n') ||
track->tag == MKTAG('m','x','5','p') || track->tag == MKTAG('m','x','5','n')) { if (st->codecpar->width != 720 || (st->codecpar->height != 608 && st->codecpar->height != 512)) { av_log(VAR_0, AV_LOG_ERROR, "D-10/IMX must use 720x608 or 720x512 video resolution\n"); return AVERROR(EINVAL); } track->height = track->tag >> 24 == 'n' ? 486 : 576; } if (mov->video_track_timescale) { track->timescale = mov->video_track_timescale; } else { track->timescale = st->time_base.den; while(track->timescale < 10000)
track->timescale *= 2; } if (st->codecpar->width > 65535 || st->codecpar->height > 65535) { av_log(VAR_0, AV_LOG_ERROR, "Resolution %dx%d too large for mov/mp4\n", st->codecpar->width, st->codecpar->height); return AVERROR(EINVAL); } if (track->mode == MODE_MOV && track->timescale > 100000)
av_log(VAR_0, AV_LOG_WARNING,
"WARNING codec timebase is very high. If duration is too long,\n"
"file may not be playable by quicktime. Specify a shorter timebase\n"
"or choose different container.\n"); if (track->mode == MODE_MOV &&
track->par->codec_id == AV_CODEC_ID_RAWVIDEO &&
track->tag == MKTAG('r','a','w',' ')) { enum AVPixelFormat pix_fmt = track->par->format; if (pix_fmt == AV_PIX_FMT_NONE && track->par->bits_per_coded_sample == 1)
pix_fmt = AV_PIX_FMT_MONOWHITE; track->is_unaligned_qt_rgb =
pix_fmt == AV_PIX_FMT_RGB24 ||
pix_fmt == AV_PIX_FMT_BGR24 ||
pix_fmt == AV_PIX_FMT_PAL8 ||
pix_fmt == AV_PIX_FMT_GRAY8 ||
pix_fmt == AV_PIX_FMT_MONOWHITE ||
pix_fmt == AV_PIX_FMT_MONOBLACK; } if (track->par->codec_id == AV_CODEC_ID_VP9) { if (track->mode != MODE_MP4) { av_log(VAR_0, AV_LOG_ERROR, "VP9 only supported in MP4.\n"); return AVERROR(EINVAL); } if (VAR_0->strict_std_compliance > FF_COMPLIANCE_EXPERIMENTAL) { av_log(VAR_0, AV_LOG_ERROR,
"VP9 in MP4 support is experimental, add "
"'-strict %d' if you want to use it.\n",
FF_COMPLIANCE_EXPERIMENTAL); return AVERROR_EXPERIMENTAL; } } } else if (st->codecpar->codec_type == AVMEDIA_TYPE_AUDIO) { track->timescale = st->codecpar->sample_rate; if (!st->codecpar->frame_size && !av_get_bits_per_sample(st->codecpar->codec_id)) { av_log(VAR_0, AV_LOG_WARNING, "track %d: codec frame size is not set\n", VAR_1); track->audio_vbr = 1; }else if (st->codecpar->codec_id == AV_CODEC_ID_ADPCM_MS || st->codecpar->codec_id == AV_CODEC_ID_ADPCM_IMA_WAV ||
st->codecpar->codec_id == AV_CODEC_ID_ILBC){ if (!st->codecpar->block_align) { av_log(VAR_0, AV_LOG_ERROR, "track %d: codec block align is not set for adpcm\n", VAR_1); return AVERROR(EINVAL); } track->sample_size = st->codecpar->block_align; }else if (st->codecpar->frame_size > 1){ track->audio_vbr = 1; }else{ track->sample_size = (av_get_bits_per_sample(st->codecpar->codec_id) >> 3) * st->codecpar->channels; } if (st->codecpar->codec_id == AV_CODEC_ID_ILBC ||
st->codecpar->codec_id == AV_CODEC_ID_ADPCM_IMA_QT) { track->audio_vbr = 1; } if (track->mode != MODE_MOV &&
track->par->codec_id == AV_CODEC_ID_MP3 && track->timescale < 16000) { if (VAR_0->strict_std_compliance >= FF_COMPLIANCE_NORMAL) { av_log(VAR_0, AV_LOG_ERROR, "track %d: muxing mp3 at %dhz is not standard, to mux anyway set strict to -1\n",
VAR_1, track->par->sample_rate); return AVERROR(EINVAL); } else { av_log(VAR_0, AV_LOG_WARNING, "track %d: muxing mp3 at %dhz is not standard in MP4\n",
VAR_1, track->par->sample_rate); } } if (track->par->codec_id == AV_CODEC_ID_FLAC ||
track->par->codec_id == AV_CODEC_ID_OPUS) { if (track->mode != MODE_MP4) { av_log(VAR_0, AV_LOG_ERROR, "%VAR_0 only supported in MP4.\n", avcodec_get_name(track->par->codec_id)); return AVERROR(EINVAL); } if (VAR_0->strict_std_compliance > FF_COMPLIANCE_EXPERIMENTAL) { av_log(VAR_0, AV_LOG_ERROR,
"%VAR_0 in MP4 support is experimental, add "
"'-strict %d' if you want to use it.\n",
avcodec_get_name(track->par->codec_id), FF_COMPLIANCE_EXPERIMENTAL); return AVERROR_EXPERIMENTAL; } } } else if (st->codecpar->codec_type == AVMEDIA_TYPE_SUBTITLE) { track->timescale = st->time_base.den; } else if (st->codecpar->codec_type == AVMEDIA_TYPE_DATA) { track->timescale = st->time_base.den; } else { track->timescale = MOV_TIMESCALE; } if (!track->height)
track->height = st->codecpar->height; if (mov->mode == MODE_ISM)
track->timescale = 10000000; avpriv_set_pts_info(st, 64, 1, track->timescale); if (mov->encryption_scheme == MOV_ENC_CENC_AES_CTR) { VAR_2 = ff_mov_cenc_init(&track->cenc, mov->encryption_key,
track->par->codec_id == AV_CODEC_ID_H264, VAR_0->flags & AVFMT_FLAG_BITEXACT); if (VAR_2)
return VAR_2; } } enable_tracks(VAR_0); return 0; }