static int mkv_write_trailer(AVFormatContext *s)

{

    MatroskaMuxContext *mkv = s->priv_data;

    AVIOContext *pb = s->pb;

    int64_t currentpos, cuespos;

    int ret;



    // check if we have an audio packet cached

    if (mkv->cur_audio_pkt.size > 0) {

        ret = mkv_write_packet_internal(s, &mkv->cur_audio_pkt, 0);

        av_free_packet(&mkv->cur_audio_pkt);

        if (ret < 0) {

            av_log(s, AV_LOG_ERROR,

                   "Could not write cached audio packet ret:%d\n", ret);

            return ret;

        }

    }



    if (mkv->dyn_bc) {

        end_ebml_master(mkv->dyn_bc, mkv->cluster);

        mkv_flush_dynbuf(s);

    } else if (mkv->cluster_pos != -1) {

        end_ebml_master(pb, mkv->cluster);

    }



    if (mkv->mode != MODE_WEBM) {

        ret = mkv_write_chapters(s);

        if (ret < 0)

            return ret;

    }



    if (pb->seekable) {

        if (mkv->cues->num_entries) {

            if (mkv->reserve_cues_space) {

                int64_t cues_end;



                currentpos = avio_tell(pb);

                avio_seek(pb, mkv->cues_pos, SEEK_SET);



                cuespos  = mkv_write_cues(s, mkv->cues, mkv->tracks, s->nb_streams);

                cues_end = avio_tell(pb);

                if (cues_end > cuespos + mkv->reserve_cues_space) {

                    av_log(s, AV_LOG_ERROR,

                           "Insufficient space reserved for cues: %d "

                           "(needed: %" PRId64 ").\n",

                           mkv->reserve_cues_space, cues_end - cuespos);

                    return AVERROR(EINVAL);

                }



                if (cues_end < cuespos + mkv->reserve_cues_space)

                    put_ebml_void(pb, mkv->reserve_cues_space -

                                  (cues_end - cuespos));



                avio_seek(pb, currentpos, SEEK_SET);

            } else {

                cuespos = mkv_write_cues(s, mkv->cues, mkv->tracks, s->nb_streams);

            }



            ret = mkv_add_seekhead_entry(mkv->main_seekhead, MATROSKA_ID_CUES,

                                         cuespos);

            if (ret < 0)

                return ret;

        }



        mkv_write_seekhead(pb, mkv->main_seekhead);



        // update the duration

        av_log(s, AV_LOG_DEBUG, "end duration = %" PRIu64 "\n", mkv->duration);

        currentpos = avio_tell(pb);

        avio_seek(pb, mkv->duration_offset, SEEK_SET);

        put_ebml_float(pb, MATROSKA_ID_DURATION, mkv->duration);



        // update stream durations

        if (mkv->stream_durations) {

            int i;

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

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

                double duration_sec = mkv->stream_durations[i] * av_q2d(st->time_base);

                char duration_string[20] = "";



                av_log(s, AV_LOG_DEBUG, "stream %d end duration = %" PRIu64 "\n", i,

                       mkv->stream_durations[i]);



                if (!mkv->is_live && mkv->stream_duration_offsets[i] > 0) {

                    avio_seek(pb, mkv->stream_duration_offsets[i], SEEK_SET);



                    snprintf(duration_string, 20, "%02d:%02d:%012.9f",

                             (int) duration_sec / 3600, ((int) duration_sec / 60) % 60,

                             fmod(duration_sec, 60));



                    put_ebml_binary(pb, MATROSKA_ID_TAGSTRING, duration_string, 20);

                }

            }

        }



        avio_seek(pb, currentpos, SEEK_SET);

    }



    if (!mkv->is_live) {

        end_ebml_master(pb, mkv->segment);

    }

    av_freep(&mkv->tracks);

    av_freep(&mkv->cues->entries);

    av_freep(&mkv->cues);

    av_freep(&mkv->stream_durations);

    av_freep(&mkv->stream_duration_offsets);



    return 0;

}

static int mkv_write_trailer(AVFormatContext *s)

{

    MatroskaMuxContext *mkv = s->priv_data;

    AVIOContext *pb = s->pb;

    int64_t currentpos, cuespos;

    int ret;



    

    if (mkv->cur_audio_pkt.size > 0) {

        ret = mkv_write_packet_internal(s, &mkv->cur_audio_pkt, 0);

        av_free_packet(&mkv->cur_audio_pkt);

        if (ret < 0) {

            av_log(s, AV_LOG_ERROR,

                   "Could not write cached audio packet ret:%d\n", ret);

            return ret;

        }

    }



    if (mkv->dyn_bc) {

        end_ebml_master(mkv->dyn_bc, mkv->cluster);

        mkv_flush_dynbuf(s);

    } else if (mkv->cluster_pos != -1) {

        end_ebml_master(pb, mkv->cluster);

    }



    if (mkv->mode != MODE_WEBM) {

        ret = mkv_write_chapters(s);

        if (ret < 0)

            return ret;

    }



    if (pb->seekable) {

        if (mkv->cues->num_entries) {

            if (mkv->reserve_cues_space) {

                int64_t cues_end;



                currentpos = avio_tell(pb);

                avio_seek(pb, mkv->cues_pos, SEEK_SET);



                cuespos  = mkv_write_cues(s, mkv->cues, mkv->tracks, s->nb_streams);

                cues_end = avio_tell(pb);

                if (cues_end > cuespos + mkv->reserve_cues_space) {

                    av_log(s, AV_LOG_ERROR,

                           "Insufficient space reserved for cues: %d "

                           "(needed: %" PRId64 ").\n",

                           mkv->reserve_cues_space, cues_end - cuespos);

                    return AVERROR(EINVAL);

                }



                if (cues_end < cuespos + mkv->reserve_cues_space)

                    put_ebml_void(pb, mkv->reserve_cues_space -

                                  (cues_end - cuespos));



                avio_seek(pb, currentpos, SEEK_SET);

            } else {

                cuespos = mkv_write_cues(s, mkv->cues, mkv->tracks, s->nb_streams);

            }



            ret = mkv_add_seekhead_entry(mkv->main_seekhead, MATROSKA_ID_CUES,

                                         cuespos);

            if (ret < 0)

                return ret;

        }



        mkv_write_seekhead(pb, mkv->main_seekhead);



        

        av_log(s, AV_LOG_DEBUG, "end duration = %" PRIu64 "\n", mkv->duration);

        currentpos = avio_tell(pb);

        avio_seek(pb, mkv->duration_offset, SEEK_SET);

        put_ebml_float(pb, MATROSKA_ID_DURATION, mkv->duration);



        

        if (mkv->stream_durations) {

            int i;

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

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

                double duration_sec = mkv->stream_durations[i] * av_q2d(st->time_base);

                char duration_string[20] = "";



                av_log(s, AV_LOG_DEBUG, "stream %d end duration = %" PRIu64 "\n", i,

                       mkv->stream_durations[i]);



                if (!mkv->is_live && mkv->stream_duration_offsets[i] > 0) {

                    avio_seek(pb, mkv->stream_duration_offsets[i], SEEK_SET);



                    snprintf(duration_string, 20, "%02d:%02d:%012.9f",

                             (int) duration_sec / 3600, ((int) duration_sec / 60) % 60,

                             fmod(duration_sec, 60));



                    put_ebml_binary(pb, MATROSKA_ID_TAGSTRING, duration_string, 20);

                }

            }

        }



        avio_seek(pb, currentpos, SEEK_SET);

    }



    if (!mkv->is_live) {

        end_ebml_master(pb, mkv->segment);

    }

    av_freep(&mkv->tracks);

    av_freep(&mkv->cues->entries);

    av_freep(&mkv->cues);

    av_freep(&mkv->stream_durations);

    av_freep(&mkv->stream_duration_offsets);



    return 0;

}

            return ret;             return ret;             return ret;         mkv_write_seekhead(pb, mkv->main_seekhead);         mkv_write_seekhead(pb, mkv->main_seekhead);     av_freep(&mkv->tracks);     av_freep(&mkv->cues->entries);     av_freep(&mkv->cues);     av_freep(&mkv->stream_durations);     av_freep(&mkv->stream_duration_offsets);
static int FUNC_0(AVFormatContext *VAR_0)

{

    MatroskaMuxContext *mkv = VAR_0->priv_data;

    AVIOContext *pb = VAR_0->pb;

    int64_t currentpos, cuespos;

    int VAR_1;



    

    if (mkv->cur_audio_pkt.size > 0) {

        VAR_1 = mkv_write_packet_internal(VAR_0, &mkv->cur_audio_pkt, 0);

        av_free_packet(&mkv->cur_audio_pkt);

        if (VAR_1 < 0) {

            av_log(VAR_0, AV_LOG_ERROR,

                   "Could not write cached audio packet VAR_1:%d\n", VAR_1);

            return VAR_1;

        }

    }



    if (mkv->dyn_bc) {

        end_ebml_master(mkv->dyn_bc, mkv->cluster);

        mkv_flush_dynbuf(VAR_0);

    } else if (mkv->cluster_pos != -1) {

        end_ebml_master(pb, mkv->cluster);

    }



    if (mkv->mode != MODE_WEBM) {

        VAR_1 = mkv_write_chapters(VAR_0);

        if (VAR_1 < 0)

            return VAR_1;

    }



    if (pb->seekable) {

        if (mkv->cues->num_entries) {

            if (mkv->reserve_cues_space) {

                int64_t cues_end;



                currentpos = avio_tell(pb);

                avio_seek(pb, mkv->cues_pos, SEEK_SET);



                cuespos  = mkv_write_cues(VAR_0, mkv->cues, mkv->tracks, VAR_0->nb_streams);

                cues_end = avio_tell(pb);

                if (cues_end > cuespos + mkv->reserve_cues_space) {

                    av_log(VAR_0, AV_LOG_ERROR,

                           "Insufficient space reserved for cues: %d "

                           "(needed: %" PRId64 ").\n",

                           mkv->reserve_cues_space, cues_end - cuespos);

                    return AVERROR(EINVAL);

                }



                if (cues_end < cuespos + mkv->reserve_cues_space)

                    put_ebml_void(pb, mkv->reserve_cues_space -

                                  (cues_end - cuespos));



                avio_seek(pb, currentpos, SEEK_SET);

            } else {

                cuespos = mkv_write_cues(VAR_0, mkv->cues, mkv->tracks, VAR_0->nb_streams);

            }



            VAR_1 = mkv_add_seekhead_entry(mkv->main_seekhead, MATROSKA_ID_CUES,

                                         cuespos);

            if (VAR_1 < 0)

                return VAR_1;

        }



        mkv_write_seekhead(pb, mkv->main_seekhead);



        

        av_log(VAR_0, AV_LOG_DEBUG, "end duration = %" PRIu64 "\n", mkv->duration);

        currentpos = avio_tell(pb);

        avio_seek(pb, mkv->duration_offset, SEEK_SET);

        put_ebml_float(pb, MATROSKA_ID_DURATION, mkv->duration);



        

        if (mkv->stream_durations) {

            int VAR_2;

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

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

                double duration_sec = mkv->stream_durations[VAR_2] * av_q2d(st->time_base);

                char duration_string[20] = "";



                av_log(VAR_0, AV_LOG_DEBUG, "stream %d end duration = %" PRIu64 "\n", VAR_2,

                       mkv->stream_durations[VAR_2]);



                if (!mkv->is_live && mkv->stream_duration_offsets[VAR_2] > 0) {

                    avio_seek(pb, mkv->stream_duration_offsets[VAR_2], SEEK_SET);



                    snprintf(duration_string, 20, "%02d:%02d:%012.9f",

                             (int) duration_sec / 3600, ((int) duration_sec / 60) % 60,

                             fmod(duration_sec, 60));



                    put_ebml_binary(pb, MATROSKA_ID_TAGSTRING, duration_string, 20);

                }

            }

        }



        avio_seek(pb, currentpos, SEEK_SET);

    }



    if (!mkv->is_live) {

        end_ebml_master(pb, mkv->segment);

    }

    av_freep(&mkv->tracks);

    av_freep(&mkv->cues->entries);

    av_freep(&mkv->cues);

    av_freep(&mkv->stream_durations);

    av_freep(&mkv->stream_duration_offsets);



    return 0;

}

static int FUNC_0(AVFormatContext *VAR_0)
{ MatroskaMuxContext *mkv = VAR_0->priv_data; AVIOContext *pb = VAR_0->pb; int64_t currentpos, cuespos; int VAR_1; if (mkv->cur_audio_pkt.size > 0) { VAR_1 = mkv_write_packet_internal(VAR_0, &mkv->cur_audio_pkt, 0); av_free_packet(&mkv->cur_audio_pkt); if (VAR_1 < 0) { av_log(VAR_0, AV_LOG_ERROR,
"Could not write cached audio packet VAR_1:%d\n", VAR_1); return VAR_1; } } if (mkv->dyn_bc) { end_ebml_master(mkv->dyn_bc, mkv->cluster); mkv_flush_dynbuf(VAR_0); } else if (mkv->cluster_pos != -1) { end_ebml_master(pb, mkv->cluster); } if (mkv->mode != MODE_WEBM) { VAR_1 = mkv_write_chapters(VAR_0); if (VAR_1 < 0)
return VAR_1; } if (pb->seekable) { if (mkv->cues->num_entries) { if (mkv->reserve_cues_space) { int64_t cues_end; currentpos = avio_tell(pb); avio_seek(pb, mkv->cues_pos, SEEK_SET); cuespos  = mkv_write_cues(VAR_0, mkv->cues, mkv->tracks, VAR_0->nb_streams); cues_end = avio_tell(pb); if (cues_end > cuespos + mkv->reserve_cues_space) { av_log(VAR_0, AV_LOG_ERROR,
"Insufficient space reserved for cues: %d "
"(needed: %" PRId64 ").\n",
mkv->reserve_cues_space, cues_end - cuespos); return AVERROR(EINVAL); } if (cues_end < cuespos + mkv->reserve_cues_space)
put_ebml_void(pb, mkv->reserve_cues_space -
(cues_end - cuespos)); avio_seek(pb, currentpos, SEEK_SET); } else { cuespos = mkv_write_cues(VAR_0, mkv->cues, mkv->tracks, VAR_0->nb_streams); } VAR_1 = mkv_add_seekhead_entry(mkv->main_seekhead, MATROSKA_ID_CUES,
cuespos); if (VAR_1 < 0)
return VAR_1; } mkv_write_seekhead(pb, mkv->main_seekhead); av_log(VAR_0, AV_LOG_DEBUG, "end duration = %" PRIu64 "\n", mkv->duration); currentpos = avio_tell(pb); avio_seek(pb, mkv->duration_offset, SEEK_SET); put_ebml_float(pb, MATROSKA_ID_DURATION, mkv->duration); if (mkv->stream_durations) { int VAR_2; for (VAR_2 = 0; VAR_2 < VAR_0->nb_streams; ++VAR_2) { AVStream *st = VAR_0->streams[VAR_2]; double duration_sec = mkv->stream_durations[VAR_2] * av_q2d(st->time_base); char duration_string[20] = ""; av_log(VAR_0, AV_LOG_DEBUG, "stream %d end duration = %" PRIu64 "\n", VAR_2,
mkv->stream_durations[VAR_2]); if (!mkv->is_live && mkv->stream_duration_offsets[VAR_2] > 0) { avio_seek(pb, mkv->stream_duration_offsets[VAR_2], SEEK_SET); snprintf(duration_string, 20, "%02d:%02d:%012.9f",
(int) duration_sec / 3600, ((int) duration_sec / 60) % 60,
fmod(duration_sec, 60)); put_ebml_binary(pb, MATROSKA_ID_TAGSTRING, duration_string, 20); } } } avio_seek(pb, currentpos, SEEK_SET); } if (!mkv->is_live) { end_ebml_master(pb, mkv->segment); } av_freep(&mkv->tracks); av_freep(&mkv->cues->entries); av_freep(&mkv->cues); av_freep(&mkv->stream_durations); av_freep(&mkv->stream_duration_offsets); return 0; }