static int mxf_write_header(AVFormatContext *s)

{

    MXFContext *mxf = s->priv_data;

    int i, ret;

    uint8_t present[FF_ARRAY_ELEMS(mxf_essence_container_uls)] = {0};

    const MXFSamplesPerFrame *spf = NULL;

    AVDictionaryEntry *t;

    int64_t timestamp = 0;



    if (!s->nb_streams)

        return -1;



    if (s->oformat == &ff_mxf_opatom_muxer && s->nb_streams !=1){

        av_log(s, AV_LOG_ERROR, "there must be exactly one stream for mxf opatom\n");

        return -1;

    }



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

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

        MXFStreamContext *sc = av_mallocz(sizeof(*sc));

        if (!sc)

            return AVERROR(ENOMEM);

        st->priv_data = sc;



        if (((i == 0) ^ (st->codec->codec_type == AVMEDIA_TYPE_VIDEO)) && s->oformat != &ff_mxf_opatom_muxer) {

            av_log(s, AV_LOG_ERROR, "there must be exactly one video stream and it must be the first one\n");

            return -1;

        }



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

            const AVPixFmtDescriptor *pix_desc = av_pix_fmt_desc_get(st->codec->pix_fmt);

            // TODO: should be avg_frame_rate

            AVRational rate, tbc = st->time_base;

            // Default component depth to 8

            sc->component_depth = 8;

            sc->h_chroma_sub_sample = 2;

            sc->color_siting = 0xFF;



            if (pix_desc) {

                sc->component_depth     = pix_desc->comp[0].depth_minus1 + 1;

                sc->h_chroma_sub_sample = 1 << pix_desc->log2_chroma_w;

            }

            switch (ff_choose_chroma_location(s, st)) {

            case AVCHROMA_LOC_TOPLEFT: sc->color_siting = 0; break;

            case AVCHROMA_LOC_LEFT:    sc->color_siting = 6; break;

            case AVCHROMA_LOC_TOP:     sc->color_siting = 1; break;

            case AVCHROMA_LOC_CENTER:  sc->color_siting = 3; break;

            }



            mxf->timecode_base = (tbc.den + tbc.num/2) / tbc.num;

            spf = ff_mxf_get_samples_per_frame(s, tbc);

            if (!spf) {

                av_log(s, AV_LOG_ERROR, "Unsupported video frame rate %d/%d\n",

                       tbc.den, tbc.num);

                return AVERROR(EINVAL);

            }

            mxf->time_base = spf->time_base;

            rate = av_inv_q(mxf->time_base);

            avpriv_set_pts_info(st, 64, mxf->time_base.num, mxf->time_base.den);

            if((ret = mxf_init_timecode(s, st, rate)) < 0)

                return ret;



            sc->video_bit_rate = st->codec->bit_rate ? st->codec->bit_rate : st->codec->rc_max_rate;

            if (s->oformat == &ff_mxf_d10_muxer) {

                if (sc->video_bit_rate == 50000000) {

                    if (mxf->time_base.den == 25) sc->index = 3;

                    else                          sc->index = 5;

                } else if (sc->video_bit_rate == 40000000) {

                    if (mxf->time_base.den == 25) sc->index = 7;

                    else                          sc->index = 9;

                } else if (sc->video_bit_rate == 30000000) {

                    if (mxf->time_base.den == 25) sc->index = 11;

                    else                          sc->index = 13;

                } else {

                    av_log(s, AV_LOG_ERROR, "error MXF D-10 only support 30/40/50 mbit/s\n");

                    return -1;

                }



                mxf->edit_unit_byte_count = KAG_SIZE; // system element

                mxf->edit_unit_byte_count += 16 + 4 + (uint64_t)sc->video_bit_rate *

                    mxf->time_base.num / (8*mxf->time_base.den);

                mxf->edit_unit_byte_count += klv_fill_size(mxf->edit_unit_byte_count);

                mxf->edit_unit_byte_count += 16 + 4 + 4 + spf->samples_per_frame[0]*8*4;

                mxf->edit_unit_byte_count += klv_fill_size(mxf->edit_unit_byte_count);



                sc->signal_standard = 1;

            }

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

            if (st->codec->sample_rate != 48000) {

                av_log(s, AV_LOG_ERROR, "only 48khz is implemented\n");

                return -1;

            }

            avpriv_set_pts_info(st, 64, 1, st->codec->sample_rate);

            if (s->oformat == &ff_mxf_d10_muxer) {

                if (st->index != 1) {

                    av_log(s, AV_LOG_ERROR, "MXF D-10 only support one audio track\n");

                    return -1;

                }

                if (st->codec->codec_id != AV_CODEC_ID_PCM_S16LE &&

                    st->codec->codec_id != AV_CODEC_ID_PCM_S24LE) {

                    av_log(s, AV_LOG_ERROR, "MXF D-10 only support 16 or 24 bits le audio\n");

                }

                sc->index = ((MXFStreamContext*)s->streams[0]->priv_data)->index + 1;

            } else if (s->oformat == &ff_mxf_opatom_muxer) {

                AVRational tbc = av_inv_q(mxf->audio_edit_rate);



                if (st->codec->codec_id != AV_CODEC_ID_PCM_S16LE &&

                    st->codec->codec_id != AV_CODEC_ID_PCM_S24LE) {

                    av_log(s, AV_LOG_ERROR, "Only pcm_s16le and pcm_s24le audio codecs are implemented\n");

                    return AVERROR_PATCHWELCOME;

                }

                if (st->codec->channels != 1) {

                    av_log(s, AV_LOG_ERROR, "MXF OPAtom only supports single channel audio\n");

                    return AVERROR(EINVAL);

                }



                spf = ff_mxf_get_samples_per_frame(s, tbc);

                if (!spf){

                    av_log(s, AV_LOG_ERROR, "Unsupported timecode frame rate %d/%d\n", tbc.den, tbc.num);

                    return AVERROR(EINVAL);

                }



                mxf->time_base = st->time_base;

                if((ret = mxf_init_timecode(s, st, av_inv_q(spf->time_base))) < 0)

                    return ret;



                mxf->timecode_base = (tbc.den + tbc.num/2) / tbc.num;

                mxf->edit_unit_byte_count = (av_get_bits_per_sample(st->codec->codec_id) * st->codec->channels) >> 3;

                sc->index = 2;

            } else {

                mxf->slice_count = 1;

            }

        }



        if (!sc->index) {

            sc->index = mxf_get_essence_container_ul_index(st->codec->codec_id);

            if (sc->index == -1) {

                av_log(s, AV_LOG_ERROR, "track %d: could not find essence container ul, "

                       "codec not currently supported in container\n", i);

                return -1;

            }

        }



        sc->codec_ul = &mxf_essence_container_uls[sc->index].codec_ul;



        memcpy(sc->track_essence_element_key, mxf_essence_container_uls[sc->index].element_ul, 15);

        sc->track_essence_element_key[15] = present[sc->index];

        PRINT_KEY(s, "track essence element key", sc->track_essence_element_key);



        if (!present[sc->index])

            mxf->essence_container_count++;

        present[sc->index]++;

    }



    if (s->oformat == &ff_mxf_d10_muxer || s->oformat == &ff_mxf_opatom_muxer) {

        mxf->essence_container_count = 1;

    }



    if (!(s->flags & AVFMT_FLAG_BITEXACT))

        mxf_gen_umid(s);



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

        MXFStreamContext *sc = s->streams[i]->priv_data;

        // update element count

        sc->track_essence_element_key[13] = present[sc->index];

        if (!memcmp(sc->track_essence_element_key, mxf_essence_container_uls[15].element_ul, 13)) // DV

            sc->order = (0x15 << 24) | AV_RB32(sc->track_essence_element_key+13);

        else

            sc->order = AV_RB32(sc->track_essence_element_key+12);

    }



    if (t = av_dict_get(s->metadata, "creation_time", NULL, 0))

        timestamp = ff_iso8601_to_unix_time(t->value);

    if (timestamp)

        mxf->timestamp = mxf_parse_timestamp(timestamp);

    mxf->duration = -1;



    mxf->timecode_track = av_mallocz(sizeof(*mxf->timecode_track));

    if (!mxf->timecode_track)

        return AVERROR(ENOMEM);

    mxf->timecode_track->priv_data = av_mallocz(sizeof(MXFStreamContext));

    if (!mxf->timecode_track->priv_data)

        return AVERROR(ENOMEM);

    mxf->timecode_track->index = -1;



    if (!spf)

        spf = ff_mxf_get_samples_per_frame(s, (AVRational){ 1, 25 });



    if (ff_audio_interleave_init(s, spf->samples_per_frame, mxf->time_base) < 0)

        return -1;



    return 0;

}

static int mxf_write_header(AVFormatContext *s)

{

    MXFContext *mxf = s->priv_data;

    int i, ret;

    uint8_t present[FF_ARRAY_ELEMS(mxf_essence_container_uls)] = {0};

    const MXFSamplesPerFrame *spf = NULL;

    AVDictionaryEntry *t;

    int64_t timestamp = 0;



    if (!s->nb_streams)

        return -1;



    if (s->oformat == &ff_mxf_opatom_muxer && s->nb_streams !=1){

        av_log(s, AV_LOG_ERROR, "there must be exactly one stream for mxf opatom\n");

        return -1;

    }



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

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

        MXFStreamContext *sc = av_mallocz(sizeof(*sc));

        if (!sc)

            return AVERROR(ENOMEM);

        st->priv_data = sc;



        if (((i == 0) ^ (st->codec->codec_type == AVMEDIA_TYPE_VIDEO)) && s->oformat != &ff_mxf_opatom_muxer) {

            av_log(s, AV_LOG_ERROR, "there must be exactly one video stream and it must be the first one\n");

            return -1;

        }



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

            const AVPixFmtDescriptor *pix_desc = av_pix_fmt_desc_get(st->codec->pix_fmt);

            

            AVRational rate, tbc = st->time_base;

            

            sc->component_depth = 8;

            sc->h_chroma_sub_sample = 2;

            sc->color_siting = 0xFF;



            if (pix_desc) {

                sc->component_depth     = pix_desc->comp[0].depth_minus1 + 1;

                sc->h_chroma_sub_sample = 1 << pix_desc->log2_chroma_w;

            }

            switch (ff_choose_chroma_location(s, st)) {

            case AVCHROMA_LOC_TOPLEFT: sc->color_siting = 0; break;

            case AVCHROMA_LOC_LEFT:    sc->color_siting = 6; break;

            case AVCHROMA_LOC_TOP:     sc->color_siting = 1; break;

            case AVCHROMA_LOC_CENTER:  sc->color_siting = 3; break;

            }



            mxf->timecode_base = (tbc.den + tbc.num/2) / tbc.num;

            spf = ff_mxf_get_samples_per_frame(s, tbc);

            if (!spf) {

                av_log(s, AV_LOG_ERROR, "Unsupported video frame rate %d/%d\n",

                       tbc.den, tbc.num);

                return AVERROR(EINVAL);

            }

            mxf->time_base = spf->time_base;

            rate = av_inv_q(mxf->time_base);

            avpriv_set_pts_info(st, 64, mxf->time_base.num, mxf->time_base.den);

            if((ret = mxf_init_timecode(s, st, rate)) < 0)

                return ret;



            sc->video_bit_rate = st->codec->bit_rate ? st->codec->bit_rate : st->codec->rc_max_rate;

            if (s->oformat == &ff_mxf_d10_muxer) {

                if (sc->video_bit_rate == 50000000) {

                    if (mxf->time_base.den == 25) sc->index = 3;

                    else                          sc->index = 5;

                } else if (sc->video_bit_rate == 40000000) {

                    if (mxf->time_base.den == 25) sc->index = 7;

                    else                          sc->index = 9;

                } else if (sc->video_bit_rate == 30000000) {

                    if (mxf->time_base.den == 25) sc->index = 11;

                    else                          sc->index = 13;

                } else {

                    av_log(s, AV_LOG_ERROR, "error MXF D-10 only support 30/40/50 mbit/s\n");

                    return -1;

                }



                mxf->edit_unit_byte_count = KAG_SIZE; 

                mxf->edit_unit_byte_count += 16 + 4 + (uint64_t)sc->video_bit_rate *

                    mxf->time_base.num / (8*mxf->time_base.den);

                mxf->edit_unit_byte_count += klv_fill_size(mxf->edit_unit_byte_count);

                mxf->edit_unit_byte_count += 16 + 4 + 4 + spf->samples_per_frame[0]*8*4;

                mxf->edit_unit_byte_count += klv_fill_size(mxf->edit_unit_byte_count);



                sc->signal_standard = 1;

            }

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

            if (st->codec->sample_rate != 48000) {

                av_log(s, AV_LOG_ERROR, "only 48khz is implemented\n");

                return -1;

            }

            avpriv_set_pts_info(st, 64, 1, st->codec->sample_rate);

            if (s->oformat == &ff_mxf_d10_muxer) {

                if (st->index != 1) {

                    av_log(s, AV_LOG_ERROR, "MXF D-10 only support one audio track\n");

                    return -1;

                }

                if (st->codec->codec_id != AV_CODEC_ID_PCM_S16LE &&

                    st->codec->codec_id != AV_CODEC_ID_PCM_S24LE) {

                    av_log(s, AV_LOG_ERROR, "MXF D-10 only support 16 or 24 bits le audio\n");

                }

                sc->index = ((MXFStreamContext*)s->streams[0]->priv_data)->index + 1;

            } else if (s->oformat == &ff_mxf_opatom_muxer) {

                AVRational tbc = av_inv_q(mxf->audio_edit_rate);



                if (st->codec->codec_id != AV_CODEC_ID_PCM_S16LE &&

                    st->codec->codec_id != AV_CODEC_ID_PCM_S24LE) {

                    av_log(s, AV_LOG_ERROR, "Only pcm_s16le and pcm_s24le audio codecs are implemented\n");

                    return AVERROR_PATCHWELCOME;

                }

                if (st->codec->channels != 1) {

                    av_log(s, AV_LOG_ERROR, "MXF OPAtom only supports single channel audio\n");

                    return AVERROR(EINVAL);

                }



                spf = ff_mxf_get_samples_per_frame(s, tbc);

                if (!spf){

                    av_log(s, AV_LOG_ERROR, "Unsupported timecode frame rate %d/%d\n", tbc.den, tbc.num);

                    return AVERROR(EINVAL);

                }



                mxf->time_base = st->time_base;

                if((ret = mxf_init_timecode(s, st, av_inv_q(spf->time_base))) < 0)

                    return ret;



                mxf->timecode_base = (tbc.den + tbc.num/2) / tbc.num;

                mxf->edit_unit_byte_count = (av_get_bits_per_sample(st->codec->codec_id) * st->codec->channels) >> 3;

                sc->index = 2;

            } else {

                mxf->slice_count = 1;

            }

        }



        if (!sc->index) {

            sc->index = mxf_get_essence_container_ul_index(st->codec->codec_id);

            if (sc->index == -1) {

                av_log(s, AV_LOG_ERROR, "track %d: could not find essence container ul, "

                       "codec not currently supported in container\n", i);

                return -1;

            }

        }



        sc->codec_ul = &mxf_essence_container_uls[sc->index].codec_ul;



        memcpy(sc->track_essence_element_key, mxf_essence_container_uls[sc->index].element_ul, 15);

        sc->track_essence_element_key[15] = present[sc->index];

        PRINT_KEY(s, "track essence element key", sc->track_essence_element_key);



        if (!present[sc->index])

            mxf->essence_container_count++;

        present[sc->index]++;

    }



    if (s->oformat == &ff_mxf_d10_muxer || s->oformat == &ff_mxf_opatom_muxer) {

        mxf->essence_container_count = 1;

    }



    if (!(s->flags & AVFMT_FLAG_BITEXACT))

        mxf_gen_umid(s);



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

        MXFStreamContext *sc = s->streams[i]->priv_data;

        

        sc->track_essence_element_key[13] = present[sc->index];

        if (!memcmp(sc->track_essence_element_key, mxf_essence_container_uls[15].element_ul, 13)) 

            sc->order = (0x15 << 24) | AV_RB32(sc->track_essence_element_key+13);

        else

            sc->order = AV_RB32(sc->track_essence_element_key+12);

    }



    if (t = av_dict_get(s->metadata, "creation_time", NULL, 0))

        timestamp = ff_iso8601_to_unix_time(t->value);

    if (timestamp)

        mxf->timestamp = mxf_parse_timestamp(timestamp);

    mxf->duration = -1;



    mxf->timecode_track = av_mallocz(sizeof(*mxf->timecode_track));

    if (!mxf->timecode_track)

        return AVERROR(ENOMEM);

    mxf->timecode_track->priv_data = av_mallocz(sizeof(MXFStreamContext));

    if (!mxf->timecode_track->priv_data)

        return AVERROR(ENOMEM);

    mxf->timecode_track->index = -1;



    if (!spf)

        spf = ff_mxf_get_samples_per_frame(s, (AVRational){ 1, 25 });



    if (ff_audio_interleave_init(s, spf->samples_per_frame, mxf->time_base) < 0)

        return -1;



    return 0;

}

static int FUNC_0(AVFormatContext *VAR_0)

{

    MXFContext *mxf = VAR_0->priv_data;

    int VAR_1, VAR_2;

    uint8_t present[FF_ARRAY_ELEMS(mxf_essence_container_uls)] = {0};

    const MXFSamplesPerFrame *VAR_3 = NULL;

    AVDictionaryEntry *t;

    int64_t timestamp = 0;



    if (!VAR_0->nb_streams)

        return -1;



    if (VAR_0->oformat == &ff_mxf_opatom_muxer && VAR_0->nb_streams !=1){

        av_log(VAR_0, AV_LOG_ERROR, "there must be exactly one stream for mxf opatom\n");

        return -1;

    }



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

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

        MXFStreamContext *sc = av_mallocz(sizeof(*sc));

        if (!sc)

            return AVERROR(ENOMEM);

        st->priv_data = sc;



        if (((VAR_1 == 0) ^ (st->codec->codec_type == AVMEDIA_TYPE_VIDEO)) && VAR_0->oformat != &ff_mxf_opatom_muxer) {

            av_log(VAR_0, AV_LOG_ERROR, "there must be exactly one video stream and it must be the first one\n");

            return -1;

        }



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

            const AVPixFmtDescriptor *pix_desc = av_pix_fmt_desc_get(st->codec->pix_fmt);

            

            AVRational rate, tbc = st->time_base;

            

            sc->component_depth = 8;

            sc->h_chroma_sub_sample = 2;

            sc->color_siting = 0xFF;



            if (pix_desc) {

                sc->component_depth     = pix_desc->comp[0].depth_minus1 + 1;

                sc->h_chroma_sub_sample = 1 << pix_desc->log2_chroma_w;

            }

            switch (ff_choose_chroma_location(VAR_0, st)) {

            case AVCHROMA_LOC_TOPLEFT: sc->color_siting = 0; break;

            case AVCHROMA_LOC_LEFT:    sc->color_siting = 6; break;

            case AVCHROMA_LOC_TOP:     sc->color_siting = 1; break;

            case AVCHROMA_LOC_CENTER:  sc->color_siting = 3; break;

            }



            mxf->timecode_base = (tbc.den + tbc.num/2) / tbc.num;

            VAR_3 = ff_mxf_get_samples_per_frame(VAR_0, tbc);

            if (!VAR_3) {

                av_log(VAR_0, AV_LOG_ERROR, "Unsupported video frame rate %d/%d\n",

                       tbc.den, tbc.num);

                return AVERROR(EINVAL);

            }

            mxf->time_base = VAR_3->time_base;

            rate = av_inv_q(mxf->time_base);

            avpriv_set_pts_info(st, 64, mxf->time_base.num, mxf->time_base.den);

            if((VAR_2 = mxf_init_timecode(VAR_0, st, rate)) < 0)

                return VAR_2;



            sc->video_bit_rate = st->codec->bit_rate ? st->codec->bit_rate : st->codec->rc_max_rate;

            if (VAR_0->oformat == &ff_mxf_d10_muxer) {

                if (sc->video_bit_rate == 50000000) {

                    if (mxf->time_base.den == 25) sc->index = 3;

                    else                          sc->index = 5;

                } else if (sc->video_bit_rate == 40000000) {

                    if (mxf->time_base.den == 25) sc->index = 7;

                    else                          sc->index = 9;

                } else if (sc->video_bit_rate == 30000000) {

                    if (mxf->time_base.den == 25) sc->index = 11;

                    else                          sc->index = 13;

                } else {

                    av_log(VAR_0, AV_LOG_ERROR, "error MXF D-10 only support 30/40/50 mbit/VAR_0\n");

                    return -1;

                }



                mxf->edit_unit_byte_count = KAG_SIZE; 

                mxf->edit_unit_byte_count += 16 + 4 + (uint64_t)sc->video_bit_rate *

                    mxf->time_base.num / (8*mxf->time_base.den);

                mxf->edit_unit_byte_count += klv_fill_size(mxf->edit_unit_byte_count);

                mxf->edit_unit_byte_count += 16 + 4 + 4 + VAR_3->samples_per_frame[0]*8*4;

                mxf->edit_unit_byte_count += klv_fill_size(mxf->edit_unit_byte_count);



                sc->signal_standard = 1;

            }

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

            if (st->codec->sample_rate != 48000) {

                av_log(VAR_0, AV_LOG_ERROR, "only 48khz is implemented\n");

                return -1;

            }

            avpriv_set_pts_info(st, 64, 1, st->codec->sample_rate);

            if (VAR_0->oformat == &ff_mxf_d10_muxer) {

                if (st->index != 1) {

                    av_log(VAR_0, AV_LOG_ERROR, "MXF D-10 only support one audio track\n");

                    return -1;

                }

                if (st->codec->codec_id != AV_CODEC_ID_PCM_S16LE &&

                    st->codec->codec_id != AV_CODEC_ID_PCM_S24LE) {

                    av_log(VAR_0, AV_LOG_ERROR, "MXF D-10 only support 16 or 24 bits le audio\n");

                }

                sc->index = ((MXFStreamContext*)VAR_0->streams[0]->priv_data)->index + 1;

            } else if (VAR_0->oformat == &ff_mxf_opatom_muxer) {

                AVRational tbc = av_inv_q(mxf->audio_edit_rate);



                if (st->codec->codec_id != AV_CODEC_ID_PCM_S16LE &&

                    st->codec->codec_id != AV_CODEC_ID_PCM_S24LE) {

                    av_log(VAR_0, AV_LOG_ERROR, "Only pcm_s16le and pcm_s24le audio codecs are implemented\n");

                    return AVERROR_PATCHWELCOME;

                }

                if (st->codec->channels != 1) {

                    av_log(VAR_0, AV_LOG_ERROR, "MXF OPAtom only supports single channel audio\n");

                    return AVERROR(EINVAL);

                }



                VAR_3 = ff_mxf_get_samples_per_frame(VAR_0, tbc);

                if (!VAR_3){

                    av_log(VAR_0, AV_LOG_ERROR, "Unsupported timecode frame rate %d/%d\n", tbc.den, tbc.num);

                    return AVERROR(EINVAL);

                }



                mxf->time_base = st->time_base;

                if((VAR_2 = mxf_init_timecode(VAR_0, st, av_inv_q(VAR_3->time_base))) < 0)

                    return VAR_2;



                mxf->timecode_base = (tbc.den + tbc.num/2) / tbc.num;

                mxf->edit_unit_byte_count = (av_get_bits_per_sample(st->codec->codec_id) * st->codec->channels) >> 3;

                sc->index = 2;

            } else {

                mxf->slice_count = 1;

            }

        }



        if (!sc->index) {

            sc->index = mxf_get_essence_container_ul_index(st->codec->codec_id);

            if (sc->index == -1) {

                av_log(VAR_0, AV_LOG_ERROR, "track %d: could not find essence container ul, "

                       "codec not currently supported in container\n", VAR_1);

                return -1;

            }

        }



        sc->codec_ul = &mxf_essence_container_uls[sc->index].codec_ul;



        memcpy(sc->track_essence_element_key, mxf_essence_container_uls[sc->index].element_ul, 15);

        sc->track_essence_element_key[15] = present[sc->index];

        PRINT_KEY(VAR_0, "track essence element key", sc->track_essence_element_key);



        if (!present[sc->index])

            mxf->essence_container_count++;

        present[sc->index]++;

    }



    if (VAR_0->oformat == &ff_mxf_d10_muxer || VAR_0->oformat == &ff_mxf_opatom_muxer) {

        mxf->essence_container_count = 1;

    }



    if (!(VAR_0->flags & AVFMT_FLAG_BITEXACT))

        mxf_gen_umid(VAR_0);



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

        MXFStreamContext *sc = VAR_0->streams[VAR_1]->priv_data;

        

        sc->track_essence_element_key[13] = present[sc->index];

        if (!memcmp(sc->track_essence_element_key, mxf_essence_container_uls[15].element_ul, 13)) 

            sc->order = (0x15 << 24) | AV_RB32(sc->track_essence_element_key+13);

        else

            sc->order = AV_RB32(sc->track_essence_element_key+12);

    }



    if (t = av_dict_get(VAR_0->metadata, "creation_time", NULL, 0))

        timestamp = ff_iso8601_to_unix_time(t->value);

    if (timestamp)

        mxf->timestamp = mxf_parse_timestamp(timestamp);

    mxf->duration = -1;



    mxf->timecode_track = av_mallocz(sizeof(*mxf->timecode_track));

    if (!mxf->timecode_track)

        return AVERROR(ENOMEM);

    mxf->timecode_track->priv_data = av_mallocz(sizeof(MXFStreamContext));

    if (!mxf->timecode_track->priv_data)

        return AVERROR(ENOMEM);

    mxf->timecode_track->index = -1;



    if (!VAR_3)

        VAR_3 = ff_mxf_get_samples_per_frame(VAR_0, (AVRational){ 1, 25 });



    if (ff_audio_interleave_init(VAR_0, VAR_3->samples_per_frame, mxf->time_base) < 0)

        return -1;



    return 0;

}

static int FUNC_0(AVFormatContext *VAR_0)
{ MXFContext *mxf = VAR_0->priv_data; int VAR_1, VAR_2; uint8_t present[FF_ARRAY_ELEMS(mxf_essence_container_uls)] = {0}; const MXFSamplesPerFrame *VAR_3 = NULL; AVDictionaryEntry *t; int64_t timestamp = 0; if (!VAR_0->nb_streams)
return -1; if (VAR_0->oformat == &ff_mxf_opatom_muxer && VAR_0->nb_streams !=1){ av_log(VAR_0, AV_LOG_ERROR, "there must be exactly one stream for mxf opatom\n"); return -1; } for (VAR_1 = 0; VAR_1 < VAR_0->nb_streams; VAR_1++) { AVStream *st = VAR_0->streams[VAR_1]; MXFStreamContext *sc = av_mallocz(sizeof(*sc)); if (!sc)
return AVERROR(ENOMEM); st->priv_data = sc; if (((VAR_1 == 0) ^ (st->codec->codec_type == AVMEDIA_TYPE_VIDEO)) && VAR_0->oformat != &ff_mxf_opatom_muxer) { av_log(VAR_0, AV_LOG_ERROR, "there must be exactly one video stream and it must be the first one\n"); return -1; } if (st->codec->codec_type == AVMEDIA_TYPE_VIDEO) { const AVPixFmtDescriptor *pix_desc = av_pix_fmt_desc_get(st->codec->pix_fmt); AVRational rate, tbc = st->time_base; sc->component_depth = 8; sc->h_chroma_sub_sample = 2; sc->color_siting = 0xFF; if (pix_desc) { sc->component_depth     = pix_desc->comp[0].depth_minus1 + 1; sc->h_chroma_sub_sample = 1 << pix_desc->log2_chroma_w; } switch (ff_choose_chroma_location(VAR_0, st)) { case AVCHROMA_LOC_TOPLEFT: sc->color_siting = 0; break; case AVCHROMA_LOC_LEFT:    sc->color_siting = 6; break; case AVCHROMA_LOC_TOP:     sc->color_siting = 1; break; case AVCHROMA_LOC_CENTER:  sc->color_siting = 3; break; } mxf->timecode_base = (tbc.den + tbc.num/2) / tbc.num; VAR_3 = ff_mxf_get_samples_per_frame(VAR_0, tbc); if (!VAR_3) { av_log(VAR_0, AV_LOG_ERROR, "Unsupported video frame rate %d/%d\n",
tbc.den, tbc.num); return AVERROR(EINVAL); } mxf->time_base = VAR_3->time_base; rate = av_inv_q(mxf->time_base); avpriv_set_pts_info(st, 64, mxf->time_base.num, mxf->time_base.den); if((VAR_2 = mxf_init_timecode(VAR_0, st, rate)) < 0)
return VAR_2; sc->video_bit_rate = st->codec->bit_rate ? st->codec->bit_rate : st->codec->rc_max_rate; if (VAR_0->oformat == &ff_mxf_d10_muxer) { if (sc->video_bit_rate == 50000000) { if (mxf->time_base.den == 25) sc->index = 3; else                          sc->index = 5; } else if (sc->video_bit_rate == 40000000) { if (mxf->time_base.den == 25) sc->index = 7; else                          sc->index = 9; } else if (sc->video_bit_rate == 30000000) { if (mxf->time_base.den == 25) sc->index = 11; else                          sc->index = 13; } else { av_log(VAR_0, AV_LOG_ERROR, "error MXF D-10 only support 30/40/50 mbit/VAR_0\n"); return -1; } mxf->edit_unit_byte_count = KAG_SIZE; mxf->edit_unit_byte_count += 16 + 4 + (uint64_t)sc->video_bit_rate *
mxf->time_base.num / (8*mxf->time_base.den); mxf->edit_unit_byte_count += klv_fill_size(mxf->edit_unit_byte_count); mxf->edit_unit_byte_count += 16 + 4 + 4 + VAR_3->samples_per_frame[0]*8*4; mxf->edit_unit_byte_count += klv_fill_size(mxf->edit_unit_byte_count); sc->signal_standard = 1; } } else if (st->codec->codec_type == AVMEDIA_TYPE_AUDIO) { if (st->codec->sample_rate != 48000) { av_log(VAR_0, AV_LOG_ERROR, "only 48khz is implemented\n"); return -1; } avpriv_set_pts_info(st, 64, 1, st->codec->sample_rate); if (VAR_0->oformat == &ff_mxf_d10_muxer) { if (st->index != 1) { av_log(VAR_0, AV_LOG_ERROR, "MXF D-10 only support one audio track\n"); return -1; } if (st->codec->codec_id != AV_CODEC_ID_PCM_S16LE &&
st->codec->codec_id != AV_CODEC_ID_PCM_S24LE) { av_log(VAR_0, AV_LOG_ERROR, "MXF D-10 only support 16 or 24 bits le audio\n"); } sc->index = ((MXFStreamContext*)VAR_0->streams[0]->priv_data)->index + 1; } else if (VAR_0->oformat == &ff_mxf_opatom_muxer) { AVRational tbc = av_inv_q(mxf->audio_edit_rate); if (st->codec->codec_id != AV_CODEC_ID_PCM_S16LE &&
st->codec->codec_id != AV_CODEC_ID_PCM_S24LE) { av_log(VAR_0, AV_LOG_ERROR, "Only pcm_s16le and pcm_s24le audio codecs are implemented\n"); return AVERROR_PATCHWELCOME; } if (st->codec->channels != 1) { av_log(VAR_0, AV_LOG_ERROR, "MXF OPAtom only supports single channel audio\n"); return AVERROR(EINVAL); } VAR_3 = ff_mxf_get_samples_per_frame(VAR_0, tbc); if (!VAR_3){ av_log(VAR_0, AV_LOG_ERROR, "Unsupported timecode frame rate %d/%d\n", tbc.den, tbc.num); return AVERROR(EINVAL); } mxf->time_base = st->time_base; if((VAR_2 = mxf_init_timecode(VAR_0, st, av_inv_q(VAR_3->time_base))) < 0)
return VAR_2; mxf->timecode_base = (tbc.den + tbc.num/2) / tbc.num; mxf->edit_unit_byte_count = (av_get_bits_per_sample(st->codec->codec_id) * st->codec->channels) >> 3; sc->index = 2; } else { mxf->slice_count = 1; } } if (!sc->index) { sc->index = mxf_get_essence_container_ul_index(st->codec->codec_id); if (sc->index == -1) { av_log(VAR_0, AV_LOG_ERROR, "track %d: could not find essence container ul, "
"codec not currently supported in container\n", VAR_1); return -1; } } sc->codec_ul = &mxf_essence_container_uls[sc->index].codec_ul; memcpy(sc->track_essence_element_key, mxf_essence_container_uls[sc->index].element_ul, 15); sc->track_essence_element_key[15] = present[sc->index]; PRINT_KEY(VAR_0, "track essence element key", sc->track_essence_element_key); if (!present[sc->index])
mxf->essence_container_count++; present[sc->index]++; } if (VAR_0->oformat == &ff_mxf_d10_muxer || VAR_0->oformat == &ff_mxf_opatom_muxer) { mxf->essence_container_count = 1; } if (!(VAR_0->flags & AVFMT_FLAG_BITEXACT))
mxf_gen_umid(VAR_0); for (VAR_1 = 0; VAR_1 < VAR_0->nb_streams; VAR_1++) { MXFStreamContext *sc = VAR_0->streams[VAR_1]->priv_data; sc->track_essence_element_key[13] = present[sc->index]; if (!memcmp(sc->track_essence_element_key, mxf_essence_container_uls[15].element_ul, 13))
sc->order = (0x15 << 24) | AV_RB32(sc->track_essence_element_key+13); else
sc->order = AV_RB32(sc->track_essence_element_key+12); } if (t = av_dict_get(VAR_0->metadata, "creation_time", NULL, 0))
timestamp = ff_iso8601_to_unix_time(t->value); if (timestamp)
mxf->timestamp = mxf_parse_timestamp(timestamp); mxf->duration = -1; mxf->timecode_track = av_mallocz(sizeof(*mxf->timecode_track)); if (!mxf->timecode_track)
return AVERROR(ENOMEM); mxf->timecode_track->priv_data = av_mallocz(sizeof(MXFStreamContext)); if (!mxf->timecode_track->priv_data)
return AVERROR(ENOMEM); mxf->timecode_track->index = -1; if (!VAR_3)
VAR_3 = ff_mxf_get_samples_per_frame(VAR_0, (AVRational){ 1, 25 }); if (ff_audio_interleave_init(VAR_0, VAR_3->samples_per_frame, mxf->time_base) < 0)
return -1; return 0; }